brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aleds...@apache.org
Subject [3/5] brooklyn-server git commit: $brooklyn:object: support explicit “deferred”
Date Fri, 10 Mar 2017 13:51:15 GMT
$brooklyn:object: support explicit “deferred”

YAML authors can specify “deferred”, to force the object to only be
constructed when the config is being retrieved.


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/b2fd0e81
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/b2fd0e81
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/b2fd0e81

Branch: refs/heads/master
Commit: b2fd0e81761b30e963ffe12ae6108565d5f2ed1a
Parents: 2fe2ba0
Author: Aled Sage <aled.sage@gmail.com>
Authored: Wed Mar 8 20:37:41 2017 +0000
Committer: Aled Sage <aled.sage@gmail.com>
Committed: Wed Mar 8 23:45:40 2017 +0000

----------------------------------------------------------------------
 .../spi/dsl/methods/BrooklynDslCommon.java      |   4 +-
 .../brooklyn/camp/brooklyn/ObjectsYamlTest.java | 101 +++++++++++++++++++
 2 files changed, 104 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/b2fd0e81/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
index 2836895..2bc8878 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
@@ -56,6 +56,7 @@ import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.flags.FlagUtils;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.core.task.DeferredSupplier;
 import org.apache.brooklyn.util.core.task.ImmediateSupplier;
 import org.apache.brooklyn.util.core.task.Tasks;
