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 72784da3f0a2276f92f3e1df1fd62afdbf6bc0c1
Author: Alex Heneveld <a...@cloudsoft.io>
AuthorDate: Tue Feb 13 09:51:24 2024 +0000

    infer type as a subworkflow step if `step` is omitted but `steps` are 
supplied
---
 .../core/workflow/WorkflowExecutionContext.java    |  3 ++-
 .../core/workflow/WorkflowStepResolution.java      | 26 ++++++++++++----------
 .../WorkflowSubAndCustomExtensionEdgeTest.java     | 25 ++++++++++++++++-----
 3 files changed, 35 insertions(+), 19 deletions(-)

diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExecutionContext.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExecutionContext.java
index f154d92df3..302ef6144e 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExecutionContext.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExecutionContext.java
@@ -557,7 +557,8 @@ public class WorkflowExecutionContext {
                     }
                     log.debug("Request to replay resuming " + 
WorkflowExecutionContext.this + " at non-idempotent step; rolling back to " + 
replayableLastStep);
                     if (replayableLastStep == null) {
-                        throw new IllegalArgumentException("Cannot replay 
resuming as there are no replay points and last step " + currentStepIndex + " 
is not idempotent");
+                        throw new IllegalArgumentException("Cannot replay 
resuming as there are no replay points and last step " + currentStepIndex + " 
is not idempotent; " +
+                                "should that step or a previous one declare 
'idempotent: true' or 'replayable: from here' ?");
                     }
                     return 
makeInstructionsForReplayingFromStep(replayableLastStep, reason, false);
                 }
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 2d17c6cdf3..e127e782fa 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
@@ -97,20 +97,22 @@ public class WorkflowStepResolution {
                 Object s = defM.remove("step");
                 if (s == null) s = defM.remove("shorthand");
                 if (s == null) s = defM.remove("s");
-                if (s == null) {
-                    if (defM.size()==1) {
-                        // assume the colon caused it accidentally to be a map
-                        s = Iterables.getOnlyElement(defM.keySet());
-                        if (s instanceof String && ((String)s).contains(" ")) {
-                            s = s + " : " + 
Iterables.getOnlyElement(defM.values());
-                        } else {
-                            s = null;
-                        }
-                    }
-                    if (s==null) {
-                        throw new IllegalArgumentException("Step definition 
must indicate a `type` or a `step` / `shorthand` / `s` (" + def + ")");
+                if (s==null && defM.containsKey("steps")) {
+                    // if it has steps, but no step or s, assume it is a 
subworkflow
+                    s = "subworkflow";
+                }
+                if (s == null && defM.size()==1) {
+                    // assume the colon caused it accidentally to be a map
+                    s = Iterables.getOnlyElement(defM.keySet());
+                    if (s instanceof String && ((String)s).contains(" ")) {
+                        s = s + " : " + 
Iterables.getOnlyElement(defM.values());
+                    } else {
+                        s = null;
                     }
                 }
+                if (s==null) {
+                    throw new IllegalArgumentException("Step definition must 
indicate a `type` or a `step` / `shorthand` / `s` (" + def + ")");
+                }
                 if (!(s instanceof String)) {
                     throw new IllegalArgumentException("step shorthand must be 
a string");
                 }
diff --git 
a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowSubAndCustomExtensionEdgeTest.java
 
b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowSubAndCustomExtensionEdgeTest.java
index dc6fe61ffc..6431170142 100644
--- 
a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowSubAndCustomExtensionEdgeTest.java
+++ 
b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowSubAndCustomExtensionEdgeTest.java
@@ -143,18 +143,31 @@ public class WorkflowSubAndCustomExtensionEdgeTest 
extends RebindTestFixture<Tes
 
     @Test
     public void testSubWorkflowStep() throws Exception {
+        MutableList<String> steps = MutableList.of(
+                "let v0 = ${v0}B",
+                "let v1 = ${v1}B",
+                "let v3 = V3B",
+                "return done");
         runWorkflow(MutableList.of(
                 "let v1 = V1",
                 "let v2 = V2",
-                MutableMap.of("step", "subworkflow",
-                    "steps", MutableList.of(
-                            "let v0 = ${v0}B",
-                            "let v1 = ${v1}B",
-                            "let v3 = V3B",
-                            "return done")),
+                MutableMap.of(
+                        "step", "subworkflow",
+                    "steps", steps),
                 "return ${v0}-${v1}-${v2}-${v3}-${output}"),
                 ConfigBag.newInstance().configure(WorkflowCommonConfig.INPUT, 
MutableMap.of("v0", "V0")) );
         Asserts.assertEquals(lastInvocation.getUnchecked(), 
"V0B-V1B-V2-V3B-done");
+
+        // subworkflow is chosen implicitly if step is omitted
+        runWorkflow(MutableList.of(
+                        "let v1 = V1",
+                        "let v2 = V2",
+                        MutableMap.of(
+                                //"step", "subworkflow",
+                                "steps", steps),
+                        "return ${v0}-${v1}-${v2}-${v3}-${output}"),
+                ConfigBag.newInstance().configure(WorkflowCommonConfig.INPUT, 
MutableMap.of("v0", "V0")) );
+        Asserts.assertEquals(lastInvocation.getUnchecked(), 
"V0B-V1B-V2-V3B-done");
     }
 
 }

Reply via email to