You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2017/03/14 17:24:09 UTC

[1/3] brooklyn-server git commit: Adds yaml-dsl rebind tests (for historic state)

Repository: brooklyn-server
Updated Branches:
  refs/heads/master e317fc5a1 -> bb1da12b9


Adds yaml-dsl rebind tests (for historic state)


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

Branch: refs/heads/master
Commit: 60b120af279a83d8db6bdfa44113144c03e403d9
Parents: e317fc5
Author: Aled Sage <al...@gmail.com>
Authored: Tue Mar 14 11:44:31 2017 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Mar 14 15:48:17 2017 +0000

----------------------------------------------------------------------
 .../camp/brooklyn/rebind/RebindDslTest.java     | 180 +++++++++++++++++++
 .../rebind/dsl-2016-07-entity-klcueb1ide        |  58 ++++++
 .../util/core/xstream/XmlSerializerTest.java    |  25 +++
 3 files changed, 263 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/60b120af/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/rebind/RebindDslTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/rebind/RebindDslTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/rebind/RebindDslTest.java
new file mode 100644
index 0000000..dd35bda
--- /dev/null
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/rebind/RebindDslTest.java
@@ -0,0 +1,180 @@
+/*
+ * 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.camp.brooklyn.rebind;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.File;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlRebindTest;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.StaticSensor;
+import org.apache.brooklyn.entity.stock.BasicApplication;
+import org.apache.brooklyn.util.os.Os;
+import org.apache.brooklyn.util.stream.Streams;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.io.Files;
+import com.google.common.reflect.TypeToken;
+
+public class RebindDslTest extends AbstractYamlRebindTest {
+
+    // TODO What about testing DslBrooklynObjectConfigSupplier?
+    
+    @SuppressWarnings("unused")
+    private static final Logger log = LoggerFactory.getLogger(RebindDslTest.class);
+
+    @SuppressWarnings("serial")
+    ConfigKey<Sensor<?>> sensorSupplier1 = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "sensorSupplier1");
+    
+    @SuppressWarnings("serial")
+    ConfigKey<String> configSupplier1 = ConfigKeys.newConfigKey(new TypeToken<String>() {}, "configSupplier1");
+    
+    @SuppressWarnings("serial")
+    ConfigKey<String> attributeWhenReady1 = ConfigKeys.newConfigKey(new TypeToken<String>() {}, "attributeWhenReady1");
+    
+    @Override
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        super.setUp();
+    }
+    
+    // Difference is that now inside DslSensorSupplier's persisted state we have:
+    //   <sensorName class="string">mysensor</sensorName>
+    // Whereas previously we just had:
+    //   <sensorName>mysensor</sensorName>
+    // The code was changed such that the field is now `Object` rather than `String`!
+    @Test
+    public void testDslSensorSupplier_2016_07() throws Exception {
+        String entityId = "klcueb1ide";
+        doAddEntityMemento("2016-07", entityId);
+        
+        rebind();
+        Entity newEntity = mgmt().getEntityManager().getEntity(entityId);
+        
+        Sensor<?> sensor = newEntity.config().get(sensorSupplier1);
+        assertEquals(sensor.getName(), "mySensorName");
+    }
+    
+    @Test
+    public void testDslConfigSupplier_2016_07() throws Exception {
+        String entityId = "klcueb1ide";
+        doAddEntityMemento("2016-07", entityId);
+        
+        rebind();
+        Entity newEntity = mgmt().getEntityManager().getEntity(entityId);
+        
+        String val = newEntity.config().get(configSupplier1);
+        assertEquals(val, "myval");
+    }
+    
+    @Test
+    public void testDslAttributeWhenReady_2016_07() throws Exception {
+        String entityId = "klcueb1ide";
+        doAddEntityMemento("2016-07", entityId);
+        
+        rebind();
+        Entity newEntity = mgmt().getEntityManager().getEntity(entityId);
+        
+        String val = newEntity.config().get(attributeWhenReady1);
+        assertEquals(val, "myval");
+    }
+    
+    @Test
+    public void testDslSensorSupplier() throws Exception {
+        final Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + BasicApplication.class.getName(),
+                "  brooklyn.config:",
+                "    " + sensorSupplier1.getName() + ": $brooklyn:sensor(\"mySensorName\")");
+        
+        rebind();
+        Entity newEntity = mgmt().getEntityManager().getEntity(app.getId());
+        
+        Sensor<?> sensor = newEntity.config().get(sensorSupplier1);
+        assertEquals(sensor.getName(), "mySensorName");
+    }
+
+    @Test
+    public void testDslConfigSupplier() throws Exception {
+        final Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + BasicApplication.class.getName(),
+                "  brooklyn.config:",
+                "    myConfigKeyName: myval",
+                "    " + configSupplier1.getName() + ": $brooklyn:config(\"myConfigKeyName\")");
+        
+        rebind();
+        Entity newEntity = mgmt().getEntityManager().getEntity(app.getId());
+        
+        String val = newEntity.config().get(configSupplier1);
+        assertEquals(val, "myval");
+    }
+
+    @Test
+    public void testDslConfigSupplierNested() throws Exception {
+        final Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + BasicApplication.class.getName(),
+                "  brooklyn.config:",
+                "    keyName: myConfigKeyName",
+                "    myConfigKeyName: myval",
+                "    " + configSupplier1.getName() + ": $brooklyn:config($brooklyn:config(\"keyName\"))");
+        
+        rebind();
+        Entity newEntity = mgmt().getEntityManager().getEntity(app.getId());
+        
+        String val = newEntity.config().get(configSupplier1);
+        assertEquals(val, "myval");
+    }
+
+    @Test
+    public void testDslAttributeSupplier() throws Exception {
+        final Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + BasicApplication.class.getName(),
+                "  brooklyn.initializers:",
+                "  - type: " + StaticSensor.class.getName(),
+                "    brooklyn.config:",
+                "      name: mySensorName",
+                "      static.value: myval",
+                "  brooklyn.config:",
+                "    " + attributeWhenReady1.getName() + ": $brooklyn:attributeWhenReady(\"mySensorName\")");
+        
+        rebind();
+        Entity newEntity = mgmt().getEntityManager().getEntity(app.getId());
+        
+        String val = newEntity.config().get(attributeWhenReady1);
+        assertEquals(val, "myval");
+    }
+
+    protected void doAddEntityMemento(String label, String entityId) throws Exception {
+        String mementoResourceName = "dsl-" + label + "-entity-" + entityId;
+        String memento = Streams.readFullyString(getClass().getResourceAsStream(mementoResourceName));
+        
+        File persistedEntityFile = new File(mementoDir, Os.mergePaths("entities", entityId));
+        Files.write(memento.getBytes(), persistedEntityFile);
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/60b120af/camp/camp-brooklyn/src/test/resources/org/apache/brooklyn/camp/brooklyn/rebind/dsl-2016-07-entity-klcueb1ide
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/resources/org/apache/brooklyn/camp/brooklyn/rebind/dsl-2016-07-entity-klcueb1ide b/camp/camp-brooklyn/src/test/resources/org/apache/brooklyn/camp/brooklyn/rebind/dsl-2016-07-entity-klcueb1ide
new file mode 100644
index 0000000..1fc5398
--- /dev/null
+++ b/camp/camp-brooklyn/src/test/resources/org/apache/brooklyn/camp/brooklyn/rebind/dsl-2016-07-entity-klcueb1ide
@@ -0,0 +1,58 @@
+<!--
+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.
+-->
+
+<entity>
+  <brooklynVersion>0.10.0-SNAPSHOT</brooklynVersion>
+  <type>org.apache.brooklyn.core.test.entity.TestApplicationNoEnrichersImpl</type>
+  <id>klcueb1ide</id>
+  <displayName>TestApplicationNoEnrichersImpl:klcu</displayName>
+  <config>
+    <myConfigKeyName>myval</myConfigKeyName>
+    <sensorSupplier1>
+      <org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent_-DslSensorSupplier>
+        <component>
+          <componentId></componentId>
+          <scope>THIS</scope>
+        </component>
+        <sensorName>mySensorName</sensorName>
+      </org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent_-DslSensorSupplier>
+    </sensorSupplier1>
+    <configSupplier1>
+      <org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent_-DslConfigSupplier>
+        <component>
+          <componentId></componentId>
+          <scope>THIS</scope>
+        </component>
+        <keyName>myConfigKeyName</keyName>
+      </org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent_-DslConfigSupplier>
+    </configSupplier1>
+    <attributeWhenReady1>
+      <org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent_-AttributeWhenReady>
+        <component>
+          <componentId></componentId>
+          <scope>THIS</scope>
+        </component>
+        <sensorName>mySensorName</sensorName>
+      </org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent_-AttributeWhenReady>
+    </attributeWhenReady1>
+  </config>
+  <attributes>
+      <mySensorName>myval</mySensorName>
+  </attributes>
+</entity>

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/60b120af/core/src/test/java/org/apache/brooklyn/util/core/xstream/XmlSerializerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/xstream/XmlSerializerTest.java b/core/src/test/java/org/apache/brooklyn/util/core/xstream/XmlSerializerTest.java
index b258482..189c8e0 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/xstream/XmlSerializerTest.java
+++ b/core/src/test/java/org/apache/brooklyn/util/core/xstream/XmlSerializerTest.java
@@ -42,8 +42,17 @@ public class XmlSerializerTest {
         assertSerializeAndDeserialize(1);
         assertSerializeAndDeserialize(true);
         assertSerializeAndDeserialize(new StringHolder("abc"));
+        assertSerializeAndDeserialize(new ObjectHolder("abc"));
     }
 
+    @Test
+    public void testObjectFieldDeserializingWhenNoClassSpecified() throws Exception {
+        String tag = "org.apache.brooklyn.util.core.xstream.XmlSerializerTest_-ObjectHolder";
+        String xml = "<"+tag+"><val>myval</val></"+tag+">";
+        Object result = serializer.fromString(xml);
+        assertEquals(((ObjectHolder)result).val, "myval");
+    }
+    
     /**
      * See https://issues.apache.org/jira/browse/BROOKLYN-305 and http://x-stream.github.io/faq.html#XML_control_char
      */
