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"));
+
+    }
+
 }

Reply via email to