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 2015/09/01 17:16:35 UTC

[12/28] incubator-brooklyn git commit: Handle class-renames in persisted state

Handle class-renames in persisted state

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

Branch: refs/heads/master
Commit: 3167af95c8ef25fa5bf787c34a73af2d7361b6bb
Parents: 6212d19
Author: Aled Sage <al...@gmail.com>
Authored: Sun Aug 30 12:03:01 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Sun Aug 30 12:03:01 2015 +0100

----------------------------------------------------------------------
 .../catalog/internal/CatalogXmlSerializer.java  |    3 +
 .../DeserializingClassRenamesProvider.java      |   78 +
 .../core/mgmt/persist/XmlMementoSerializer.java |   10 +-
 .../util/core/xstream/ClassRenamingMapper.java  |   72 +
 .../util/core/xstream/XmlSerializer.java        |   14 +-
 .../deserializingClassRenames.properties        | 1419 ++++++++++++++++++
 .../mgmt/persist/XmlMementoSerializerTest.java  |  164 +-
 .../service/BrooklynServiceTypeResolver.java    |   42 +-
 8 files changed, 1784 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3167af95/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java
index 801fac6..855a753 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.brooklyn.core.catalog.internal.CatalogClasspathDo.CatalogScanningModes;
+import org.apache.brooklyn.core.mgmt.persist.DeserializingClassRenamesProvider;
 import org.apache.brooklyn.core.objs.AbstractBrooklynObject;
 import org.apache.brooklyn.util.core.xstream.EnumCaseForgivingSingleValueConverter;
 import org.apache.brooklyn.util.core.xstream.XmlSerializer;
