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 51ea8b0cb3f8c4bbaba04406e5f143352edc6e78
Author: Alex Heneveld <[email protected]>
AuthorDate: Fri Nov 4 16:28:42 2022 +0000

    add load workflow step
---
 .../core/workflow/steps/LoadWorkflowStep.java      | 105 +++++++++++++++++++++
 .../core/workflow/steps/SetSensorWorkflowStep.java |   2 +-
 .../apache/brooklyn/util/core/ResourceUtils.java   |  11 +++
 .../brooklyn/core/workflow/WorkflowBasicTest.java  |   1 +
 .../workflow/WorkflowInputOutputExtensionTest.java |   9 ++
 karaf/init/src/main/resources/catalog.bom          |   7 +-
 .../org/apache/brooklyn/util/stream/Streams.java   |  14 ++-
 7 files changed, 146 insertions(+), 3 deletions(-)

diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/LoadWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/LoadWorkflowStep.java
new file mode 100644
index 0000000000..73ccd2afb8
--- /dev/null
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/LoadWorkflowStep.java
@@ -0,0 +1,105 @@
+/*
+ * 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 com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.reflect.TypeToken;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils;
+import org.apache.brooklyn.core.resolve.jackson.BrooklynJacksonType;
+import org.apache.brooklyn.core.workflow.WorkflowStepDefinition;
+import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
+import org.apache.brooklyn.util.collections.CollectionMerger;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.collections.MutableSet;
+import org.apache.brooklyn.util.core.ResourceUtils;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+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.text.QuotedStringTokenizer;
+import org.apache.brooklyn.util.text.Strings;
+import org.apache.brooklyn.util.yaml.Yamls;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.charset.Charset;
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class LoadWorkflowStep extends WorkflowStepDefinition {
+
+    private static final Logger log = 
LoggerFactory.getLogger(LoadWorkflowStep.class);
+
+    public static final String SHORTHAND =
+            "[ \"charset\" ${charset} ] [ ${variable.type} ] ${variable.name} 
[ \"=\" ${url...} ]";
+
+    public static final ConfigKey<TypedValueToSet> VARIABLE = 
ConfigKeys.newConfigKey(TypedValueToSet.class, "variable");
+    public static final ConfigKey<Object> URL = 
ConfigKeys.newConfigKey(Object.class, "url");
+    public static final ConfigKey<String> CHARSET = 
ConfigKeys.newStringConfigKey("charset");
+
+    @Override
+    public void populateFromShorthand(String expression) {
+        populateFromShorthandTemplate(SHORTHAND, expression, true);
+    }
+
+    @Override
+    public void validateStep() {
+        super.validateStep();
+        if (!input.containsKey(VARIABLE.getName())) {
+            throw new IllegalArgumentException("Variable name is required");
+        }
+        if (!input.containsKey(URL.getName())) {
+            throw new IllegalArgumentException("url is required");
+        }
+    }
+
+    @Override
+    protected Object doTaskBody(WorkflowStepInstanceExecutionContext context) {
+        TypedValueToSet variable = context.getInput(VARIABLE);
+        if (variable ==null) throw new IllegalArgumentException("Variable name 
is required");
+        String name = context.resolve(variable.name, String.class);
+        if (Strings.isBlank(name)) throw new 
IllegalArgumentException("Variable name is required");
+        TypeToken<?> type = context.lookupType(variable.type, () -> 
TypeToken.of(String.class));
+
+        Object url = context.getInput(URL);
+
+        ResourceUtils r = ResourceUtils.create(context.getEntity());
+
+        String csName = context.getInput(CHARSET);
+        String data;
+        if (Strings.isNonBlank(csName)) {
+            data = r.getResourceAsString("" + url, Charset.forName(csName));
+        } else {
+            data = r.getResourceAsString("" + url);
+        }
+        Object resolvedValue = context.resolve(data, type);
+
+        Object oldValue = 
context.getWorkflowExectionContext().getWorkflowScratchVariables().put(name, 
resolvedValue);
+
+        if (oldValue!=null) context.noteOtherMetadata("Previous value", 
oldValue);
+        return context.getPreviousStepOutput();
+    }
+}
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/SetSensorWorkflowStep.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/SetSensorWorkflowStep.java
index f22cc4f517..36154b7f7b 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/SetSensorWorkflowStep.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/SetSensorWorkflowStep.java
@@ -52,8 +52,8 @@ public class SetSensorWorkflowStep extends 
WorkflowStepDefinition {
         String sensorName = context.resolve(sensor.name, String.class);
         if (Strings.isBlank(sensorName)) throw new 
IllegalArgumentException("Sensor name is required");
         TypeToken<?> type = context.lookupType(sensor.type, () -> 
TypeToken.of(Object.class));
-        Object resolvedValue = context.getInput(VALUE.getName(), type);
         Entity entity = sensor.entity;
+        Object resolvedValue = context.getInput(VALUE.getName(), type);
         if (entity==null) entity = context.getEntity();
         AttributeSensor<Object> s = (AttributeSensor<Object>) 
Sensors.newSensor(type, sensorName);
         Object oldValue = entity.sensors().set( s, resolvedValue);
diff --git 
a/core/src/main/java/org/apache/brooklyn/util/core/ResourceUtils.java 
b/core/src/main/java/org/apache/brooklyn/util/core/ResourceUtils.java
index 1191b05125..2ec9da8b6e 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/ResourceUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/ResourceUtils.java
@@ -30,6 +30,7 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLDecoder;
+import java.nio.charset.Charset;
 import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.function.Supplier;
@@ -538,6 +539,16 @@ public class ResourceUtils {
         }
     }
 
+    /** takes {@link #getResourceFromUrl(String)} and reads fully, into a 
string */
+    public String getResourceAsString(String url, Charset charset) {
+        try {
+            return Streams.readFullyStringAndClose(getResourceFromUrl(url), 
charset);
+        } catch (Exception e) {
+            log.debug("ResourceUtils got error reading 
"+url+(context==null?"":" "+context)+" (rethrowing): "+e);
+            throw Throwables.propagate(e);
+        }
+    }
+
     /** @see #checkUrlExists(String, String) */
     public String checkUrlExists(String url) {
         return checkUrlExists(url, null);
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 8de3bf29b9..9788b088b4 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
@@ -85,6 +85,7 @@ public class WorkflowBasicTest extends 
BrooklynMgmtUnitTestSupport {
         addRegisteredTypeBean(mgmt, "set-sensor", SetSensorWorkflowStep.class);
         addRegisteredTypeBean(mgmt, "clear-sensor", 
ClearSensorWorkflowStep.class);
         addRegisteredTypeBean(mgmt, "let", SetVariableWorkflowStep.class);
+        addRegisteredTypeBean(mgmt, "load", LoadWorkflowStep.class);
         addRegisteredTypeBean(mgmt, "set-workflow-variable", 
SetVariableWorkflowStep.class);
         addRegisteredTypeBean(mgmt, "clear-workflow-variable", 
ClearVariableWorkflowStep.class);
         addRegisteredTypeBean(mgmt, "wait", WaitWorkflowStep.class);
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 33ebd0242a..3f335b089d 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
@@ -491,4 +491,13 @@ public class WorkflowInputOutputExtensionTest extends 
BrooklynMgmtUnitTestSuppor
             "1", "3",  "4", "12"
         ));
     }
