brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From grk...@apache.org
Subject [09/13] git commit: Changed to commons-beanutils to construct objects and added more tests
Date Sun, 05 Oct 2014 22:44:33 GMT
Changed to commons-beanutils to construct objects and added more tests


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

Branch: refs/heads/master
Commit: 3fb2ef5c694e7aabf33e00488c9289c235218f6c
Parents: e695471
Author: Andrew Kennedy <grkvlt@apache.org>
Authored: Sat Sep 27 01:36:07 2014 +0100
Committer: Andrew Kennedy <grkvlt@apache.org>
Committed: Sun Oct 5 19:45:54 2014 +0100

----------------------------------------------------------------------
 usage/camp/pom.xml                              |   9 +-
 .../creation/BrooklynYamlTypeInstantiator.java  |   2 +-
 .../spi/dsl/methods/BrooklynDslCommon.java      |  50 ++++---
 .../camp/brooklyn/MapReferenceYamlTest.java     | 132 +++++++++++++++++++
 .../brooklyn/camp/brooklyn/ObjectsYamlTest.java |  55 ++++++--
 .../test-entity-reference-map-template.yaml     |  28 ++++
 6 files changed, 247 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3fb2ef5c/usage/camp/pom.xml
----------------------------------------------------------------------
diff --git a/usage/camp/pom.xml b/usage/camp/pom.xml
index a066c14..433f07c 100644
--- a/usage/camp/pom.xml
+++ b/usage/camp/pom.xml
@@ -73,7 +73,14 @@
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
-        
+
+        <!-- for $brooklyn:object -->
+        <dependency>
+            <groupId>commons-beanutils</groupId>
+            <artifactId>commons-beanutils</artifactId>
+            <version>1.9.1</version>
+        </dependency>
+
         <!-- TODO not enamoured of including software-base here, but it allows us to reference
chef and vanilla for short names;
              ideally there is a mixin strategy by which they can be discovered (eg using
java service discovery) -->
         <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3fb2ef5c/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