@@ -292,6 +293,7 @@ public class BrooklynDslCommon {
         List<Object> factoryMethodArgs = (List<Object>) config.getStringKeyMaybe("factoryMethod.args").or(ImmutableList.of());
         Map<String,Object> objectFields = (Map<String, Object>) config.getStringKeyMaybe("object.fields").or(MutableMap.of());
         Map<String,Object> brooklynConfig = (Map<String, Object>) config.getStringKeyMaybe(BrooklynCampReservedKeys.BROOKLYN_CONFIG).or(MutableMap.of());
+        boolean deferred = TypeCoercions.coerce(config.getStringKeyMaybe("deferred").or(Boolean.FALSE),
Boolean.class);
 
         String mappedTypeName = DeserializingClassRenamesProvider.INSTANCE.findMappedName(typeName);
         Class<?> type;
@@ -302,7 +304,7 @@ public class BrooklynDslCommon {
             return new DslObject(mappedTypeName, constructorArgs, objectFields, brooklynConfig);
         }
 
-        if (resolved(constructorArgs) && resolved(factoryMethodArgs) && resolved(objectFields.values())
&& resolved(brooklynConfig.values())) {
+        if (!deferred && resolved(constructorArgs) && resolved(factoryMethodArgs)
&& resolved(objectFields.values()) && resolved(brooklynConfig.values())) {
             if (factoryMethodName == null) {
                 return DslObject.create(type, constructorArgs, objectFields, brooklynConfig);
             } else {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/b2fd0e81/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ObjectsYamlTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ObjectsYamlTest.java
b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ObjectsYamlTest.java
index b15097d..01aa477 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ObjectsYamlTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ObjectsYamlTest.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.camp.brooklyn;
 
 import static org.testng.Assert.assertEquals;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -34,6 +35,7 @@ import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
 import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.flags.SetFromFlag;
@@ -45,6 +47,7 @@ import org.testng.annotations.Test;
 
 import com.google.common.base.Charsets;
 import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.hash.HashCode;
@@ -586,6 +589,104 @@ public class ObjectsYamlTest extends AbstractYamlTest {
         assertEquals(sha256, PasswordHasher.sha256(salt, "mypassword"));
     }
 
+    @Test
+    public void testBrooklynObjectEvaluatedImmediatelyOnlyOnce() throws Exception {
+        CallRecorder.clear();
+        Entity entity = setupAndCheckTestEntityInBasicYamlWith(
+            "  brooklyn.config:",
+            "    test.confObject:",
+            "      $brooklyn:object:",
+            "        type: "+CallRecorder.class.getName(),
+            "        factoryMethod.name: call",
+            "        factoryMethod.args:",
+            "        - myval");
+        
+        // Nothing has called config().get() yet; but expect it to have been evaluated immediate,
on entity construction
+        assertEquals(CallRecorder.getCalls(), ImmutableList.of("myval"));
+
+        // The config value is set to the result of that single call; getting the config
will not invoke it again
+        Object val = entity.config().get(TestEntity.CONF_OBJECT);
+        assertEquals(val, "myval");
+        assertEquals(CallRecorder.getCalls(), ImmutableList.of("myval"));
+    }
+
+    @Test
+    public void testBrooklynObjectEvaluationDeferredIfRequired() throws Exception {
+        CallRecorder.clear();
+        Entity entity = setupAndCheckTestEntityInBasicYamlWith(
+            "  brooklyn.config:",
+            "    anotherConfig: myval",
+            "    test.confObject:",
+            "      $brooklyn:object:",
+            "        type: "+CallRecorder.class.getName(),
+            "        factoryMethod.name: call",
+            "        factoryMethod.args:",
+            "        - $brooklyn:config(\"anotherConfig\")");
+        
+        // The value is a DeferredSupplier; nothing in the blueprint will have called config().get()
yet.
+        // However, verification will have called it! Therefore not doing:
+        //   assertEquals(CallRecorder.getCalls(), ImmutableList.of());
+        CallRecorder.clear();
+
+        // Retrieving the config value causes it to be resolved
+        Object val = entity.config().get(TestEntity.CONF_OBJECT);
+        assertEquals(val, "myval");
+        assertEquals(CallRecorder.getCalls(), ImmutableList.of("myval"));
+        
+        // Retrieving the config value a second time will resolve it again
+        Object val2 = entity.config().get(TestEntity.CONF_OBJECT);
+        assertEquals(val2, "myval");
+        assertEquals(CallRecorder.getCalls(), ImmutableList.of("myval", "myval"));
+    }
+
+    @Test
+    public void testBrooklynObjectEvaluationExplicitlyDeferred() throws Exception {
+        CallRecorder.clear();
+        Entity entity = setupAndCheckTestEntityInBasicYamlWith(
+            "  brooklyn.config:",
+            "    test.confObject:",
+            "      $brooklyn:object:",
+            "        deferred: true",
+            "        type: "+CallRecorder.class.getName(),
+            "        factoryMethod.name: call",
+            "        factoryMethod.args:",
+            "        - myval");
+        
+        // The value is a DeferredSupplier; nothing in the blueprint will have called config().get()
yet.
+        // However, verification will have called it! Therefore not doing:
+        //   assertEquals(CallRecorder.getCalls(), ImmutableList.of());
+        CallRecorder.clear();
+
+        // Retrieving the config value causes it to be resolved
+        Object val = entity.config().get(TestEntity.CONF_OBJECT);
+        assertEquals(val, "myval");
+        assertEquals(CallRecorder.getCalls(), ImmutableList.of("myval"));
+        
+        // Retrieving the config value a second time will resolve it again
+        Object val2 = entity.config().get(TestEntity.CONF_OBJECT);
+        assertEquals(val2, "myval");
+        assertEquals(CallRecorder.getCalls(), ImmutableList.of("myval", "myval"));
+    }
+
+    public static class CallRecorder {
+        private static final List<String> calls = Collections.synchronizedList(Lists.<String>newArrayList());
+        
+        public static String call(String val) {
+            calls.add(val);
+            return val;
+        }
+        
+        public static void clear() {
+            calls.clear();
+        }
+        
+        public static List<String> getCalls() {
+            synchronized (calls) {
+                return MutableList.copyOf(calls);
+            }
+        }
+    }
+
     @Override
     protected Logger getLogger() {
         return log;


Mime
View raw message