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 2016/02/01 18:49:27 UTC
[23/50] brooklyn-server git commit: XML serialisation: avoid error if
try to serialize entity
XML serialisation: avoid error if try to serialize entity
- If entity/location/policy sneaks through to be serialized
(e.g. through config key of LocationConfigKeys.CALLER_CONTEXT
pointing at Entity)...
- Don't blow up: instead let it deserialize as null, which is better
than failing to serialize+deserialize everything about the entity.
- Logs at WARN for first time encountered, and debug subsequently.
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/c7ff5922
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/c7ff5922
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/c7ff5922
Branch: refs/heads/0.6.0
Commit: c7ff592232e1e3f6812e946304da03e03b017d83
Parents: 224fca6
Author: Aled Sage <al...@gmail.com>
Authored: Tue Nov 12 11:13:59 2013 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Nov 12 21:52:59 2013 +0000
----------------------------------------------------------------------
.../rebind/persister/XmlMementoSerializer.java | 74 +++++++++++++++++++-
1 file changed, 72 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c7ff5922/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java b/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java
index c8c8d36..68d8ae1 100644
--- a/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java
+++ b/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java
@@ -4,24 +4,41 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.io.IOException;
import java.io.Writer;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.Entity;
import brooklyn.entity.rebind.dto.BasicEntityMemento;
import brooklyn.entity.rebind.dto.BasicLocationMemento;
import brooklyn.entity.rebind.dto.MutableBrooklynMemento;
import brooklyn.event.basic.BasicAttributeSensor;
import brooklyn.event.basic.BasicConfigKey;
+import brooklyn.location.Location;
+import brooklyn.policy.EntityAdjunct;
import brooklyn.util.exceptions.Exceptions;
import brooklyn.util.xstream.XmlSerializer;
+import com.google.common.base.Function;
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
/* uses xml, cleaned up a bit
*
* there is an early attempt at doing this with JSON in pull request #344 but
* it is not nicely deserializable, see comments at http://xstream.codehaus.org/json-tutorial.html */
public class XmlMementoSerializer<T> extends XmlSerializer<T> implements MementoSerializer<T> {
-
+
+ private static final Logger LOG = LoggerFactory.getLogger(XmlMementoSerializer.class);
+
@SuppressWarnings("unused")
private final ClassLoader classLoader;
+ @SuppressWarnings({ "unchecked", "rawtypes" })
public XmlMementoSerializer(ClassLoader classLoader) {
this.classLoader = checkNotNull(classLoader, "classLoader");
xstream.alias("brooklyn", MutableBrooklynMemento.class);
@@ -29,6 +46,18 @@ public class XmlMementoSerializer<T> extends XmlSerializer<T> implements Memento
xstream.alias("location", BasicLocationMemento.class);
xstream.alias("configKey", BasicConfigKey.class);
xstream.alias("attributeSensor", BasicAttributeSensor.class);
+ xstream.registerConverter(new ConverterImpl(Location.class, new Function<Location,String>() {
+ @Override public String apply(Location input) {
+ return (input != null) ? input.getId() : null;
+ }}));
+ xstream.registerConverter(new ConverterImpl(Entity.class, new Function<Entity,String>() {
+ @Override public String apply(Entity input) {
+ return (input != null) ? input.getId() : null;
+ }}));
+ xstream.registerConverter(new ConverterImpl(EntityAdjunct.class, new Function<EntityAdjunct,String>() {
+ @Override public String apply(EntityAdjunct input) {
+ return (input != null) ? input.getId() : null;
+ }}));
}
@Override
@@ -41,4 +70,45 @@ public class XmlMementoSerializer<T> extends XmlSerializer<T> implements Memento
}
}
-}
\ No newline at end of file
+ public static class ConverterImpl<T> implements Converter {
+ private final AtomicBoolean hasWarned = new AtomicBoolean(false);
+ private final Class<?> converatable;
+ private final Function<T,String> idExtractor;
+
+ ConverterImpl(Class<T> converatable, Function<T,String> idExtractor) {
+ this.converatable = checkNotNull(converatable, "converatable");
+ this.idExtractor = checkNotNull(idExtractor, "idExtractor");
+ }
+
+ @SuppressWarnings({ "rawtypes" })
+ @Override
+ public boolean canConvert(Class type) {
+ return converatable.isAssignableFrom(type);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
+ if (source != null) {
+ if (hasWarned.compareAndSet(false, true)) {
+ LOG.warn("Cannot marshall to xml (for persistence) {} {}; should have been intercepted; unmarshalling will give null!", converatable.getSimpleName(), source);
+ } else {
+ LOG.debug("Cannot marshall to xml (for persistence) {} {}; should have been intercepted; unmarshalling will give null!", converatable.getSimpleName(), source);
+ }
+ }
+ // no-op; can't marshall this; deserializing will give null!
+ writer.startNode("unserializableLocation");
+ writer.setValue(idExtractor.apply((T)source));
+ writer.endNode();
+ }
+
+ @Override
+ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
+ reader.moveDown();
+ String id = reader.getValue();
+ reader.moveUp();
+ LOG.warn("Cannot unmarshall from persisted xml {} {}; should have been intercepted; returning null!", converatable.getSimpleName(), id);
+ return null;
+ }
+ }
+}