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 2015/12/24 15:00:26 UTC
[1/6] incubator-tinkerpop git commit: Add option on GryoMapper to
allow overriding the ClassResolver.
Repository: incubator-tinkerpop
Updated Branches:
refs/heads/TINKERPOP-1064 [created] 0defd91a9
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/TINKERPOP-1064
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();
[6/6] 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/TINKERPOP-1064
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
+++++++++++++++++++
[3/6] 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/TINKERPOP-1064
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");
+ }
+ }
}
[2/6] 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/TINKERPOP-1064
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);
+ }
+ }
+ }
}
[4/6] 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/TINKERPOP-1064
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.
[5/6] 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/TINKERPOP-1064
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
~~~~~~~~~~~~~~