You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2016/01/04 21:24:09 UTC

[1/9] incubator-tinkerpop git commit: Add option on GryoMapper to allow overriding the ClassResolver.

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/master f4be739e7 -> 46c7189e2


Add option on GryoMapper to allow overriding the ClassResolver.

Included tests to demonstrate capabilities.


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

Branch: refs/heads/master
Commit: a94c51f368f91a7c1204fb19517d02338ca1b141
Parents: 2f16c77
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Dec 24 06:54:11 2015 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Dec 24 06:54:11 2015 -0500

----------------------------------------------------------------------
 .../structure/io/gryo/GryoClassResolver.java    |   2 +-
 .../gremlin/structure/io/gryo/GryoMapper.java   |  25 +++-
 .../tinkerpop/gremlin/structure/io/IoX.java     |   5 +
 .../gremlin/structure/io/IoXIoRegistry.java     |  63 ++++++++++
 .../tinkerpop/gremlin/structure/io/IoY.java     |   5 +
 .../gremlin/structure/io/IoYIoRegistry.java     |  45 +++++++
 .../structure/io/gryo/GryoMapperTest.java       | 116 +++++++++++++++++++
 7 files changed, 257 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/a94c51f3/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoClassResolver.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoClassResolver.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoClassResolver.java
index 268da9c..5d51d22 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoClassResolver.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoClassResolver.java
@@ -52,7 +52,7 @@ import static org.apache.tinkerpop.shaded.kryo.util.Util.getWrapperClass;
  *
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
-class GryoClassResolver implements ClassResolver {
+public class GryoClassResolver implements ClassResolver {
     static public final byte NAME = -1;
 
     protected Kryo kryo;

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/a94c51f3/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
index 1fec5c8..7d945ce 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
@@ -57,6 +57,7 @@ import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceVertex;
 import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceVertexProperty;
 import org.apache.tinkerpop.gremlin.structure.util.star.StarGraph;
 import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGryoSerializer;
+import org.apache.tinkerpop.shaded.kryo.ClassResolver;
 import org.apache.tinkerpop.shaded.kryo.Kryo;
 import org.apache.tinkerpop.shaded.kryo.KryoSerializable;
 import org.apache.tinkerpop.shaded.kryo.Serializer;
@@ -90,6 +91,7 @@ import java.util.UUID;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.Function;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
 /**
@@ -125,18 +127,20 @@ public final class GryoMapper implements Mapper<Kryo> {
     public static final byte[] GIO = "gio".getBytes();
     public static final byte[] HEADER = Arrays.copyOf(GIO, 16);
     private final List<Triplet<Class, Function<Kryo, Serializer>, Integer>> serializationList;
-    private boolean registrationRequired;
-    private boolean referenceTracking;
+    private final boolean registrationRequired;
+    private final boolean referenceTracking;
+    private final Supplier<ClassResolver> classResolver;
 
     private GryoMapper(final Builder builder) {
         this.serializationList = builder.serializationList;
         this.registrationRequired = builder.registrationRequired;
         this.referenceTracking = builder.referenceTracking;
+        this.classResolver = builder.classResolver;
     }
 
     @Override
     public Kryo createMapper() {
-        final Kryo kryo = new Kryo(new GryoClassResolver(), new MapReferenceResolver(), new DefaultStreamFactory());
+        final Kryo kryo = new Kryo(classResolver.get(), new MapReferenceResolver(), new DefaultStreamFactory());
         kryo.addDefaultSerializer(Map.Entry.class, new EntrySerializer());
         kryo.setRegistrationRequired(registrationRequired);
         kryo.setReferences(referenceTracking);
@@ -289,6 +293,7 @@ public final class GryoMapper implements Mapper<Kryo> {
 
         private boolean registrationRequired = true;
         private boolean referenceTracking = true;
+        private Supplier<ClassResolver> classResolver = GryoClassResolver::new;
 
         private Builder() {
         }
@@ -304,6 +309,20 @@ public final class GryoMapper implements Mapper<Kryo> {
         }
 
         /**
+         * Provides a custom Kryo {@code ClassResolver} to be supplied to a {@code Kryo} instance.  If this value is
+         * not supplied then it will default to the {@link GryoClassResolver}. To ensure compatibility with Gryo it
+         * is highly recommended that objects passed to this method extend that class.
+         * <p/>
+         * If the {@code ClassResolver} implementation share state, then the {@link Supplier} should typically create
+         * new instances when requested, as the {@link Supplier} will be called for each {@link Kryo} instance created.
+         */
+        public Builder classResolver(final Supplier<ClassResolver> classResolverSupplier) {
+            if (null == classResolverSupplier) throw new IllegalArgumentException("The classResolverSupplier cannot be null");
+            this.classResolver = classResolverSupplier;
+            return this;
+        }
+
+        /**
          * Register custom classes to serializes with gryo using default serialization.
          */
         public Builder addCustom(final Class... custom) {

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/a94c51f3/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoX.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoX.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoX.java
index 2f67382..4c1698f 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoX.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoX.java
@@ -47,4 +47,9 @@ public class IoX {
     public int hashCode() {
         return x.hashCode();
     }
+
+    @Override
+    public String toString() {
+        return x;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/a94c51f3/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoXIoRegistry.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoXIoRegistry.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoXIoRegistry.java
index dabdae8..ddc5477 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoXIoRegistry.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoXIoRegistry.java
@@ -18,7 +18,21 @@
  */
 package org.apache.tinkerpop.gremlin.structure.io;
 
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
 import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoIo;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
+import org.apache.tinkerpop.shaded.kryo.Kryo;
+import org.apache.tinkerpop.shaded.kryo.Serializer;
+import org.apache.tinkerpop.shaded.kryo.io.Input;
+import org.apache.tinkerpop.shaded.kryo.io.Output;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @author Stephen Mallette (http://stephen.genoprime.com)
@@ -41,4 +55,53 @@ public class IoXIoRegistry {
             return INSTANCE;
         }
     }
+
+    public static class SerializerToVertexBased extends AbstractIoRegistry {
+        public SerializerToVertexBased() {
+            register(GryoIo.class, IoX.class, new IoXToVertexSerializer());
+        }
+    }
+
+    /**
+     * Converts an {@link IoX} to a {@link DetachedVertex}.
+     */
+    public final static class IoXToVertexSerializer extends Serializer<IoX> {
+        public IoXToVertexSerializer() {
+        }
+
+        @Override
+        public void write(final Kryo kryo, final Output output, final IoX iox) {
+            final Map<String,Object> props = new HashMap<>();
+            addSingleProperty("x", iox.toString(), props);
+            final DetachedVertex vertex = new DetachedVertex(100, Vertex.DEFAULT_LABEL, props);
+            try (final OutputStream stream = new ByteArrayOutputStream()) {
+                final Output detachedOutput = new Output(stream);
+                kryo.writeObject(detachedOutput, vertex);
+
+                // have to remove the first byte because it marks a reference we don't want to have as this
+                // serializer is trying to "act" like a DetachedVertex
+                final byte[] b = detachedOutput.toBytes();
+                output.write(b, 1, b.length - 1);
+            } catch (Exception ex) {
+                ex.printStackTrace();
+            }
+        }
+
+        @Override
+        public IoX read(final Kryo kryo, final Input input, final Class<IoX> ioxClass) {
+            throw new UnsupportedOperationException("IoX writes to DetachedVertex and can't be read back in as IoX");
+        }
+
+        private static void addSingleProperty(final String key, final Object value, final Map<String, Object> props)
+        {
+            final List<Map<String, Object>> propertyNames = new ArrayList<>(1);
+            final Map<String,Object> propertyName = new HashMap<>();
+            propertyName.put(GraphSONTokens.ID, key);
+            propertyName.put(GraphSONTokens.KEY, key);
+            propertyName.put(GraphSONTokens.VALUE, value);
+            propertyNames.add(propertyName);
+
+            props.put(key, propertyNames);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/a94c51f3/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoY.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoY.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoY.java
index ddbb221..5da7cec 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoY.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoY.java
@@ -49,4 +49,9 @@ public class IoY {
     public int hashCode() {
         return y.hashCode();
     }
+
+    @Override
+    public String toString() {
+        return y + "-" + z;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/a94c51f3/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoYIoRegistry.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoYIoRegistry.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoYIoRegistry.java
index 1d03500..53c3404 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoYIoRegistry.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoYIoRegistry.java
@@ -19,6 +19,15 @@
 package org.apache.tinkerpop.gremlin.structure.io;
 
 import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoIo;
+import org.apache.tinkerpop.shaded.kryo.Kryo;
+import org.apache.tinkerpop.shaded.kryo.Serializer;
+import org.apache.tinkerpop.shaded.kryo.io.Input;
+import org.apache.tinkerpop.shaded.kryo.io.Output;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * @author Stephen Mallette (http://stephen.genoprime.com)
@@ -41,4 +50,40 @@ public class IoYIoRegistry {
             return INSTANCE;
         }
     }
+
+    public static class SerializerToMapBased extends AbstractIoRegistry {
+        public SerializerToMapBased() {
+            register(GryoIo.class, IoY.class, new IoYToHashMapSerializer());
+        }
+    }
+
+    /**
+     * Converts an {@link IoX} to a {@link HashMap}.
+     */
+    public final static class IoYToHashMapSerializer extends Serializer<IoY> {
+        public IoYToHashMapSerializer() {
+        }
+
+        @Override
+        public void write(final Kryo kryo, final Output output, final IoY ioy) {
+            final Map<String, Object> map = new HashMap<>();
+            map.put("y", ioy.toString());
+            try (final OutputStream stream = new ByteArrayOutputStream()) {
+                final Output detachedOutput = new Output(stream);
+                kryo.writeObject(detachedOutput, map);
+
+                // have to remove the first byte because it marks a reference we don't want to have as this
+                // serializer is trying to "act" like a Map
+                final byte[] b = detachedOutput.toBytes();
+                output.write(b, 1, b.length - 1);
+            } catch (Exception ex) {
+                ex.printStackTrace();
+            }
+        }
+
+        @Override
+        public IoY read(final Kryo kryo, final Input input, final Class<IoY> ioyClass) {
+            throw new UnsupportedOperationException("IoX writes to Map and can't be read back in as IoX");
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/a94c51f3/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java
index 9bdec55..947528c 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java
@@ -18,11 +18,17 @@
  */
 package org.apache.tinkerpop.gremlin.structure.io.gryo;
 
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;
 import org.apache.tinkerpop.gremlin.structure.io.IoX;
 import org.apache.tinkerpop.gremlin.structure.io.IoXIoRegistry;
 import org.apache.tinkerpop.gremlin.structure.io.IoY;
 import org.apache.tinkerpop.gremlin.structure.io.IoYIoRegistry;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
+import org.apache.tinkerpop.shaded.kryo.ClassResolver;
 import org.apache.tinkerpop.shaded.kryo.Kryo;
+import org.apache.tinkerpop.shaded.kryo.Registration;
 import org.apache.tinkerpop.shaded.kryo.io.Input;
 import org.apache.tinkerpop.shaded.kryo.io.Output;
 import org.junit.Test;
@@ -31,6 +37,11 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
@@ -47,6 +58,111 @@ public class GryoMapperTest {
     }
 
     @Test
+    public void shouldSerializeDeserialize() throws Exception {
+        final GryoMapper mapper = GryoMapper.build().create();
+        final Kryo kryo = mapper.createMapper();
+        try (final OutputStream stream = new ByteArrayOutputStream()) {
+            final Output out = new Output(stream);
+
+            final Map<String,Object> props = new HashMap<>();
+            final List<Map<String, Object>> propertyNames = new ArrayList<>(1);
+            final Map<String,Object> propertyName = new HashMap<>();
+            propertyName.put(GraphSONTokens.ID, "x");
+            propertyName.put(GraphSONTokens.KEY, "x");
+            propertyName.put(GraphSONTokens.VALUE, "no-way-this-will-ever-work");
+            propertyNames.add(propertyName);
+            props.put("x", propertyNames);
+            final DetachedVertex v = new DetachedVertex(100, Vertex.DEFAULT_LABEL, props);
+
+            kryo.writeClassAndObject(out, v);
+
+            try (final InputStream inputStream = new ByteArrayInputStream(out.toBytes())) {
+                final Input input = new Input(inputStream);
+                final DetachedVertex readX = (DetachedVertex) kryo.readClassAndObject(input);
+                assertEquals("no-way-this-will-ever-work", readX.value("x"));
+            }
+        }
+    }
+
+    @Test
+    public void shouldSerializeWithCustomClassResolverToDetachedVertex() throws Exception {
+        final IoRegistry ioRegistry = new IoXIoRegistry.SerializerToVertexBased();
+        final Supplier<ClassResolver> classResolver = new CustomClassResolverSupplier();
+        final GryoMapper mapper = GryoMapper.build().addRegistry(ioRegistry).classResolver(classResolver).create();
+        final Kryo kryo = mapper.createMapper();
+        try (final OutputStream stream = new ByteArrayOutputStream()) {
+            final Output out = new Output(stream);
+            final IoX x = new IoX("no-way-this-will-ever-work");
+
+            kryo.writeClassAndObject(out, x);
+
+            final GryoMapper mapperWithoutKnowledgeOfIox = GryoMapper.build().create();
+            final Kryo kryoWithoutKnowledgeOfIox = mapperWithoutKnowledgeOfIox.createMapper();
+            try (final InputStream inputStream = new ByteArrayInputStream(out.toBytes())) {
+                final Input input = new Input(inputStream);
+                final DetachedVertex readX = (DetachedVertex) kryoWithoutKnowledgeOfIox.readClassAndObject(input);
+                assertEquals("no-way-this-will-ever-work", readX.value("x"));
+            }
+        }
+    }
+
+    @Test
+    public void shouldSerializeWithCustomClassResolverToHashMap() throws Exception {
+        final IoRegistry ioRegistry = new IoXIoRegistry.SerializerToVertexBased();
+        final Supplier<ClassResolver> classResolver = new CustomClassResolverSupplier();
+        final GryoMapper mapper = GryoMapper.build().addRegistry(ioRegistry).classResolver(classResolver).create();
+        final Kryo kryo = mapper.createMapper();
+        try (final OutputStream stream = new ByteArrayOutputStream()) {
+            final Output out = new Output(stream);
+            final IoY y = new IoY(100, 200);
+
+            kryo.writeClassAndObject(out, y);
+
+            final GryoMapper mapperWithoutKnowledgeOfIoy = GryoMapper.build().create();
+            final Kryo kryoWithoutKnowledgeOfIox = mapperWithoutKnowledgeOfIoy.createMapper();
+            try (final InputStream inputStream = new ByteArrayInputStream(out.toBytes())) {
+                final Input input = new Input(inputStream);
+                final Map readY = (HashMap) kryoWithoutKnowledgeOfIox.readClassAndObject(input);
+                assertEquals("100-200", readY.get("y"));
+            }
+        }
+    }
+
+    /**
+     * Creates new {@link CustomClassResolver} when requested.
+     */
+    public static class CustomClassResolverSupplier implements Supplier<ClassResolver> {
+        @Override
+        public ClassResolver get() {
+            return new CustomClassResolver();
+        }
+    }
+
+    /**
+     * A custom {@code ClassResolver} that alters the {@code Registration} returned to Kryo when an {@link IoX} class
+     * is requested, coercing it to a totally different class (a {@link DetachedVertex}).  This coercion demonstrates
+     * how a TinkerPop provider might take a custom internal class and serialize it into something core to
+     * TinkerPop which then removes the requirement for providers to expose serializers on the client side for user
+     * consumption.
+     */
+    public static class CustomClassResolver extends GryoClassResolver {
+        private IoXIoRegistry.IoXToVertexSerializer ioXToVertexSerializer = new IoXIoRegistry.IoXToVertexSerializer();
+        private IoYIoRegistry.IoYToHashMapSerializer ioYToHashMapSerializer = new IoYIoRegistry.IoYToHashMapSerializer();
+
+        public Registration getRegistration(final Class clazz) {
+            if (IoX.class.isAssignableFrom(clazz)) {
+                final Registration registration = super.getRegistration(DetachedVertex.class);
+                return new Registration(registration.getType(), ioXToVertexSerializer, registration.getId());
+            } else if (IoY.class.isAssignableFrom(clazz)) {
+                final Registration registration = super.getRegistration(HashMap.class);
+                return new Registration(registration.getType(), ioYToHashMapSerializer, registration.getId());
+            } else {
+                return super.getRegistration(clazz);
+            }
+        }
+    }
+
+    @Test
     public void shouldSerializeWithoutRegistration() throws Exception {
         final GryoMapper mapper = GryoMapper.build().registrationRequired(false).create();
         final Kryo kryo = mapper.createMapper();


[9/9] incubator-tinkerpop git commit: Merge remote-tracking branch 'origin/TINKERPOP-1064'

Posted by sp...@apache.org.
Merge remote-tracking branch 'origin/TINKERPOP-1064'


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/46c7189e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/46c7189e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/46c7189e

Branch: refs/heads/master
Commit: 46c7189e29a7ae22195106fca59ce248ae715a58
Parents: f4be739 f8dc1aa
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Mon Jan 4 15:23:48 2016 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon Jan 4 15:23:48 2016 -0500

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   1 +
 .../src/reference/gremlin-applications.asciidoc |  10 +-
 .../upgrade/release-3.1.x-incubating.asciidoc   |  15 +++
 .../structure/io/gryo/GryoClassResolver.java    |   2 +-
 .../gremlin/structure/io/gryo/GryoMapper.java   |  25 +++-
 .../tinkerpop/gremlin/structure/io/IoX.java     |   5 +
 .../gremlin/structure/io/IoXIoRegistry.java     |  57 +++++++++
 .../tinkerpop/gremlin/structure/io/IoY.java     |   5 +
 .../gremlin/structure/io/IoYIoRegistry.java     |  39 +++++++
 .../structure/io/gryo/GryoMapperTest.java       | 113 ++++++++++++++++++
 .../AbstractGraphSONMessageSerializerV1d0.java  |   5 +-
 .../driver/ser/AbstractMessageSerializer.java   |  82 +++++++++++++
 .../driver/ser/GryoMessageSerializerV1d0.java   |  49 +++-----
 ...raphSONMessageSerializerGremlinV1d0Test.java |   5 +-
 .../ser/GraphSONMessageSerializerV1d0Test.java  |  60 ++++++++++
 .../ser/GryoMessageSerializerV1d0Test.java      | 115 ++++++++++++++++++-
 16 files changed, 544 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/46c7189e/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --cc CHANGELOG.asciidoc
index e131b81,5d0feae..43fb4b6
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@@ -27,9 -27,9 +27,10 @@@ TinkerPop 3.1.1 (NOT OFFICIALLY RELEASE
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
  * Execute the `LifeCycle.beforeEval()` in the same thread that `eval()` is executed in for `GremlinExecutor`.
 +* Improved error handling of Gremlin Console initialization scripts to better separate errors in initialization script I/O versus execution of the script itself.
  * Fixed a bug in `Graph.OptOut` when trying to opt-out of certain test cases with the `method` property set to "*".
  * Added another `BulkLoader` implementation (`OneTimeBulkLoader`) that doesn't store temporary properties in the target graph.
+ * Added option to allow for a custom `ClassResolver` to be assigned to a `GryoMapper` instance.
  * Fixed a `SparkGraphComputer` sorting bug in MapReduce that occurred when there was more than one partition.
  * Added `strictTransactionManagement` to the Gremlin Server settings to indicate that the `aliases` parameter must be passed on requests and that transaction management will be scoped to the graphs provided in that argument.
  * Fixed a `NullPointerException` bug in `PeerPressureVertexProgram` that occurred when an adjacency traversal was not provided.


[3/9] incubator-tinkerpop git commit: Enable the message serializers to use the ClassResolver setting.

Posted by sp...@apache.org.
Enable the message serializers to use the ClassResolver setting.

This will allow Gremlin Server to get configured with the custom ClassResolver instance.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/5c196db6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/5c196db6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/5c196db6

Branch: refs/heads/master
Commit: 5c196db6fde877abfdb4c1d07049fe8cf8d16bb8
Parents: a51701d
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Dec 24 07:59:46 2015 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Dec 24 07:59:46 2015 -0500

----------------------------------------------------------------------
 .../driver/ser/GryoMessageSerializerV1d0.java   | 34 +++++++--
 .../ser/GryoMessageSerializerV1d0Test.java      | 72 +++++++++++++++++++-
 2 files changed, 97 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/5c196db6/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0.java
index 2d44711..721d596 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0.java
@@ -29,6 +29,7 @@ import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;
 import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoIo;
 import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoMapper;
+import org.apache.tinkerpop.shaded.kryo.ClassResolver;
 import org.apache.tinkerpop.shaded.kryo.Kryo;
 import org.apache.tinkerpop.shaded.kryo.Serializer;
 import org.apache.tinkerpop.shaded.kryo.io.Input;
@@ -44,6 +45,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.UUID;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
 /**
@@ -63,11 +65,12 @@ public final class GryoMessageSerializerV1d0 implements MessageSerializer {
     private static final String MIME_TYPE = SerTokens.MIME_GRYO_V1D0;
     private static final String MIME_TYPE_STRINGD = SerTokens.MIME_GRYO_V1D0 + "-stringd";
 
-    private static final String TOKEN_IO_REGISTRIES = "ioRegistries";
-    private static final String TOKEN_CUSTOM = "custom";
-    private static final String TOKEN_SERIALIZE_RESULT_TO_STRING = "serializeResultToString";
-    private static final String TOKEN_USE_MAPPER_FROM_GRAPH = "useMapperFromGraph";
-    private static final String TOKEN_BUFFER_SIZE = "bufferSize";
+    public static final String TOKEN_IO_REGISTRIES = "ioRegistries";
+    public static final String TOKEN_CUSTOM = "custom";
+    public static final String TOKEN_SERIALIZE_RESULT_TO_STRING = "serializeResultToString";
+    public static final String TOKEN_USE_MAPPER_FROM_GRAPH = "useMapperFromGraph";
+    public static final String TOKEN_BUFFER_SIZE = "bufferSize";
+    public static final String TOKEN_CLASS_RESOLVER_SUPPLIER = "classResolverSupplier";
 
     private boolean serializeToString = false;
     private int bufferSize = 4096;
@@ -82,7 +85,7 @@ public final class GryoMessageSerializerV1d0 implements MessageSerializer {
 
     /**
      * Creates an instance with a provided mapper configured {@link GryoMapper} instance. Note that this instance
-     * will be overriden by {@link #configure} is called.
+     * will be overridden by {@link #configure} is called.
      */
     public GryoMessageSerializerV1d0(final GryoMapper kryo) {
         this.gryoMapper = kryo;
@@ -112,6 +115,7 @@ public final class GryoMessageSerializerV1d0 implements MessageSerializer {
         }
 
         addIoRegistries(config, builder);
+        addClassResolverSupplier(config, builder);
         addCustomClasses(config, builder);
 
         this.serializeToString = Boolean.parseBoolean(config.getOrDefault(TOKEN_SERIALIZE_RESULT_TO_STRING, "false").toString());
@@ -142,6 +146,24 @@ public final class GryoMessageSerializerV1d0 implements MessageSerializer {
         });
     }
 
+    private void addClassResolverSupplier(final Map<String, Object> config, final GryoMapper.Builder builder) {
+        final String className = (String) config.getOrDefault(TOKEN_CLASS_RESOLVER_SUPPLIER, null);
+        if (className != null && !className.isEmpty()) {
+            try {
+                final Class<?> clazz = Class.forName(className);
+                try {
+                    final Method instanceMethod = clazz.getDeclaredMethod("getInstance");
+                    builder.classResolver((Supplier<ClassResolver>) instanceMethod.invoke(null));
+                } catch (Exception methodex) {
+                    // tried getInstance() and that failed so try newInstance() no-arg constructor
+                    builder.classResolver((Supplier<ClassResolver>) clazz.newInstance());
+                }
+            } catch (Exception ex) {
+                throw new IllegalStateException(ex);
+            }
+        }
+    }
+
     private void addCustomClasses(final Map<String, Object> config, final GryoMapper.Builder builder) {
         final List<String> classNameList = getClassNamesFromConfig(TOKEN_CUSTOM, config);
 

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/5c196db6/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0Test.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0Test.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0Test.java
index e8951fc..f56bf51 100644
--- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0Test.java
+++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0Test.java
@@ -29,6 +29,7 @@ import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoClassResolver;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerFactory;
@@ -37,8 +38,9 @@ import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufAllocator;
 import io.netty.buffer.UnpooledByteBufAllocator;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
-import org.apache.tinkerpop.shaded.jackson.databind.util.StdDateFormat;
+import org.apache.tinkerpop.shaded.kryo.ClassResolver;
 import org.apache.tinkerpop.shaded.kryo.KryoException;
+import org.apache.tinkerpop.shaded.kryo.Registration;
 import org.junit.Test;
 
 import java.util.ArrayList;
@@ -46,8 +48,8 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.UUID;
+import java.util.function.Supplier;
 
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.CoreMatchers.is;
@@ -64,7 +66,7 @@ import static org.junit.Assert.fail;
  */
 public class GryoMessageSerializerV1d0Test {
     private static final Map<String, Object> config = new HashMap<String, Object>() {{
-        put("serializeResultToString", true);
+        put(GryoMessageSerializerV1d0.TOKEN_SERIALIZE_RESULT_TO_STRING, true);
     }};
 
     private UUID requestId = UUID.fromString("6457272A-4018-4538-B9AE-08DD5DDC0AA1");
@@ -80,6 +82,40 @@ public class GryoMessageSerializerV1d0Test {
     }
 
     @Test
+    public void shouldConfigureCustomClassResolver() {
+        final MessageSerializer serializer = new GryoMessageSerializerV1d0();
+        final Map<String, Object> config = new HashMap<String, Object>() {{
+            put(GryoMessageSerializerV1d0.TOKEN_CLASS_RESOLVER_SUPPLIER, ErrorOnlyClassResolverSupplier.class.getName());
+        }};
+
+        serializer.configure(config, null);
+
+        try {
+            serializer.serializeResponseAsBinary(responseMessageBuilder.create(), allocator);
+            fail("Should fail because the ClassResolver used here always generates an error");
+        } catch (Exception ex) {
+            assertEquals("java.lang.RuntimeException: Registration is not allowed with this ClassResolver - it is not a good implementation", ex.getMessage());
+        }
+    }
+
+    @Test
+    public void shouldConfigureCustomClassResolverFromInstance() {
+        final MessageSerializer serializer = new GryoMessageSerializerV1d0();
+        final Map<String, Object> config = new HashMap<String, Object>() {{
+            put(GryoMessageSerializerV1d0.TOKEN_CLASS_RESOLVER_SUPPLIER, ErrorOnlyClassResolverSupplierAsInstance.class.getName());
+        }};
+
+        serializer.configure(config, null);
+
+        try {
+            serializer.serializeResponseAsBinary(responseMessageBuilder.create(), allocator);
+            fail("Should fail because the ClassResolver used here always generates an error");
+        } catch (Exception ex) {
+            assertEquals("java.lang.RuntimeException: Registration is not allowed with this ClassResolver - it is not a good implementation", ex.getMessage());
+        }
+    }
+
+    @Test
     public void shouldSerializeIterable() throws Exception {
         final ArrayList<Integer> list = new ArrayList<>();
         list.add(1);
@@ -490,4 +526,34 @@ public class GryoMessageSerializerV1d0Test {
         final ByteBuf bb = textSerializer.serializeResponseAsBinary(responseMessageBuilder.result(toSerialize).create(), allocator);
         return textSerializer.deserializeResponse(bb);
     }
+
+    public static class ErrorOnlyClassResolverSupplierAsInstance implements Supplier<ClassResolver> {
+
+        private static final ErrorOnlyClassResolverSupplierAsInstance instance = new ErrorOnlyClassResolverSupplierAsInstance();
+
+        private ErrorOnlyClassResolverSupplierAsInstance() {}
+
+        public static ErrorOnlyClassResolverSupplierAsInstance getInstance() {
+            return instance;
+        }
+
+        @Override
+        public ClassResolver get() {
+            return new ErrorOnlyClassResolver();
+        }
+    }
+
+    public static class ErrorOnlyClassResolverSupplier implements Supplier<ClassResolver> {
+        @Override
+        public ClassResolver get() {
+            return new ErrorOnlyClassResolver();
+        }
+    }
+
+    public static class ErrorOnlyClassResolver extends GryoClassResolver {
+        @Override
+        public Registration getRegistration(Class clazz) {
+            throw new RuntimeException("Registration is not allowed with this ClassResolver - it is not a good implementation");
+        }
+    }
 }


[5/9] incubator-tinkerpop git commit: Update reference docs.

Posted by sp...@apache.org.
Update reference docs.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/34db8921
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/34db8921
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/34db8921

Branch: refs/heads/master
Commit: 34db89216dfda92e8dbe1389feb8dc8690c088ba
Parents: c288d65
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Dec 24 08:30:22 2015 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Dec 24 08:30:22 2015 -0500

----------------------------------------------------------------------
 docs/src/reference/gremlin-applications.asciidoc | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/34db8921/docs/src/reference/gremlin-applications.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index 747e693..0db16d2 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -1094,10 +1094,11 @@ It has the MIME type of `application/vnd.gremlin-v1.0+gryo` and the following co
 |=========================================================
 |Key |Description |Default
 |bufferSize |The maximum size of the Kryo buffer for use on a single object being serialized.  Increasing this value will correct `KryoException` errors that complain of "Buffer too small". |_4096_
+|classResolverSupplier |The fully qualified classname of a custom `Supplier<ClassResolver>` which will be used when constructing `Kryo` instances. There is no direct default for this setting, but without a setting the `GryoClassResolver` is used. |_none_
+|custom |A list of classes with custom kryo `Serializer` implementations related to them in the form of `<class>;<serializer-class>`. |_none_
+|ioRegistries |A list of `IoRegistry` implementations to be applied to the serializer. |_none_
 |serializeResultToString |When set to `true`, results are serialized by first calling `toString()` on each object in the result list resulting in an extended MIME Type of `application/vnd.gremlin-v1.0+gryo-stringd`.  When set to `false` Kryo-based serialization is applied. |_false_
 |useMapperFromGraph |Specifies the name of the `Graph` (from the `graphs` `Map` in the configuration file) from which to plugin any custom serializers that are tied to it. |_none_
-|ioRegistries |A list of `IoRegistry` implementations to be applied to the serializer.
-|custom |A list of classes with custom kryo `Serializer` implementations related to them in the form of `<class>;<serializer-class>`. |_none_
 |=========================================================
 
 As described above, there are multiple ways in which to register serializers for Kryo-based serialization.  These
@@ -1105,6 +1106,11 @@ configurations can be used in conjunction with one another where there is a spec
 are applied.  The `userMapperFromGraph` setting is applied first, followed by any `ioRegistries` and finalized by the
 `custom` setting.
 
+Those configuring or implementing a `Supplier<ClassResolver>` should consider this an "advanced" option and typically
+important to use cases where server types need to be coerced to client types (i.e. a type is available on the server
+but not on the client).  Implementations should typically instantiate `ClassResolver` implementations that are
+extensions of the `GryoClassResolver` as this class is important to most serialization tasks in TinkerPop.
+
 Best Practices
 ~~~~~~~~~~~~~~
 


[4/9] incubator-tinkerpop git commit: Updated changelog.

Posted by sp...@apache.org.
Updated changelog.


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

Branch: refs/heads/master
Commit: c288d658438008e3e5a66efe7ed39a2444552d9e
Parents: 5c196db
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Dec 24 08:01:16 2015 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Dec 24 08:01:16 2015 -0500

----------------------------------------------------------------------
 CHANGELOG.asciidoc | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c288d658/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 25773e8..23ae585 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -28,6 +28,7 @@ TinkerPop 3.1.1 (NOT OFFICIALLY RELEASED YET)
 
 * Fixed a bug in `Graph.OptOut` when trying to opt-out of certain test cases with the `method` property set to "*".
 * Added another `BulkLoader` implementation (`OneTimeBulkLoader`) that doesn't store temporary properties in the target graph.
+* Added option to allow for a custom `ClassResolver` to be assigned to a `GryoMapper` instance.
 * Fixed a `SparkGraphComputer` sorting bug in MapReduce that occurred when there was more than one partition.
 * Added `strictTransactionManagement` to the Gremlin Server settings to indicate that the `aliases` parameter must be passed on requests and that transaction management will be scoped to the graphs provided in that argument.
 * Fixed a `NullPointerException` bug in `PeerPressureVertexProgram` that occurred when an adjacency traversal was not provided.


[7/9] incubator-tinkerpop git commit: Merge remote-tracking branch 'origin/master' into TINKERPOP-1064

Posted by sp...@apache.org.
Merge remote-tracking branch 'origin/master' into TINKERPOP-1064


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

Branch: refs/heads/master
Commit: e480f4aa9ac419443b54df3ccc9bc538dfeffe28
Parents: 0defd91 a705c21
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Dec 29 18:45:19 2015 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Dec 29 18:45:19 2015 -0500

----------------------------------------------------------------------
 CHANGELOG.asciidoc                               |   1 +
 README.asciidoc                                  |  12 ++++++------
 docs/src/dev/developer/release.asciidoc          |   4 ++--
 docs/src/reference/gremlin-applications.asciidoc |   7 +++++--
 docs/static/images/quantum-gremlin-full.png      | Bin 0 -> 1877990 bytes
 5 files changed, 14 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/e480f4aa/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --cc CHANGELOG.asciidoc
index 23ae585,028f20f..5d0feae
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@@ -26,9 -26,9 +26,10 @@@ image::https://raw.githubusercontent.co
  TinkerPop 3.1.1 (NOT OFFICIALLY RELEASED YET)
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
+ * Execute the `LifeCycle.beforeEval()` in the same thread that `eval()` is executed in for `GremlinExecutor`.
  * Fixed a bug in `Graph.OptOut` when trying to opt-out of certain test cases with the `method` property set to "*".
  * Added another `BulkLoader` implementation (`OneTimeBulkLoader`) that doesn't store temporary properties in the target graph.
 +* Added option to allow for a custom `ClassResolver` to be assigned to a `GryoMapper` instance.
  * Fixed a `SparkGraphComputer` sorting bug in MapReduce that occurred when there was more than one partition.
  * Added `strictTransactionManagement` to the Gremlin Server settings to indicate that the `aliases` parameter must be passed on requests and that transaction management will be scoped to the graphs provided in that argument.
  * Fixed a `NullPointerException` bug in `PeerPressureVertexProgram` that occurred when an adjacency traversal was not provided.

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/e480f4aa/docs/src/reference/gremlin-applications.asciidoc
----------------------------------------------------------------------


[2/9] incubator-tinkerpop git commit: Removed test IoRegistry implementations for ClassResolver.

Posted by sp...@apache.org.
Removed test IoRegistry implementations for ClassResolver.

Apparently, it is unnecessary to register a serializer to a class whose registration is overriden by the ClassResolver.  That's kinda cool.


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

Branch: refs/heads/master
Commit: a51701d907539328d8a486cfb4f03e7ef5082554
Parents: a94c51f
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Dec 24 07:00:12 2015 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Dec 24 07:00:12 2015 -0500

----------------------------------------------------------------------
 .../gremlin/structure/io/IoXIoRegistry.java     |  6 --
 .../gremlin/structure/io/IoYIoRegistry.java     |  6 --
 .../structure/io/gryo/GryoMapperTest.java       | 75 ++++++++++----------
 3 files changed, 36 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/a51701d9/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoXIoRegistry.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoXIoRegistry.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoXIoRegistry.java
index ddc5477..c49ea0b 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoXIoRegistry.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoXIoRegistry.java
@@ -56,12 +56,6 @@ public class IoXIoRegistry {
         }
     }
 
-    public static class SerializerToVertexBased extends AbstractIoRegistry {
-        public SerializerToVertexBased() {
-            register(GryoIo.class, IoX.class, new IoXToVertexSerializer());
-        }
-    }
-
     /**
      * Converts an {@link IoX} to a {@link DetachedVertex}.
      */

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/a51701d9/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoYIoRegistry.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoYIoRegistry.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoYIoRegistry.java
index 53c3404..1654945 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoYIoRegistry.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoYIoRegistry.java
@@ -51,12 +51,6 @@ public class IoYIoRegistry {
         }
     }
 
-    public static class SerializerToMapBased extends AbstractIoRegistry {
-        public SerializerToMapBased() {
-            register(GryoIo.class, IoY.class, new IoYToHashMapSerializer());
-        }
-    }
-
     /**
      * Converts an {@link IoX} to a {@link HashMap}.
      */

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/a51701d9/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java
index 947528c..76a2804 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java
@@ -19,7 +19,6 @@
 package org.apache.tinkerpop.gremlin.structure.io.gryo;
 
 import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;
 import org.apache.tinkerpop.gremlin.structure.io.IoX;
 import org.apache.tinkerpop.gremlin.structure.io.IoXIoRegistry;
 import org.apache.tinkerpop.gremlin.structure.io.IoY;
@@ -86,9 +85,8 @@ public class GryoMapperTest {
 
     @Test
     public void shouldSerializeWithCustomClassResolverToDetachedVertex() throws Exception {
-        final IoRegistry ioRegistry = new IoXIoRegistry.SerializerToVertexBased();
         final Supplier<ClassResolver> classResolver = new CustomClassResolverSupplier();
-        final GryoMapper mapper = GryoMapper.build().addRegistry(ioRegistry).classResolver(classResolver).create();
+        final GryoMapper mapper = GryoMapper.build().classResolver(classResolver).create();
         final Kryo kryo = mapper.createMapper();
         try (final OutputStream stream = new ByteArrayOutputStream()) {
             final Output out = new Output(stream);
@@ -108,9 +106,8 @@ public class GryoMapperTest {
 
     @Test
     public void shouldSerializeWithCustomClassResolverToHashMap() throws Exception {
-        final IoRegistry ioRegistry = new IoXIoRegistry.SerializerToVertexBased();
         final Supplier<ClassResolver> classResolver = new CustomClassResolverSupplier();
-        final GryoMapper mapper = GryoMapper.build().addRegistry(ioRegistry).classResolver(classResolver).create();
+        final GryoMapper mapper = GryoMapper.build().classResolver(classResolver).create();
         final Kryo kryo = mapper.createMapper();
         try (final OutputStream stream = new ByteArrayOutputStream()) {
             final Output out = new Output(stream);
@@ -128,40 +125,6 @@ public class GryoMapperTest {
         }
     }
 
-    /**
-     * Creates new {@link CustomClassResolver} when requested.
-     */
-    public static class CustomClassResolverSupplier implements Supplier<ClassResolver> {
-        @Override
-        public ClassResolver get() {
-            return new CustomClassResolver();
-        }
-    }
-
-    /**
-     * A custom {@code ClassResolver} that alters the {@code Registration} returned to Kryo when an {@link IoX} class
-     * is requested, coercing it to a totally different class (a {@link DetachedVertex}).  This coercion demonstrates
-     * how a TinkerPop provider might take a custom internal class and serialize it into something core to
-     * TinkerPop which then removes the requirement for providers to expose serializers on the client side for user
-     * consumption.
-     */
-    public static class CustomClassResolver extends GryoClassResolver {
-        private IoXIoRegistry.IoXToVertexSerializer ioXToVertexSerializer = new IoXIoRegistry.IoXToVertexSerializer();
-        private IoYIoRegistry.IoYToHashMapSerializer ioYToHashMapSerializer = new IoYIoRegistry.IoYToHashMapSerializer();
-
-        public Registration getRegistration(final Class clazz) {
-            if (IoX.class.isAssignableFrom(clazz)) {
-                final Registration registration = super.getRegistration(DetachedVertex.class);
-                return new Registration(registration.getType(), ioXToVertexSerializer, registration.getId());
-            } else if (IoY.class.isAssignableFrom(clazz)) {
-                final Registration registration = super.getRegistration(HashMap.class);
-                return new Registration(registration.getType(), ioYToHashMapSerializer, registration.getId());
-            } else {
-                return super.getRegistration(clazz);
-            }
-        }
-    }
-
     @Test
     public void shouldSerializeWithoutRegistration() throws Exception {
         final GryoMapper mapper = GryoMapper.build().registrationRequired(false).create();
@@ -236,4 +199,38 @@ public class GryoMapperTest {
             }
         }
     }
+
+    /**
+     * Creates new {@link CustomClassResolver} when requested.
+     */
+    public static class CustomClassResolverSupplier implements Supplier<ClassResolver> {
+        @Override
+        public ClassResolver get() {
+            return new CustomClassResolver();
+        }
+    }
+
+    /**
+     * A custom {@code ClassResolver} that alters the {@code Registration} returned to Kryo when an {@link IoX} class
+     * is requested, coercing it to a totally different class (a {@link DetachedVertex}).  This coercion demonstrates
+     * how a TinkerPop provider might take a custom internal class and serialize it into something core to
+     * TinkerPop which then removes the requirement for providers to expose serializers on the client side for user
+     * consumption.
+     */
+    public static class CustomClassResolver extends GryoClassResolver {
+        private IoXIoRegistry.IoXToVertexSerializer ioXToVertexSerializer = new IoXIoRegistry.IoXToVertexSerializer();
+        private IoYIoRegistry.IoYToHashMapSerializer ioYToHashMapSerializer = new IoYIoRegistry.IoYToHashMapSerializer();
+
+        public Registration getRegistration(final Class clazz) {
+            if (IoX.class.isAssignableFrom(clazz)) {
+                final Registration registration = super.getRegistration(DetachedVertex.class);
+                return new Registration(registration.getType(), ioXToVertexSerializer, registration.getId());
+            } else if (IoY.class.isAssignableFrom(clazz)) {
+                final Registration registration = super.getRegistration(HashMap.class);
+                return new Registration(registration.getType(), ioYToHashMapSerializer, registration.getId());
+            } else {
+                return super.getRegistration(clazz);
+            }
+        }
+    }
 }


[6/9] incubator-tinkerpop git commit: Update upgrade docs.

Posted by sp...@apache.org.
Update upgrade docs.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/0defd91a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/0defd91a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/0defd91a

Branch: refs/heads/master
Commit: 0defd91a992e1abbbefc1519871f501bc17a4711
Parents: 34db892
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Dec 24 08:30:35 2015 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Dec 24 08:30:35 2015 -0500

----------------------------------------------------------------------
 docs/src/upgrade/release-3.1.x-incubating.asciidoc | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/0defd91a/docs/src/upgrade/release-3.1.x-incubating.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.1.x-incubating.asciidoc b/docs/src/upgrade/release-3.1.x-incubating.asciidoc
index b50f3e1..8f487a2 100644
--- a/docs/src/upgrade/release-3.1.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.1.x-incubating.asciidoc
@@ -161,6 +161,21 @@ link:https://issues.apache.org/jira/browse/TINKERPOP-1000[TINKERPOP-1000]
 Graph Database Providers
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
+Custom ClassResolver
+++++++++++++++++++++
+
+For providers who have built custom serializers in Gryo, there is a new feature open that can be considered.  A
+`GryoMapper` can now take a custom Kryo `ClassResolver`, which means that custom types can be coerced to other types
+during serialization (e.g. a custom identifier could be serialized as a `HashMap`).  The advantage to taking this
+approach is that users will not need to have the provider's serializers on the client side.  They will only need to
+exist on the server (presuming that the a type is coerced to a type available on the client, of course).  The downside
+is that serialization is then no longer a two way street. For example, a custom `ClassResolver` that coerced a
+custom identifier to `HashMap` would let the client work with the identifier as a `HashMap`, but the client would then
+have to send that identifier back to the server as a `HashMap` where it would be recognized as a `HashMap` (not an
+identifier).
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1064[TINKERPOP-1064]
+
 Feature Consistency
 +++++++++++++++++++
 


[8/9] incubator-tinkerpop git commit: TINKERPOP-1066 Allow ioRegistries to be set on GraphSON MessageSerializers

Posted by sp...@apache.org.
TINKERPOP-1066 Allow ioRegistries to be set on GraphSON MessageSerializers

This makes the configuration symmetrical to Gryo.


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

Branch: refs/heads/master
Commit: f8dc1aabd280bde7711d873c8ac0083eacf6e2c9
Parents: e480f4a
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Dec 30 13:59:50 2015 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Dec 30 13:59:50 2015 -0500

----------------------------------------------------------------------
 .../AbstractGraphSONMessageSerializerV1d0.java  |  5 +-
 .../driver/ser/AbstractMessageSerializer.java   | 82 ++++++++++++++++++++
 .../driver/ser/GryoMessageSerializerV1d0.java   | 41 +---------
 ...raphSONMessageSerializerGremlinV1d0Test.java |  5 +-
 .../ser/GraphSONMessageSerializerV1d0Test.java  | 60 ++++++++++++++
 .../ser/GryoMessageSerializerV1d0Test.java      | 43 ++++++++++
 6 files changed, 194 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f8dc1aab/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractGraphSONMessageSerializerV1d0.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractGraphSONMessageSerializerV1d0.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractGraphSONMessageSerializerV1d0.java
index 3410ede..810220b 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractGraphSONMessageSerializerV1d0.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractGraphSONMessageSerializerV1d0.java
@@ -18,7 +18,6 @@
  */
 package org.apache.tinkerpop.gremlin.driver.ser;
 
-import org.apache.tinkerpop.gremlin.driver.MessageSerializer;
 import org.apache.tinkerpop.gremlin.driver.message.RequestMessage;
 import org.apache.tinkerpop.gremlin.driver.message.ResponseMessage;
 import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
@@ -51,7 +50,7 @@ import java.util.UUID;
 /**
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
-public abstract class AbstractGraphSONMessageSerializerV1d0 implements MessageSerializer {
+public abstract class AbstractGraphSONMessageSerializerV1d0 extends AbstractMessageSerializer {
     private static final Logger logger = LoggerFactory.getLogger(AbstractGraphSONMessageSerializerV1d0.class);
 
     protected ObjectMapper mapper;
@@ -97,6 +96,8 @@ public abstract class AbstractGraphSONMessageSerializerV1d0 implements MessageSe
             initialBuilder = GraphSONMapper.build();
         }
 
+        addIoRegistries(config, initialBuilder);
+
         mapper = configureBuilder(initialBuilder).create().createMapper();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f8dc1aab/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractMessageSerializer.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractMessageSerializer.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractMessageSerializer.java
new file mode 100644
index 0000000..3c4380c
--- /dev/null
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractMessageSerializer.java
@@ -0,0 +1,82 @@
+/*
+ * 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.tinkerpop.gremlin.driver.ser;
+
+import org.apache.tinkerpop.gremlin.driver.MessageSerializer;
+import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;
+import org.apache.tinkerpop.gremlin.structure.io.Mapper;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Base {@link MessageSerializer} that serializers can implement to get some helper methods around configuring a
+ * {@link org.apache.tinkerpop.gremlin.structure.io.Mapper.Builder}.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public abstract class AbstractMessageSerializer implements MessageSerializer {
+    public static final String TOKEN_IO_REGISTRIES = "ioRegistries";
+
+    /**
+     * Reads a list of fully qualified class names from the value of the {@link #TOKEN_IO_REGISTRIES} configuration
+     * key. These classes should equate to {@link IoRegistry} implementations that will be assigned to the
+     * {@link org.apache.tinkerpop.gremlin.structure.io.Mapper.Builder}.  The assumption is that the
+     * {@link IoRegistry} either has a static {@code getInstance()} method or has a zero-arg constructor from which
+     * it can be instantiated.
+     */
+    protected void addIoRegistries(final Map<String, Object> config, final Mapper.Builder builder) {
+        final List<String> classNameList = getListStringFromConfig(TOKEN_IO_REGISTRIES, config);
+
+        classNameList.stream().forEach(className -> {
+            try {
+                final Class<?> clazz = Class.forName(className);
+                try {
+                    final Method instanceMethod = clazz.getDeclaredMethod("getInstance");
+                    if (IoRegistry.class.isAssignableFrom(instanceMethod.getReturnType()))
+                        builder.addRegistry((IoRegistry) instanceMethod.invoke(null));
+                    else
+                        throw new Exception();
+                } catch (Exception methodex) {
+                    // tried getInstance() and that failed so try newInstance() no-arg constructor
+                    builder.addRegistry((IoRegistry) clazz.newInstance());
+                }
+            } catch (Exception ex) {
+                throw new IllegalStateException(ex);
+            }
+        });
+    }
+
+    /**
+     * Gets a {@link List} of strings from the configuration object.
+     */
+    protected List<String> getListStringFromConfig(final String token, final Map<String, Object> config) {
+        final List<String> classNameList;
+        try {
+            classNameList = (List<String>) config.getOrDefault(token, Collections.emptyList());
+        } catch (Exception ex) {
+            throw new IllegalStateException(String.format("Invalid configuration value of [%s] for [%s] setting on %s serialization configuration",
+                    config.getOrDefault(token, ""), token, this.getClass().getName()), ex);
+        }
+
+        return classNameList;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f8dc1aab/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0.java
index 721d596..ce46dfc 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0.java
@@ -21,12 +21,10 @@ package org.apache.tinkerpop.gremlin.driver.ser;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufAllocator;
 import io.netty.util.ReferenceCountUtil;
-import org.apache.tinkerpop.gremlin.driver.MessageSerializer;
 import org.apache.tinkerpop.gremlin.driver.message.RequestMessage;
 import org.apache.tinkerpop.gremlin.driver.message.ResponseMessage;
 import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
 import org.apache.tinkerpop.gremlin.structure.Graph;
-import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;
 import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoIo;
 import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoMapper;
 import org.apache.tinkerpop.shaded.kryo.ClassResolver;
@@ -38,7 +36,6 @@ import org.apache.tinkerpop.shaded.kryo.io.Output;
 import java.io.ByteArrayOutputStream;
 import java.lang.reflect.Method;
 import java.nio.charset.Charset;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
@@ -51,7 +48,7 @@ import java.util.stream.Collectors;
 /**
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
-public final class GryoMessageSerializerV1d0 implements MessageSerializer {
+public final class GryoMessageSerializerV1d0 extends AbstractMessageSerializer {
     private GryoMapper gryoMapper;
     private ThreadLocal<Kryo> kryoThreadLocal = new ThreadLocal<Kryo>() {
         @Override
@@ -65,7 +62,6 @@ public final class GryoMessageSerializerV1d0 implements MessageSerializer {
     private static final String MIME_TYPE = SerTokens.MIME_GRYO_V1D0;
     private static final String MIME_TYPE_STRINGD = SerTokens.MIME_GRYO_V1D0 + "-stringd";
 
-    public static final String TOKEN_IO_REGISTRIES = "ioRegistries";
     public static final String TOKEN_CUSTOM = "custom";
     public static final String TOKEN_SERIALIZE_RESULT_TO_STRING = "serializeResultToString";
     public static final String TOKEN_USE_MAPPER_FROM_GRAPH = "useMapperFromGraph";
@@ -124,28 +120,6 @@ public final class GryoMessageSerializerV1d0 implements MessageSerializer {
         this.gryoMapper = builder.create();
     }
 
-    private void addIoRegistries(final Map<String, Object> config, final GryoMapper.Builder builder) {
-        final List<String> classNameList = getClassNamesFromConfig(TOKEN_IO_REGISTRIES, config);
-
-        classNameList.stream().forEach(className -> {
-            try {
-                final Class<?> clazz = Class.forName(className);
-                try {
-                    final Method instanceMethod = clazz.getDeclaredMethod("getInstance");
-                    if (IoRegistry.class.isAssignableFrom(instanceMethod.getReturnType()))
-                        builder.addRegistry((IoRegistry) instanceMethod.invoke(null));
-                    else
-                        throw new Exception();
-                } catch (Exception methodex) {
-                    // tried getInstance() and that failed so try newInstance() no-arg constructor
-                    builder.addRegistry((IoRegistry) clazz.newInstance());
-                }
-            } catch (Exception ex) {
-                throw new IllegalStateException(ex);
-            }
-        });
-    }
-
     private void addClassResolverSupplier(final Map<String, Object> config, final GryoMapper.Builder builder) {
         final String className = (String) config.getOrDefault(TOKEN_CLASS_RESOLVER_SUPPLIER, null);
         if (className != null && !className.isEmpty()) {
@@ -165,7 +139,7 @@ public final class GryoMessageSerializerV1d0 implements MessageSerializer {
     }
 
     private void addCustomClasses(final Map<String, Object> config, final GryoMapper.Builder builder) {
-        final List<String> classNameList = getClassNamesFromConfig(TOKEN_CUSTOM, config);
+        final List<String> classNameList = getListStringFromConfig(TOKEN_CUSTOM, config);
 
         classNameList.stream().forEach(serializerDefinition -> {
             String className;
@@ -197,17 +171,6 @@ public final class GryoMessageSerializerV1d0 implements MessageSerializer {
         });
     }
 
-    private List<String> getClassNamesFromConfig(final String token, final Map<String, Object> config) {
-        final List<String> classNameList;
-        try {
-            classNameList = (List<String>) config.getOrDefault(token, new ArrayList<String>());
-        } catch (Exception ex) {
-            throw new IllegalStateException(String.format("Invalid configuration value of [%s] for [%s] setting on %s serialization configuration",
-                    config.getOrDefault(token, ""), token, this.getClass().getName()), ex);
-        }
-        return classNameList;
-    }
-
     @Override
     public String[] mimeTypesSupported() {
         return new String[]{this.serializeToString ? MIME_TYPE_STRINGD : MIME_TYPE};

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f8dc1aab/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerGremlinV1d0Test.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerGremlinV1d0Test.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerGremlinV1d0Test.java
index 91fa899..de719c1 100644
--- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerGremlinV1d0Test.java
+++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerGremlinV1d0Test.java
@@ -44,7 +44,10 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
 
 /**
  * Serializer tests that cover non-lossy serialization/deserialization methods.

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f8dc1aab/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV1d0Test.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV1d0Test.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV1d0Test.java
index 3772c7d..de4b4b6 100644
--- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV1d0Test.java
+++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV1d0Test.java
@@ -27,22 +27,39 @@ import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.AbstractIoRegistry;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONIo;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerFactory;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerationException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.core.JsonParser;
+import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
+import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
 import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
 import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.module.SimpleModule;
 import org.apache.tinkerpop.shaded.jackson.databind.node.NullNode;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
 import org.apache.tinkerpop.shaded.jackson.databind.util.StdDateFormat;
 import org.junit.Test;
 
+import java.awt.*;
+import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
@@ -61,6 +78,23 @@ public class GraphSONMessageSerializerV1d0Test {
     private static final ObjectMapper mapper = new ObjectMapper();
 
     @Test
+    public void shouldConfigureIoRegistry() throws Exception {
+        final GraphSONMessageSerializerV1d0 serializer = new GraphSONMessageSerializerV1d0();
+        final Map<String, Object> config = new HashMap<String, Object>() {{
+            put(GryoMessageSerializerV1d0.TOKEN_IO_REGISTRIES, Arrays.asList(ColorIoRegistry.class.getName()));
+        }};
+
+        serializer.configure(config, null);
+
+        final ResponseMessage toSerialize = ResponseMessage.build(UUID.fromString("2D62161B-9544-4F39-AF44-62EC49F9A595"))
+                .result(Color.RED).create();
+        final String results = serializer.serializeResponseAsString(toSerialize);
+        final JsonNode json = mapper.readTree(results);
+        assertNotNull(json);
+        assertThat(json.get(SerTokens.TOKEN_RESULT).get(SerTokens.TOKEN_DATA).booleanValue(), is(true));
+    }
+
+    @Test
     public void shouldSerializeToJsonNullResultReturnsNull() throws Exception {
         final ResponseMessage message = ResponseMessage.build(msg).create();
         final String results = SERIALIZER.serializeResponseAsString(message);
@@ -385,4 +419,30 @@ public class GraphSONMessageSerializerV1d0Test {
             return this.val;
         }
     }
+
+    public static class ColorIoRegistry extends AbstractIoRegistry {
+        public ColorIoRegistry() {
+            register(GraphSONIo.class, null, new ColorSimpleModule());
+        }
+    }
+
+    public static class ColorSimpleModule extends SimpleModule {
+        public ColorSimpleModule() {
+            super("color-fun");
+            addSerializer(Color.class, new ColorSerializer());
+
+        }
+    }
+
+    public static class ColorSerializer extends StdSerializer<Color> {
+        public ColorSerializer() {
+            super(Color.class);
+        }
+
+        @Override
+        public void serialize(final Color color, final JsonGenerator jsonGenerator,
+                              final SerializerProvider serializerProvider) throws IOException, JsonGenerationException {
+            jsonGenerator.writeBoolean(color.equals(Color.RED));
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f8dc1aab/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0Test.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0Test.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0Test.java
index f56bf51..bb731a9 100644
--- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0Test.java
+++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GryoMessageSerializerV1d0Test.java
@@ -29,7 +29,9 @@ import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.AbstractIoRegistry;
 import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoClassResolver;
+import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoIo;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerFactory;
@@ -39,11 +41,17 @@ import io.netty.buffer.ByteBufAllocator;
 import io.netty.buffer.UnpooledByteBufAllocator;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 import org.apache.tinkerpop.shaded.kryo.ClassResolver;
+import org.apache.tinkerpop.shaded.kryo.Kryo;
 import org.apache.tinkerpop.shaded.kryo.KryoException;
 import org.apache.tinkerpop.shaded.kryo.Registration;
+import org.apache.tinkerpop.shaded.kryo.Serializer;
+import org.apache.tinkerpop.shaded.kryo.io.Input;
+import org.apache.tinkerpop.shaded.kryo.io.Output;
 import org.junit.Test;
 
+import java.awt.*;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -82,6 +90,23 @@ public class GryoMessageSerializerV1d0Test {
     }
 
     @Test
+    public void shouldConfigureIoRegistry() throws Exception {
+        final MessageSerializer serializer = new GryoMessageSerializerV1d0();
+        final Map<String, Object> config = new HashMap<String, Object>() {{
+            put(GryoMessageSerializerV1d0.TOKEN_IO_REGISTRIES, Arrays.asList(ColorIoRegistry.class.getName()));
+        }};
+
+        serializer.configure(config, null);
+
+        final ResponseMessage toSerialize = ResponseMessage.build(requestId).result(Color.RED).create();
+        final ByteBuf bb = serializer.serializeResponseAsBinary(toSerialize, allocator);
+        final ResponseMessage deserialized = serializer.deserializeResponse(bb);
+
+        assertCommon(deserialized);
+        assertEquals(Color.RED, deserialized.getResult().getData());
+    }
+
+    @Test
     public void shouldConfigureCustomClassResolver() {
         final MessageSerializer serializer = new GryoMessageSerializerV1d0();
         final Map<String, Object> config = new HashMap<String, Object>() {{
@@ -556,4 +581,22 @@ public class GryoMessageSerializerV1d0Test {
             throw new RuntimeException("Registration is not allowed with this ClassResolver - it is not a good implementation");
         }
     }
+
+    public static class ColorIoRegistry extends AbstractIoRegistry {
+        public ColorIoRegistry() {
+            register(GryoIo.class, Color.class, new ColorSerializer());
+        }
+    }
+
+    public static class ColorSerializer extends Serializer<Color> {
+        @Override
+        public void write(final Kryo kryo, final Output output, final Color color) {
+            output.write(color.equals(Color.RED) ? 1 : 0);
+        }
+
+        @Override
+        public Color read(final Kryo kryo, final Input input, final Class<Color> aClass) {
+            return input.read() == 1 ? Color.RED : Color.BLACK;
+        }
+    }
 }