@@ -32,6 +33,8 @@ public class CatalogXmlSerializer extends XmlSerializer<Object> {
 
     @SuppressWarnings("deprecation")
     public CatalogXmlSerializer() {
+        super(DeserializingClassRenamesProvider.loadDeserializingClassRenames());
+        
         xstream.addDefaultImplementation(ArrayList.class, Collection.class);
         
         xstream.aliasType("list", List.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3167af95/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/DeserializingClassRenamesProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/DeserializingClassRenamesProvider.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/DeserializingClassRenamesProvider.java
new file mode 100644
index 0000000..e8ac5a4
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/DeserializingClassRenamesProvider.java
@@ -0,0 +1,78 @@
+/*
+ * 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.mgmt.persist;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.stream.Streams;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+@Beta
+public class DeserializingClassRenamesProvider {
+
+    public static final String DESERIALIZING_CLASS_RENAMES_PROPERTIES_PATH = "classpath://org/apache/brooklyn/deserializingClassRenames.properties";
+    
+    @Beta
+    public static Map<String, String> loadDeserializingClassRenames() {
+        InputStream resource = XmlMementoSerializer.class.getClassLoader().getResourceAsStream(DESERIALIZING_CLASS_RENAMES_PROPERTIES_PATH);
+        if (resource != null) {
+            try {
+                Properties props = new Properties();
+                props.load(resource);
+                
+                Map<String, String> result = Maps.newLinkedHashMap();
+                for (Enumeration<?> iter = props.propertyNames(); iter.hasMoreElements();) {
+                    String key = (String) iter.nextElement();
+                    String value = props.getProperty(key);
+                    result.put(key, value);
+                }
+                return result;
+            } catch (IOException e) {
+                throw Exceptions.propagate(e);
+            } finally {
+                Streams.closeQuietly(resource);
+            }
+        } else {
+            return ImmutableMap.<String, String>of();
+        }
+    }
+
+    @Beta
+    public static Optional<String> tryFindMappedName(Map<String, String> renames, String name) {
+        String mappedName = (String) renames.get(name);
+        if (mappedName != null) {
+            return Optional.of(mappedName);
+        }
+        for (Map.Entry<String, String> entry : renames.entrySet()) {
+            if (name.startsWith(entry.getKey())) {
+                return Optional.of(entry.getValue()+ name.substring(entry.getKey().length()));
+            }
+        }
+        return Optional.<String>absent();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3167af95/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
index b232ce4..a8a20b7 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
@@ -22,13 +22,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.io.IOException;
 import java.io.Writer;
+import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Stack;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.effector.Effector;
 import org.apache.brooklyn.api.entity.Entity;
@@ -63,6 +62,8 @@ import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
 import org.apache.brooklyn.util.core.xstream.XmlSerializer;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.thoughtworks.xstream.converters.Converter;
 import com.thoughtworks.xstream.converters.MarshallingContext;
@@ -89,6 +90,11 @@ public class XmlMementoSerializer<T> extends XmlSerializer<T> implements Memento
     private LookupContext lookupContext;
 
     public XmlMementoSerializer(ClassLoader classLoader) {
+        this(classLoader, DeserializingClassRenamesProvider.loadDeserializingClassRenames());
+    }
+    
+    public XmlMementoSerializer(ClassLoader classLoader, Map<String, String> deserializingClassRenames) {
+        super(deserializingClassRenames);
         this.classLoader = checkNotNull(classLoader, "classLoader");
         xstream.setClassLoader(this.classLoader);
         

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3167af95/core/src/main/java/org/apache/brooklyn/util/core/xstream/ClassRenamingMapper.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/xstream/ClassRenamingMapper.java b/core/src/main/java/org/apache/brooklyn/util/core/xstream/ClassRenamingMapper.java
new file mode 100644
index 0000000..13fd032
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/util/core/xstream/ClassRenamingMapper.java
@@ -0,0 +1,72 @@
+/*
+ * 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 static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+
+import org.apache.brooklyn.core.mgmt.persist.DeserializingClassRenamesProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.thoughtworks.xstream.mapper.Mapper;
+import com.thoughtworks.xstream.mapper.MapperWrapper;
+
+public class ClassRenamingMapper extends MapperWrapper {
+    public static final Logger LOG = LoggerFactory.getLogger(ClassRenamingMapper.class);
+    
+    private final Map<String, String> nameToType;
+
+    public ClassRenamingMapper(Mapper wrapped, Map<String, String> nameToType) {
+        super(wrapped);
+        this.nameToType = checkNotNull(nameToType, "nameToType");
+    }
+    
+    @Override
+    public Class realClass(String elementName) {
+        String nameToUse;
+        Optional<String> mappedName = DeserializingClassRenamesProvider.tryFindMappedName(nameToType, elementName);
+        if (mappedName.isPresent()) {
+            LOG.debug("Transforming xstream "+elementName+" to "+mappedName);
+            nameToUse = mappedName.get();
+        } else {
+            nameToUse = elementName;
+        }
+        return super.realClass(nameToUse);
+    }
+
+//    public boolean aliasIsAttribute(String name) {
+//        return nameToType.containsKey(name);
+//    }
+//    
+//    private Object readResolve() {
+//        nameToType = new HashMap();
+//        for (final Iterator iter = classToName.keySet().iterator(); iter.hasNext();) {
+//            final Object type = iter.next();
+//            nameToType.put(classToName.get(type), type);
+//        }
+//        for (final Iterator iter = typeToName.keySet().iterator(); iter.hasNext();) {
+//            final Class type = (Class)iter.next();
+//            nameToType.put(typeToName.get(type), type.getName());
+//        }
+//        return this;
+//    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3167af95/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 4a95bc2..9ed5b88 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
@@ -32,15 +32,22 @@ import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.collections.MutableSet;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.mapper.MapperWrapper;
 
 public class XmlSerializer<T> {
 
+    private final Map<String, String> deserializingClassRenames;
     protected final XStream xstream;
-    
+
     public XmlSerializer() {
-        xstream = new XStream() {
+        this(ImmutableMap.<String, String>of());
+    }
+    
+    public XmlSerializer(Map<String, String> deserializingClassRenames) {
+        this.deserializingClassRenames = deserializingClassRenames;
+        this.xstream = new XStream() {
             @Override
             protected MapperWrapper wrapMapper(MapperWrapper next) {
                 MapperWrapper result = super.wrapMapper(next);
@@ -72,7 +79,8 @@ public class XmlSerializer<T> {
     }
     
     protected MapperWrapper wrapMapper(MapperWrapper next) {
-        return new CompilerIndependentOuterClassFieldMapper(next);
+        MapperWrapper result = new CompilerIndependentOuterClassFieldMapper(next);
+        return new ClassRenamingMapper(result, deserializingClassRenames);
     }
 
     public void serialize(Object object, Writer writer) {