@@ -78,4 +87,20 @@ public class XmlSerializerTest {
             return val.hashCode();
         }
     }
+    
+    public static class ObjectHolder {
+        public Object val;
+        
+        ObjectHolder(Object val) {
+            this.val = val;
+        }
+        @Override
+        public boolean equals(Object obj) {
+            return (obj instanceof ObjectHolder) && val.equals(((ObjectHolder)obj).val);
+        }
+        @Override
+        public int hashCode() {
+            return (val == null) ? 259238 : val.hashCode();
+        }
+    }
 }


[2/3] brooklyn-server git commit: Fix yaml-dsl rebind tests (for historic state)

Posted by al...@apache.org.
Fix yaml-dsl rebind tests (for historic state)


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

Branch: refs/heads/master
Commit: a536cdc1066b64782d0d0333061d69ad63133557
Parents: 60b120a
Author: Aled Sage <al...@gmail.com>
Authored: Tue Mar 14 14:50:37 2017 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Mar 14 17:22:31 2017 +0000

----------------------------------------------------------------------
 .../spi/dsl/methods/BrooklynDslCommon.java      |   3 +
 .../brooklyn/spi/dsl/methods/DslComponent.java  |   5 +
 .../ObjectWithDefaultStringImplConverter.java   |  89 ++++++++++++++
 .../util/core/xstream/XmlSerializer.java        |   5 +
 .../util/core/xstream/XmlSerializerTest.java    | 117 ++++++++++++++++++-
 5 files changed, 215 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a536cdc1/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 9fbab0e..9f589a1 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
