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 2bca22a8fa5ad1407e4942c8d499d61db2ad7c43
Author: Alex Heneveld <a...@cloudsoft.io>
AuthorDate: Mon Feb 26 11:33:52 2024 +0000

    make more context for workflow step resolution
    
    and better errors if cannot resolve
---
 .../jackson/ObjectReferencingSerialization.java    |  5 +++-
 .../core/workflow/WorkflowExecutionContext.java    |  5 ++--
 .../core/workflow/WorkflowStepDefinition.java      |  3 +--
 .../core/workflow/WorkflowStepResolution.java      | 30 ++++++++++++++++++----
 .../core/workflow/steps/CustomWorkflowStep.java    |  7 +++--
 .../steps/appmodel/AddEntityWorkflowStep.java      | 14 +++-------
 .../steps/appmodel/AddPolicyWorkflowStep.java      | 10 +++-----
 .../appmodel/ApplyInitializerWorkflowStep.java     | 10 +++-----
 .../steps/appmodel/DeleteEntityWorkflowStep.java   |  8 ++----
 .../steps/appmodel/DeletePolicyWorkflowStep.java   |  8 ++----
 .../appmodel/DeployApplicationWorkflowStep.java    | 13 +++-------
 .../steps/appmodel/HasBlueprintWorkflowStep.java   |  3 ++-
 .../steps/appmodel/InvokeEffectorWorkflowStep.java |  7 ++---
 .../steps/appmodel/ReparentEntityWorkflowStep.java |  7 ++---
 .../steps/appmodel/UpdateChildrenWorkflowStep.java |  7 +++--
 .../core/workflow/steps/flow/GotoWorkflowStep.java | 12 +++------
 .../workflow/steps/flow/RetryWorkflowStep.java     |  6 ++---
 .../workflow/steps/flow/SwitchWorkflowStep.java    |  8 +++---
 .../workflow/steps/variables/LoadWorkflowStep.java |  8 +++---
 .../steps/variables/SetVariableWorkflowStep.java   |  8 +++---
 .../variables/TransformVariableWorkflowStep.java   |  8 +++---
 .../rest/resources/ApplicationResourceTest.java    |  4 +--
 22 files changed, 81 insertions(+), 110 deletions(-)

diff --git 
a/core/src/main/java/org/apache/brooklyn/core/resolve/jackson/ObjectReferencingSerialization.java
 
