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
The following commit(s) were added to refs/heads/master by this push:
new 6c6a71187e fix DSL resolution for workflow steps
6c6a71187e is described below
commit 6c6a71187ee75e3606000fb88e9ecfe732d05b06
Author: Alex Heneveld <[email protected]>
AuthorDate: Tue Nov 8 13:15:25 2022 +0000
fix DSL resolution for workflow steps
---
.../brooklyn/camp/brooklyn/WorkflowYamlTest.java | 34 ++++++++++++++++++----
.../workflow/WorkflowExpressionResolution.java | 25 +++++++++++++++-
.../core/workflow/WorkflowBeefyStepTest.java | 1 +
.../brooklyn/rest/transform/TaskTransformer.java | 4 +--
.../tasks/kubectl/ContainerEffectorTest.java | 29 ++++++++++++++++--
5 files changed, 83 insertions(+), 10 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 6025815a66..effd85b8af 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
@@ -20,12 +20,12 @@ package org.apache.brooklyn.camp.brooklyn;
import com.google.common.base.Stopwatch;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.api.mgmt.ManagementContext;
@@ -34,6 +34,7 @@ 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.methods.BrooklynDslCommon;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
@@ -41,10 +42,9 @@ import org.apache.brooklyn.core.entity.Dumper;
import org.apache.brooklyn.core.entity.EntityAsserts;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils;
import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.typereg.BasicBrooklynTypeRegistry;
+import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.typereg.BasicTypeImplementationPlan;
import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer;
import org.apache.brooklyn.core.typereg.RegisteredTypes;
@@ -56,13 +56,14 @@ import org.apache.brooklyn.entity.stock.BasicEntity;
import org.apache.brooklyn.location.byon.FixedListMachineProvisioningLocation;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.location.winrm.WinrmWorkflowStep;
+import org.apache.brooklyn.tasks.kubectl.ContainerEffectorTest;
import org.apache.brooklyn.tasks.kubectl.ContainerWorkflowStep;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.ClassLogWatcher;
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.internal.ssh.RecordingSshTool;
-import org.apache.brooklyn.util.core.json.BrooklynObjectsJsonMapper;
import org.apache.brooklyn.util.text.Strings;
import org.apache.brooklyn.util.time.Duration;
import org.testng.Assert;
@@ -72,7 +73,6 @@ import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
-import java.util.Optional;
import java.util.function.Predicate;
import static
org.apache.brooklyn.util.core.internal.ssh.ExecCmdAsserts.assertExecContains;
@@ -664,4 +664,28 @@ public class WorkflowYamlTest extends AbstractYamlTest {
Asserts.assertEquals(result, 11);
}
+ @Test
+ public void testEchoBashCommandAsWorkflowEffectorWithVarFromConfig()
throws Exception {
+ WorkflowBasicTest.addRegisteredTypeBean(mgmt(), "container",
ContainerWorkflowStep.class);
+ BrooklynDslCommon.registerSerializationHooks();
+ final String message = ("hello " +
Strings.makeRandomId(10)).toLowerCase();
+
+ EntitySpec<TestApplication> appSpec =
EntitySpec.create(TestApplication.class);
+ TestApplication app = mgmt().getEntityManager().createEntity(appSpec);
+
+ Object output = ContainerEffectorTest.doTestEchoBashCommand(app, () ->
{
+ ConfigBag parameters = ConfigBag.newInstance(ImmutableMap.of(
+ WorkflowEffector.EFFECTOR_NAME, "test-container-effector",
+ WorkflowEffector.STEPS, MutableList.of(
+ MutableMap.<String, Object>of("s", "container " +
ContainerEffectorTest.BASH_SCRIPT_CONTAINER + " echo " + message + " $VAR",
+ "input",
+ MutableMap.of("env", MutableMap.of("VAR",
"$brooklyn:config(\"hello\")")),
+ "output", "${stdout}"))));
+
+ return new WorkflowEffector(parameters);
+ }, entity ->
entity.config().set(ConfigKeys.newStringConfigKey("hello"), "world"));
+ Asserts.assertEquals(output.toString().trim(), message + " world");
+ }
+
+
}
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 51393a6797..5baf4b50d6 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
@@ -24,6 +24,7 @@ import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils;
+import
org.apache.brooklyn.core.resolve.jackson.BrooklynJacksonSerializationUtils;
import org.apache.brooklyn.core.typereg.RegisteredTypes;
import org.apache.brooklyn.util.collections.Jsonya;
import org.apache.brooklyn.util.collections.MutableMap;
@@ -43,6 +44,7 @@ import org.slf4j.LoggerFactory;
import javax.swing.*;
import java.util.Collection;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@@ -241,13 +243,34 @@ public class WorkflowExpressionResolution {
}
private Object resolveDsl(Object expression) {
+ boolean DEFINITELY_DSL = false;
+ if (expression instanceof String || expression instanceof Map ||
expression instanceof Collection) {
+ if (expression instanceof String) {
+ if (!((String)expression).startsWith("$brooklyn:")) {
+ // not DSL
+ return expression;
+ } else {
+ DEFINITELY_DSL = true;
+ }
+ }
+ if
(BrooklynJacksonSerializationUtils.JsonDeserializerForCommonBrooklynThings.BROOKLYN_PARSE_DSL_FUNCTION==null)
{
+ if (DEFINITELY_DSL) {
+ log.warn("BROOKLYN_PARSE_DSL_FUNCTION not set when
processing DSL expression "+expression+"; will not be resolved");
+ }
+ } else {
+ expression =
BrooklynJacksonSerializationUtils.JsonDeserializerForCommonBrooklynThings.BROOKLYN_PARSE_DSL_FUNCTION.apply(context.getManagementContext(),
expression);
+ }
+ }
return
Tasks.resolving(expression).as(Object.class).context(context.getEntity()).get();
}
public Object processTemplateExpressionString(String expression) {
if (expression==null) return null;
if (expression.startsWith("$brooklyn:")) {
- return processTemplateExpression(resolveDsl(expression));
+ Object e2 = resolveDsl(expression);
+ if (!Objects.equals(e2, expression)) {
+ return processTemplateExpression(e2);
+ }
}
TemplateHashModel model = new WorkflowFreemarkerModel();
diff --git
a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBeefyStepTest.java
b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBeefyStepTest.java
index 7a68f95124..41d4fd870b 100644
---
a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBeefyStepTest.java
+++
b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBeefyStepTest.java
@@ -24,6 +24,7 @@ import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.api.location.NoMachinesAvailableException;
import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.EntityAsserts;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.sensor.Sensors;
diff --git
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TaskTransformer.java
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TaskTransformer.java
index 004625dabc..2ac902244d 100644
---
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TaskTransformer.java
+++
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TaskTransformer.java
@@ -120,6 +120,7 @@ public class TaskTransformer {
if (includeDetail) {
try {
+ detailedStatus = (String)
resolver.getValueForDisplay(task.getStatusDetail(true), true, false,
suppressSecrets);
if (task.isDone()) {
result = resolver.getValueForDisplay(task.get(), true,
false, suppressSecrets);
} else {
@@ -130,8 +131,7 @@ public class TaskTransformer {
}
}
- detailedStatus = (String)
resolver.getValueForDisplay(task.getStatusDetail(true), true, false,
suppressSecrets);
-
+
return new TaskSummary(task.getId(), task.getDisplayName(),
task.getDescription(), entityId, entityDisplayName,
tags, ifPositive(task.getSubmitTimeUtc()),
ifPositive(task.getStartTimeUtc()), ifPositive(task.getEndTimeUtc()),
task.getStatusSummary(), result, task.isError(),
task.isCancelled(),
diff --git
a/software/base/src/test/java/org/apache/brooklyn/tasks/kubectl/ContainerEffectorTest.java
b/software/base/src/test/java/org/apache/brooklyn/tasks/kubectl/ContainerEffectorTest.java
index 705b7b119f..0e2dbeba39 100644
---
a/software/base/src/test/java/org/apache/brooklyn/tasks/kubectl/ContainerEffectorTest.java
+++
b/software/base/src/test/java/org/apache/brooklyn/tasks/kubectl/ContainerEffectorTest.java
@@ -22,15 +22,16 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.apache.brooklyn.api.entity.EntityInitializer;
import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityAsserts;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.workflow.WorkflowBasicTest;
import org.apache.brooklyn.core.workflow.WorkflowEffector;
-import org.apache.brooklyn.core.workflow.steps.HttpWorkflowStep;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
@@ -40,6 +41,7 @@ import org.apache.brooklyn.util.time.Duration;
import org.testng.annotations.Test;
import java.util.Map;
+import java.util.function.Consumer;
import java.util.function.Supplier;
import static org.testng.Assert.assertTrue;
@@ -102,7 +104,7 @@ public class ContainerEffectorTest extends
BrooklynAppUnitTestSupport {
}
// `bash` installs to /usr/local/bin/bash but we hardcode /bin/bash so
can't use `bash`
- private static final String BASH_SCRIPT_CONTAINER = "perl";
+ public static final String BASH_SCRIPT_CONTAINER = "perl";
@Test
public void testEchoBashCommandAsWorkflowEffector() {
@@ -164,12 +166,18 @@ public class ContainerEffectorTest extends
BrooklynAppUnitTestSupport {
}
protected Object doTestEchoBashCommand(Supplier<EntityInitializer>
initializerMaker) {
+ return doTestEchoBashCommand(app, initializerMaker, null);
+ }
+
+ // used also in WorkflowYamlTest
+ public static Object doTestEchoBashCommand(TestApplication app,
Supplier<EntityInitializer> initializerMaker, Consumer<TestEntity>
appCustomizer) {
EntityInitializer initializer = initializerMaker.get();
TestEntity parentEntity =
app.createAndManageChild(EntitySpec.create(TestEntity.class).addInitializer(initializer));
app.start(ImmutableList.of());
EntityAsserts.assertAttributeEqualsEventually(parentEntity,
Attributes.SERVICE_UP, true);
+ if (appCustomizer!=null) appCustomizer.accept(parentEntity);
return Entities.invokeEffector(app, parentEntity,
parentEntity.getEffector("test-container-effector")).getUnchecked(Duration.ONE_MINUTE);
}
@@ -206,4 +214,21 @@ public class ContainerEffectorTest extends
BrooklynAppUnitTestSupport {
Object output = Entities.invokeEffector(app, parentEntity,
parentEntity.getEffector("test-container-effector")).getUnchecked(Duration.ONE_MINUTE);
assertTrue(output.toString().contains("WORLD"));
}
+
+ @Test
+ public void testEchoMultiBashCommandWithEnv() {
+ ConfigBag parameters = ConfigBag.newInstance(ImmutableMap.of(
+ ContainerEffector.EFFECTOR_NAME, "test-container-effector",
+ ContainerCommons.CONTAINER_IMAGE, "bash",
+ ContainerCommons.ARGUMENTS, ImmutableList.of( "-c", "date;
echo $HELLO"),
+ BrooklynConfigKeys.SHELL_ENVIRONMENT, ImmutableMap.<String,
Object>of("HELLO", "$brooklyn:config(\"hello\")")));
+
+ ContainerEffector initializer = new ContainerEffector(parameters);
+ TestEntity parentEntity =
app.createAndManageChild(EntitySpec.create(TestEntity.class).configure("hello",
"world").addInitializer(initializer));
+ app.start(ImmutableList.of());
+
+ EntityAsserts.assertAttributeEqualsEventually(parentEntity,
Attributes.SERVICE_UP, true);
+ Object output = Entities.invokeEffector(app, parentEntity,
parentEntity.getEffector("test-container-effector")).getUnchecked(Duration.ONE_MINUTE);
+ assertTrue(output.toString().contains("WORLD"), "Wrong output:
"+output);
+ }
}