You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2022/10/22 00:38:25 UTC

[brooklyn-server] 01/02: add fail and goto steps, and accept step as keyword for shorthand

This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit 7fce67194f261d2b41cfd4b508170bad21216cc8
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Sat Oct 22 01:29:23 2022 +0100

    add fail and goto steps, and accept step as keyword for shorthand
---
 .../core/workflow/WorkflowStepResolution.java      |  7 +-
 .../core/workflow/steps/FailWorkflowStep.java      | 77 ++++++++++++++++++++++
 .../core/workflow/steps/GotoWorkflowStep.java      | 51 ++++++++++++++
 .../brooklyn/core/workflow/WorkflowBasicTest.java  |  2 +
 .../workflow/WorkflowInputOutputExtensionTest.java |  7 +-
 .../workflow/WorkflowPersistReplayErrorsTest.java  | 12 ++++
 karaf/init/src/main/resources/catalog.bom          | 10 +++
 7 files changed, 159 insertions(+), 7 deletions(-)

diff --git a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepResolution.java b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepResolution.java
index 464f7f217f..b38667f315 100644
--- a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepResolution.java
+++ b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepResolution.java
@@ -57,13 +57,14 @@ public class WorkflowStepResolution {
             defM = MutableMap.copyOf((Map)def);
             if (!defM.containsKey("type")) {
                 // if there isn't a type, pull out shorthand
-                Object s = defM.remove("shorthand");
+                Object s = defM.remove("step");
+                if (s == null) s = defM.remove("shorthand");
                 if (s == null) s = defM.remove("s");
                 if (s == null) {
-                    throw new IllegalArgumentException("Step definition must indicate a `type` or a `shorthand` / `s`");
+                    throw new IllegalArgumentException("Step definition must indicate a `type` or a `step` / `shorthand` / `s`");
                 }
                 if (!(s instanceof String)) {
-                    throw new IllegalArgumentException("shorthand must be a string");
+                    throw new IllegalArgumentException("step shorthand must be a string");
                 }
                 shorthand = (String) s;
             }
diff --git a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/FailWorkflowStep.java b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/FailWorkflowStep.java
new file mode 100644
index 0000000000..95b4698c58
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/FailWorkflowStep.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.workflow.steps;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.sun.org.apache.bcel.internal.generic.RET;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
+import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
+import org.apache.brooklyn.util.text.Strings;
+
+public class FailWorkflowStep extends WorkflowStepDefinition {
+
+    public static final String SHORTHAND = "[ ?${rethrow} \"rethrow\" ] [ \"message\" ${message...} ]";
+
+    public static final ConfigKey<Boolean> RETHROW = ConfigKeys.newBooleanConfigKey("rethrow");
+    public static final ConfigKey<String> MESSAGE = ConfigKeys.newStringConfigKey("message");
+
+    @Override
+    public void populateFromShorthand(String expression) {
+        populateFromShorthandTemplate(SHORTHAND, expression);
+    }
+
+    @Override
+    protected Object doTaskBody(WorkflowStepInstanceExecutionContext context) {
+        Boolean rethrow = context.getInput(RETHROW);
+        String message = context.getInput(MESSAGE);
+        boolean hasError = context.getError() != null;
+        Throwable cause = context.getError();
+        if (cause==null && Boolean.TRUE.equals(rethrow)) cause = new IllegalArgumentException("Fail specified with rethrow but no contextual error available");
+        if (Boolean.FALSE.equals(rethrow)) cause = null;
+
+        if (Strings.isBlank(message) && cause instanceof RuntimeException) {
+            throw (RuntimeException) cause;
+        }
+        if (Strings.isBlank(message) && cause instanceof Error) {
+            throw (Error) cause;
+        }
+
+        throw new WorkflowFailException(message, cause);
+    }
+
+
+    public static class WorkflowFailException extends RuntimeException {
+        public WorkflowFailException() {
+        }
+
+        public WorkflowFailException(String message) {
+            super(message);
+        }
+
+        public WorkflowFailException(String message, Throwable cause) {
+            super(message, cause);
+        }
+
+        public WorkflowFailException(Throwable cause) {
+            super(cause);
+        }
+    }
+}
diff --git a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/GotoWorkflowStep.java b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/GotoWorkflowStep.java
new file mode 100644
index 0000000000..73b72f010b
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/GotoWorkflowStep.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.workflow.steps;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
+import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
+
+public class GotoWorkflowStep extends WorkflowStepDefinition {
+
+    public static final String SHORTHAND = "${next}";
+
+    @Override
+    public void populateFromShorthand(String expression) {
+        populateFromShorthandTemplate(SHORTHAND, expression);
+        Object next = input.remove("next");
+        if (next instanceof String) { this.next = (String)next; }
+        else throw new IllegalArgumentException("Shorthand should point to the next step");
+    }
+
+    @JsonIgnore
+    @Override
+    public String getNext() {
+        if (next==null) throw new IllegalStateException("next is required for goto step");
+        return next;
+    }
+
+    @Override
+    protected Object doTaskBody(WorkflowStepInstanceExecutionContext context) {
+        return context.getPreviousStepOutput();
+    }
+
+}
diff --git a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java
index 073b477c2f..86cc36012d 100644
--- a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java
@@ -89,6 +89,8 @@ public class WorkflowBasicTest extends BrooklynMgmtUnitTestSupport {
         addRegisteredTypeBean(mgmt, "clear-workflow-variable", ClearVariableWorkflowStep.class);
         addRegisteredTypeBean(mgmt, "wait", WaitWorkflowStep.class);
         addRegisteredTypeBean(mgmt, "return", ReturnWorkflowStep.class);
+        addRegisteredTypeBean(mgmt, "goto", GotoWorkflowStep.class);
+        addRegisteredTypeBean(mgmt, "fail", FailWorkflowStep.class);
         addRegisteredTypeBean(mgmt, "invoke-effector", InvokeEffectorWorkflowStep.class);
 
         addRegisteredTypeBean(mgmt, "retry", RetryWorkflowStep.class);
diff --git a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowInputOutputExtensionTest.java b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowInputOutputExtensionTest.java
index 43e9cf732a..13ed23191e 100644
--- a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowInputOutputExtensionTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowInputOutputExtensionTest.java
@@ -315,15 +315,14 @@ public class WorkflowInputOutputExtensionTest extends BrooklynMgmtUnitTestSuppor
     public void testAccessLocalOutput() throws Exception {
         Object output = invokeWorkflowStepsWithLogging(MutableList.of(
                 MutableMap.of("id" , "l1",
-                        "s", "let x = ${x} + ${workflow.step.l1.output.prev} ?? 1",
+                        "step", "let x = ${x} + ${workflow.step.l1.output.prev} ?? 1",
                         "output", MutableMap.of("prev", "${x}")),
                 "log ${x}",
                 MutableMap.of(
-                        "s", "let x = ${x} + 2 * ${prev}",
+                        "step", "let x = ${x} + 2 * ${prev}",
                         "output", MutableMap.of("prev", "${x}")),
                 "log ${x}",
-                MutableMap.of("type" , "no-op",
-                        "next", "l1",
+                MutableMap.of("step" , "goto l1",
                         "condition", MutableMap.of("target", "${x}", "less-than", 10)),
                 "return ${workflow.step.l1.output.prev}"
         ));
diff --git a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowPersistReplayErrorsTest.java b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowPersistReplayErrorsTest.java
index b68d8bbb83..3c86216a9e 100644
--- a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowPersistReplayErrorsTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowPersistReplayErrorsTest.java
@@ -659,4 +659,16 @@ public class WorkflowPersistReplayErrorsTest extends RebindTestFixture<BasicAppl
         );
     }
 
+    @Test
+    public void testFail() {
+        Task<?> out = runSteps(
+                MutableList.of("fail message wtf"),
+                null,
+                ConfigBag.newInstance().configure(WorkflowCommonConfig.ON_ERROR,
+                        MutableList.of(MutableMap.of("step", "return Yay WTF",
+                                "condition", MutableMap.of("error-cause", MutableMap.of("regex", ".*Fail.*wtf.*")))))
+        );
+        Asserts.assertEquals(out.getUnchecked(), "Yay WTF");
+    }
+
 }
diff --git a/karaf/init/src/main/resources/catalog.bom b/karaf/init/src/main/resources/catalog.bom
index 5242ed6e58..bd9472ea1d 100644
--- a/karaf/init/src/main/resources/catalog.bom
+++ b/karaf/init/src/main/resources/catalog.bom
@@ -134,6 +134,16 @@ brooklyn.catalog:
     itemType: bean
     item:
       type: org.apache.brooklyn.core.workflow.steps.ReturnWorkflowStep
+  - id: goto
+    format: java-type-name
+    itemType: bean
+    item:
+      type: org.apache.brooklyn.core.workflow.steps.GotoWorkflowStep
+  - id: fail
+    format: java-type-name
+    itemType: bean
+    item:
+      type: org.apache.brooklyn.core.workflow.steps.FailWorkflowStep
 
   - id: workflow
     format: java-type-name