infer type as a subworkflow step if `step` is omitted but `steps` are supplied
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 f154d92..302ef61 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 @@
}
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 2d17c6c..e127e78 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,19 +97,21 @@
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 && 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==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 dc6fe61..6431170 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 @@
@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");
}
}