You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2022/10/21 13:57:54 UTC
[brooklyn-server] 02/11: make step output available on errors, and improve short name metadata for types
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 84876d12fde500c4054228a7fa22516e98fafb2f
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Wed Oct 19 15:55:18 2022 +0100
make step output available on errors, and improve short name metadata for types
---
.../brooklyn/core/workflow/WorkflowStepDefinition.java | 8 +++++++-
.../core/workflow/WorkflowStepInstanceExecutionContext.java | 7 +++++++
.../brooklyn/core/workflow/WorkflowStepResolution.java | 3 +++
.../brooklyn/core/workflow/steps/HttpWorkflowStep.java | 4 +++-
.../apache/brooklyn/core/workflow/steps/SshWorkflowStep.java | 9 ++++++---
.../org/apache/brooklyn/core/workflow/WorkflowBasicTest.java | 12 ++++++++++--
.../core/workflow/WorkflowPersistReplayErrorsTest.java | 2 +-
7 files changed, 37 insertions(+), 8 deletions(-)
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 92532a0bc9..9a2d5b2d05 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,6 +43,7 @@ import javax.annotation.Nonnull;
import java.util.List;
import java.util.Map;
+@JsonInclude(JsonInclude.Include.NON_EMPTY)
public abstract class WorkflowStepDefinition {
private static final Logger log = LoggerFactory.getLogger(WorkflowStepDefinition.class);
@@ -59,6 +60,7 @@ public abstract class WorkflowStepDefinition {
}
protected String userSuppliedShorthand;
+ protected String shorthandTypeName;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
protected Map<String,Object> input = MutableMap.of();
@@ -229,7 +231,11 @@ public abstract class WorkflowStepDefinition {
return Strings.join(parts, " - ");
}
- protected String getShorthandTypeName() {
+ public void setShorthandTypeName(String shorthandTypeDefinition) { this.shorthandTypeName = shorthandTypeDefinition; }
+ @JsonProperty("shorthandTypeName") // REST API should prefer this accessor
+ public String getShorthandTypeName() {
+ if (Strings.isNonBlank(shorthandTypeName)) return shorthandTypeName;
+
String name = getClass().getSimpleName();
if (Strings.isBlank(name)) return getClass().getCanonicalName();
name = Strings.removeFromEnd(name, "WorkflowStep");
diff --git a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepInstanceExecutionContext.java b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepInstanceExecutionContext.java
index 85d238e552..b3bc5065f5 100644
--- a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepInstanceExecutionContext.java
+++ b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepInstanceExecutionContext.java
@@ -136,6 +136,13 @@ public class WorkflowStepInstanceExecutionContext {
return context;
}
+ public Object getOutput() {
+ return output;
+ }
+ public void setOutput(Object output) {
+ this.output = output;
+ }
+
@JsonIgnore
public Object getPreviousStepOutput() {
return getWorkflowExectionContext().getPreviousStepOutput();
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 439e0ffe78..464f7f217f 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
@@ -105,6 +105,9 @@ public class WorkflowStepResolution {
if (userSuppliedShorthand!=null) {
defW.userSuppliedShorthand = userSuppliedShorthand;
}
+ if (typeBestGuess!=null) {
+ defW.shorthandTypeName = typeBestGuess;
+ }
List<Object> onError = defW.getOnError();
if (onError!=null && !onError.isEmpty()) {
diff --git a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/HttpWorkflowStep.java b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/HttpWorkflowStep.java
index 8a4988029b..d003510cc5 100644
--- a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/HttpWorkflowStep.java
+++ b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/HttpWorkflowStep.java
@@ -160,8 +160,10 @@ public class HttpWorkflowStep extends WorkflowStepDefinition {
Predicate<Integer> exitcode = context.getInput(STATUS_CODE);
if (exitcode==null) exitcode = code -> HttpTool.isStatusCodeHealthy(code);
+ context.setOutput(MutableMap.of("status_code", response.code(), "headers", response.headers(), "content", contentString, "content_bytes", contentBytes, "duration", Duration.millis(endTime - startTime)));
+ // make sure the output is set even if there is an error
checkExitCode(response.code(), exitcode);
- return MutableMap.of("status_code", response.code(), "headers", response.headers(), "content", contentString, "content_bytes", contentBytes, "duration", Duration.millis(endTime - startTime));
+ return context.getOutput();
}
protected void checkExitCode(Integer code, Predicate<Integer> exitcode) {
diff --git a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/SshWorkflowStep.java b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/SshWorkflowStep.java
index 5b084c8bd9..8db28cbd51 100644
--- a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/SshWorkflowStep.java
+++ b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/SshWorkflowStep.java
@@ -34,6 +34,7 @@ import org.apache.brooklyn.util.core.task.ssh.SshTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.text.Strings;
+import org.apache.brooklyn.util.time.Duration;
import java.util.Map;
@@ -75,10 +76,12 @@ public class SshWorkflowStep extends WorkflowStepDefinition {
Map<String, Object> env = context.getInput(ENV);
if (env!=null) tf.environmentVariables(new ShellEnvironmentSerializer(context.getWorkflowExectionContext().getManagementContext()).serialize(env));
return tf.returning(ptw -> {
- checkExitCode(ptw, exitcode);
- return MutableMap.of("stdout", ptw.getStdout(),
+ context.setOutput(MutableMap.of("stdout", ptw.getStdout(),
"stderr", ptw.getStderr(),
- "exit_code", ptw.getExitCode());
+ "exit_code", ptw.getExitCode()));
+ // make sure the output is set even if there is an error
+ checkExitCode(ptw, exitcode);
+ return (Map<?,?>) context.getOutput();
});
}
diff --git a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java
index e1cf23932a..08c5f7f467 100644
--- a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java
@@ -46,8 +46,10 @@ 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.json.BrooklynObjectsJsonMapper;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.yaml.Yamls;
import org.testng.annotations.Test;
import java.io.IOException;
@@ -122,14 +124,20 @@ public class WorkflowBasicTest extends BrooklynMgmtUnitTestSupport {
}
@Test
- public void testShorthandStepResolution() {
+ public void testShorthandStepResolution() throws JsonProcessingException {
loadTypes();
String input = "sleep 1s";
- // only util will work for shorthand
+ // jackson doesn't handle shorthand; our custom method does that
WorkflowStepDefinition s = WorkflowStepResolution.resolveStep(mgmt, input);
Asserts.assertInstanceOf(s, SleepWorkflowStep.class);
Asserts.assertEquals( Duration.of(s.getInput().get(SleepWorkflowStep.DURATION.getName())), Duration.ONE_SECOND);
+
+ String output1 = BrooklynObjectsJsonMapper.newDslToStringSerializingMapper(mgmt).writeValueAsString(s);
+ String output2 = BeanWithTypeUtils.newYamlMapper(mgmt, false, null, false).writerFor(Object.class).writeValueAsString(s);
+
+ Asserts.assertStringContains(output1, "\"shorthandTypeName\":\"sleep\"");
+ Asserts.assertStringContains(output2, "shorthandTypeName: \"sleep\"");
}
@Test
diff --git a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowPersistReplayErrorsTest.java b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowPersistReplayErrorsTest.java
index 3987e3cfdb..049a69235d 100644
--- a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowPersistReplayErrorsTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowPersistReplayErrorsTest.java
@@ -577,7 +577,7 @@ public class WorkflowPersistReplayErrorsTest extends RebindTestFixture<BasicAppl
m -> m.matches("Encountered error in workflow .*/.* 'myWorkflow' .handler present.: No effector matching 'does-not-exist'"),
m -> m.matches("Creating workflow .* error handler .*-error-handler in task .*"),
m -> m.matches("Starting .*-error-handler with 1 handler in task .*"),
- m -> m.matches("Creating handler .*-error-handler-1 'NoOp' in task .*"),
+ m -> m.matches("Creating handler .*-error-handler-1 'no-op' in task .*"),
m -> m.matches("Starting .*-error-handler-1 in task .*"),
m -> m.matches("Completed handler .*-error-handler-1; proceeding to default next step"),
m -> m.matches("Handled error in workflow around step .*-1; explicit next 'end': Workflow completed")));