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/07/20 00:19:45 UTC

[brooklyn-server] 01/02: allow changing return type

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 37f453c291bfb4d4b00de5c76781503407d6c213
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Tue Jul 19 20:05:19 2022 +0100

    allow changing return type
---
 .../brooklyn/tasks/kubectl/ContainerEffector.java  |  2 +-
 .../brooklyn/tasks/kubectl/ContainerSensor.java    |  2 +-
 .../tasks/kubectl/ContainerTaskFactory.java        | 29 +++++++++++++++++-----
 .../brooklyn/tasks/kubectl/ContainerTaskTest.java  | 18 +++++++-------
 4 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerEffector.java b/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerEffector.java
index 0c41de1a24..efc9950028 100644
--- a/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerEffector.java
+++ b/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerEffector.java
@@ -66,7 +66,7 @@ public class ContainerEffector extends AddEffectorInitializerAbstract implements
         @Override
         public String call(ConfigBag parameters) {
             ConfigBag configBag = ConfigBag.newInstanceCopying(this.params).putAll(parameters);
-            Task<ContainerTaskFactory.ContainerTaskResult> containerTask = new ContainerTaskFactory.ConcreteContainerTaskFactory()
+            Task<ContainerTaskFactory.ContainerTaskResult> containerTask = ContainerTaskFactory.newInstance()
                     .summary("Executing Container Image: " + EntityInitializers.resolve(configBag, CONTAINER_IMAGE))
                     .jobIdentifier(entity().getId() + "-" + EFFECTOR_TAG)
                     .configure(configBag.getAllConfig())
diff --git a/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerSensor.java b/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerSensor.java
index 7bb8dccc4e..66c9e94eef 100644
--- a/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerSensor.java
+++ b/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerSensor.java
@@ -75,7 +75,7 @@ public class ContainerSensor<T> extends AbstractAddSensorFeed<T> implements Cont
                         .callable(new Callable<Object>() {
                             @Override
                             public Object call() throws Exception {
-                                Task<ContainerTaskFactory.ContainerTaskResult> containerTask = new ContainerTaskFactory.ConcreteContainerTaskFactory()
+                                Task<ContainerTaskFactory.ContainerTaskResult> containerTask = ContainerTaskFactory.newInstance()
                                         .summary("Running " + EntityInitializers.resolve(configBag, SENSOR_NAME))
                                         .jobIdentifier(entity.getId() + "-" + SENSOR_TAG)
                                         .configure(configBag.getAllConfig())
diff --git a/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerTaskFactory.java b/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerTaskFactory.java
index a03f6f2b1a..40d01a47d7 100644
--- a/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerTaskFactory.java
+++ b/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerTaskFactory.java
@@ -55,11 +55,12 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import static org.apache.brooklyn.tasks.kubectl.ContainerCommons.*;
 
-public class ContainerTaskFactory<T extends ContainerTaskFactory<T>> implements TaskFactory<Task<ContainerTaskFactory.ContainerTaskResult>> {
+public class ContainerTaskFactory<T extends ContainerTaskFactory<T,RET>,RET> implements TaskFactory<Task<RET>> {
 
     private static final Logger LOG = LoggerFactory.getLogger(ContainerTaskFactory.class);
 
@@ -69,11 +70,12 @@ public class ContainerTaskFactory<T extends ContainerTaskFactory<T>> implements
     private String namespace;
     private Boolean createNamespace;
     private Boolean deleteNamespace;
+    Function<ContainerTaskResult,RET> returnConversion;
 
     @Override
-    public Task<ContainerTaskResult> newTask() {
+    public Task<RET> newTask() {
         final ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-        TaskBuilder<ContainerTaskResult> taskBuilder = Tasks.<ContainerTaskResult>builder().dynamic(true)
+        TaskBuilder<RET> taskBuilder = Tasks.<RET>builder().dynamic(true)
                 .displayName(this.summary)
                 .tag(BrooklynTaskTags.tagForStream(BrooklynTaskTags.STREAM_STDOUT, stdout))
                 .body(()-> {
@@ -265,7 +267,7 @@ public class ContainerTaskFactory<T extends ContainerTaskFactory<T>> implements
                                 throw new IllegalStateException("Non-zero exit code (" + result.mainExitCode + ") disallowed");
                             }
 
-                            return result;
+                            return returnConversion==null ? (RET) result : returnConversion.apply(result);
 
                         } finally {
                             // clean up - delete namespace
@@ -306,6 +308,17 @@ public class ContainerTaskFactory<T extends ContainerTaskFactory<T>> implements
     public T env(String key, Object val) {
         return env(MutableMap.copyOf( config.get(BrooklynConfigKeys.SHELL_ENVIRONMENT) ).add(key, val));
     }
+    public <RET2,T2 extends ContainerTaskFactory<T2,RET2>> T2 returning(Function<ContainerTaskResult,RET2> conversion) {
+        T2 result = (T2) self();
+        result.returnConversion = conversion;
+        return result;
+    }
+    public <T2 extends ContainerTaskFactory<T2,String>> T2 returningStdout() {
+        return returning(ContainerTaskResult::getMainStdout);
+    }
+    public <T2 extends ContainerTaskFactory<T2,Integer>> T2 returningExitCode() {
+        return returning(ContainerTaskResult::getMainExitCode);
+    }
 
     /** specify the namespace to use, and whether to create or delete it. by default a randomly generated namespace is used and always cleaned up,
      * but by using this, a caller can ensure the namespace persists. if using this, it is the caller's responsibility to avoid collisions.
@@ -347,8 +360,12 @@ public class ContainerTaskFactory<T extends ContainerTaskFactory<T>> implements
                 .requiringExitCodeZero();
     }
 
-    public static class ConcreteContainerTaskFactory extends ContainerTaskFactory<ConcreteContainerTaskFactory> {
-        public ConcreteContainerTaskFactory() {
+    public static ConcreteContainerTaskFactory<ContainerTaskResult> newInstance() {
+        return new ConcreteContainerTaskFactory<>();
+    }
+
+    public static class ConcreteContainerTaskFactory<RET> extends ContainerTaskFactory<ConcreteContainerTaskFactory<RET>,RET> {
+        private ConcreteContainerTaskFactory() {
             super();
         }
     }
diff --git a/software/base/src/test/java/org/apache/brooklyn/tasks/kubectl/ContainerTaskTest.java b/software/base/src/test/java/org/apache/brooklyn/tasks/kubectl/ContainerTaskTest.java
index 4dda230118..fa9c61df1c 100644
--- a/software/base/src/test/java/org/apache/brooklyn/tasks/kubectl/ContainerTaskTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/tasks/kubectl/ContainerTaskTest.java
@@ -47,7 +47,7 @@ public class ContainerTaskTest extends BrooklynAppUnitTestSupport {
     public void testSuccessfulContainerTask() {
         TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
 
-        Task<ContainerTaskFactory.ContainerTaskResult> containerTask =  new ContainerTaskFactory.ConcreteContainerTaskFactory()
+        Task<ContainerTaskFactory.ContainerTaskResult> containerTask =  ContainerTaskFactory.newInstance()
                 .summary("Running container task")
                 .jobIdentifier("test-container-task")
                 .imagePullPolicy(PullPolicy.IF_NOT_PRESENT)
@@ -65,7 +65,7 @@ public class ContainerTaskTest extends BrooklynAppUnitTestSupport {
     public void testContainerTaskWithVar() {
         TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
 
-        Task<ContainerTaskFactory.ContainerTaskResult> containerTask =  new ContainerTaskFactory.ConcreteContainerTaskFactory()
+        Task<ContainerTaskFactory.ContainerTaskResult> containerTask =  ContainerTaskFactory.newInstance()
                 .summary("Running container task")
                 .jobIdentifier("test-container-task")
                 .imagePullPolicy(PullPolicy.IF_NOT_PRESENT)
@@ -85,25 +85,25 @@ public class ContainerTaskTest extends BrooklynAppUnitTestSupport {
     public void testSuccessfulContainerTerraformTask() {
         TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
 
-        Task<ContainerTaskFactory.ContainerTaskResult> containerTask = new ContainerTaskFactory.ConcreteContainerTaskFactory()
+        Task<String> containerTask = ContainerTaskFactory.newInstance()
                 .summary("Running terraform-container task")
                 .jobIdentifier("test-container-task")
                 .timeout(Duration.TWO_MINUTES)
                 .image("hashicorp/terraform:latest")
                 .imagePullPolicy(PullPolicy.IF_NOT_PRESENT)
                 .command( "terraform", "version" )
+                .returningStdout()
                 .newTask();
         DynamicTasks.queueIfPossible(containerTask).orSubmitAsync(entity);
 
-        ContainerTaskFactory.ContainerTaskResult result = containerTask.getUnchecked();
-        assertTrue(result.getMainStdout().startsWith("Terraform"));
+        assertTrue(containerTask.getUnchecked().startsWith("Terraform"));
     }
 
     @Test // execute local command, assert we get exit code, and it fails
     public void testExpectedFailingContainerTask() {
         TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
 
-        Task<ContainerTaskFactory.ContainerTaskResult> containerTask =  new ContainerTaskFactory.ConcreteContainerTaskFactory()
+        Task<ContainerTaskFactory.ContainerTaskResult> containerTask =  ContainerTaskFactory.newInstance()
                 .summary("Running container task")
                 .jobIdentifier("test-container-task")
                 .imagePullPolicy(PullPolicy.IF_NOT_PRESENT)
@@ -125,7 +125,7 @@ public class ContainerTaskTest extends BrooklynAppUnitTestSupport {
     public void testSleepingAndExpectedFailingContainerTask() {
         TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
 
-        Task<ContainerTaskFactory.ContainerTaskResult> containerTask =  new ContainerTaskFactory.ConcreteContainerTaskFactory()
+        Task<ContainerTaskFactory.ContainerTaskResult> containerTask =  ContainerTaskFactory.newInstance()
                 .summary("Running container task")
                 .jobIdentifier("test-container-task")
                 .imagePullPolicy(PullPolicy.IF_NOT_PRESENT)
@@ -159,7 +159,7 @@ public class ContainerTaskTest extends BrooklynAppUnitTestSupport {
     public void testNotExpectedFailingContainerTask() {
         TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
 
-        Task<ContainerTaskFactory.ContainerTaskResult> containerTask =  new ContainerTaskFactory.ConcreteContainerTaskFactory()
+        Task<ContainerTaskFactory.ContainerTaskResult> containerTask =  ContainerTaskFactory.newInstance()
                 .summary("Running container task")
                 .jobIdentifier("test-container-task")
                 .imagePullPolicy(PullPolicy.IF_NOT_PRESENT)
@@ -191,7 +191,7 @@ public class ContainerTaskTest extends BrooklynAppUnitTestSupport {
         configBag.put("volumes", Sets.newHashSet(volumes));
         configBag.put("volumeMounts", Sets.newHashSet(Maps.newHashMap("name", volumeId, "mountPath", "/brooklyn-mount-dir")));
 
-        ContainerTaskFactory.ConcreteContainerTaskFactory baseFactory = new ContainerTaskFactory.ConcreteContainerTaskFactory()
+        ContainerTaskFactory.ConcreteContainerTaskFactory baseFactory = ContainerTaskFactory.newInstance()
                 .summary("Running container task")
                 .jobIdentifier("test-container-task")
                 .imagePullPolicy(PullPolicy.IF_NOT_PRESENT)