index ae3fb31..6046491 100644
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
+++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
@@ -179,7 +179,7 @@ public abstract class BrooklynYamlTypeInstantiator {
     public abstract Maybe<String> getTypeName();
     
     public BrooklynClassLoadingContext getClassLoadingContext() {
-        Preconditions.checkNotNull("No factory set; cannot use this instance for type loading");
+        Preconditions.checkNotNull(factory, "No factory set; cannot use this instance for
type loading");
         return factory.loader;
     }
     

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3fb2ef5c/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
index 6a50eef..a9a80a6 100644
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
+++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
@@ -28,6 +28,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.beanutils.BeanUtils;
+
 import brooklyn.entity.Entity;
 import brooklyn.entity.basic.EntityDynamicType;
 import brooklyn.event.Sensor;
@@ -38,22 +40,17 @@ import brooklyn.management.TaskFactory;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.javalang.Reflections;
 import brooklyn.util.task.DeferredSupplier;
 
 import com.google.common.base.Function;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import com.google.gson.Gson;
 
 /** static import functions which can be used in `$brooklyn:xxx` contexts */
 public class BrooklynDslCommon {
 
-    private static final ThreadLocal<Gson> gson = new ThreadLocal<Gson>() {
-        protected Gson initialValue() {
-            return new Gson();
-        }
-    };
-
     // Access specific entities
 
     public static DslComponent entity(String scopeOrId) {
@@ -135,18 +132,27 @@ public class BrooklynDslCommon {
      * yet fully resolved.
      */
     public static Object object(Map<String, Object> arguments) {
+        ConfigBag config = ConfigBag.newInstance(arguments);
+        String typeName = BrooklynYamlTypeInstantiator.InstantiatorFromKey.extractTypeName("object",
config).orNull();
+        Map<String,Object> fields = Maybe.fromNullable((Map<String, Object>)
config.getStringKey("object.fields"))
+                .or(MutableMap.<String, Object>of());
         try {
-            ConfigBag config = ConfigBag.newInstance(arguments);
-            String typeName = BrooklynYamlTypeInstantiator.InstantiatorFromKey.extractTypeName("object",
config).orNull();
-            Map<String,Object> fields = (Map<String, Object>) config.getStringKey("object.fields");
             Class<?> type = Class.forName(typeName);
-            if (DslUtils.resolved(fields.values())) {
-                String json = gson.get().toJson(fields);
-                return gson.get().fromJson(json, type);
+            if (!Reflections.hasNoArgConstructor(type)) {
+                throw new IllegalStateException(String.format("Cannot construct %s bean:
No public no-arg constructor available present", type));
+            }
+            if (fields.isEmpty() || DslUtils.resolved(fields.values())) {
+                try {
+                    Object bean = Reflections.invokeConstructorWithArgs(type).get();
+                    BeanUtils.populate(bean, fields);
+                    return bean;
+                } catch (Exception e) {
+                    throw Exceptions.propagate(e);
+                }
             } else {
                 return new DslObject(type, fields);
             }
-        } catch (Exception e) {
+        } catch (ClassNotFoundException e) {
             throw Exceptions.propagate(e);
         }
     }
@@ -162,12 +168,13 @@ public class BrooklynDslCommon {
      * Returns a formatted string or a {@link BrooklynDslDeferredSupplier} if the arguments
      * are not yet fully resolved.
      */
-    public static Object formatString(final String pattern, final Object ...args) {
+    public static Object formatString(final String pattern, final Object...args) {
         if (DslUtils.resolved(args)) {
             // if all args are resolved, apply the format string now
             return String.format(pattern, args);
+        } else {
+            return new DslFormatString(pattern, args);
         }
-        return new DslFormatString(pattern, args);
     }
 
     /**
@@ -236,11 +243,16 @@ public class BrooklynDslCommon {
                                 } else if (fieldValue instanceof DeferredSupplier) {
                                      output.put(fieldName, ((DeferredSupplier<?>) fieldValue).get());
                                 } else {
-                                     output.put(fieldName, fieldValue);
+                                    output.put(fieldName, fieldValue);
                                 }
                             }
-                            String json = gson.get().toJson(output);
-                            return gson.get().fromJson(json, type);
+                            try {
+                                Object bean = Reflections.invokeConstructorWithArgs(type).get();
+                                BeanUtils.populate(bean, output);
+                                return bean;
+                            } catch (Exception e) {
+                                throw Exceptions.propagate(e);
+                            }
                         }
                     }, tasks);
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3fb2ef5c/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/MapReferenceYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/MapReferenceYamlTest.java
b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/MapReferenceYamlTest.java
new file mode 100644
index 0000000..72ca01e
--- /dev/null
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/MapReferenceYamlTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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 io.brooklyn.camp.brooklyn;
+
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BasicEntity;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.proxy.ProxySslConfig;
+import brooklyn.test.entity.TestEntity;
+import brooklyn.util.task.Tasks;
+
+import com.google.common.collect.Iterables;
+
+@Test
+public class MapReferenceYamlTest extends AbstractYamlTest {
+    private static final Logger log = LoggerFactory.getLogger(MapReferenceYamlTest.class);
+
+    protected Entity setupAndCheckTestEntityInBasicYamlWith(String ...extras) throws Exception
{
+        Entity app = createAndStartApplication(loadYaml("test-entity-reference-map-template.yaml",
extras));
+        waitForApplicationTasks(app);
+
+        Assert.assertEquals(app.getDisplayName(), "test-entity-reference-map-template");
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+
+        Assert.assertEquals(Iterables.size(app.getChildren()), 3, "Expected app to have child
entity");
+        Iterable<BasicEntity> basicEntities = Iterables.filter(app.getChildren(), BasicEntity.class);
+        Iterable<TestEntity> testEntities = Iterables.filter(app.getChildren(), TestEntity.class);
+        Assert.assertEquals(Iterables.size(basicEntities), 2, "Expected app to have two basic
entities");
+        Assert.assertEquals(Iterables.size(testEntities), 1, "Expected app to have one test
entity");
+
+        return Iterables.getOnlyElement(testEntities);
+    }
+
+    @Test
+    public void testSingleEntity() throws Exception {
+        setupAndCheckTestEntityInBasicYamlWith();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testBrooklynConfigWithMapFunction() throws Exception {
+        final Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
+            "  brooklyn.config:",
+            "    test.confMapThing.obj:",
+            "      frog: $brooklyn:formatString(\"%s\", \"frog\")",
+            "      object:",
+            "        $brooklyn:object:",
+            "          type: brooklyn.entity.proxy.ProxySslConfig",
+            "      one: $brooklyn:entity(\"one\")",
+            "      two: $brooklyn:entity(\"two\")");
+
+        Map<?,?> testMap = (Map) Entities.submit(testEntity, Tasks.builder().body(new
Callable<Object>() {
+            @Override
+            public Object call() throws Exception {
+                return testEntity.getConfig(TestEntity.CONF_MAP_THING_OBJECT);
+            }
+        }).build()).get();
+        Object frog = testMap.get("frog");
+        Object one = testMap.get("one");
+        Object two = testMap.get("two");
+        Object object = testMap.get("object");
+
+        Assert.assertTrue(frog instanceof String, "Should have found a String: " + frog);
+        Assert.assertEquals(frog, "frog", "Should have found a formatted String: " + frog);
+        Assert.assertTrue(object instanceof ProxySslConfig, "Should have found a ProxySslConfig:
" + object);
+        Assert.assertTrue(one instanceof BasicEntity, "Should have found a BasicEntity: "
+ one);
+        Assert.assertTrue(two instanceof BasicEntity, "Should have found a BasicEntity: "
+ two);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testBrooklynConfigWithPlainMapFunction() throws Exception {
+        final Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
+            "  brooklyn.config:",
+            "    test.confMapPlain:",
+            "      frog: $brooklyn:formatString(\"%s\", \"frog\")",
+            "      object:",
+            "        $brooklyn:object:",
+            "          type: brooklyn.entity.proxy.ProxySslConfig",
+            "      one: $brooklyn:entity(\"one\")",
+            "      two: $brooklyn:entity(\"two\")");
+
+        Map<?,?> testMap = (Map) Entities.submit(testEntity, Tasks.builder().body(new
Callable<Object>() {
+            @Override
+            public Object call() throws Exception {
+                return testEntity.getConfig(TestEntity.CONF_MAP_PLAIN);
+            }
+        }).build()).get();
+        Object frog = testMap.get("frog");
+        Object one = testMap.get("one");
+        Object two = testMap.get("two");
+        Object object = testMap.get("object");
+
+        Assert.assertTrue(frog instanceof String, "Should have found a String: " + frog);
+        Assert.assertEquals(frog, "frog", "Should have found a formatted String: " + frog);
+        Assert.assertTrue(object instanceof ProxySslConfig, "Should have found a ProxySslConfig:
" + object);
+        Assert.assertTrue(one instanceof BasicEntity, "Should have found a BasicEntity: "
+ one);
+        Assert.assertTrue(two instanceof BasicEntity, "Should have found a BasicEntity: "
+ two);
+    }
+
+    @Override
+    protected Logger getLogger() {
+        return log;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3fb2ef5c/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ObjectsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ObjectsYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ObjectsYamlTest.java
index 925d63c..1572c31 100644
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ObjectsYamlTest.java
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ObjectsYamlTest.java
@@ -18,6 +18,7 @@
  */
 package io.brooklyn.camp.brooklyn;
 
+import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.slf4j.Logger;
@@ -27,6 +28,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.Entity;
 import brooklyn.entity.basic.Entities;
+import brooklyn.entity.proxy.ProxySslConfig;
 import brooklyn.management.ManagementContext;
 import brooklyn.management.ManagementContextInjectable;
 import brooklyn.test.entity.TestEntity;
@@ -40,6 +42,7 @@ public class ObjectsYamlTest extends AbstractYamlTest {
     public static class TestObject implements ManagementContextInjectable {
         private String string;
         private Integer number;
+        private Object object;
 
         public TestObject() { }
 
@@ -49,6 +52,9 @@ public class ObjectsYamlTest extends AbstractYamlTest {
         public Integer getNumber() { return number; }
         public void setNumber(Integer number) { this.number = number; }
 
+        public Object getObject() { return object; }
+        public void setObject(Object object) { this.object = object; }
+
         @Override
         public void injectManagementContext(ManagementContext managementContext) {
             log.info("Detected injection of {}", managementContext);
@@ -85,17 +91,44 @@ public class ObjectsYamlTest extends AbstractYamlTest {
             "  brooklyn.config:",
             "    test.confObject:",
             "      $brooklyn:object:",
-            "        objectType: io.brooklyn.camp.brooklyn.ObjectsYamlTest$TestObject",
+            "        type: io.brooklyn.camp.brooklyn.ObjectsYamlTest$TestObject",
             "        object.fields:",
-            "          number: 5",
+            "          number: 7",
+            "          object:",
+            "            $brooklyn:object:",
+            "              type: brooklyn.entity.proxy.ProxySslConfig",
             "          string: \"frog\"");
 
         Object testObject = testEntity.getConfig(TestEntity.CONF_OBJECT);
 
-        Assert.assertTrue(testObject instanceof TestObject);
+        Assert.assertTrue(testObject instanceof TestObject, "Expected a TestObject: "+testObject);
         Assert.assertTrue(managementContextInjected.get());
-        Assert.assertEquals(((TestObject) testObject).getNumber(), Integer.valueOf(5));
+        Assert.assertEquals(((TestObject) testObject).getNumber(), Integer.valueOf(7));
         Assert.assertEquals(((TestObject) testObject).getString(), "frog");
+
+        Object testObjectObject = ((TestObject) testObject).getObject();
+        Assert.assertTrue(testObjectObject instanceof ProxySslConfig, "Expected a ProxySslConfig:
"+testObjectObject);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testBrooklynObjectPrefix() throws Exception {
+        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
+            "  brooklyn.config:",
+            "    test.confListPlain:",
+            "    - $brooklyn:object:",
+            "        objectType: brooklyn.entity.proxy.ProxySslConfig",
+            "    - $brooklyn:object:",
+            "        object_type: brooklyn.entity.proxy.ProxySslConfig",
+            "    - $brooklyn:object:",
+            "        type: brooklyn.entity.proxy.ProxySslConfig");
+
+        List testList = testEntity.getConfig(TestEntity.CONF_LIST_PLAIN);
+
+        Assert.assertEquals(testList.size(), 3);
+        for (Object entry : testList) {
+            Assert.assertTrue(entry instanceof ProxySslConfig, "Expected a ProxySslConfig:
"+entry);
+        }
     }
 
     @SuppressWarnings("unchecked")
@@ -105,18 +138,24 @@ public class ObjectsYamlTest extends AbstractYamlTest {
             "  brooklyn.config:",
             "    test.confObject:",
             "      $brooklyn:object:",
-            "        objectType: io.brooklyn.camp.brooklyn.ObjectsYamlTest$TestObject",
+            "        type: io.brooklyn.camp.brooklyn.ObjectsYamlTest$TestObject",
             "        object.fields:",
             "          number: 7",
+            "          object:",
+            "            $brooklyn:object:",
+            "              type: brooklyn.entity.proxy.ProxySslConfig",
             "          string:",
-            "            $brooklyn:formatString(\"%s\", \"7\")");
+            "            $brooklyn:formatString(\"%s\", \"frog\")");
 
         Object testObject = testEntity.getConfig(TestEntity.CONF_OBJECT);
 
-        Assert.assertTrue(testObject instanceof TestObject);
+        Assert.assertTrue(testObject instanceof TestObject, "Expected a TestObject: "+testObject);
         Assert.assertTrue(managementContextInjected.get());
         Assert.assertEquals(((TestObject) testObject).getNumber(), Integer.valueOf(7));
-        Assert.assertEquals(((TestObject) testObject).getString(), "7");
+        Assert.assertEquals(((TestObject) testObject).getString(), "frog");
+
+        Object testObjectObject = ((TestObject) testObject).getObject();
+        Assert.assertTrue(testObjectObject instanceof ProxySslConfig, "Expected a ProxySslConfig:
"+testObjectObject);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3fb2ef5c/usage/camp/src/test/resources/test-entity-reference-map-template.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/test-entity-reference-map-template.yaml b/usage/camp/src/test/resources/test-entity-reference-map-template.yaml
new file mode 100644
index 0000000..b724cd7
--- /dev/null
+++ b/usage/camp/src/test/resources/test-entity-reference-map-template.yaml
@@ -0,0 +1,28 @@
+# 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.
+#
+name: test-entity-reference-map-template
+description: TestEntity with templated brooklyn.config and additional config (such as services)
+origin: http://brooklyn.io
+services:
+- serviceType: brooklyn.entity.basic.BasicEntity
+  id: one
+- serviceType: brooklyn.entity.basic.BasicEntity
+  id: two
+- serviceType: brooklyn.test.entity.TestEntity
+  name: testentity
+# should have nothing below here as the test appends things underneath


Mime
View raw message