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 b8be0b1697 Workflow step to log messages
b8be0b1697 is described below
commit b8be0b1697906ec00e9aec245e7a0712ac46fb2c
Author: Mykola Mandra <[email protected]>
AuthorDate: Mon Sep 12 21:36:22 2022 +0100
Workflow step to log messages
Signed-off-by: Mykola Mandra <[email protected]>
---
.../brooklyn/camp/brooklyn/WorkflowYamlTest.java | 76 +++++++++++++++-------
.../core/workflow/steps/LogWorkflowStep.java | 55 ++++++++++++++++
.../brooklyn/core/workflow/WorkflowBasicTest.java | 12 ++--
3 files changed, 114 insertions(+), 29 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 6ec1b48091..277ad0d0bd 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
@@ -18,49 +18,33 @@
*/
package org.apache.brooklyn.camp.brooklyn;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.google.common.base.Stopwatch;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.read.ListAppender;
import com.google.common.collect.Iterables;
-import com.google.common.reflect.TypeToken;
import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
import org.apache.brooklyn.api.typereg.RegisteredType;
import org.apache.brooklyn.core.entity.Dumper;
import org.apache.brooklyn.core.entity.EntityAsserts;
-import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils;
import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynMgmtUnitTestSupport;
import org.apache.brooklyn.core.typereg.BasicBrooklynTypeRegistry;
import org.apache.brooklyn.core.typereg.BasicTypeImplementationPlan;
import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer;
import org.apache.brooklyn.core.typereg.RegisteredTypes;
-import org.apache.brooklyn.core.workflow.WorkflowDefinition;
import org.apache.brooklyn.core.workflow.WorkflowEffector;
-import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
-import org.apache.brooklyn.core.workflow.WorkflowStepResolution;
+import org.apache.brooklyn.core.workflow.steps.LogWorkflowStep;
import org.apache.brooklyn.core.workflow.steps.NoOpWorkflowStep;
import org.apache.brooklyn.core.workflow.steps.SetSensorWorkflowStep;
import org.apache.brooklyn.core.workflow.steps.SleepWorkflowStep;
-import org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess;
-import org.apache.brooklyn.entity.stock.BasicApplication;
import org.apache.brooklyn.entity.stock.BasicEntity;
-import org.apache.brooklyn.test.Asserts;
-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.exceptions.Exceptions;
-import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
-import java.util.Map;
-
public class WorkflowYamlTest extends AbstractYamlTest {
static final String VERSION = "0.1.0-SNAPSHOT";
@@ -77,6 +61,7 @@ public class WorkflowYamlTest extends AbstractYamlTest {
@Override
public void setUp() throws Exception {
super.setUp();
+ addRegisteredTypeBean(mgmt(), "log", LogWorkflowStep.class);
addRegisteredTypeBean(mgmt(), "sleep", SleepWorkflowStep.class);
addRegisteredTypeBean(mgmt(), "no-op", NoOpWorkflowStep.class);
addRegisteredTypeBean(mgmt(), "set-sensor",
SetSensorWorkflowStep.class);
@@ -95,11 +80,11 @@ public class WorkflowYamlTest extends AbstractYamlTest {
" steps:",
" step1:",
" type: no-op",
- " step1:",
+ " step2:",
" type: set-sensor",
" sensor: foo",
" value: bar",
- " step2: set-sensor integer bar = 1");
+ " step3: set-sensor integer bar = 1");
waitForApplicationTasks(app);
Entity entity = Iterables.getOnlyElement(app.getChildren());
@@ -113,4 +98,47 @@ public class WorkflowYamlTest extends AbstractYamlTest {
EntityAsserts.assertAttributeEquals(app,
Sensors.newSensor(Object.class, "bar"), 1);
}
+ @Test
+ public void testWorkflowEffectorLogStep() throws Exception {
+
+ // Prepare log watcher.
+ ListAppender<ILoggingEvent> logWatcher;
+ logWatcher = new ListAppender<>();
+ logWatcher.start();
+ ((Logger)
LoggerFactory.getLogger(LogWorkflowStep.class)).addAppender(logWatcher);
+
+ // Declare workflow in a blueprint, add various log steps.
+ Entity app = createAndStartApplication(
+ "services:",
+ "- type: " + BasicEntity.class.getName(),
+ " brooklyn.initializers:",
+ " - type: workflow-effector",
+ " brooklyn.config:",
+ " name: myWorkflow",
+ " steps:",
+ " step1:", // this step runs 3rd... so confused :-(
+ " type: log",
+ " message: test message 1",
+ " step2: log test message 2",
+ " step3: no-op",
+ " 6: log ??", // this step runs 2nd...
+ " step4: log test message 3",
+ " 5: log test message N"); // this step runs 1st !...
+ waitForApplicationTasks(app);
+
+ // Deploy the blueprint.
+ Entity entity = Iterables.getOnlyElement(app.getChildren());
+ Effector<?> effector =
entity.getEntityType().getEffectorByName("myWorkflow").get();
+ Task<?> invocation = app.invoke(effector, null);
+ invocation.getUnchecked();
+ Dumper.dumpInfo(invocation);
+
+ // Verify expected log messages.
+ Assert.assertEquals(5, logWatcher.list.size());
+ Assert.assertEquals(logWatcher.list.get(0).getFormattedMessage(), "5:
test message N");
+ Assert.assertEquals(logWatcher.list.get(1).getFormattedMessage(), "6:
??");
+ Assert.assertEquals(logWatcher.list.get(2).getFormattedMessage(),
"step1: test message 1");
+ Assert.assertEquals(logWatcher.list.get(3).getFormattedMessage(),
"step2: test message 2");
+ Assert.assertEquals(logWatcher.list.get(4).getFormattedMessage(),
"step4: test message 3");
+ }
}
diff --git
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/LogWorkflowStep.java
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/LogWorkflowStep.java
new file mode 100644
index 0000000000..e96e1808c4
--- /dev/null
+++
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/LogWorkflowStep.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.workflow.steps;
+
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.workflow.WorkflowExecutionContext;
+import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LogWorkflowStep extends WorkflowStepDefinition {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(LogWorkflowStep.class);
+
+ String message;
+
+ public String getMessage() {
+ return message;
+ }
+
+ @Override
+ public void setShorthand(String value) {
+ message = value;
+ }
+
+ @Override
+ protected Task<?> newTask(String name, WorkflowExecutionContext
workflowExecutionContext) {
+ return Tasks.create(getDefaultTaskName(workflowExecutionContext), ()
-> {
+
+ if (Strings.isBlank(message)) {
+ throw new IllegalArgumentException("Log message is required");
+ }
+
+ LOG.info("{}: {}", name, getMessage());
+ });
+ }
+}
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 5eeaebfdc0..517befdcb2 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
@@ -19,9 +19,7 @@
package org.apache.brooklyn.core.workflow;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.google.common.base.Stopwatch;
import com.google.common.reflect.TypeToken;
-import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.mgmt.ManagementContext;
@@ -37,6 +35,7 @@ import
org.apache.brooklyn.core.typereg.BasicBrooklynTypeRegistry;
import org.apache.brooklyn.core.typereg.BasicTypeImplementationPlan;
import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer;
import org.apache.brooklyn.core.typereg.RegisteredTypes;
+import org.apache.brooklyn.core.workflow.steps.LogWorkflowStep;
import org.apache.brooklyn.core.workflow.steps.NoOpWorkflowStep;
import org.apache.brooklyn.core.workflow.steps.SetSensorWorkflowStep;
import org.apache.brooklyn.core.workflow.steps.SleepWorkflowStep;
@@ -63,6 +62,7 @@ public class WorkflowBasicTest extends
BrooklynMgmtUnitTestSupport {
}
protected void loadTypes() {
+ addRegisteredTypeBean(mgmt, "log", LogWorkflowStep.class);
addRegisteredTypeBean(mgmt, "sleep", SleepWorkflowStep.class);
addRegisteredTypeBean(mgmt, "no-op", NoOpWorkflowStep.class);
addRegisteredTypeBean(mgmt, "set-sensor", SetSensorWorkflowStep.class);
@@ -115,14 +115,15 @@ public class WorkflowBasicTest extends
BrooklynMgmtUnitTestSupport {
"steps", MutableMap.of(
"step1", MutableMap.of("type", "no-op"),
"step2", MutableMap.of("type", "sleep", "duration",
"1s"),
- "step3", "sleep 1s"
+ "step3", "sleep 1s",
+ "step4", "log test message"
));
WorkflowDefinition w = convert(input, WorkflowDefinition.class);
Asserts.assertNotNull(w);
w.validate(mgmt);
Map<String, WorkflowStepDefinition> steps = w.getStepsResolved(mgmt);
- Asserts.assertSize(steps, 3);
+ Asserts.assertSize(steps, 4);
}
@Test
@@ -135,7 +136,8 @@ public class WorkflowBasicTest extends
BrooklynMgmtUnitTestSupport {
.configure(WorkflowEffector.STEPS, MutableMap.of(
"step1", MutableMap.of("type", "no-op"),
"step2", MutableMap.of("type", "set-sensor", "sensor",
"foo", "value", "bar"),
- "step3", "set-sensor integer bar = 1"
+ "step3", "set-sensor integer bar = 1",
+ "step4", "log test message"
))
);
eff.apply((EntityLocal)app);