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/02/24 20:57:27 UTC

incubator-tinkerpop git commit: Added serialization support for TraversalExplanation.

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1147 [created] c2a5da2c7


Added serialization support for TraversalExplanation.

Covers both gryo and graphson. Gryo uses standard Java serialization as the object graph is mighty deep and building a native kryo serializer would have been a lot. GraphSON serializes to a JSON format which pretty much just allows you to get the data required to build what would have come from TraversalExplanation.toString().  It's mostly just for display purposes.


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

Branch: refs/heads/TINKERPOP-1147
Commit: c2a5da2c72c7eb268883825c8cda18decb9b804a
Parents: 00e9b20
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Feb 24 14:55:11 2016 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Feb 24 14:55:11 2016 -0500

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  2 +-
 .../traversal/util/TraversalExplanation.java    |  8 +--
 .../structure/io/graphson/GraphSONModule.java   |  2 +
 .../io/graphson/GraphSONSerializers.java        | 52 ++++++++++++++++++++
 .../structure/io/graphson/GraphSONTokens.java   |  9 ++++
 .../gremlin/structure/io/gryo/GryoMapper.java   |  3 +-
 .../structure/io/gryo/GryoSerializers.java      |  1 -
 .../io/graphson/GraphSONMapperTest.java         |  9 ++++
 .../structure/io/gryo/GryoMapperTest.java       |  8 +++
 9 files changed, 87 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c2a5da2c/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 910d9b6..22cb67e 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -38,7 +38,7 @@ TinkerPop 3.1.2 (NOT OFFICIALLY RELEASED YET)
 * Better handled errors that occurred on commits and serialization in Gremlin Server to first break the result iteration loop and to ensure commit errors were reported to the client.
 * Added GraphSON serializers for the `java.time.*` classes.
 * Improved the logging of the Gremlin Server REST endpoint as it pertained to script execution failures.
