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 063a289c4f0962e5312f1324492ce6e7cf7b261e Author: Alex Heneveld <[email protected]> AuthorDate: Wed Nov 9 15:30:30 2022 +0000 ensure DSL components deep in vars get resolved for workflow --- .../brooklyn/camp/brooklyn/WorkflowYamlTest.java | 27 ++++++++++++++++++---- .../workflow/WorkflowExpressionResolution.java | 22 ++++++++++++++---- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/WorkflowYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/WorkflowYamlTest.java index 6de56af90c..be6af46518 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/WorkflowYamlTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/WorkflowYamlTest.java @@ -34,7 +34,9 @@ import org.apache.brooklyn.api.objs.BrooklynObject; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.sensor.AttributeSensor; import org.apache.brooklyn.api.typereg.RegisteredType; +import org.apache.brooklyn.camp.brooklyn.spi.dsl.DslUtils; import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.BrooklynDslCommon; +import org.apache.brooklyn.camp.brooklyn.spi.dsl.parse.DslParser; import org.apache.brooklyn.core.config.ConfigKeys; import org.apache.brooklyn.core.entity.*; import org.apache.brooklyn.core.entity.lifecycle.Lifecycle; @@ -686,9 +688,22 @@ public class WorkflowYamlTest extends AbstractYamlTest { Asserts.assertEquals(output.toString().trim(), message + " world"); } + public static class SetDeepTestStep extends WorkflowStepDefinition { + @Override + public void populateFromShorthand(String value) { + // no shorthand + } + + @Override + protected Object doTaskBody(WorkflowStepInstanceExecutionContext context) { + return MutableMap.of("x", DslUtils.parseBrooklynDsl(context.getManagementContext(), "$brooklyn:config(\"arg1\")")); + } + } + @Test(groups="Live") - public void testSshEchoBashCommandAsWorkflowEffectorWithVarFromConfig() throws Exception { + public void testSshEchoBashCommandAsWorkflowEffectorWithDeepVarFromConfig() throws Exception { WorkflowBasicTest.addRegisteredTypeBean(mgmt(), "container", ContainerWorkflowStep.class); + WorkflowBasicTest.addRegisteredTypeBean(mgmt(), "set-deep", SetDeepTestStep.class); BrooklynDslCommon.registerSerializationHooks(); final String message = ("hello " + Strings.makeRandomId(10)).toLowerCase(); @@ -701,7 +716,9 @@ public class WorkflowYamlTest extends AbstractYamlTest { WorkflowEffector.STEPS, MutableList.of( MutableMap.of("step", "let map env_local", "value", MutableMap.of("VAR1", "$brooklyn:config(\"hello\")", "ENTITY_ID", "$brooklyn:entityId()")), "let merge map env = ${env} ${env_local}", - MutableMap.<String, Object>of("step", "ssh echo "+ message+" Entity:$ENTITY_ID:$VAR1:$VAR2", + "set-deep", + "let env.VAR3 = ${workflow.previous_step.output}", + MutableMap.<String, Object>of("step", "ssh echo "+ message+" Entity:$ENTITY_ID:$VAR1:$VAR2:$VAR3", "input", MutableMap.of("env", "${env}"), "output", "${stdout}")))); @@ -712,10 +729,12 @@ public class WorkflowYamlTest extends AbstractYamlTest { addInitializer(initializer)); app.start(ImmutableList.of()); child.config().set(ConfigKeys.newStringConfigKey("hello"), "world"); + child.config().set(ConfigKeys.newStringConfigKey("arg1"), "Arg1"); - Object output = Entities.invokeEffector(app, child, ((EntityInternal) child).getEffector("test-ssh-effector"), MutableMap.of("env", MutableMap.of("VAR2","Arg1"))).getUnchecked(Duration.ONE_MINUTE); + Object output = Entities.invokeEffector(app, child, ((EntityInternal) child).getEffector("test-ssh-effector"), MutableMap.of("env", + MutableMap.of("VAR2", DslUtils.parseBrooklynDsl(mgmt(), "$brooklyn:config(\"arg1\")")))).getUnchecked(Duration.ONE_MINUTE); - Asserts.assertEquals(output.toString().trim(), message + " Entity:"+app.getChildren().iterator().next().getId()+":"+"world:Arg1"); + Asserts.assertEquals(output.toString().trim(), message + " Entity:"+app.getChildren().iterator().next().getId()+":"+"world:Arg1:{\"x\":\"Arg1\"}"); } diff --git a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExpressionResolution.java b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExpressionResolution.java index 0f23092745..7a623396dd 100644 --- a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExpressionResolution.java +++ b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExpressionResolution.java @@ -427,7 +427,11 @@ public class WorkflowExpressionResolution { expression = BrooklynJacksonSerializationUtils.JsonDeserializerForCommonBrooklynThings.BROOKLYN_PARSE_DSL_FUNCTION.apply(context.getManagementContext(), expression); } } - return Tasks.resolving(expression).as(Object.class).context(context.getEntity()).get(); + return processDslComponents(expression); + } + + private Object processDslComponents(Object expression) { + return Tasks.resolving(expression).as(Object.class).deep().context(context.getEntity()).get(); } public Object processTemplateExpressionString(String expression) { @@ -435,7 +439,12 @@ public class WorkflowExpressionResolution { if (expression.startsWith("$brooklyn:")) { Object e2 = resolveDsl(expression); if (!Objects.equals(e2, expression)) { - return processTemplateExpression(e2); + if (e2 instanceof String) { + // proceed to below + expression = (String) e2; + } else { + return processTemplateExpression(e2); + } } } @@ -463,8 +472,13 @@ public class WorkflowExpressionResolution { } } - if (useWrappedValue) { - if (!expression.equals(result)) return new WrappedResolvedExpression<Object>(expression, result); + if (!expression.equals(result)) { + if (useWrappedValue) { + return new WrappedResolvedExpression<Object>(expression, result); + } else { + // we try, but don't guarantee, that DSL expressions aren't re-resolved, ie $brooklyn:literal("$brooklyn:literal(\"x\")") won't return x + result = processDslComponents(result); + } } return result;