b/core/src/main/java/org/apache/brooklyn/core/resolve/jackson/ObjectReferencingSerialization.java
index 9d3af1c773..6ad6990ec4 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/resolve/jackson/ObjectReferencingSerialization.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/resolve/jackson/ObjectReferencingSerialization.java
@@ -180,7 +180,10 @@ public class ObjectReferencingSerialization {
                         // but so long as this deserializer is preferred which 
it normally is, losing the alias reference is okay.
                         Maybe resultCoerced = ((Maybe) 
TypeCoercions.tryCoerce(result, TypeToken.of(expected)));
                         if (resultCoerced.isAbsent()) {
-                            // not uncommon when we are trying to deserialize 
in a few different ways, or if we are using a string deserializer because the 
json input is a string
+                            // not uncommon when we are trying to deserialize 
in a few different ways, or if we are using a string deserializer because the 
json input is a string;
+                            // however it can be useful, to explain why some 
things aren't coercing via BeanWithTypeUtils.convert.
+                            // caller can do 'tryCoerce' to explain.
+
 //                            if (LOG.isDebugEnabled()) LOG.debug("Reference 
to "+result+" when deserialization could not be coerced to expected type 
"+expected+"; proceeding but might cause errors");
                         }
                         return resultCoerced.or(result);
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 a26febbd3e..8cffdcbcc3 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
@@ -42,7 +42,6 @@ import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
 import org.apache.brooklyn.core.resolve.jackson.JsonPassThroughDeserializer;
 import org.apache.brooklyn.core.sensor.Sensors;
 import org.apache.brooklyn.core.typereg.RegisteredTypes;
-import 
org.apache.brooklyn.core.workflow.steps.flow.FailWorkflowStep.WorkflowFailException;
 import org.apache.brooklyn.core.workflow.store.WorkflowRetentionAndExpiration;
 import 
org.apache.brooklyn.core.workflow.store.WorkflowStatePersistenceViaSensors;
 import org.apache.brooklyn.core.workflow.utils.WorkflowRetentionParser;
@@ -391,9 +390,9 @@ public class WorkflowExecutionContext {
         return parent;
     }
 
-    public static void validateSteps(ManagementContext mgmt, 
List<WorkflowStepDefinition> steps, boolean alreadyValidatedIndividualSteps) {
+    public static void validateSteps(WorkflowStepResolution 
workflowStepResolution, List<WorkflowStepDefinition> steps, boolean 
alreadyValidatedIndividualSteps) {
         if (!alreadyValidatedIndividualSteps) {
-            steps.forEach(w -> w.validateStep(mgmt, null));
+            steps.forEach(w -> w.validateStep(workflowStepResolution));
         }
 
         computeStepsWithExplicitIdById(steps);
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepDefinition.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepDefinition.java
index 3a5ab6b530..e3f17c9d88 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepDefinition.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepDefinition.java
@@ -43,7 +43,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
@@ -322,7 +321,7 @@ public abstract class WorkflowStepDefinition {
     /**
      * allows subclasses to throw exception early if required fields not set
      */
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
         validateReplayableAndIdempotent();
     }
 
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 358687a048..cbcff72f17 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
@@ -39,6 +39,7 @@ import 
org.apache.brooklyn.core.workflow.steps.flow.SubWorkflowStep;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.core.task.Tasks;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
@@ -107,7 +108,7 @@ public class WorkflowStepResolution {
                 throw Exceptions.propagateAnnotated("Error in definition of 
step "+(i+1)+" ("+steps.get(i)+")", e);
             }
         }
-        WorkflowExecutionContext.validateSteps(mgmt(), result, true);
+        WorkflowExecutionContext.validateSteps(this, result, true);
         return result;
     }
 
@@ -128,6 +129,8 @@ public class WorkflowStepResolution {
         return result;
     }
 
+    static boolean inCoercionErrorBlock = false;
+
     public WorkflowStepDefinition resolveStep(Object def) {
         if (def instanceof WorkflowStepDefinition) return 
(WorkflowStepDefinition) def;
 
@@ -200,9 +203,26 @@ public class WorkflowStepResolution {
         try {
             Object def0 = defM !=null ? defM : def;
 
-            // if it's unable to convert a complex type via the above, the 
original type will be returned; the above doesn't fail.
-            // this is checked below so it's not a serious error, but the 
reason for it might be obscured.
-            Callable<Object> converter = () -> 
BeanWithTypeUtils.convert(mgmt(), def0, 
TypeToken.of(WorkflowStepDefinition.class), true, loader, true);
+            Callable<Object> converter = () -> {
+                Object result = BeanWithTypeUtils.convert(mgmt(), def0, 
TypeToken.of(WorkflowStepDefinition.class), true, loader, true);
+                if (!(result instanceof WorkflowStepDefinition)) {
+                    // if it's unable to convert a complex type via the above, 
the original type may be returned,
+                    // in particular by ObjectReferencingSerialization; so the 
conversion doesn't report failure,
+                    // and the actual failure is masked by 
ObjectReferencingSerialization
+                    if (!inCoercionErrorBlock) {
+                        inCoercionErrorBlock = true;
+                        try {
+                            return TypeCoercions.tryCoerce(def0, 
WorkflowStepDefinition.class).get();
+                        } finally {
+                            inCoercionErrorBlock = false;
+                        }
+                    }
+                    // prefer above to give a better error -- but need to 
prevent recursion (NBD not thread safe, just won't always get best error)
+                    throw new IllegalArgumentException("Cannot convert 
"+def0+" to workflow step; either wrong step input or insufficient context");
+                }
+
+                return result;
+            };
             Entity entity = entity();
             if (entity==null) {
                 def = converter.call();
@@ -236,7 +256,7 @@ public class WorkflowStepResolution {
                 defW.onError = resolveSubSteps("error handling", onError);
             }
 
-            defW.validateStep(mgmt(), null);
+            defW.validateStep(this);
 
             return defW;
         } else {
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/CustomWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/CustomWorkflowStep.java
index a7c766f339..ddfc6d9f17 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/CustomWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/CustomWorkflowStep.java
@@ -57,7 +57,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
@@ -176,12 +175,12 @@ public class CustomWorkflowStep extends 
WorkflowStepDefinition implements Workfl
     protected Map<String,Object> reducing;
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
 
         if (steps instanceof List) {
             if (steps.isEmpty()) throw new IllegalArgumentException("Workflow 
`steps` must be supplied for a custom or nested workflow");
-            new WorkflowStepResolution(mgmt, null, 
workflow).resolveSteps(steps, null);
+            workflowStepResolution.resolveSteps(steps, null);
         } else if (steps!=null) throw new IllegalArgumentException("Workflow 
`steps` must be a list");
         else if (target!=null) throw new IllegalArgumentException("Workflow 
cannot take a `target` without `steps`");
     }
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/AddEntityWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/AddEntityWorkflowStep.java
index 4713391a9f..667c164d44 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/AddEntityWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/AddEntityWorkflowStep.java
@@ -19,7 +19,6 @@
 package org.apache.brooklyn.core.workflow.steps.appmodel;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -37,25 +36,20 @@ import org.apache.brooklyn.core.entity.trait.Startable;
 import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
 import org.apache.brooklyn.core.mgmt.internal.EntityManagerInternal;
 import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils;
-import org.apache.brooklyn.core.resolve.jackson.JsonPassThroughDeserializer;
-import org.apache.brooklyn.core.workflow.WorkflowExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
 import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
+import org.apache.brooklyn.core.workflow.WorkflowStepResolution;
 import 
org.apache.brooklyn.core.workflow.steps.appmodel.DeployApplicationWorkflowStep.StartMode;
-import 
org.apache.brooklyn.core.workflow.steps.variables.SetVariableWorkflowStep;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.text.TemplateProcessor;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.text.Identifiers;
-import org.apache.brooklyn.util.text.StringEscapes;
 import org.apache.brooklyn.util.text.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
 import java.util.List;
 import java.util.Map;
 
@@ -82,9 +76,9 @@ public class AddEntityWorkflowStep extends 
WorkflowStepDefinition implements Has
     }
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
-        validateStepBlueprint(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
+        validateStepBlueprint(workflowStepResolution);
     }
 
     @Override
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/AddPolicyWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/AddPolicyWorkflowStep.java
index d941d8c9fa..f27c481054 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/AddPolicyWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/AddPolicyWorkflowStep.java
@@ -21,7 +21,6 @@ package org.apache.brooklyn.core.workflow.steps.appmodel;
 import com.google.common.collect.Iterables;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.objs.BrooklynObject;
 import org.apache.brooklyn.api.objs.BrooklynObjectType;
 import org.apache.brooklyn.api.objs.EntityAdjunct;
@@ -29,7 +28,6 @@ import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.entity.EntityAdjuncts;
 import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils;
-import org.apache.brooklyn.core.workflow.WorkflowExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
 import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowStepResolution;
@@ -43,8 +41,6 @@ import org.apache.brooklyn.util.yaml.Yamls;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
-
 public class AddPolicyWorkflowStep extends WorkflowStepDefinition implements 
HasBlueprintWorkflowStep {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(AddPolicyWorkflowStep.class);
@@ -65,9 +61,9 @@ public class AddPolicyWorkflowStep extends 
WorkflowStepDefinition implements Has
     }
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
-        validateStepBlueprint(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
+        validateStepBlueprint(workflowStepResolution);
     }
 
     @Override
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/ApplyInitializerWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/ApplyInitializerWorkflowStep.java
index 08845ce4df..6ddc9ae40f 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/ApplyInitializerWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/ApplyInitializerWorkflowStep.java
@@ -22,11 +22,9 @@ import com.google.common.collect.Iterables;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntityInitializer;
 import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils;
-import org.apache.brooklyn.core.workflow.WorkflowExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
 import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowStepResolution;
@@ -36,8 +34,6 @@ import org.apache.brooklyn.util.yaml.Yamls;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
-
 public class ApplyInitializerWorkflowStep extends WorkflowStepDefinition 
implements HasBlueprintWorkflowStep {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(ApplyInitializerWorkflowStep.class);
@@ -57,9 +53,9 @@ public class ApplyInitializerWorkflowStep extends 
WorkflowStepDefinition impleme
     }
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
-        validateStepBlueprint(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
+        validateStepBlueprint(workflowStepResolution);
     }
 
     @Override
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/DeleteEntityWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/DeleteEntityWorkflowStep.java
index f1e8250242..4cfb401f5c 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/DeleteEntityWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/DeleteEntityWorkflowStep.java
@@ -19,19 +19,15 @@
 package org.apache.brooklyn.core.workflow.steps.appmodel;
 
 import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.workflow.WorkflowExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
 import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowStepResolution;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
-
 public class DeleteEntityWorkflowStep extends WorkflowStepDefinition {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(DeleteEntityWorkflowStep.class);
@@ -46,8 +42,8 @@ public class DeleteEntityWorkflowStep extends 
WorkflowStepDefinition {
     }
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
 
         if (!getInput().containsKey(ENTITY.getName())) throw new 
IllegalArgumentException("Missing required argument: "+ENTITY.getName());
     }
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/DeletePolicyWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/DeletePolicyWorkflowStep.java
index d9eb89f4c4..bb7addd326 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/DeletePolicyWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/DeletePolicyWorkflowStep.java
@@ -19,12 +19,10 @@
 package org.apache.brooklyn.core.workflow.steps.appmodel;
 
 import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.objs.EntityAdjunct;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.entity.EntityAdjuncts;
-import org.apache.brooklyn.core.workflow.WorkflowExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
 import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowStepResolution;
@@ -32,8 +30,6 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
-
 public class DeletePolicyWorkflowStep extends WorkflowStepDefinition {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(DeletePolicyWorkflowStep.class);
@@ -49,8 +45,8 @@ public class DeletePolicyWorkflowStep extends 
WorkflowStepDefinition {
     }
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
 
         if (!getInput().containsKey(POLICY.getName())) throw new 
IllegalArgumentException("Missing required argument: "+POLICY.getName());
     }
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/DeployApplicationWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/DeployApplicationWorkflowStep.java
index 94ca80ea93..9ff94048eb 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/DeployApplicationWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/DeployApplicationWorkflowStep.java
@@ -19,19 +19,16 @@
 package org.apache.brooklyn.core.workflow.steps.appmodel;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.google.common.base.Optional;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
 import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils;
-import org.apache.brooklyn.core.resolve.jackson.JsonPassThroughDeserializer;
-import org.apache.brooklyn.core.workflow.WorkflowExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
 import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
+import org.apache.brooklyn.core.workflow.WorkflowStepResolution;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.text.Identifiers;
@@ -40,8 +37,6 @@ import org.apache.brooklyn.util.text.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
-
 public class DeployApplicationWorkflowStep extends WorkflowStepDefinition 
implements HasBlueprintWorkflowStep {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(DeployApplicationWorkflowStep.class);
@@ -69,9 +64,9 @@ public class DeployApplicationWorkflowStep extends 
WorkflowStepDefinition implem
     }
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
-        validateStepBlueprint(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
+        validateStepBlueprint(workflowStepResolution);
     }
 
     @Override
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/HasBlueprintWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/HasBlueprintWorkflowStep.java
index 4b141d5f1e..981e852316 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/HasBlueprintWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/HasBlueprintWorkflowStep.java
@@ -25,6 +25,7 @@ import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.resolve.jackson.JsonPassThroughDeserializer;
 import org.apache.brooklyn.core.workflow.WorkflowExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
+import org.apache.brooklyn.core.workflow.WorkflowStepResolution;
 import 
org.apache.brooklyn.core.workflow.steps.variables.SetVariableWorkflowStep;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.text.TemplateProcessor;
@@ -47,7 +48,7 @@ public interface HasBlueprintWorkflowStep {
     Map<String, Object> getInput();
     Logger logger();
 
-    default void validateStepBlueprint(@Nullable ManagementContext mgmt, 
@Nullable WorkflowExecutionContext workflow) {
+    default void validateStepBlueprint(WorkflowStepResolution 
workflowStepResolution) {
         boolean hasBlueprint = getInput().containsKey(BLUEPRINT.getName());
         boolean hasType = getInput().containsKey(TYPE.getName());
         if (!hasBlueprint && !hasType) throw new IllegalArgumentException("A 
'"+BLUEPRINT.getName()+"' must be defined or a type supplied");
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/InvokeEffectorWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/InvokeEffectorWorkflowStep.java
index 25f1901524..35fef8354a 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/InvokeEffectorWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/InvokeEffectorWorkflowStep.java
@@ -21,13 +21,11 @@ package org.apache.brooklyn.core.workflow.steps.appmodel;
 import java.util.List;
 import java.util.Map;
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.google.common.collect.Iterables;
 import org.apache.brooklyn.api.effector.Effector;
 import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.mgmt.TaskAdaptable;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
@@ -41,7 +39,6 @@ import 
org.apache.brooklyn.core.workflow.WorkflowStepResolution;
 import org.apache.brooklyn.core.workflow.utils.ExpressionParser;
 import org.apache.brooklyn.core.workflow.utils.ExpressionParserImpl;
 import 
org.apache.brooklyn.core.workflow.utils.ExpressionParserImpl.CharactersCollectingParseMode;
-import 
org.apache.brooklyn.core.workflow.utils.ExpressionParserImpl.CommonParseMode;
 import org.apache.brooklyn.core.workflow.utils.ExpressionParserImpl.ParseNode;
 import 
org.apache.brooklyn.core.workflow.utils.ExpressionParserImpl.ParseNodeOrValue;
 import org.apache.brooklyn.core.workflow.utils.ExpressionParserImpl.ParseValue;
@@ -164,8 +161,8 @@ public class InvokeEffectorWorkflowStep extends 
WorkflowStepDefinition implement
     }
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
 
         if (!getInput().containsKey(EFFECTOR.getName())) throw new 
IllegalArgumentException("Missing required input: "+EFFECTOR.getName());
     }
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/ReparentEntityWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/ReparentEntityWorkflowStep.java
index d06bb9195e..df7c372ece 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/ReparentEntityWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/ReparentEntityWorkflowStep.java
@@ -19,17 +19,14 @@
 package org.apache.brooklyn.core.workflow.steps.appmodel;
 
 import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.workflow.WorkflowExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
 import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowStepResolution;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
 import java.util.Objects;
 
 public class ReparentEntityWorkflowStep extends WorkflowStepDefinition {
@@ -47,8 +44,8 @@ public class ReparentEntityWorkflowStep extends 
WorkflowStepDefinition {
     }
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
 
         if (!getInput().containsKey(CHILD.getName())) throw new 
IllegalArgumentException("Missing required argument: "+CHILD.getName());
         if (!getInput().containsKey(PARENT.getName())) throw new 
IllegalArgumentException("Missing required argument: "+PARENT.getName());
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/UpdateChildrenWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/UpdateChildrenWorkflowStep.java
index 0db1cf6a88..df2cd13533 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/UpdateChildrenWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/appmodel/UpdateChildrenWorkflowStep.java
@@ -46,7 +46,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import java.util.List;
 import java.util.Map;
 import java.util.function.BiFunction;
@@ -143,9 +142,9 @@ public class UpdateChildrenWorkflowStep extends 
WorkflowStepDefinition implement
     }
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
-        validateStepBlueprint(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
+        validateStepBlueprint(workflowStepResolution);
     }
 
     @Override
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/GotoWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/GotoWorkflowStep.java
index 3d22f39301..4d8d807339 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/GotoWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/GotoWorkflowStep.java
@@ -18,16 +18,10 @@
  */
 package org.apache.brooklyn.core.workflow.steps.flow;
 
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.workflow.WorkflowExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowExpressionResolution;
 import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
 import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
-
-import javax.annotation.Nullable;
+import org.apache.brooklyn.core.workflow.WorkflowStepResolution;
 
 public class GotoWorkflowStep extends WorkflowStepDefinition {
 
@@ -42,8 +36,8 @@ public class GotoWorkflowStep extends WorkflowStepDefinition {
     }
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
         if (next==null) throw new IllegalStateException("next is required for 
goto step");
     }
 
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/RetryWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/RetryWorkflowStep.java
index e35574707f..07a635336b 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/RetryWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/RetryWorkflowStep.java
@@ -20,7 +20,6 @@ package org.apache.brooklyn.core.workflow.steps.flow;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.google.common.reflect.TypeToken;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.workflow.*;
@@ -37,7 +36,6 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
 import java.time.Instant;
 import java.util.*;
 import java.util.concurrent.TimeoutException;
@@ -214,8 +212,8 @@ public class RetryWorkflowStep extends 
WorkflowStepDefinition {
     }
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
 
         TypeCoercions.coerce(input.get(REPLAY.getName()), 
REPLAY.getTypeToken());
         TypeCoercions.coerce(input.get(LIMIT.getName()), LIMIT.getTypeToken());
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/SwitchWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/SwitchWorkflowStep.java
index d1da619394..42598bf8f0 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/SwitchWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/SwitchWorkflowStep.java
@@ -19,7 +19,6 @@
 package org.apache.brooklyn.core.workflow.steps.flow;
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
@@ -35,7 +34,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import java.util.List;
 import java.util.function.Function;
 
@@ -57,10 +55,10 @@ public class SwitchWorkflowStep extends 
WorkflowStepDefinition implements Workfl
     List<Object> cases;
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
         if (cases==null) throw new IllegalStateException("No cases defined for 
"+Strings.firstNonBlank(getName(), "switch"));
-        List<WorkflowStepDefinition> stepsResolved = new 
WorkflowStepResolution(mgmt, null, 
workflow).resolveSubSteps(Strings.firstNonBlank(getName(), "switch"), cases);
+        List<WorkflowStepDefinition> stepsResolved = 
workflowStepResolution.resolveSubSteps(Strings.firstNonBlank(getName(), 
"switch"), cases);
         if (stepsResolved.size()>1) {
             for (int i = 0; i < stepsResolved.size()-1; i++) {
                 if (stepsResolved.get(i).getConditionRaw() == null) {
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/variables/LoadWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/variables/LoadWorkflowStep.java
index da68001c05..1ee67a6e02 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/variables/LoadWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/variables/LoadWorkflowStep.java
@@ -19,13 +19,12 @@
 package org.apache.brooklyn.core.workflow.steps.variables;
 
 import com.google.common.reflect.TypeToken;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.workflow.WorkflowExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowExpressionResolution;
 import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
 import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
+import org.apache.brooklyn.core.workflow.WorkflowStepResolution;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.text.TemplateProcessor;
 import org.apache.brooklyn.util.text.ByteSizeStrings;
@@ -33,7 +32,6 @@ import org.apache.brooklyn.util.text.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
 import java.nio.charset.Charset;
 
 public class LoadWorkflowStep extends WorkflowStepDefinition {
@@ -56,8 +54,8 @@ public class LoadWorkflowStep extends WorkflowStepDefinition {
     }
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
 
         if (!input.containsKey(VARIABLE.getName())) {
             throw new IllegalArgumentException("Variable name is required");
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/variables/SetVariableWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/variables/SetVariableWorkflowStep.java
index 508d885dfc..06ef869aa3 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/variables/SetVariableWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/variables/SetVariableWorkflowStep.java
@@ -20,13 +20,12 @@ package org.apache.brooklyn.core.workflow.steps.variables;
 
 import com.google.common.reflect.TypeToken;
 import freemarker.core.ParseException;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.workflow.WorkflowExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowExpressionResolution;
 import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
 import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
+import org.apache.brooklyn.core.workflow.WorkflowStepResolution;
 import org.apache.brooklyn.core.workflow.utils.WorkflowSettingItemsUtils;
 import org.apache.brooklyn.util.collections.*;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
@@ -43,7 +42,6 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
 import java.time.Instant;
 import java.util.*;
 import java.util.function.BiFunction;
@@ -83,8 +81,8 @@ public class SetVariableWorkflowStep extends 
WorkflowStepDefinition {
     }
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
 
         if (input.get(VARIABLE.getName())==null) {
             throw new IllegalArgumentException("Variable name is required");
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/variables/TransformVariableWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/variables/TransformVariableWorkflowStep.java
index 09907ffe38..e46261ed2a 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/variables/TransformVariableWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/variables/TransformVariableWorkflowStep.java
@@ -26,21 +26,19 @@ import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
-import javax.annotation.Nullable;
 
 import com.google.common.collect.Iterables;
 import com.google.common.reflect.TypeToken;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.typereg.RegisteredType;
 import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.typereg.RegisteredTypeLoadingContexts;
 import org.apache.brooklyn.core.typereg.RegisteredTypes;
-import org.apache.brooklyn.core.workflow.WorkflowExecutionContext;
 import org.apache.brooklyn.core.workflow.WorkflowExpressionResolution;
 import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
 import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
+import org.apache.brooklyn.core.workflow.WorkflowStepResolution;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
@@ -94,8 +92,8 @@ public class TransformVariableWorkflowStep extends 
WorkflowStepDefinition {
     }
 
     @Override
-    public void validateStep(@Nullable ManagementContext mgmt, @Nullable 
WorkflowExecutionContext workflow) {
-        super.validateStep(mgmt, workflow);
+    public void validateStep(WorkflowStepResolution workflowStepResolution) {
+        super.validateStep(workflowStepResolution);
         if (!input.containsKey(TRANSFORM.getName())) {
             throw new IllegalArgumentException("Transform is required");
         }
diff --git 
a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
 
b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
index 48d037e262..6c2ac33d91 100644
--- 
a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
+++ 
b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
@@ -302,7 +302,7 @@ public class ApplicationResourceTest extends 
BrooklynRestResourceTest {
 
         // Expect app to be running
         URI appUri = response.getLocation();
-        waitForApplicationToBeRunning(response.getLocation());
+        waitForApplicationToBeRunning(response.getLocation());  // observed to 
fail here, app ERROR, 2024-02
         
assertEquals(client().path(appUri).get(ApplicationSummary.class).getSpec().getName(),
 "simple-app-yaml");
 
         Response response2 = client().path(appUri.getPath())
@@ -721,7 +721,7 @@ public class ApplicationResourceTest extends 
BrooklynRestResourceTest {
         log.info("LOCATIONS: " + result);
         Assert.assertEquals(result.size(), 1);
         Map details = (Map) result.values().iterator().next();
-        assertEquals(details.get("leafEntityCount"), 2);
+        assertEquals(details.get("leafEntityCount"), 2);  // observed to fail 
here once, 2024-02, size 1
     }
 
     


Reply via email to