@@ -60,6 +60,7 @@ 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;
+import org.apache.brooklyn.util.core.xstream.ObjectWithDefaultStringImplConverter;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.javalang.Reflections;
@@ -75,6 +76,7 @@ import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
 
 /**
  * static import functions which can be used in `$brooklyn:xxx` contexts
@@ -154,6 +156,7 @@ public class BrooklynDslCommon {
 
         // Keep in mind this object gets serialized so is the following reference
         private BrooklynObjectInternal obj;
+        @XStreamConverter(ObjectWithDefaultStringImplConverter.class)
         private Object keyName;
 
         public DslBrooklynObjectConfigSupplier(BrooklynObjectInternal obj, Object keyName) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a536cdc1/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
index 867c108..b7e29a7 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
@@ -50,6 +50,7 @@ import org.apache.brooklyn.util.core.task.ImmediateSupplier;
 import org.apache.brooklyn.util.core.task.TaskBuilder;
 import org.apache.brooklyn.util.core.task.TaskTags;
 import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.xstream.ObjectWithDefaultStringImplConverter;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
 import org.apache.brooklyn.util.guava.Maybe;
@@ -64,6 +65,7 @@ import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 import com.google.common.collect.Iterables;
 import com.google.common.util.concurrent.Callables;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
 
 public class DslComponent extends BrooklynDslDeferredSupplier<Entity> implements DslFunctionSource {
 
@@ -454,6 +456,7 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity> implements
     protected static class AttributeWhenReady extends BrooklynDslDeferredSupplier<Object> {
         private static final long serialVersionUID = 1740899524088902383L;
         private final DslComponent component;
+        @XStreamConverter(ObjectWithDefaultStringImplConverter.class)
         private final Object sensorName;
 
         public AttributeWhenReady(DslComponent component, Object sensorName) {
@@ -526,6 +529,7 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity> implements
     }
     protected final static class DslConfigSupplier extends BrooklynDslDeferredSupplier<Object> {
         private final DslComponent component;
+        @XStreamConverter(ObjectWithDefaultStringImplConverter.class)
         private final Object keyName;
         private static final long serialVersionUID = -4735177561947722511L;
 
@@ -642,6 +646,7 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity> implements
     }
     protected final static class DslSensorSupplier extends BrooklynDslDeferredSupplier<Sensor<?>> {
         private final DslComponent component;
+        @XStreamConverter(ObjectWithDefaultStringImplConverter.class)
         private final Object sensorName;
         private static final long serialVersionUID = -4735177561947722511L;
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a536cdc1/core/src/main/java/org/apache/brooklyn/util/core/xstream/ObjectWithDefaultStringImplConverter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/xstream/ObjectWithDefaultStringImplConverter.java b/core/src/main/java/org/apache/brooklyn/util/core/xstream/ObjectWithDefaultStringImplConverter.java
new file mode 100644
index 0000000..116a309
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/util/core/xstream/ObjectWithDefaultStringImplConverter.java
@@ -0,0 +1,89 @@
+/*
+ * 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.util.core.xstream;
+
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.javalang.Boxing;
+
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.ConverterLookup;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+/**
+ * A converter that delegates to {@link ConverterLookup#lookupConverterForType(Class)}, where
+ * possible. On unmarshalling, if there is no {@code class} attribute then it assumes that the
+ * type must be a {@link String}.
+ * 
+ * This is useful if a class has its field changed from type {@link String} to {@link Object}.
+ * The old persisted state will look like {@code <mykey>myval</mykey>}, rather than 
+ * {@code <mykey class="string">myval</mykey>}.
+ * 
+ * Use this converter by annotation the field with
+ * {@code @XStreamConverter(ObjectWithDefaultStringImplConverter.class)}. One must also call
+ * {@code xstream.processAnnotations(MyClazz.class)} to ensure the annotation is actually parsed.
+ */
+public class ObjectWithDefaultStringImplConverter implements Converter {
+    private final ConverterLookup lookup;
+    private final ClassLoader loader;
+    private final Class<?> defaultImpl = String.class;
+
+    public ObjectWithDefaultStringImplConverter(ConverterLookup lookup, ClassLoader loader) {
+        this.lookup = lookup;
+        this.loader = loader;
+    }
+
+    @Override
+    public boolean canConvert(@SuppressWarnings("rawtypes") Class type) {
+        // We expect this to be used for a field of type `Object`, so could be passed an instance
+        // of anything at all to marshal - therefore say we can convert anything!
+        // We'll then delegate, based on the type we're given.
+        return true;
+    }
+
+    @Override
+    public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
+        if (source == null) return;
+        Converter converter = lookup.lookupConverterForType(source.getClass());
+        converter.marshal(source, writer, context);
+    }
+
+    @Override
+    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
+        String clazzName = reader.getAttribute("class");
+        Class<?> clazz;
+        if (clazzName == null) {
+            clazz = defaultImpl;
+        } else if (clazzName.equals("string")) {
+            clazz = String.class;
+        } else if (Boxing.getPrimitiveType(clazzName).isPresent()) {
+            clazz = Boxing.getPrimitiveType(clazzName).get();
+        } else {
+            try {
+                clazz = loader.loadClass(clazzName);
+            } catch (ClassNotFoundException e) {
+                throw Exceptions.propagate(e);
+            }
+        }
+        Converter converter = lookup.lookupConverterForType(clazz);
+        return converter.unmarshal(reader, context);
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a536cdc1/core/src/main/java/org/apache/brooklyn/util/core/xstream/XmlSerializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/xstream/XmlSerializer.java b/core/src/main/java/org/apache/brooklyn/util/core/xstream/XmlSerializer.java
index 12561d3..0ef8943 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/xstream/XmlSerializer.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/xstream/XmlSerializer.java
@@ -80,6 +80,11 @@ public class XmlSerializer<T> {
 
         xstream.registerConverter(new EnumCaseForgivingConverter());
         xstream.registerConverter(new Inet4AddressConverter());
+        
+        // See ObjectWithDefaultStringImplConverter (and its usage) for why we want to auto-detect 
+        // annotations (usages of this is in the camp project, so we can't just list it statically
+        // here unfortunately).
+        xstream.autodetectAnnotations(true);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a536cdc1/core/src/test/java/org/apache/brooklyn/util/core/xstream/XmlSerializerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/xstream/XmlSerializerTest.java b/core/src/test/java/org/apache/brooklyn/util/core/xstream/XmlSerializerTest.java
index 189c8e0..13ccb38 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/xstream/XmlSerializerTest.java
+++ b/core/src/test/java/org/apache/brooklyn/util/core/xstream/XmlSerializerTest.java
@@ -20,11 +20,19 @@ package org.apache.brooklyn.util.core.xstream;
 
 import static org.testng.Assert.assertEquals;
 
+import java.util.Arrays;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import com.google.common.base.Objects;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+import com.thoughtworks.xstream.converters.basic.BooleanConverter;
+import com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter;
+
 public class XmlSerializerTest {
 
     private static final Logger LOG = LoggerFactory.getLogger(XmlSerializerTest.class);
@@ -41,18 +49,44 @@ public class XmlSerializerTest {
         assertSerializeAndDeserialize("abc");
         assertSerializeAndDeserialize(1);
         assertSerializeAndDeserialize(true);
+        assertSerializeAndDeserialize(new ObjectHolder(null));
         assertSerializeAndDeserialize(new StringHolder("abc"));
         assertSerializeAndDeserialize(new ObjectHolder("abc"));
+        assertSerializeAndDeserialize(new ObjectHolder(Arrays.asList("val1", "val2")));
+        assertSerializeAndDeserialize(new ObjectHolder(123));
+        assertSerializeAndDeserialize(new IntHolder(123));
+        assertSerializeAndDeserialize(new IntegerHolder(123));
+    }
+    
+    @Test
+    public void testAnnotationsExample() throws Exception {
+        assertSerializeAndDeserialize(new RendezvousMessage(123, true, "mycontent"));
     }
 
     @Test
-    public void testObjectFieldDeserializingWhenNoClassSpecified() throws Exception {
+    public void testObjectFieldDeserializingStringWhenNoClassSpecified() throws Exception {
         String tag = "org.apache.brooklyn.util.core.xstream.XmlSerializerTest_-ObjectHolder";
         String xml = "<"+tag+"><val>myval</val></"+tag+">";
         Object result = serializer.fromString(xml);
         assertEquals(((ObjectHolder)result).val, "myval");
     }
     
+    @Test
+    public void testIntFieldDeserializingStringWhenNoClassSpecified() throws Exception {
+        String tag = "org.apache.brooklyn.util.core.xstream.XmlSerializerTest_-IntHolder";
+        String xml = "<"+tag+"><val>123</val></"+tag+">";
+        Object result = serializer.fromString(xml);
+        assertEquals(((IntHolder)result).val, 123);
+    }
+    
+    @Test
+    public void testIntegerFieldDeserializingStringWhenNoClassSpecified() throws Exception {
+        String tag = "org.apache.brooklyn.util.core.xstream.XmlSerializerTest_-IntegerHolder";
+        String xml = "<"+tag+"><val>123</val></"+tag+">";
+        Object result = serializer.fromString(xml);
+        assertEquals(((IntegerHolder)result).val, Integer.valueOf(123));
+    }
+    
     /**
      * See https://issues.apache.org/jira/browse/BROOKLYN-305 and http://x-stream.github.io/faq.html#XML_control_char
      */
@@ -68,6 +102,7 @@ public class XmlSerializerTest {
     protected void assertSerializeAndDeserialize(Object val) throws Exception {
         String xml = serializer.toString(val);
         Object result = serializer.fromString(xml);
+        System.out.println("val="+val+"'; xml="+xml+"; result="+result);
         LOG.debug("val="+val+"'; xml="+xml+"; result="+result);
         assertEquals(result, val);
     }
@@ -88,19 +123,93 @@ public class XmlSerializerTest {
         }
     }
     
-    public static class ObjectHolder {
-        public Object val;
+    private static class ObjectHolder {
+        @XStreamConverter(ObjectWithDefaultStringImplConverter.class)
+        private final Object val;
         
         ObjectHolder(Object val) {
             this.val = val;
         }
         @Override
         public boolean equals(Object obj) {
-            return (obj instanceof ObjectHolder) && val.equals(((ObjectHolder)obj).val);
+            return (obj instanceof ObjectHolder) && Objects.equal(val, ((ObjectHolder)obj).val);
         }
         @Override
         public int hashCode() {
             return (val == null) ? 259238 : val.hashCode();
         }
+        @Override
+        public String toString() {
+            try {
+                return "ObjectHolder(val="+val+", type="+(val == null ? null : val.getClass())+")";
+            } catch (NullPointerException e) {
+                System.out.println("val="+val);
+                e.printStackTrace();
+                return "what?";
+            }
+        }
+    }
+
+    public static class IntHolder {
+        public int val;
+        
+        IntHolder(int val) {
+            this.val = val;
+        }
+        @Override
+        public boolean equals(Object obj) {
+            return (obj instanceof IntHolder) && val == ((IntHolder)obj).val;
+        }
+        @Override
+        public int hashCode() {
+            return val;
+        }
+    }
+    
+    public static class IntegerHolder {
+        public Integer val;
+        
+        IntegerHolder(int val) {
+            this.val = val;
+        }
+        @Override
+        public boolean equals(Object obj) {
+            return (obj instanceof IntegerHolder) && val.equals(((IntegerHolder)obj).val);
+        }
+        @Override
+        public int hashCode() {
+            return (val == null) ? 259238 : val.hashCode();
+        }
+    }
+    
+    @XStreamAlias("message")
+    @XStreamConverter(value=ToAttributedValueConverter.class, strings={"content"})
+    static class RendezvousMessage {
+
+        @XStreamAlias("type")
+        private int messageType;
+
+        private String content;
+        
+        @XStreamConverter(value=BooleanConverter.class, booleans={false}, strings={"yes", "no"})
+        private boolean important;
+
+        public RendezvousMessage(int messageType, boolean important, String content) {
+            this.messageType = messageType;
+            this.important = important;
+            this.content = content;
+        }
+
+        @Override
+        public int hashCode() {
+            return messageType;
+        }
+        
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof RendezvousMessage)) return false;
+            RendezvousMessage o = (RendezvousMessage) obj;
+            return (messageType == o.messageType) && important == o.important && content.equals(o.content);
+        }
     }
 }


[3/3] brooklyn-server git commit: This closes #593

Posted by al...@apache.org.
This closes #593


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

Branch: refs/heads/master
Commit: bb1da12b9e014ee8d681200c72d70e5279d96d1a
Parents: e317fc5 a536cdc
Author: Aled Sage <al...@gmail.com>
Authored: Tue Mar 14 17:23:38 2017 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Mar 14 17:23:38 2017 +0000

----------------------------------------------------------------------
 .../spi/dsl/methods/BrooklynDslCommon.java      |   3 +
 .../brooklyn/spi/dsl/methods/DslComponent.java  |   5 +
 .../camp/brooklyn/rebind/RebindDslTest.java     | 180 +++++++++++++++++++
 .../rebind/dsl-2016-07-entity-klcueb1ide        |  58 ++++++
 .../ObjectWithDefaultStringImplConverter.java   |  89 +++++++++
 .../util/core/xstream/XmlSerializer.java        |   5 +
 .../util/core/xstream/XmlSerializerTest.java    | 134 ++++++++++++++
 7 files changed, 474 insertions(+)
----------------------------------------------------------------------