+
+    @Test
+    public void testLoadData() throws Exception {
+        Object output = invokeWorkflowStepsWithLogging(MutableList.of(
+                "load x = classpath://hello-world.txt",
+                "return ${x}"));
+        Asserts.assertStringContains((String)output, "The file hello-world.war 
contains its source code.");
+    }
+
 }
diff --git a/karaf/init/src/main/resources/catalog.bom 
b/karaf/init/src/main/resources/catalog.bom
index bd9472ea1d..b5cbfbfbdd 100644
--- a/karaf/init/src/main/resources/catalog.bom
+++ b/karaf/init/src/main/resources/catalog.bom
@@ -19,7 +19,7 @@ brooklyn.catalog:
   version: "1.1.0-SNAPSHOT" # BROOKLYN_VERSION
 
   items:
-  # provides aliases for the most common items
+  # provides aliases for the most common items
   # (used to import the other bundles but now this is done by dist feature 
catalog-core)
   - id: server
     iconUrl: classpath://brooklyn/icons/server.svg
@@ -129,6 +129,11 @@ brooklyn.catalog:
     itemType: bean
     item:
       type: org.apache.brooklyn.core.workflow.steps.WaitWorkflowStep
+  - id: load
+    format: java-type-name
+    itemType: bean
+    item:
+      type: org.apache.brooklyn.core.workflow.steps.LoadWorkflowStep
   - id: return
     format: java-type-name
     itemType: bean
diff --git 
a/utils/common/src/main/java/org/apache/brooklyn/util/stream/Streams.java 
b/utils/common/src/main/java/org/apache/brooklyn/util/stream/Streams.java
index a14f8b2feb..c6456f2e8c 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/stream/Streams.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/stream/Streams.java
@@ -86,6 +86,7 @@ public class Streams {
     }
     
     public static Reader reader(InputStream stream, Charset charset) {
+        if (charset==null) return new InputStreamReader(stream);
         return new InputStreamReader(stream, charset);
     }
 
@@ -128,8 +129,19 @@ public class Streams {
     }
 
     public static String readFullyStringAndClose(InputStream is) {
+        return readFullyStringAndClose(is, null);
+    }
+
+    /**
+     * Consider using {@link #readFullyStringAndClose(InputStream)} instead.
+     */
+    public static String readFullyString(InputStream is, Charset charset) {
+        return readFully(reader(is, charset));
+    }
+
+    public static String readFullyStringAndClose(InputStream is, Charset 
charset) {
         try {
-            return readFullyString(is);
+            return readFullyString(is, charset);
         } finally {
             Streams.closeQuietly(is);
         }

Reply via email to