-* `TraversalExplanation` is now `Serializable` and registered with `GryoMapper`.
+* `TraversalExplanation` is now `Serializable` and compatible with GraphSON and Gryo serialization.
 * Fixed a problem with global bindings in Gremlin Server which weren't properly designed to handle concurrent modification.
 * Deprecated `ScriptElementFactory` and made the local `StarGraph` globally available for `ScriptInputFormat`'s `parse()` method.
 * Improved reusability of unique test directory creation in `/target` for `AbstractGraphProvider`, which was formerly only available to Neo4j, by adding `makeTestDirectory()`.

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c2a5da2c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanation.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanation.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanation.java
index 786b994..98596b5 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanation.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanation.java
@@ -31,10 +31,10 @@ import java.util.List;
 import java.util.stream.Stream;
 
 /**
- * A TraversalExplanation takes a {@link Traversal} and, for each registered {@link TraversalStrategy}, it creates a mapping reflecting how each strategy alters the traversal.
- * This is useful for understanding how each traversal strategy mutates the traversal.
- * This is useful in debugging and analysis of traversal compilation.
- * The {@link TraversalExplanation#toString()} has a pretty-print representation that is useful in the Gremlin Console.
+ * A TraversalExplanation takes a {@link Traversal} and, for each registered {@link TraversalStrategy}, it creates a
+ * mapping reflecting how each strategy alters the traversal. This is useful for understanding how each traversal
+ * strategy mutates the traversal. This is useful in debugging and analysis of traversal compilation. The
+ * {@link TraversalExplanation#toString()} has a pretty-print representation that is useful in the Gremlin Console.
  *
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c2a5da2c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
index ba9d9ac..821a5dd 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
@@ -19,6 +19,7 @@
 package org.apache.tinkerpop.gremlin.structure.io.graphson;
 
 import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Property;
@@ -74,6 +75,7 @@ abstract class GraphSONModule extends SimpleModule {
             addSerializer(VertexProperty.class, new GraphSONSerializers.VertexPropertyJacksonSerializer(normalize));
             addSerializer(Property.class, new GraphSONSerializers.PropertyJacksonSerializer());
             addSerializer(TraversalMetrics.class, new GraphSONSerializers.TraversalMetricsJacksonSerializer());
+            addSerializer(TraversalExplanation.class, new GraphSONSerializers.TraversalExplanationJacksonSerializer());
             addSerializer(Path.class, new GraphSONSerializers.PathJacksonSerializer());
             addSerializer(StarGraphGraphSONSerializer.DirectionalStarGraph.class, new StarGraphGraphSONSerializer(normalize));
 

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c2a5da2c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializers.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializers.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializers.java
index 5b2a8b7..e21bb0e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializers.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializers.java
@@ -19,7 +19,10 @@
 package org.apache.tinkerpop.gremlin.structure.io.graphson;
 
 import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Element;
@@ -36,6 +39,7 @@ import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
 import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdKeySerializer;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+import org.javatuples.Pair;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -278,6 +282,54 @@ final class GraphSONSerializers {
         }
     }
 
+    final static class TraversalExplanationJacksonSerializer extends StdSerializer<TraversalExplanation> {
+        public TraversalExplanationJacksonSerializer() {
+            super(TraversalExplanation.class);
+        }
+
+        @Override
+        public void serialize(final TraversalExplanation traversalExplanation, final JsonGenerator jsonGenerator,
+                              final SerializerProvider serializerProvider) throws IOException {
+            ser(traversalExplanation, jsonGenerator);
+        }
+
+        @Override
+        public void serializeWithType(final TraversalExplanation value, final JsonGenerator gen,
+                                      final SerializerProvider serializers, final TypeSerializer typeSer) throws IOException {
+            ser(value, gen);
+        }
+
+        public void ser(final TraversalExplanation te, final JsonGenerator jsonGenerator) throws IOException {
+            final Map<String, Object> m = new HashMap<>();
+            m.put(GraphSONTokens.ORIGINAL, getStepsAsList(te.getOriginalTraversal()));
+
+            final List<Pair<TraversalStrategy, Traversal.Admin<?,?>>> strategyTraversals = te.getStrategyTraversals();
+
+            final List<Map<String,Object>> intermediates = new ArrayList<>();
+            for (final Pair<TraversalStrategy, Traversal.Admin<?, ?>> pair : strategyTraversals) {
+                final Map<String,Object> intermediate = new HashMap<>();
+                intermediate.put(GraphSONTokens.STRATEGY, pair.getValue0().toString());
+                intermediate.put(GraphSONTokens.CATEGORY, pair.getValue0().getTraversalCategory().getSimpleName());
+                intermediate.put(GraphSONTokens.TRAVERSAL, getStepsAsList(pair.getValue1()));
+                intermediates.add(intermediate);
+            }
+            m.put(GraphSONTokens.INTERMEDIATE, intermediates);
+
+            if (strategyTraversals.isEmpty())
+                m.put(GraphSONTokens.FINAL, getStepsAsList(te.getOriginalTraversal()));
+            else
+                m.put(GraphSONTokens.FINAL, getStepsAsList(strategyTraversals.get(strategyTraversals.size() - 1).getValue1()));
+
+            jsonGenerator.writeObject(m);
+        }
+
+        private List<String> getStepsAsList(final Traversal.Admin<?,?> t) {
+            final List<String> steps = new ArrayList<>();
+            t.getSteps().iterator().forEachRemaining(s -> steps.add(s.toString()));
+            return steps;
+        }
+    }
+
     final static class TraversalMetricsJacksonSerializer extends StdSerializer<TraversalMetrics> {
         public TraversalMetricsJacksonSerializer() {
             super(TraversalMetrics.class);

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c2a5da2c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java
index 599b6fa..a91c2d4 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java
@@ -44,6 +44,15 @@ public final class GraphSONTokens {
     public static final String OBJECTS = "objects";
     public static final String IN_LABEL = "inVLabel";
     public static final String OUT_LABEL = "outVLabel";
+
+    // TraversalExplanation Tokens
+    public static final String ORIGINAL = "original";
+    public static final String FINAL = "final";
+    public static final String INTERMEDIATE = "intermediate";
+    public static final String CATEGORY = "category";
+    public static final String TRAVERSAL = "traversal";
+    public static final String STRATEGY = "strategy";
+
     // TraversalMetrics Tokens
     public static final String METRICS = "metrics";
     public static final String DURATION = "dur";

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c2a5da2c/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 9a6f636..c20655e 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
@@ -62,6 +62,7 @@ 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;
+import org.apache.tinkerpop.shaded.kryo.serializers.JavaSerializer;
 import org.apache.tinkerpop.shaded.kryo.util.DefaultStreamFactory;
 import org.apache.tinkerpop.shaded.kryo.util.MapReferenceResolver;
 import org.javatuples.Pair;
@@ -296,7 +297,7 @@ public final class GryoMapper implements Mapper<Kryo> {
             add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(AtomicLong.class, null, 79));
             add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(DependantMutableMetrics.class, null, 80));
             add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(Pair.class, kryo -> new PairSerializer(), 88));
-            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(TraversalExplanation.class, null, 106)); // ***LAST ID**
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(TraversalExplanation.class, kryo -> new JavaSerializer(), 106)); // ***LAST ID**
 
             add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(Duration.class, kryo -> new JavaTimeSerializers.DurationSerializer(), 93));
             add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(Instant.class, kryo -> new JavaTimeSerializers.InstantSerializer(), 94));

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c2a5da2c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializers.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializers.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializers.java
index 314caf1..a38de03 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializers.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializers.java
@@ -130,6 +130,5 @@ final class GryoSerializers {
         public Path read(final Kryo kryo, final Input input, final Class<Path> pathClass) {
             return (Path) kryo.readClassAndObject(input);
         }
-
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c2a5da2c/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
index 0a16a4e..41e24c6 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.structure.io.graphson;
 
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation;
 import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
 import org.junit.Test;
 
@@ -35,12 +36,20 @@ import java.time.YearMonth;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.__;
 import static org.junit.Assert.assertEquals;
 
 public class GraphSONMapperTest {
     private final ObjectMapper mapper = GraphSONMapper.build().embedTypes(false).create().createMapper();
 
     @Test
+    public void shouldHandleTraversalExplanation() throws Exception {
+        final TraversalExplanation te = __().out().outV().outE().explain();
+        final String json = mapper.writeValueAsString(te);
+        assertEquals("{\"original\":[\"InjectStep([])\",\"VertexStep(OUT,vertex)\",\"EdgeVertexStep(OUT)\",\"VertexStep(OUT,edge)\"],\"intermediate\":[],\"final\":[\"InjectStep([])\",\"VertexStep(OUT,vertex)\",\"EdgeVertexStep(OUT)\",\"VertexStep(OUT,edge)\"]}", json);
+    }
+
+    @Test
     public void shouldHandleDuration()throws Exception  {
         final Duration o = Duration.ZERO;
         final String json = mapper.writeValueAsString(o);

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c2a5da2c/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 e92eaf9..861c6f6 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,6 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.structure.io.gryo;
 
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.io.IoX;
 import org.apache.tinkerpop.gremlin.structure.io.IoXIoRegistry;
@@ -55,6 +56,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.Supplier;
 
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.__;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotSame;
@@ -295,6 +297,12 @@ public class GryoMapperTest {
         assertEquals(o, serializeDeserialize(o, ZoneOffset.class));
     }
 
+    @Test
+    public void shouldHandleTraversalExplanation()throws Exception  {
+        final TraversalExplanation te = __().out().outV().outE().explain();
+        assertEquals(te.toString(), serializeDeserialize(te, TraversalExplanation.class).toString());
+    }
+
     public <T> T serializeDeserialize(final Object o, final Class<T> clazz) throws Exception {
         try (final ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
             final Output out = new Output(stream);