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:11 UTC

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

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");
+        }
+    }
 }