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 c0b03e152a1d05f261a64fc06deb6a4df2478ddf Author: Alex Heneveld <[email protected]> AuthorDate: Fri Dec 2 10:21:50 2022 +0000 add a workflow.util expression namespace with time and random capabilities --- .../workflow/WorkflowExpressionResolution.java | 27 +++++++++++++++ .../workflow/WorkflowInputOutputExtensionTest.java | 40 ++++++++++++++++++++++ 2 files changed, 67 insertions(+) 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 4faeb11519..eede7a77c6 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 @@ -37,9 +37,11 @@ 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.javalang.Boxing; +import org.apache.brooklyn.util.time.Time; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.time.Instant; import java.util.*; import java.util.concurrent.Callable; import java.util.function.Supplier; @@ -228,6 +230,7 @@ public class WorkflowExpressionResolution { if ("current_step".equals(key)) return new WorkflowStepModel(currentStepInstance); if ("previous_step".equals(key)) return newWorkflowStepModelForStepIndex(context.previousStepIndex); if ("step".equals(key)) return new WorkflowStepModel(); + if ("util".equals(key)) return new WorkflowUtilModel(); if ("var".equals(key)) return TemplateProcessor.wrapAsTemplateModel(context.workflowScratchVariables); @@ -291,6 +294,30 @@ public class WorkflowExpressionResolution { } } + class WorkflowUtilModel implements TemplateHashModel { + + WorkflowUtilModel() {} + @Override + public TemplateModel get(String key) throws TemplateModelException { + + //id (a token representing an item uniquely within its root instance) + if ("now".equals(key)) return TemplateProcessor.wrapAsTemplateModel(System.currentTimeMillis()); + if ("now_utc".equals(key)) return TemplateProcessor.wrapAsTemplateModel(System.currentTimeMillis()); + if ("now_instant".equals(key)) return TemplateProcessor.wrapAsTemplateModel(Instant.now()); + if ("now_iso".equals(key)) return TemplateProcessor.wrapAsTemplateModel(Time.makeIso8601DateStringZ(Instant.now())); + if ("now_stamp".equals(key)) return TemplateProcessor.wrapAsTemplateModel(Time.makeDateStampString()); + if ("now_nice".equals(key)) return TemplateProcessor.wrapAsTemplateModel(Time.makeDateString(Instant.now())); + if ("random".equals(key)) return TemplateProcessor.wrapAsTemplateModel(Math.random()); + + return ifNoMatches(); + } + + @Override + public boolean isEmpty() throws TemplateModelException { + return false; + } + } + public <T> T resolveWithTemplates(Object expression, TypeToken<T> type) { expression = processTemplateExpression(expression); return resolveCoercingOnly(expression, type); diff --git a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowInputOutputExtensionTest.java b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowInputOutputExtensionTest.java index a15376328c..ecd28d2f31 100644 --- a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowInputOutputExtensionTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowInputOutputExtensionTest.java @@ -23,6 +23,7 @@ import org.apache.brooklyn.api.entity.EntityLocal; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.mgmt.Task; 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.BeanWithTypePlanTransformer; import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils; @@ -44,6 +45,7 @@ import org.apache.brooklyn.util.text.StringEscapes; import org.apache.brooklyn.util.text.Strings; import org.testng.annotations.Test; +import java.time.Instant; import java.util.List; import java.util.Map; import java.util.function.BiFunction; @@ -669,4 +671,42 @@ public class WorkflowInputOutputExtensionTest extends BrooklynMgmtUnitTestSuppor Asserts.assertEquals(app.invoke(app.getEntityType().getEffectorByName("myWorkflow").get(), MutableMap.of("x", "A")).getUnchecked(), "Zzz"); } + @Test + public void testUtil() throws JsonProcessingException { + loadTypes(); + BasicApplication app = mgmt.getEntityManager().createEntity(EntitySpec.create(BasicApplication.class)); + + WorkflowEffector eff = new WorkflowEffector(ConfigBag.newInstance() + .configure(WorkflowEffector.EFFECTOR_NAME, "myWorkflow") + .configure(WorkflowEffector.EFFECTOR_PARAMETER_DEFS, MutableMap.of("x", null)) + .configure(WorkflowEffector.STEPS, MutableList.<Object>of( + "set-sensor random = ${workflow.util.random}", + "set-sensor random2 = ${workflow.util.random}", + "set-sensor now = ${workflow.util.now}", + "set-sensor now_utc = ${workflow.util.now_utc}", + "set-sensor now_instant = ${workflow.util.now_instant}", + "set-sensor now_stamp = ${workflow.util.now_stamp}", + "set-sensor now_iso = ${workflow.util.now_iso}", + "set-sensor now_nice = ${workflow.util.now_nice}" + )) + ); + eff.apply((EntityLocal) app); + + app.invoke(app.getEntityType().getEffectorByName("myWorkflow").get(), null).getUnchecked(); + Dumper.dumpInfo(app); + + EntityAsserts.assertAttribute(app, Sensors.newSensor(Double.class, "random"), x -> x>0); + EntityAsserts.assertAttribute(app, Sensors.newSensor(Double.class, "random2"), x -> x>0); + EntityAsserts.assertAttribute(app, Sensors.newSensor(Double.class, "random"), x -> !app.sensors().get(Sensors.newSensor(Double.class, "random2")).equals(x)); + + EntityAsserts.assertAttribute(app, Sensors.newSensor(Long.class, "now"), l -> l > System.currentTimeMillis() - 5*1000 && l <= System.currentTimeMillis()); + EntityAsserts.assertAttribute(app, Sensors.newSensor(Long.class, "now_utc"), l -> l > System.currentTimeMillis() - 5*1000 && l <= System.currentTimeMillis()); + + EntityAsserts.assertAttribute(app, Sensors.newSensor(Instant.class, "now_instant"), l -> l.toEpochMilli() > System.currentTimeMillis() - 5*1000 && l.toEpochMilli() <= System.currentTimeMillis()); + EntityAsserts.assertAttribute(app, Sensors.newSensor(String.class, "now_iso"), l -> l.startsWith("202") && l.endsWith("Z")); + EntityAsserts.assertAttribute(app, Sensors.newSensor(String.class, "now_nice"), l -> l.startsWith("202")); + EntityAsserts.assertAttribute(app, Sensors.newSensor(String.class, "now_stamp"), l -> l.startsWith("202")); + + } + }
