You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by dk...@apache.org on 2018/08/09 17:27:21 UTC

[01/41] tinkerpop git commit: TINKERPOP-2005 Reject multiple final responses in AbstractEvalOpProcessor [Forced Update!]

Repository: tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1990 25a4ba250 -> 91af0a2bf (forced update)


TINKERPOP-2005 Reject multiple final responses in AbstractEvalOpProcessor

Add isFinalResponse() getter to ResponseStatusCode

Introduce ResponseHandlerContext to allow tracking the final response
status per request message.

Update AbstractOpProcessor, AbstractEvalOpProcessor and related classes
to write response messages through ResponseHandlerContext methods as
opposed to ChannelHandlerContext methods.


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

Branch: refs/heads/TINKERPOP-1990
Commit: f592e3446c84e9398e242a072cdfec64025e9566
Parents: f9ad72a
Author: Dmitri Bourlatchkov <dm...@datastax.com>
Authored: Fri Jul 27 15:54:06 2018 -0400
Committer: Dmitri Bourlatchkov <dm...@datastax.com>
Committed: Fri Jul 27 15:54:06 2018 -0400

----------------------------------------------------------------------
 .../driver/message/ResponseStatusCode.java      |   7 ++
 .../driver/message/ResponseStatusCodeTest.java  |  35 ++++++
 .../gremlin/server/ResponseHandlerContext.java  |  80 ++++++++++++++
 .../server/op/AbstractEvalOpProcessor.java      |  17 +--
 .../gremlin/server/op/AbstractOpProcessor.java  |  34 +++++-
 .../AbstractGremlinServerIntegrationTest.java   |   9 +-
 .../server/GremlinServerIntegrateTest.java      |  51 +++++++++
 .../server/ResponseHandlerContextTest.java      | 110 +++++++++++++++++++
 .../server/op/AbstractOpProcessorTest.java      |  73 ++++++++++++
 9 files changed, 401 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f592e344/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java
index 3348107..f4e7f65 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java
@@ -123,4 +123,11 @@ public enum ResponseStatusCode {
     public boolean isSuccess() {
         return String.valueOf(this.value).startsWith("2");
     }
+
+    /**
+     * Indicates whether the status code can only be used in the last response for a particular request.
+     */
+    public boolean isFinalResponse() {
+        return this != PARTIAL_CONTENT && this != AUTHENTICATE;
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f592e344/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCodeTest.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCodeTest.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCodeTest.java
new file mode 100644
index 0000000..a231489
--- /dev/null
+++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCodeTest.java
@@ -0,0 +1,35 @@
+/*
+ * 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.message;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class ResponseStatusCodeTest {
+
+    @Test
+    public void shouldIndicateFinalMessagesStatusCodes() {
+        assertFalse(ResponseStatusCode.AUTHENTICATE.isFinalResponse());
+        assertFalse(ResponseStatusCode.PARTIAL_CONTENT.isFinalResponse());
+        assertTrue(ResponseStatusCode.SUCCESS.isFinalResponse());
+        assertTrue(ResponseStatusCode.SERVER_ERROR_TIMEOUT.isFinalResponse());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f592e344/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContext.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContext.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContext.java
new file mode 100644
index 0000000..fff4480
--- /dev/null
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContext.java
@@ -0,0 +1,80 @@
+/*
+ * 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.server;
+
+import org.apache.tinkerpop.gremlin.driver.message.ResponseMessage;
+import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A context for asynchronously writing response messages related to a particular request.
+ * <p>The "write" methods of this class ensure that at most one {@link ResponseStatusCode#isFinalResponse() final}
+ * response message is written to the underlying channel. Attempts to write more than one final response message will
+ * result in an {@link IllegalStateException}.</p>
+ * <p>Note: an object of this class should be used instead of writing to the channel directly when multiple threads
+ * are expected to produce final response messages concurrently. Callers must ensure that the same
+ * {@link ResponseHandlerContext} is used by all threads writing response messages for the same request.</p>
+ *
+ * @author Dmitri Bourlatchkov
+ */
+public class ResponseHandlerContext {
+
+    private final Context context;
+    private final AtomicBoolean finalResponseWritten = new AtomicBoolean();
+
+    public ResponseHandlerContext(Context context) {
+        this.context = context;
+    }
+
+    public Context getContext() {
+        return context;
+    }
+
+    /**
+     * Writes a response message to the underlying channel while ensuring that at most one
+     * {@link ResponseStatusCode#isFinalResponse() final} response is written.
+     * <p>Note: this method should be used instead of writing to the channel directly when multiple threads
+     * are expected to produce response messages concurrently.</p>
+     * <p>Attempts to write more than one final response message will result in an {@link IllegalStateException}.</p>
+     * @see #writeAndFlush(ResponseStatusCode, Object)
+     */
+    public void writeAndFlush(ResponseMessage message) {
+        writeAndFlush(message.getStatus().getCode(), message);
+    }
+
+    /**
+     * Writes a response message to the underlying channel while ensuring that at most one
+     * {@link ResponseStatusCode#isFinalResponse() final} response is written.
+     * <p>The caller must make sure that the provided response status code matches the content of the message.</p>
+     * <p>Note: this method should be used instead of writing to the channel directly when multiple threads
+     * are expected to produce response messages concurrently.</p>
+     * <p>Attempts to write more than one final response message will result in an {@link IllegalStateException}.</p>
+     * @see #writeAndFlush(ResponseMessage)
+     */
+    public void writeAndFlush(ResponseStatusCode code, Object responseMessage) {
+        final boolean messageIsFinal = code.isFinalResponse();
+        if(!finalResponseWritten.compareAndSet(false, messageIsFinal)) {
+            final String errorMessage = String.format("Another final response message was already written for request %s", context.getRequestMessage().getRequestId());
+            throw new IllegalStateException(errorMessage);
+        }
+
+        context.getChannelHandlerContext().writeAndFlush(responseMessage);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f592e344/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
index 5c43b4d..6ff0452 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
@@ -36,6 +36,7 @@ import org.apache.tinkerpop.gremlin.structure.Column;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.server.Context;
 import org.apache.tinkerpop.gremlin.server.GremlinServer;
+import org.apache.tinkerpop.gremlin.server.ResponseHandlerContext;
 import org.apache.tinkerpop.gremlin.server.Settings;
 import org.apache.tinkerpop.gremlin.server.util.MetricManager;
 import org.apache.tinkerpop.gremlin.util.function.ThrowingConsumer;
@@ -245,6 +246,8 @@ public abstract class AbstractEvalOpProcessor extends AbstractOpProcessor {
         final long seto = args.containsKey(Tokens.ARGS_SCRIPT_EVAL_TIMEOUT) ?
                 Long.parseLong(args.get(Tokens.ARGS_SCRIPT_EVAL_TIMEOUT).toString()) : settings.scriptEvaluationTimeout;
 
+        ResponseHandlerContext rhc = new ResponseHandlerContext(context);
+
         final GremlinExecutor.LifeCycle lifeCycle = GremlinExecutor.LifeCycle.build()
                 .scriptEvaluationTimeoutOverride(seto)
                 .afterFailure((b,t) -> {
@@ -265,7 +268,7 @@ public abstract class AbstractEvalOpProcessor extends AbstractOpProcessor {
                     logger.debug("Preparing to iterate results from - {} - in thread [{}]", msg, Thread.currentThread().getName());
 
                     try {
-                        handleIterator(context, itty);
+                        handleIterator(rhc, itty);
                     } catch (Exception ex) {
                         if (managedTransactionsForRequest) attemptRollback(msg, context.getGraphManager(), settings.strictTransactionManagement);
 
@@ -282,25 +285,25 @@ public abstract class AbstractEvalOpProcessor extends AbstractOpProcessor {
 
             if (t != null) {
                 if (t instanceof OpProcessorException) {
-                    ctx.writeAndFlush(((OpProcessorException) t).getResponseMessage());
+                    rhc.writeAndFlush(((OpProcessorException) t).getResponseMessage());
                 } else if (t instanceof TimedInterruptTimeoutException) {
                     // occurs when the TimedInterruptCustomizerProvider is in play
                     final String errorMessage = String.format("A timeout occurred within the script during evaluation of [%s] - consider increasing the limit given to TimedInterruptCustomizerProvider", msg);
                     logger.warn(errorMessage);
-                    ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
+                    rhc.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
                             .statusMessage("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider")
                             .statusAttributeException(t).create());
                 } else if (t instanceof org.apache.tinkerpop.gremlin.groovy.jsr223.TimedInterruptTimeoutException) {
                     // occurs when the TimedInterruptCustomizerProvider is in play
                     final String errorMessage = String.format("A timeout occurred within the script during evaluation of [%s] - consider increasing the limit given to TimedInterruptCustomizerProvider", msg);
                     logger.warn(errorMessage);
-                    ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
+                    rhc.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
                             .statusMessage("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider")
                             .statusAttributeException(t).create());
                 } else if (t instanceof TimeoutException) {
                     final String errorMessage = String.format("Script evaluation exceeded the configured threshold for request [%s]", msg);
                     logger.warn(errorMessage, t);
-                    ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
+                    rhc.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
                             .statusMessage(t.getMessage())
                             .statusAttributeException(t).create());
                 } else {
@@ -314,12 +317,12 @@ public abstract class AbstractEvalOpProcessor extends AbstractOpProcessor {
                             ((MultipleCompilationErrorsException) t).getErrorCollector().getErrorCount() == 1) {
                         final String errorMessage = String.format("The Gremlin statement that was submitted exceed the maximum compilation size allowed by the JVM, please split it into multiple smaller statements - %s", trimMessage(msg));
                         logger.warn(errorMessage);
-                        ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION)
+                        rhc.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION)
                                 .statusMessage(errorMessage)
                                 .statusAttributeException(t).create());
                     } else {
                         logger.warn(String.format("Exception processing a script on request [%s].", msg), t);
-                        ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION)
+                        rhc.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION)
                                 .statusMessage(t.getMessage())
                                 .statusAttributeException(t).create());
                     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f592e344/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
index 8899bb5..1263c81 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
@@ -29,6 +29,7 @@ import org.apache.tinkerpop.gremlin.driver.ser.MessageTextSerializer;
 import org.apache.tinkerpop.gremlin.server.Context;
 import org.apache.tinkerpop.gremlin.server.GraphManager;
 import org.apache.tinkerpop.gremlin.server.OpProcessor;
+import org.apache.tinkerpop.gremlin.server.ResponseHandlerContext;
 import org.apache.tinkerpop.gremlin.server.Settings;
 import org.apache.tinkerpop.gremlin.server.handler.Frame;
 import org.apache.tinkerpop.gremlin.server.handler.StateKey;
@@ -72,8 +73,19 @@ public abstract class AbstractOpProcessor implements OpProcessor {
      * @param context The Gremlin Server {@link Context} object containing settings, request message, etc.
      * @param itty The result to iterator
      * @throws TimeoutException if the time taken to serialize the entire result set exceeds the allowable time.
+     * @see #handleIterator(ResponseHandlerContext, Iterator)
      */
     protected void handleIterator(final Context context, final Iterator itty) throws TimeoutException, InterruptedException {
+        handleIterator(new ResponseHandlerContext(context), itty);
+    }
+
+    /**
+     * A variant of {@link #handleIterator(Context, Iterator)} that is suitable for use in situations when mutiple
+     * threads may produce {@link ResponseStatusCode#isFinalResponse() final} response messages concurrently.
+     * @see #handleIterator(Context, Iterator)
+     */
+    protected void handleIterator(final ResponseHandlerContext rhc, final Iterator itty) throws TimeoutException, InterruptedException {
+        final Context context = rhc.getContext();
         final ChannelHandlerContext ctx = context.getChannelHandlerContext();
         final RequestMessage msg = context.getRequestMessage();
         final Settings settings = context.getSettings();
@@ -90,7 +102,7 @@ public abstract class AbstractOpProcessor implements OpProcessor {
             // as there is nothing left to iterate if we are transaction managed then we should execute a
             // commit here before we send back a NO_CONTENT which implies success
             if (managedTransactionsForRequest) attemptCommit(msg, context.getGraphManager(), settings.strictTransactionManagement);
-            ctx.writeAndFlush(ResponseMessage.build(msg)
+            rhc.writeAndFlush(ResponseMessage.build(msg)
                     .code(ResponseStatusCode.NO_CONTENT)
                     .create());
             return;
@@ -143,7 +155,7 @@ public abstract class AbstractOpProcessor implements OpProcessor {
                     // thread that processed the eval of the script so, we have to push serialization down into that
                     Frame frame = null;
                     try {
-                        frame = makeFrame(ctx, msg, serializer, useBinary, aggregate, code, generateMetaData(ctx, msg, code, itty));
+                        frame = makeFrame(rhc, msg, serializer, useBinary, aggregate, code, generateMetaData(ctx, msg, code, itty));
                     } catch (Exception ex) {
                         // a frame may use a Bytebuf which is a countable release - if it does not get written
                         // downstream it needs to be released here
@@ -191,7 +203,7 @@ public abstract class AbstractOpProcessor implements OpProcessor {
                     // required then it will be 100% complete before the client receives it. the "frame" at this point
                     // should have completely detached objects from the transaction (i.e. serialization has occurred)
                     // so a new one should not be opened on the flush down the netty pipeline
-                    ctx.writeAndFlush(frame);
+                    rhc.writeAndFlush(code, frame);
                 }
             } else {
                 // don't keep triggering this warning over and over again for the same request
@@ -252,15 +264,29 @@ public abstract class AbstractOpProcessor implements OpProcessor {
     /**
      * @deprecated As of release 3.2.2, replaced by {@link #makeFrame(ChannelHandlerContext, RequestMessage, MessageSerializer, boolean, List, ResponseStatusCode, Map)}.
      */
+    @Deprecated
     protected static Frame makeFrame(final ChannelHandlerContext ctx, final RequestMessage msg,
                                      final MessageSerializer serializer, final boolean useBinary, final List<Object> aggregate,
                                      final ResponseStatusCode code) throws Exception {
         return makeFrame(ctx, msg, serializer, useBinary, aggregate, code, Collections.emptyMap());
     }
 
+    /**
+     * Caution: {@link #makeFrame(ResponseHandlerContext, RequestMessage, MessageSerializer, boolean, List, ResponseStatusCode, Map)}
+     * should be used instead of this method whenever a {@link ResponseHandlerContext} is available.
+     */
     protected static Frame makeFrame(final ChannelHandlerContext ctx, final RequestMessage msg,
                                    final MessageSerializer serializer, final boolean useBinary, final List<Object> aggregate,
                                    final ResponseStatusCode code, final Map<String,Object> responseMetaData) throws Exception {
+        Context context = new Context(msg, ctx, null, null, null, null); // dummy context, good only for writing response messages to the channel
+        ResponseHandlerContext rhc = new ResponseHandlerContext(context);
+        return makeFrame(rhc, msg, serializer, useBinary, aggregate, code, responseMetaData);
+    }
+
+    protected static Frame makeFrame(final ResponseHandlerContext rhc, final RequestMessage msg,
+                                   final MessageSerializer serializer, final boolean useBinary, final List<Object> aggregate,
+                                   final ResponseStatusCode code, final Map<String,Object> responseMetaData) throws Exception {
+        final ChannelHandlerContext ctx = rhc.getContext().getChannelHandlerContext();
         try {
             if (useBinary) {
                 return new Frame(serializer.serializeResponseAsBinary(ResponseMessage.build(msg)
@@ -283,7 +309,7 @@ public abstract class AbstractOpProcessor implements OpProcessor {
                     .statusMessage(errorMessage)
                     .statusAttributeException(ex)
                     .code(ResponseStatusCode.SERVER_ERROR_SERIALIZATION).create();
-            ctx.writeAndFlush(error);
+            rhc.writeAndFlush(error);
             throw ex;
         }
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f592e344/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java
index 7c124f0..a8a8853 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java
@@ -39,6 +39,7 @@ import static org.junit.Assume.assumeThat;
  */
 public abstract class AbstractGremlinServerIntegrationTest {
     protected GremlinServer server;
+    protected Settings overriddenSettings;
     private final static String epollOption = "gremlin.server.epoll";
     private static final boolean GREMLIN_SERVER_EPOLL = "true".equalsIgnoreCase(System.getProperty(epollOption));
     private static final Logger logger = LoggerFactory.getLogger(AbstractGremlinServerIntegrationTest.class);
@@ -87,13 +88,13 @@ public abstract class AbstractGremlinServerIntegrationTest {
     public void startServer() throws Exception {
         final InputStream stream = getSettingsInputStream();
         final Settings settings = Settings.read(stream);
-        final Settings overridenSettings = overrideSettings(settings);
-        ServerTestHelper.rewritePathsInGremlinServerSettings(overridenSettings);
+        overriddenSettings = overrideSettings(settings);
+        ServerTestHelper.rewritePathsInGremlinServerSettings(overriddenSettings);
         if (GREMLIN_SERVER_EPOLL) {
-            overridenSettings.useEpollEventLoop = true;
+            overriddenSettings.useEpollEventLoop = true;
         }
 
-        this.server = new GremlinServer(overridenSettings);
+        this.server = new GremlinServer(overriddenSettings);
 
         server.start().join();
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f592e344/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
index 1db7a50..9256458 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
@@ -66,6 +66,7 @@ import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
 import org.apache.tinkerpop.gremlin.util.Log4jRecordingAppender;
 import org.apache.tinkerpop.gremlin.util.function.Lambda;
 import org.hamcrest.CoreMatchers;
+import org.hamcrest.Matchers;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -75,6 +76,7 @@ import java.nio.channels.ClosedChannelException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -376,6 +378,40 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
     }
 
     @Test
+    public void shouldProduceProperExceptionOnTimeout() throws Exception {
+        final Cluster cluster = TestClientFactory.open();
+        final Client client = cluster.connect(name.getMethodName());
+
+        boolean success = false;
+        // Run a short test script a few times with progressively longer timeouts.
+        // Each submissions should either succeed or fail with a timeout.
+        // Note: the range of timeouts is intended to cover the case when the script finishes at about the
+        // same time when the timeout occurs. In this situation either a timeout response or a successful
+        // response is acceptable, however no other processing errors should occur.
+        // Note: the timeout of 30 ms is generally sufficient for running a simple groovy script, so using longer
+        // timeouts are not likely to results in a success/timeout response collision, which is the purpose
+        // of this test.
+        // Note: this test may have a false negative result, but a failure  would indicate a real problem.
+        for(int i = 0; i < 30; i++) {
+            int timeout = 1 + i;
+            overriddenSettings.scriptEvaluationTimeout = timeout;
+
+            try {
+                client.submit("x = 1 + 1").all().get().get(0).getInt();
+                success = true;
+            } catch (Exception ex) {
+                final Throwable t = ex.getCause();
+                assertThat("Unexpected exception with script evaluation timeout: " + timeout, t, instanceOf(ResponseException.class));
+                assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
+            }
+        }
+
+        assertTrue("Some script submissions should succeed", success);
+
+        cluster.close();
+    }
+
+    @Test
     public void shouldUseBaseScript() throws Exception {
         final Cluster cluster = TestClientFactory.open();
         final Client client = cluster.connect(name.getMethodName());
@@ -985,6 +1021,21 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
     }
 
     @Test
+    public void shouldHavePartialContentWithLongResultsCollection() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
+            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+                    .addArg(Tokens.ARGS_GREMLIN, "new String[100]").create();
+            final List<ResponseMessage> responses = client.submit(request);
+            assertThat(responses.size(), Matchers.greaterThan(1));
+            for (Iterator<ResponseMessage> it = responses.iterator(); it.hasNext(); ) {
+                ResponseMessage msg = it.next();
+                ResponseStatusCode expected = it.hasNext() ? ResponseStatusCode.PARTIAL_CONTENT : ResponseStatusCode.SUCCESS;
+                assertEquals(expected, msg.getStatus().getCode());
+            }
+        }
+    }
+
+    @Test
     public void shouldFailWithBadScriptEval() throws Exception {
         try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
             final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f592e344/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
new file mode 100644
index 0000000..bea318b
--- /dev/null
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.server;
+
+import io.netty.channel.ChannelHandlerContext;
+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.hamcrest.CoreMatchers;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.mockito.Mockito;
+
+import java.util.Arrays;
+import java.util.UUID;
+import java.util.function.BiFunction;
+
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+@RunWith(Parameterized.class)
+public class ResponseHandlerContextTest {
+
+    @Parameterized.Parameter(value = 0)
+    public BiFunction<ResponseHandlerContext, ResponseStatusCode, Void> writeInvoker;
+
+    private final ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
+    private final RequestMessage request = RequestMessage.build("test").create();
+    private final Context context = new Context(request, ctx, null, null, null, null);
+    private final ResponseHandlerContext rhc = new ResponseHandlerContext(context);
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Iterable<Object[]> data() {
+        return Arrays.asList(new Object[][] {
+                {
+                    new BiFunction<ResponseHandlerContext, ResponseStatusCode, Void>() {
+                        @Override
+                        public Void apply(ResponseHandlerContext context, ResponseStatusCode code) {
+                            context.writeAndFlush(code, "testMessage");
+                            return null;
+                        }
+
+                        @Override
+                        public String toString() {
+                            return "writeAndFlush(ResponseStatusCode, Object)";
+                        }
+                    }
+                }, {
+                    new BiFunction<ResponseHandlerContext, ResponseStatusCode, Void>() {
+                        @Override
+                        public Void apply(ResponseHandlerContext context, ResponseStatusCode code) {
+                            context.writeAndFlush(ResponseMessage.build(UUID.randomUUID()).code(code).create());
+                            return null;
+                        }
+
+                        @Override
+                        public String toString() {
+                            return "writeAndFlush(ResponseMessage)";
+                        }
+                    }
+                },
+        });
+    }
+
+    @Test
+    public void shouldAllowMultipleNonFinalResponses() {
+        writeInvoker.apply(rhc, ResponseStatusCode.AUTHENTICATE);
+        Mockito.verify(ctx, Mockito.times(1)).writeAndFlush(Mockito.any());
+
+        writeInvoker.apply(rhc, ResponseStatusCode.PARTIAL_CONTENT);
+        Mockito.verify(ctx, Mockito.times(2)).writeAndFlush(Mockito.any());
+
+        writeInvoker.apply(rhc, ResponseStatusCode.PARTIAL_CONTENT);
+        Mockito.verify(ctx, Mockito.times(3)).writeAndFlush(Mockito.any());
+    }
+
+    @Test
+    public void shouldAllowAtMostOneFinalResponse() {
+        writeInvoker.apply(rhc, ResponseStatusCode.AUTHENTICATE);
+        Mockito.verify(ctx, Mockito.times(1)).writeAndFlush(Mockito.any());
+
+        writeInvoker.apply(rhc, ResponseStatusCode.SUCCESS);
+        Mockito.verify(ctx, Mockito.times(2)).writeAndFlush(Mockito.any());
+
+        try {
+            writeInvoker.apply(rhc, ResponseStatusCode.SERVER_ERROR_TIMEOUT);
+            fail("Expected an IllegalStateException");
+        } catch (IllegalStateException ex) {
+            assertThat(ex.toString(), CoreMatchers.containsString(request.getRequestId().toString()));
+        }
+        Mockito.verify(ctx, Mockito.times(2)).writeAndFlush(Mockito.any());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f592e344/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessorTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessorTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessorTest.java
new file mode 100644
index 0000000..cf42737
--- /dev/null
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessorTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.server.op;
+
+import io.netty.channel.ChannelHandlerContext;
+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.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class AbstractOpProcessorTest {
+
+    @Test
+    public void deprecatedMakeFrameMethodShouldRedirectCorrectly() throws Exception {
+        ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
+        RequestMessage request = RequestMessage.build("test").create();
+        ArgumentCaptor<ResponseMessage> responseCaptor = ArgumentCaptor.forClass(ResponseMessage.class);
+
+        try {
+            // Induce a NullPointerException to validate error response message writing
+            //noinspection deprecation
+            AbstractOpProcessor.makeFrame(ctx, request, null, true, null, ResponseStatusCode.PARTIAL_CONTENT);
+            fail("Expected a NullPointerException");
+        } catch (NullPointerException expected) {
+            // nop
+        }
+
+        Mockito.verify(ctx, Mockito.times(1)).writeAndFlush(responseCaptor.capture());
+        assertEquals(ResponseStatusCode.SERVER_ERROR_SERIALIZATION, responseCaptor.getValue().getStatus().getCode());
+        assertEquals(request.getRequestId(), responseCaptor.getValue().getRequestId());
+    }
+
+    @Test
+    public void alternativeMakeFrameMethodShouldRedirectCorrectly() throws Exception {
+        ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
+        RequestMessage request = RequestMessage.build("test").create();
+        ArgumentCaptor<ResponseMessage> responseCaptor = ArgumentCaptor.forClass(ResponseMessage.class);
+
+        try {
+            // Induce a NullPointerException to validate error response message writing
+            AbstractOpProcessor.makeFrame(ctx, request, null, true, null, ResponseStatusCode.PARTIAL_CONTENT, null);
+            fail("Expected a NullPointerException");
+        } catch (NullPointerException expected) {
+            // nop
+        }
+
+        Mockito.verify(ctx, Mockito.times(1)).writeAndFlush(responseCaptor.capture());
+        assertEquals(ResponseStatusCode.SERVER_ERROR_SERIALIZATION, responseCaptor.getValue().getStatus().getCode());
+        assertEquals(request.getRequestId(), responseCaptor.getValue().getRequestId());
+    }
+
+}
\ No newline at end of file


[09/41] tinkerpop git commit: This closes #891

Posted by dk...@apache.org.
This closes #891


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

Branch: refs/heads/TINKERPOP-1990
Commit: 665daa7f28e677ad0da29301d981b2cb82709013
Parents: 8f1fe6d
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Sat Aug 4 06:06:44 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Sat Aug 4 06:06:44 2018 -0400

----------------------------------------------------------------------

----------------------------------------------------------------------



[24/41] tinkerpop git commit: Merge branch 'pr-899' into tp32

Posted by dk...@apache.org.
Merge branch 'pr-899' into tp32


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

Branch: refs/heads/TINKERPOP-1990
Commit: 387cf69323b1ea0a7194033fe951db8f9e43b799
Parents: 2d315e8 fe9c26f
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Aug 7 10:51:23 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Aug 7 10:51:23 2018 -0400

----------------------------------------------------------------------
 .../driver/message/ResponseStatusCode.java      |   7 +
 .../driver/message/ResponseStatusCodeTest.java  |  36 +++++
 .../gremlin/server/ResponseHandlerContext.java  |  85 +++++++++++
 .../server/op/AbstractEvalOpProcessor.java      |  40 ++++--
 .../gremlin/server/op/AbstractOpProcessor.java  |  34 ++++-
 .../AbstractGremlinServerIntegrationTest.java   |  20 ++-
 .../server/GremlinServerIntegrateTest.java      |  51 +++++++
 .../server/ResponseHandlerContextTest.java      | 143 +++++++++++++++++++
 .../server/op/AbstractEvalOpProcessorTest.java  |  62 ++++++++
 .../server/op/AbstractOpProcessorTest.java      |  73 ++++++++++
 10 files changed, 535 insertions(+), 16 deletions(-)
----------------------------------------------------------------------



[25/41] tinkerpop git commit: Updated changelog CTR

Posted by dk...@apache.org.
Updated changelog CTR


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

Branch: refs/heads/TINKERPOP-1990
Commit: 37476a2b46467c2d704cbef977225d8da3cddd64
Parents: 387cf69
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Aug 7 10:52:29 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Aug 7 10:52:29 2018 -0400

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


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37476a2b/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 495abd7..f6413e2 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -23,6 +23,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 [[release-3-2-10]]
 === TinkerPop 3.2.10 (Release Date: NOT OFFICIALLY RELEASED YET)
 
+* Fixed problem with Gremlin Server sometimes returning an additional message after a failure.
 * Added an system error code for failed plugin installs for Gremlin Server `-i` option.
 * Match numbers in `choose()` options using `NumberHelper` (match values, ignore data type).
 * Added support for GraphSON serialization of `Date` in Javascript.


[37/41] tinkerpop git commit: Merge branch 'tp32' into tp33

Posted by dk...@apache.org.
Merge branch 'tp32' into tp33

Conflicts:
	gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
	gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPeerPressureTest.groovy
	gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
	gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java


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

Branch: refs/heads/TINKERPOP-1990
Commit: b12a3fdd01f0505773d865538e987de66c74d044
Parents: fa7a7f6 a533878
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Aug 9 10:12:44 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Aug 9 10:12:44 2018 -0400

----------------------------------------------------------------------
 .../gremlin/process/remote/RemoteGraph.java     |  17 ---
 .../io/graphson/TraversalSerializersV2d0.java   |   4 -
 .../ModernGraphTypeInformation.cs               |   4 +
 .../DriverRemoteTraversalSideEffects.java       |   3 +-
 .../test/cucumber/feature-steps.js              |  14 +-
 .../glv/GraphTraversalSource.template           |   2 +-
 .../gremlin_python/process/graph_traversal.py   |   2 +-
 .../RemoteGraphGroovyTranslatorProvider.java    |   3 +-
 gremlin-test/features/map/PageRank.feature      | 132 +++++++++++++++++++
 gremlin-test/features/map/PeerPressure.feature  |  60 +++++++++
 .../process/AbstractGremlinProcessTest.java     |  26 ++--
 .../traversal/step/map/PageRankTest.java        |  37 +++---
 .../traversal/step/map/PeerPressureTest.java    |  25 ++--
 .../TranslationStrategyProcessTest.java         |   3 +
 .../gremlin/process/FeatureCoverageTest.java    |   6 +-
 15 files changed, 266 insertions(+), 72 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b12a3fdd/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b12a3fdd/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b12a3fdd/gremlin-python/glv/GraphTraversalSource.template
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b12a3fdd/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b12a3fdd/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/RemoteGraphGroovyTranslatorProvider.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/RemoteGraphGroovyTranslatorProvider.java
index 6949426,e170cb1..38935a0
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/RemoteGraphGroovyTranslatorProvider.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/RemoteGraphGroovyTranslatorProvider.java
@@@ -35,28 -29,9 +35,29 @@@ import java.util.Set
   */
  public class RemoteGraphGroovyTranslatorProvider extends RemoteGraphProvider {
  
 +    private static boolean SKIP = false;
 +
 +    private static Set<String> SKIP_TESTS = new HashSet<>(Arrays.asList(
-             "g_injectXg_VX1X_propertiesXnameX_nextX_value"));
++            "g_injectXg_VX1X_propertiesXnameX_nextX_value",
++            "shouldNotHaveAnonymousTraversalMixups"));
 +
 +
 +    @Override
 +    public Map<String, Object> getBaseConfiguration(final String graphName, final Class<?> test, final String testMethodName,
 +                                                    final LoadGraphWith.GraphData loadGraphWith) {
 +
 +        final Map<String, Object> config = super.getBaseConfiguration(graphName, test, testMethodName, loadGraphWith);
 +        SKIP = SKIP_TESTS.contains(testMethodName) || SKIP_TESTS.contains(test.getCanonicalName());
 +        return config;
 +    }
 +
      @Override
      public GraphTraversalSource traversal(final Graph graph) {
 -        final GraphTraversalSource g = graph.traversal();
 -        return g.withStrategies(new TranslationStrategy(g, GroovyTranslator.of("g")));
 +        if (SKIP)
 +            return super.traversal(graph);
 +        else {
 +            final GraphTraversalSource g = super.traversal(graph);
 +            return g.withStrategies(new TranslationStrategy(g, GroovyTranslator.of("g")));
 +        }
      }
  }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b12a3fdd/gremlin-test/features/map/PageRank.feature
----------------------------------------------------------------------
diff --cc gremlin-test/features/map/PageRank.feature
index 0000000,bf2ed26..8ead2d4
mode 000000,100644..100644
--- a/gremlin-test/features/map/PageRank.feature
+++ b/gremlin-test/features/map/PageRank.feature
@@@ -1,0 -1,142 +1,132 @@@
+ # 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.
+ 
+ Feature: Step - pageRank()
+                 
+   Scenario: g_V_pageRank_hasXpageRankX
+     Given the modern graph
+     And the traversal of
+       """
+       g.withComputer().V().pageRank().has("gremlin.pageRankVertexProgram.pageRank")
+       """
+     When iterated to list
+     Then the result should be unordered
+       | result |
+       | v[marko] |
+       | v[vadas] |
+       | v[lop] |
+       | v[josh] |
+       | v[ripple] |
+       | v[peter] |
+     And the graph should return 6 for count of "g.withComputer().V().pageRank().has(\"gremlin.pageRankVertexProgram.pageRank\")"
+ 
+   Scenario: g_V_outXcreatedX_pageRank_byXbothEX_byXprojectRankX_timesX0X_valueMapXname_projectRankX
+     Given the modern graph
+     And the traversal of
+       """
+       g.withComputer().V().out("created").pageRank().by(__.bothE()).by("projectRank").times(0).valueMap("name", "projectRank")
+       """
+     When iterated to list
+     Then the result should be unordered
+       | result |
+       | m[{"name": ["lop"], "projectRank": [3.0]}] |
+       | m[{"name": ["lop"], "projectRank": [3.0]}] |
+       | m[{"name": ["lop"], "projectRank": [3.0]}] |
+       | m[{"name": ["ripple"], "projectRank": [1.0]}] |
+ 
+   Scenario: g_V_pageRank_order_byXpageRank_decrX_byXnameX_name
+     Given the modern graph
+     And the traversal of
+       """
+       g.withComputer().V().pageRank().order().by("gremlin.pageRankVertexProgram.pageRank", Order.decr).by("name").values("name")
+       """
+     When iterated to list
+     Then the result should be ordered
+       | result |
+       | lop    |
+       | ripple |
+       | josh   |
+       | vadas  |
+       | marko  |
+       | peter  |
+ 
+   Scenario: g_V_pageRank_order_byXpageRank_decrX_name_limitX2X
+     Given the modern graph
+     And the traversal of
+       """
+       g.withComputer().V().pageRank().order().by("gremlin.pageRankVertexProgram.pageRank", Order.decr).values("name").limit(2)
+       """
+     When iterated to list
+     Then the result should be ordered
+       | result |
+       | lop    |
+       | ripple |
+ 
+   Scenario: g_V_pageRank_byXoutEXknowsXX_byXfriendRankX_valueMapXname_friendRankX
+     Given the modern graph
+     And the traversal of
+       """
+       g.withComputer().V().pageRank().by(__.outE("knows")).by("friendRank").valueMap("name", "friendRank")
+       """
+     When iterated to list
+     Then the result should be unordered
+       | result |
 -      | m[{"name": ["marko"], "friendRank": [0.15000000000000002]}] |
 -      | m[{"name": ["vadas"], "friendRank": [0.21375000000000002]}] |
 -      | m[{"name": ["lop"], "friendRank": [0.15000000000000002]}] |
 -      | m[{"name": ["josh"], "friendRank": [0.21375000000000002]}] |
 -      | m[{"name": ["ripple"], "friendRank": [0.15000000000000002]}] |
 -      | m[{"name": ["peter"], "friendRank": [0.15000000000000002]}] |
++      | m[{"name": ["marko"], "friendRank": [0.14598537777608422]}] |
++      | m[{"name": ["vadas"], "friendRank": [0.20802924444783155]}] |
++      | m[{"name": ["lop"], "friendRank": [0.14598537777608422]}] |
++      | m[{"name": ["josh"], "friendRank": [0.20802924444783155]}] |
++      | m[{"name": ["ripple"], "friendRank": [0.14598537777608422]}] |
++      | m[{"name": ["peter"], "friendRank": [0.14598537777608422]}] |
+ 
+   Scenario: g_V_hasLabelXpersonX_pageRank_byXpageRankX_order_byXpageRankX_valueMapXname_pageRankX
 -    Given the modern graph
 -    And the traversal of
++    Given an unsupported test
++    Then nothing should happen because
+       """
 -      g.withComputer().V().hasLabel("person").pageRank().by("pageRank").order().by("pageRank").valueMap("name", "pageRank")
++      The result is not completely deterministic with respect to the decimals that pageRank() produces and the
++      GLV framework does not have a notion for asserting anything beyond an equals() sort of state.
+       """
 -    When iterated to list
 -    Then the result should be unordered
 -      | result |
 -      | m[{"name": ["marko"], "pageRank": [0.15000000000000002]}] |
 -      | m[{"name": ["vadas"], "pageRank": [0.19250000000000003]}] |
 -      | m[{"name": ["josh"], "pageRank": [0.19250000000000003]}] |
 -      | m[{"name": ["peter"], "pageRank": [0.15000000000000002]}] |
+ 
+   Scenario: g_V_pageRank_byXpageRankX_asXaX_outXknowsX_pageRank_asXbX_selectXa_bX
 -    Given the modern graph
 -    And the traversal of
++    Given an unsupported test
++    Then nothing should happen because
+       """
 -      g.withComputer().V().pageRank().by("pageRank").as("a").out("knows").values("pageRank").as("b").select("a", "b")
++      The result is not completely deterministic with respect to the decimals that pageRank() produces and the
++      GLV framework does not have a notion for asserting anything beyond an equals() sort of state.
+       """
 -    When iterated to list
 -    Then the result should be unordered
 -      | result |
 -      | m[{"a": "v[marko]", "b": 0.19250000000000003}] |
 -      | m[{"a": "v[marko]", "b": 0.19250000000000003}] |
+ 
+   Scenario: g_V_hasLabelXsoftwareX_hasXname_rippleX_pageRankX1X_byXinEXcreatedXX_timesX1X_byXpriorsX_inXcreatedX_unionXboth__identityX_valueMapXname_priorsX
+     Given the modern graph
+     And the traversal of
+       """
+       g.withComputer().V().hasLabel("software").has("name", "ripple").pageRank(1.0).by(__.inE("created")).times(1).by("priors").in("created").union(__.both(), __.identity()).valueMap("name", "priors")
+       """
+     When iterated to list
+     Then the result should be unordered
+       | result |
+       | m[{"name": ["josh"], "priors": [1.0]}] |
+       | m[{"name": ["marko"], "priors": [0.0]}] |
+       | m[{"name": ["lop"], "priors": [0.0]}] |
+       | m[{"name": ["ripple"], "priors": [0.0]}] |
+ 
+   Scenario: g_V_outXcreatedX_groupXmX_byXlabelX_pageRankX1X_byXpageRankX_byXinEX_timesX1X_inXcreatedX_groupXmX_byXpageRankX_capXmX()
+     Given an unsupported test
+     Then nothing should happen because
+       """
+       The result returned is not supported under GraphSON 2.x and therefore cannot be properly asserted. More
+       specifically it has long keys which basically get toString()'d under GraphSON 2.x. This test can be supported
+       with GraphSON 3.x.
+       """

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b12a3fdd/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
----------------------------------------------------------------------
diff --cc gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
index 2861724,c3f4dc2..4749e93
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
@@@ -128,9 -136,7 +136,9 @@@ public abstract class AbstractGremlinPr
  
          for (T t : results) {
              if (t instanceof Map) {
-                 assertThat("Checking map result existence: " + t, expectedResults.stream().filter(e -> e instanceof Map).filter(e -> internalCheckMap((Map) e, (Map) t)).findAny().isPresent(), is(true));
+                 assertThat("Checking map result existence: " + t, expectedResults.stream().filter(e -> e instanceof Map).anyMatch(e -> internalCheckMap((Map) e, (Map) t)), is(true));
 +            } else if (t instanceof List) {
-                 assertThat("Checking list result existence: " + t, expectedResults.stream().filter(e -> e instanceof List).filter(e -> internalCheckList((List) e, (List) t)).findAny().isPresent(), is(true));
++                assertThat("Checking list result existence: " + t, expectedResults.stream().filter(e -> e instanceof List).anyMatch(e -> internalCheckList((List) e, (List) t)), is(true));
              } else {
                  assertThat("Checking result existence: " + t, expectedResults.contains(t), is(true));
              }
@@@ -164,21 -170,9 +172,21 @@@
          }
      }
  
 +    private static <A> boolean internalCheckList(final List<A> expectedList, final List<A> actualList) {
 +        if (expectedList.size() != actualList.size()) {
 +            return false;
 +        }
 +        for (int i = 0; i < actualList.size(); i++) {
 +            if (!actualList.get(i).equals(expectedList.get(i))) {
 +                return false;
 +            }
 +        }
 +        return true;
 +    }
 +
      private static <A, B> boolean internalCheckMap(final Map<A, B> expectedMap, final Map<A, B> actualMap) {
-         final List<Map.Entry<A, B>> actualList = actualMap.entrySet().stream().sorted((a, b) -> a.getKey().toString().compareTo(b.getKey().toString())).collect(Collectors.toList());
-         final List<Map.Entry<A, B>> expectedList = expectedMap.entrySet().stream().sorted((a, b) -> a.getKey().toString().compareTo(b.getKey().toString())).collect(Collectors.toList());
+         final List<Map.Entry<A, B>> actualList = actualMap.entrySet().stream().sorted(Comparator.comparing(a -> a.getKey().toString())).collect(Collectors.toList());
+         final List<Map.Entry<A, B>> expectedList = expectedMap.entrySet().stream().sorted(Comparator.comparing(a -> a.getKey().toString())).collect(Collectors.toList());
  
          if (expectedList.size() != actualList.size()) {
              return false;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b12a3fdd/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
----------------------------------------------------------------------
diff --cc gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
index 07a2b04,0c0a91d..620d0e3
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
@@@ -51,9 -52,9 +52,9 @@@ public abstract class PageRankTest exte
  
      public abstract Traversal<Vertex, Map<String, List<Object>>> get_g_V_outXcreatedX_pageRank_byXbothEX_byXprojectRankX_timesX0X_valueMapXname_projectRankX();
  
-     public abstract Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_descX_name();
 -    public abstract Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_decrX_byXnameX_name();
++    public abstract Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_descX_byXnameX_name();
  
 -    public abstract Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_decrX_name_limitX2X();
 +    public abstract Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_descX_name_limitX2X();
  
      public abstract Traversal<Vertex, Map<String, List<Object>>> get_g_V_pageRank_byXoutEXknowsXX_byXfriendRankX_valueMapXname_friendRankX();
  
@@@ -99,8 -94,8 +94,8 @@@
  
      @Test
      @LoadGraphWith(MODERN)
-     public void g_V_pageRank_order_byXpageRank_descX_name() {
-         final Traversal<Vertex, String> traversal = get_g_V_pageRank_order_byXpageRank_descX_name();
 -    public void g_V_pageRank_order_byXpageRank_decrX_byXnameX_name() {
 -        final Traversal<Vertex, String> traversal = get_g_V_pageRank_order_byXpageRank_decrX_byXnameX_name();
++    public void g_V_pageRank_order_byXpageRank_descX_byXnameX_name() {
++        final Traversal<Vertex, String> traversal = get_g_V_pageRank_order_byXpageRank_descX_byXnameX_name();
          printTraversalForm(traversal);
          final List<String> names = traversal.toList();
          assertEquals(6, names.size());
@@@ -256,8 -251,8 +251,8 @@@
          }
  
          @Override
-         public Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_descX_name() {
-             return g.V().pageRank().order().by(PageRankVertexProgram.PAGE_RANK, Order.desc).values("name");
 -        public Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_decrX_byXnameX_name() {
 -            return g.V().pageRank().order().by(PageRankVertexProgram.PAGE_RANK, Order.decr).by("name").values("name");
++        public Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_descX_byXnameX_name() {
++            return g.V().pageRank().order().by(PageRankVertexProgram.PAGE_RANK, Order.desc).by("name").values("name");
          }
  
          @Override

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b12a3fdd/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
----------------------------------------------------------------------


[06/41] tinkerpop git commit: TINKERPOP-2005 Set/restore log level in ResponseHandlerContextTest

Posted by dk...@apache.org.
TINKERPOP-2005 Set/restore log level in ResponseHandlerContextTest

This is to allow these tests to capture intended log messages in the
CI environment.


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

Branch: refs/heads/TINKERPOP-1990
Commit: fe9c26f656cf79f513af5b1230f498934a796063
Parents: 0e0d26c
Author: Dmitri Bourlatchkov <dm...@datastax.com>
Authored: Tue Jul 31 12:11:34 2018 -0400
Committer: Dmitri Bourlatchkov <dm...@datastax.com>
Committed: Tue Jul 31 12:11:34 2018 -0400

----------------------------------------------------------------------
 .../tinkerpop/gremlin/server/ResponseHandlerContextTest.java   | 6 ++++++
 1 file changed, 6 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fe9c26f6/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
index 13c9992..2babee9 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
@@ -19,6 +19,7 @@
 package org.apache.tinkerpop.gremlin.server;
 
 import io.netty.channel.ChannelHandlerContext;
+import org.apache.log4j.Level;
 import org.apache.log4j.Logger;
 import org.apache.tinkerpop.gremlin.driver.message.RequestMessage;
 import org.apache.tinkerpop.gremlin.driver.message.ResponseMessage;
@@ -49,6 +50,8 @@ public class ResponseHandlerContextTest {
     private final ResponseHandlerContext rhc = new ResponseHandlerContext(context);
     private final Log4jRecordingAppender recordingAppender = new Log4jRecordingAppender();
 
+    private Level originalLogLevel;
+
     @Parameterized.Parameters(name = "{0}")
     public static Iterable<Object[]> data() {
         return Arrays.asList(new Object[][] {
@@ -86,11 +89,14 @@ public class ResponseHandlerContextTest {
     public void addRecordingAppender() {
         final Logger rootLogger = Logger.getRootLogger();
         rootLogger.addAppender(recordingAppender);
+        originalLogLevel = rootLogger.getLevel();
+        rootLogger.setLevel(Level.ALL);
     }
 
     @After
     public void removeRecordingAppender() {
         final Logger rootLogger = Logger.getRootLogger();
+        rootLogger.setLevel(originalLogLevel);
         rootLogger.removeAppender(recordingAppender);
     }
 


[05/41] tinkerpop git commit: TINKERPOP-2005 Minor code cleanup

Posted by dk...@apache.org.
TINKERPOP-2005 Minor code cleanup

* Declare variables 'final'
* Remove unused variables


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

Branch: refs/heads/TINKERPOP-1990
Commit: 0e0d26cdafca3c2a3244fe224f3f08391669d470
Parents: 63ae13c
Author: Dmitri Bourlatchkov <dm...@datastax.com>
Authored: Tue Jul 31 10:48:12 2018 -0400
Committer: Dmitri Bourlatchkov <dm...@datastax.com>
Committed: Tue Jul 31 10:48:12 2018 -0400

----------------------------------------------------------------------
 .../gremlin/server/ResponseHandlerContext.java        |  6 +++---
 .../gremlin/server/op/AbstractEvalOpProcessor.java    |  3 +--
 .../gremlin/server/op/AbstractOpProcessor.java        |  4 ++--
 .../gremlin/server/GremlinServerIntegrateTest.java    |  4 ++--
 .../gremlin/server/ResponseHandlerContextTest.java    |  4 ++--
 .../server/op/AbstractEvalOpProcessorTest.java        | 14 +++++++-------
 .../gremlin/server/op/AbstractOpProcessorTest.java    | 12 ++++++------
 7 files changed, 23 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0e0d26cd/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContext.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContext.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContext.java
index 3c8c13c..5cc79b5 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContext.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContext.java
@@ -42,7 +42,7 @@ public class ResponseHandlerContext {
     private final Context context;
     private final AtomicBoolean finalResponseWritten = new AtomicBoolean();
 
-    public ResponseHandlerContext(Context context) {
+    public ResponseHandlerContext(final Context context) {
         this.context = context;
     }
 
@@ -58,7 +58,7 @@ public class ResponseHandlerContext {
      * <p>Attempts to write more than one final response message will be ignored.</p>
      * @see #writeAndFlush(ResponseStatusCode, Object)
      */
-    public void writeAndFlush(ResponseMessage message) {
+    public void writeAndFlush(final ResponseMessage message) {
         writeAndFlush(message.getStatus().getCode(), message);
     }
 
@@ -71,7 +71,7 @@ public class ResponseHandlerContext {
      * <p>Attempts to write more than one final response message will be ignored.</p>
      * @see #writeAndFlush(ResponseMessage)
      */
-    public void writeAndFlush(ResponseStatusCode code, Object responseMessage) {
+    public void writeAndFlush(final ResponseStatusCode code, final Object responseMessage) {
         final boolean messageIsFinal = code.isFinalResponse();
         if(finalResponseWritten.compareAndSet(false, messageIsFinal)) {
             context.getChannelHandlerContext().writeAndFlush(responseMessage);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0e0d26cd/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
index 39168c2..ca1ee53 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
@@ -227,7 +227,7 @@ public abstract class AbstractEvalOpProcessor extends AbstractOpProcessor {
      */
     protected void evalOpInternal(final Context context, final Supplier<GremlinExecutor> gremlinExecutorSupplier,
                                   final BindingSupplier bindingsSupplier) throws OpProcessorException {
-        ResponseHandlerContext rhc = new ResponseHandlerContext(context);
+        final ResponseHandlerContext rhc = new ResponseHandlerContext(context);
         try {
             evalOpInternal(rhc, gremlinExecutorSupplier, bindingsSupplier);
         } catch (Exception ex) {
@@ -251,7 +251,6 @@ public abstract class AbstractEvalOpProcessor extends AbstractOpProcessor {
                                   final BindingSupplier bindingsSupplier) throws OpProcessorException {
         final Context context = rhc.getContext();
         final Timer.Context timerContext = evalOpTimer.time();
-        final ChannelHandlerContext ctx = context.getChannelHandlerContext();
         final RequestMessage msg = context.getRequestMessage();
         final GremlinExecutor gremlinExecutor = gremlinExecutorSupplier.get();
         final Settings settings = context.getSettings();

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0e0d26cd/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
index c2b6f1f..38ca3e1 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
@@ -278,8 +278,8 @@ public abstract class AbstractOpProcessor implements OpProcessor {
     protected static Frame makeFrame(final ChannelHandlerContext ctx, final RequestMessage msg,
                                    final MessageSerializer serializer, final boolean useBinary, final List<Object> aggregate,
                                    final ResponseStatusCode code, final Map<String,Object> responseMetaData) throws Exception {
-        Context context = new Context(msg, ctx, null, null, null, null); // dummy context, good only for writing response messages to the channel
-        ResponseHandlerContext rhc = new ResponseHandlerContext(context);
+        final Context context = new Context(msg, ctx, null, null, null, null); // dummy context, good only for writing response messages to the channel
+        final ResponseHandlerContext rhc = new ResponseHandlerContext(context);
         return makeFrame(rhc, msg, serializer, useBinary, aggregate, code, responseMetaData);
     }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0e0d26cd/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
index 0867fd3..eb5def9 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
@@ -1028,8 +1028,8 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
             final List<ResponseMessage> responses = client.submit(request);
             assertThat(responses.size(), Matchers.greaterThan(1));
             for (Iterator<ResponseMessage> it = responses.iterator(); it.hasNext(); ) {
-                ResponseMessage msg = it.next();
-                ResponseStatusCode expected = it.hasNext() ? ResponseStatusCode.PARTIAL_CONTENT : ResponseStatusCode.SUCCESS;
+                final ResponseMessage msg = it.next();
+                final ResponseStatusCode expected = it.hasNext() ? ResponseStatusCode.PARTIAL_CONTENT : ResponseStatusCode.SUCCESS;
                 assertEquals(expected, msg.getStatus().getCode());
             }
         }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0e0d26cd/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
index 6f15a33..13c9992 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
@@ -55,7 +55,7 @@ public class ResponseHandlerContextTest {
                 {
                     new BiFunction<ResponseHandlerContext, ResponseStatusCode, Void>() {
                         @Override
-                        public Void apply(ResponseHandlerContext context, ResponseStatusCode code) {
+                        public Void apply(final ResponseHandlerContext context, final ResponseStatusCode code) {
                             context.writeAndFlush(code, "testMessage");
                             return null;
                         }
@@ -68,7 +68,7 @@ public class ResponseHandlerContextTest {
                 }, {
                     new BiFunction<ResponseHandlerContext, ResponseStatusCode, Void>() {
                         @Override
-                        public Void apply(ResponseHandlerContext context, ResponseStatusCode code) {
+                        public Void apply(final ResponseHandlerContext context, final ResponseStatusCode code) {
                             context.writeAndFlush(ResponseMessage.build(UUID.randomUUID()).code(code).create());
                             return null;
                         }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0e0d26cd/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessorTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessorTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessorTest.java
index 6f25e2e..72b9c5c 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessorTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessorTest.java
@@ -41,17 +41,17 @@ public class AbstractEvalOpProcessorTest {
 
     @Test
     public void evalOpInternalShouldHandleAllEvaluationExceptions() throws OpProcessorException {
-        AbstractEvalOpProcessor processor = new StandardOpProcessor();
-        RequestMessage request = RequestMessage.build("test").create();
-        Settings settings = new Settings();
-        ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
-        ArgumentCaptor<ResponseMessage> responseCaptor = ArgumentCaptor.forClass(ResponseMessage.class);
+        final AbstractEvalOpProcessor processor = new StandardOpProcessor();
+        final RequestMessage request = RequestMessage.build("test").create();
+        final Settings settings = new Settings();
+        final ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
+        final ArgumentCaptor<ResponseMessage> responseCaptor = ArgumentCaptor.forClass(ResponseMessage.class);
 
-        GremlinExecutor gremlinExecutor = Mockito.mock(GremlinExecutor.class);
+        final GremlinExecutor gremlinExecutor = Mockito.mock(GremlinExecutor.class);
         Mockito.when(gremlinExecutor.eval(anyString(), anyString(), Mockito.any(), Mockito.<GremlinExecutor.LifeCycle>any()))
                 .thenThrow(new IllegalStateException("test-exception"));
 
-        Context context = new Context(request, ctx, settings, null, gremlinExecutor, null);
+        final Context context = new Context(request, ctx, settings, null, gremlinExecutor, null);
         processor.evalOpInternal(context, context::getGremlinExecutor, SimpleBindings::new);
 
         Mockito.verify(ctx, Mockito.times(1)).writeAndFlush(responseCaptor.capture());

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0e0d26cd/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessorTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessorTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessorTest.java
index cf42737..a7cee1a 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessorTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessorTest.java
@@ -33,9 +33,9 @@ public class AbstractOpProcessorTest {
 
     @Test
     public void deprecatedMakeFrameMethodShouldRedirectCorrectly() throws Exception {
-        ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
-        RequestMessage request = RequestMessage.build("test").create();
-        ArgumentCaptor<ResponseMessage> responseCaptor = ArgumentCaptor.forClass(ResponseMessage.class);
+        final ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
+        final RequestMessage request = RequestMessage.build("test").create();
+        final ArgumentCaptor<ResponseMessage> responseCaptor = ArgumentCaptor.forClass(ResponseMessage.class);
 
         try {
             // Induce a NullPointerException to validate error response message writing
@@ -53,9 +53,9 @@ public class AbstractOpProcessorTest {
 
     @Test
     public void alternativeMakeFrameMethodShouldRedirectCorrectly() throws Exception {
-        ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
-        RequestMessage request = RequestMessage.build("test").create();
-        ArgumentCaptor<ResponseMessage> responseCaptor = ArgumentCaptor.forClass(ResponseMessage.class);
+        final ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
+        final RequestMessage request = RequestMessage.build("test").create();
+        final ArgumentCaptor<ResponseMessage> responseCaptor = ArgumentCaptor.forClass(ResponseMessage.class);
 
         try {
             // Induce a NullPointerException to validate error response message writing


[07/41] tinkerpop git commit: TINKERPOP-2016 Bumped to Jackson 2.9.6

Posted by dk...@apache.org.
TINKERPOP-2016 Bumped to Jackson 2.9.6


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

Branch: refs/heads/TINKERPOP-1990
Commit: 1829318f6bfce1bc360818c6a0c34492fa69ec9a
Parents: 7fce137
Author: Robert Dale <ro...@gmail.com>
Authored: Wed Aug 1 20:02:14 2018 -0400
Committer: Robert Dale <ro...@gmail.com>
Committed: Wed Aug 1 20:02:14 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc     | 1 +
 gremlin-shaded/pom.xml | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1829318f/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index b6e85ce..8137b45 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -44,6 +44,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 * Added concrete configuration methods to `SparkGraphComputer` to make a more clear API for configuring it.
 * Fixed a bug in `TinkerGraphCountStrategy`, which didn't consider that certain map steps may not emit an element.
 * Fixed a bug in JavaScript GLV where DriverRemoteConnection close() method didn't returned a Promise instance.
+* Bumped to Jackson 2.9.6.
 
 [[release-3-2-9]]
 === TinkerPop 3.2.9 (Release Date: May 8, 2018)

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1829318f/gremlin-shaded/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-shaded/pom.xml b/gremlin-shaded/pom.xml
index 192262d..3f41b30 100644
--- a/gremlin-shaded/pom.xml
+++ b/gremlin-shaded/pom.xml
@@ -49,8 +49,8 @@ limitations under the License.
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
-            <!-- Update the shade plugin config whenever you change this version -->
-            <version>2.9.4</version>
+            <!-- Update the shade plugin config whenever you change this version; update what exactly? -->
+            <version>2.9.6</version>
             <optional>true</optional>
         </dependency>
     </dependencies>


[21/41] tinkerpop git commit: Merge branch 'tp32' into tp33

Posted by dk...@apache.org.
Merge branch 'tp32' into tp33


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

Branch: refs/heads/TINKERPOP-1990
Commit: 2cf551f089221f29e38627cf684fd89d6b3a3cea
Parents: 3e308f5 2d315e8
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Aug 7 06:30:22 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Aug 7 06:30:22 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                                                | 1 +
 .../tinkerpop/gremlin/server/util/GremlinServerInstall.java       | 3 +++
 2 files changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2cf551f0/CHANGELOG.asciidoc
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2cf551f0/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/GremlinServerInstall.java
----------------------------------------------------------------------


[35/41] tinkerpop git commit: TINKERPOP-1976 Can't assert order() for pageRank()

Posted by dk...@apache.org.
TINKERPOP-1976 Can't assert order() for pageRank()


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

Branch: refs/heads/TINKERPOP-1990
Commit: 13440d6b6720b5d4f091f51674e7b341cc40e8a0
Parents: 0a5d8ce
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Aug 8 06:38:21 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Aug 9 07:28:09 2018 -0400

----------------------------------------------------------------------
 gremlin-test/features/map/PageRank.feature | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/13440d6b/gremlin-test/features/map/PageRank.feature
----------------------------------------------------------------------
diff --git a/gremlin-test/features/map/PageRank.feature b/gremlin-test/features/map/PageRank.feature
index 76af1ed..049b8c2 100644
--- a/gremlin-test/features/map/PageRank.feature
+++ b/gremlin-test/features/map/PageRank.feature
@@ -48,6 +48,8 @@ Feature: Step - pageRank()
       | m[{"name": ["lop"], "projectRank": [3.0]}] |
       | m[{"name": ["ripple"], "projectRank": [1.0]}] |
 
+  # can't fully assert order here because some ranks are equivalent. the java test does an "or" type assert to deal
+  # with this, which we can't express here in these tests. should probably change the test or
   Scenario: g_V_pageRank_order_byXpageRank_decrX_name
     Given the modern graph
     And the traversal of
@@ -55,7 +57,7 @@ Feature: Step - pageRank()
       g.withComputer().V().pageRank().order().by("gremlin.pageRankVertexProgram.pageRank", Order.decr).values("name")
       """
     When iterated to list
-    Then the result should be ordered
+    Then the result should be unordered
       | result |
       | lop    |
       | ripple |


[23/41] tinkerpop git commit: This closes #906

Posted by dk...@apache.org.
This closes #906


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

Branch: refs/heads/TINKERPOP-1990
Commit: 1e8baec975fa23be4c4e59566ab69dd803352215
Parents: 9b41f5a
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Aug 7 10:25:28 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Aug 7 10:25:28 2018 -0400

----------------------------------------------------------------------

----------------------------------------------------------------------



[12/41] tinkerpop git commit: Merge branch 'tp32' into tp33

Posted by dk...@apache.org.
Merge branch 'tp32' into tp33


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

Branch: refs/heads/TINKERPOP-1990
Commit: b779a2a3e26c2b5c9c961b083b0bc1a89ead6440
Parents: 8af7837 ce94738
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Sat Aug 4 06:28:10 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Sat Aug 4 06:28:10 2018 -0400

----------------------------------------------------------------------
 .../apache/tinkerpop/gremlin/driver/Client.java  | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)
----------------------------------------------------------------------



[33/41] tinkerpop git commit: TINKERPOP-1976 Added pageRank() test for GLVs

Posted by dk...@apache.org.
TINKERPOP-1976 Added pageRank() test for GLVs


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

Branch: refs/heads/TINKERPOP-1990
Commit: 85fbd7cd471a5f4276ba19fddb28f3f4d376e643
Parents: 682bdde
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Aug 7 08:53:32 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Aug 9 07:28:09 2018 -0400

----------------------------------------------------------------------
 .../ModernGraphTypeInformation.cs               |   3 +
 .../test/cucumber/feature-steps.js              |  11 +-
 .../glv/GraphTraversalSource.template           |   2 +-
 .../gremlin_python/process/graph_traversal.py   |   2 +-
 gremlin-test/features/map/PageRank.feature      | 142 +++++++++++++++++++
 .../gremlin/process/FeatureCoverageTest.java    |   3 +-
 6 files changed, 159 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/85fbd7cd/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ModernGraphTypeInformation.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ModernGraphTypeInformation.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ModernGraphTypeInformation.cs
index 7489b44..75dd37c 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ModernGraphTypeInformation.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ModernGraphTypeInformation.cs
@@ -38,6 +38,9 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
             {"name", typeof(string)},
             {"lang", typeof(string)},
             {"weight", typeof(float)},
+            {"gremlin.pageRankVertexProgram.pageRank", typeof(double)},
+            {"friendRank", typeof(double)},
+            {"pageRank", typeof(double)},
             {"foo", typeof(object)}, // used when for invalid property key lookups
             {"friendWeight", typeof(float)},  // used in an AddVertex.feature test
             {"performances", typeof(int)} // grateful dead graph

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/85fbd7cd/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
index 3976348..3f76052 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
@@ -55,12 +55,21 @@ const parsers = [
 
 const ignoreReason = {
   lambdaNotSupported: 'Lambdas are not supported on gremlin-javascript',
+  computerNotSupported: "withComputer() is not supported on gremlin-javascript",
   needsFurtherInvestigation: '',
 };
 
 const ignoredScenarios = {
   // An associative array containing the scenario name as key, for example:
-  // 'g_V_asXa_bX_out_asXcX_path_selectXkeysX': new IgnoreError(ignoreReason.embeddedListAssertion),
+  'g_V_pageRank': new IgnoreError(ignoreReason.computerNotSupported),
+  'g_V_outXcreatedX_pageRank_byXbothEX_byXprojectRankX_timesX0X_valueMapXname_projectRankX': new IgnoreError(ignoreReason.computerNotSupported),
+  'g_V_pageRank_order_byXpageRank_decrX_name': new IgnoreError(ignoreReason.computerNotSupported),
+  'g_V_pageRank_order_byXpageRank_decrX_name_limitX2X': new IgnoreError(ignoreReason.computerNotSupported),
+  'g_V_pageRank_byXoutEXknowsXX_byXfriendRankX_valueMapXname_friendRankX': new IgnoreError(ignoreReason.computerNotSupported),
+  'g_V_hasLabelXpersonX_pageRank_byXpageRankX_order_byXpageRankX_valueMapXname_pageRankX': new IgnoreError(ignoreReason.computerNotSupported),
+  'g_V_pageRank_byXpageRankX_asXaX_outXknowsX_pageRank_asXbX_selectXa_bX': new IgnoreError(ignoreReason.computerNotSupported),
+  'g_V_hasLabelXsoftwareX_hasXname_rippleX_pageRankX1X_byXinEXcreatedXX_timesX1X_byXpriorsX_inXcreatedX_unionXboth__identityX_valueMapXname_priorsX': new IgnoreError(ignoreReason.computerNotSupported),
+  'g_V_outXcreatedX_groupXmX_byXlabelX_pageRankX1X_byXpageRankX_byXinEX_timesX1X_inXcreatedX_groupXmX_byXpageRankX_capXmX': new IgnoreError(ignoreReason.computerNotSupported),
 };
 
 defineSupportCode(function(methods) {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/85fbd7cd/gremlin-python/glv/GraphTraversalSource.template
----------------------------------------------------------------------
diff --git a/gremlin-python/glv/GraphTraversalSource.template b/gremlin-python/glv/GraphTraversalSource.template
index 54b339e..d7ef973 100644
--- a/gremlin-python/glv/GraphTraversalSource.template
+++ b/gremlin-python/glv/GraphTraversalSource.template
@@ -52,9 +52,9 @@ class GraphTraversalSource(object):
         source = self.get_graph_traversal_source()
         source.traversal_strategies.add_strategies([RemoteStrategy(remote_connection)])
         return source
+
     def withComputer(self,graph_computer=None, workers=None, result=None, persist=None, vertices=None, edges=None, configuration=None):
         return self.withStrategies(VertexProgramStrategy(graph_computer,workers,result,persist,vertices,edges,configuration))
-
 <% sourceSpawnMethods.each { method -> %>
     def <%= method %>(self, *args):
         traversal = self.get_graph_traversal()

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/85fbd7cd/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py b/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
index b1056f0..b515e95 100644
--- a/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
+++ b/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
@@ -77,10 +77,10 @@ class GraphTraversalSource(object):
         source = self.get_graph_traversal_source()
         source.traversal_strategies.add_strategies([RemoteStrategy(remote_connection)])
         return source
+
     def withComputer(self,graph_computer=None, workers=None, result=None, persist=None, vertices=None, edges=None, configuration=None):
         return self.withStrategies(VertexProgramStrategy(graph_computer,workers,result,persist,vertices,edges,configuration))
 
-
     def E(self, *args):
         traversal = self.get_graph_traversal()
         traversal.bytecode.add_step("E", *args)

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/85fbd7cd/gremlin-test/features/map/PageRank.feature
----------------------------------------------------------------------
diff --git a/gremlin-test/features/map/PageRank.feature b/gremlin-test/features/map/PageRank.feature
new file mode 100644
index 0000000..76af1ed
--- /dev/null
+++ b/gremlin-test/features/map/PageRank.feature
@@ -0,0 +1,142 @@
+# 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.
+
+Feature: Step - pageRank()
+                
+  Scenario: g_V_pageRank
+    Given the modern graph
+    And the traversal of
+      """
+      g.withComputer().V().pageRank()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | v[marko] |
+      | v[vadas] |
+      | v[lop] |
+      | v[josh] |
+      | v[ripple] |
+      | v[peter] |
+    And the graph should return 6 for count of "g.withComputer().V().pageRank().has(\"gremlin.pageRankVertexProgram.pageRank\")"
+
+  Scenario: g_V_outXcreatedX_pageRank_byXbothEX_byXprojectRankX_timesX0X_valueMapXname_projectRankX
+    Given the modern graph
+    And the traversal of
+      """
+      g.withComputer().V().out("created").pageRank().by(__.bothE()).by("projectRank").times(0).valueMap("name", "projectRank")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | m[{"name": ["lop"], "projectRank": [3.0]}] |
+      | m[{"name": ["lop"], "projectRank": [3.0]}] |
+      | m[{"name": ["lop"], "projectRank": [3.0]}] |
+      | m[{"name": ["ripple"], "projectRank": [1.0]}] |
+
+  Scenario: g_V_pageRank_order_byXpageRank_decrX_name
+    Given the modern graph
+    And the traversal of
+      """
+      g.withComputer().V().pageRank().order().by("gremlin.pageRankVertexProgram.pageRank", Order.decr).values("name")
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | lop    |
+      | ripple |
+      | vadas  |
+      | josh   |
+      | marko  |
+      | peter  |
+
+  Scenario: g_V_pageRank_order_byXpageRank_decrX_name_limitX2X
+    Given the modern graph
+    And the traversal of
+      """
+      g.withComputer().V().pageRank().order().by("gremlin.pageRankVertexProgram.pageRank", Order.decr).values("name").limit(2)
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | lop    |
+      | ripple |
+
+  Scenario: g_V_pageRank_byXoutEXknowsXX_byXfriendRankX_valueMapXname_friendRankX
+    Given the modern graph
+    And the traversal of
+      """
+      g.withComputer().V().pageRank().by(__.outE("knows")).by("friendRank").valueMap("name", "friendRank")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | m[{"name": ["marko"], "friendRank": [0.15000000000000002]}] |
+      | m[{"name": ["vadas"], "friendRank": [0.21375000000000002]}] |
+      | m[{"name": ["lop"], "friendRank": [0.15000000000000002]}] |
+      | m[{"name": ["josh"], "friendRank": [0.21375000000000002]}] |
+      | m[{"name": ["ripple"], "friendRank": [0.15000000000000002]}] |
+      | m[{"name": ["peter"], "friendRank": [0.15000000000000002]}] |
+
+  Scenario: g_V_hasLabelXpersonX_pageRank_byXpageRankX_order_byXpageRankX_valueMapXname_pageRankX
+    Given the modern graph
+    And the traversal of
+      """
+      g.withComputer().V().hasLabel("person").pageRank().by("pageRank").order().by("pageRank").valueMap("name", "pageRank")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | m[{"name": ["marko"], "pageRank": [0.15000000000000002]}] |
+      | m[{"name": ["vadas"], "pageRank": [0.19250000000000003]}] |
+      | m[{"name": ["josh"], "pageRank": [0.19250000000000003]}] |
+      | m[{"name": ["peter"], "pageRank": [0.15000000000000002]}] |
+
+  Scenario: g_V_pageRank_byXpageRankX_asXaX_outXknowsX_pageRank_asXbX_selectXa_bX
+    Given the modern graph
+    And the traversal of
+      """
+      g.withComputer().V().pageRank().by("pageRank").as("a").out("knows").values("pageRank").as("b").select("a", "b")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | m[{"a": "v[marko]", "b": 0.19250000000000003}] |
+      | m[{"a": "v[marko]", "b": 0.19250000000000003}] |
+
+  Scenario: g_V_hasLabelXsoftwareX_hasXname_rippleX_pageRankX1X_byXinEXcreatedXX_timesX1X_byXpriorsX_inXcreatedX_unionXboth__identityX_valueMapXname_priorsX
+    Given the modern graph
+    And the traversal of
+      """
+      g.withComputer().V().hasLabel("software").has("name", "ripple").pageRank(1.0).by(__.inE("created")).times(1).by("priors").in("created").union(__.both(), __.identity()).valueMap("name", "priors")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | m[{"name": ["josh"], "priors": [1.0]}] |
+      | m[{"name": ["marko"], "priors": [0.0]}] |
+      | m[{"name": ["lop"], "priors": [0.0]}] |
+      | m[{"name": ["ripple"], "priors": [0.0]}] |
+
+  Scenario: g_V_outXcreatedX_groupXmX_byXlabelX_pageRankX1X_byXpageRankX_byXinEX_timesX1X_inXcreatedX_groupXmX_byXpageRankX_capXmX()
+    Given an unsupported test
+    Then nothing should happen because
+      """
+      The result returned is not supported under GraphSON 2.x and therefore cannot be properly asserted. More
+      specifically it has long keys which basically get toString()'d under GraphSON 2.x. This test can be supported
+      with GraphSON 3.x.
+      """

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/85fbd7cd/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java b/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java
index 503df77..6a45d38 100644
--- a/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java
+++ b/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java
@@ -53,6 +53,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.MaxTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.MeanTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.MinTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderTest;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.PageRankTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PathTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProjectTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesTest;
@@ -140,7 +141,7 @@ public class FeatureCoverageTest {
                 MeanTest.class,
                 MinTest.class,
                 OrderTest.class,
-                //PageRankTest.class,
+                PageRankTest.class,
                 PathTest.class,
                 // PeerPressureTest.class,
                 // ProfileTest.class,


[16/41] tinkerpop git commit: Merge branch 'tp33'

Posted by dk...@apache.org.
Merge branch 'tp33'


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

Branch: refs/heads/TINKERPOP-1990
Commit: 891e7da50a3e6d3396e66a7a74c43934b325792d
Parents: 226ef6e 3e308f5
Author: Robert Dale <ro...@gmail.com>
Authored: Sat Aug 4 16:45:50 2018 -0400
Committer: Robert Dale <ro...@gmail.com>
Committed: Sat Aug 4 16:45:50 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc     | 1 +
 gremlin-shaded/pom.xml | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/891e7da5/CHANGELOG.asciidoc
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/891e7da5/gremlin-shaded/pom.xml
----------------------------------------------------------------------


[31/41] tinkerpop git commit: TINKERPOP-1976 Minor refactoring and test message improvement

Posted by dk...@apache.org.
TINKERPOP-1976 Minor refactoring and test message improvement


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

Branch: refs/heads/TINKERPOP-1990
Commit: c03b575fe27f8e917f705e593e66250962dcfdf4
Parents: f7ccb67
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Sat Aug 4 06:01:53 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Aug 9 07:28:09 2018 -0400

----------------------------------------------------------------------
 .../io/graphson/TraversalSerializersV2d0.java         |  4 ----
 .../gremlin/process/AbstractGremlinProcessTest.java   | 14 +++++++-------
 2 files changed, 7 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c03b575f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java
index 040fd1d..2a07723 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java
@@ -37,18 +37,14 @@ import org.apache.tinkerpop.shaded.jackson.core.JsonParser;
 import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
 import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
 import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
-import org.apache.tinkerpop.shaded.jackson.databind.JavaType;
-import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
 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.ser.std.StdScalarSerializer;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
-import org.apache.tinkerpop.shaded.jackson.databind.type.TypeFactory;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c03b575f/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
index 9dbf261..96dee1d 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
@@ -30,6 +30,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -40,7 +41,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeTrue;
 
 /**
@@ -81,7 +81,7 @@ public abstract class AbstractGremlinProcessTest extends AbstractGremlinTest {
             final String methodName = testName.contains("[") ? testName.substring(0, testName.indexOf('[')) : testName;
             final IgnoreEngine ignoreEngine = this.getClass().getMethod(methodName).getAnnotation(IgnoreEngine.class);
             if (ignoreEngine != null)
-                assumeTrue(String.format("This test is ignored for %s", ignoreEngine.value()), !ignoreEngine.value().equals(GraphManager.getTraversalEngineType()));
+                assumeTrue(String.format("%s.%s is ignored for %s", this.getClass().getName(), testName, ignoreEngine.value()), !ignoreEngine.value().equals(GraphManager.getTraversalEngineType()));
         } catch (NoSuchMethodException nsme) {
             // some tests are parameterized
             throw new RuntimeException(String.format("Could not find test method %s in test case %s", name.getMethodName(), this.getClass().getName()));
@@ -128,7 +128,7 @@ public abstract class AbstractGremlinProcessTest extends AbstractGremlinTest {
 
         for (T t : results) {
             if (t instanceof Map) {
-                assertThat("Checking map result existence: " + t, expectedResults.stream().filter(e -> e instanceof Map).filter(e -> internalCheckMap((Map) e, (Map) t)).findAny().isPresent(), is(true));
+                assertThat("Checking map result existence: " + t, expectedResults.stream().filter(e -> e instanceof Map).anyMatch(e -> internalCheckMap((Map) e, (Map) t)), is(true));
             } else {
                 assertThat("Checking result existence: " + t, expectedResults.contains(t), is(true));
             }
@@ -153,8 +153,8 @@ public abstract class AbstractGremlinProcessTest extends AbstractGremlinTest {
     }
 
     public static <A, B> void checkMap(final Map<A, B> expectedMap, final Map<A, B> actualMap) {
-        final List<Map.Entry<A, B>> actualList = actualMap.entrySet().stream().sorted((a, b) -> a.getKey().toString().compareTo(b.getKey().toString())).collect(Collectors.toList());
-        final List<Map.Entry<A, B>> expectedList = expectedMap.entrySet().stream().sorted((a, b) -> a.getKey().toString().compareTo(b.getKey().toString())).collect(Collectors.toList());
+        final List<Map.Entry<A, B>> actualList = actualMap.entrySet().stream().sorted(Comparator.comparing(a -> a.getKey().toString())).collect(Collectors.toList());
+        final List<Map.Entry<A, B>> expectedList = expectedMap.entrySet().stream().sorted(Comparator.comparing(a -> a.getKey().toString())).collect(Collectors.toList());
         assertEquals(expectedList.size(), actualList.size());
         for (int i = 0; i < actualList.size(); i++) {
             assertEquals(expectedList.get(i).getKey(), actualList.get(i).getKey());
@@ -163,8 +163,8 @@ public abstract class AbstractGremlinProcessTest extends AbstractGremlinTest {
     }
 
     private static <A, B> boolean internalCheckMap(final Map<A, B> expectedMap, final Map<A, B> actualMap) {
-        final List<Map.Entry<A, B>> actualList = actualMap.entrySet().stream().sorted((a, b) -> a.getKey().toString().compareTo(b.getKey().toString())).collect(Collectors.toList());
-        final List<Map.Entry<A, B>> expectedList = expectedMap.entrySet().stream().sorted((a, b) -> a.getKey().toString().compareTo(b.getKey().toString())).collect(Collectors.toList());
+        final List<Map.Entry<A, B>> actualList = actualMap.entrySet().stream().sorted(Comparator.comparing(a -> a.getKey().toString())).collect(Collectors.toList());
+        final List<Map.Entry<A, B>> expectedList = expectedMap.entrySet().stream().sorted(Comparator.comparing(a -> a.getKey().toString())).collect(Collectors.toList());
 
         if (expectedList.size() != actualList.size()) {
             return false;


[19/41] tinkerpop git commit: Update bulk import/export section for graph providers given g.io() CTR

Posted by dk...@apache.org.
Update bulk import/export section for graph providers given g.io() CTR


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

Branch: refs/heads/TINKERPOP-1990
Commit: a5d1aa660b28a5c126b3f7dec945f8558d42816c
Parents: 72b264d
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Mon Aug 6 07:46:58 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon Aug 6 07:46:58 2018 -0400

----------------------------------------------------------------------
 docs/src/dev/provider/index.asciidoc | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a5d1aa66/docs/src/dev/provider/index.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/dev/provider/index.asciidoc b/docs/src/dev/provider/index.asciidoc
index ab57020..49bc7c7 100644
--- a/docs/src/dev/provider/index.asciidoc
+++ b/docs/src/dev/provider/index.asciidoc
@@ -620,12 +620,17 @@ reason to implement this interface.
 ==== Bulk Import Export
 
 When it comes to doing "bulk" operations, the diverse nature of the available graph databases and their specific
-capabilities, prevents TinkerPop from doing a good job of generalizing that capability well. TinkerPop refers users to
-the bulk import/export facilities of specific graph providers as they tend to be more efficient and easier to use than
-the options TinkerPop has tried to generalize in the past.
+capabilities, prevents TinkerPop from doing a good job of generalizing that capability well. TinkerPop thus maintains
+two positions on the concept of import and export:
 
-That said, for graph providers that don't have a special bulk loading feature, they can get a basic bulk loader from
-TinkerPop using the link:http://tinkerpop.apache.org/docs/x.y.z/reference/#clonevertexprogram[CloneVertexProgram].
+1. TinkerPop refers users to the bulk import/export facilities of specific graph providers as they tend to be more
+efficient and easier to use than the options TinkerPop has tried to generalize in the past.
+2. TinkerPop encourages graph providers to expose those capabilities via `g.io()` and the `IoStep` by way of a
+`TraversalStrategy`.
+
+That said, for graph providers that don't have a special bulk loading feature, they can either rely on the default
+OLTP (single-threaded) `GraphReader` and `GraphWriter` options that are embedded in `IoStep` or get a basic bulk loader
+from TinkerPop using the link:http://tinkerpop.apache.org/docs/x.y.z/reference/#clonevertexprogram[CloneVertexProgram].
 Simply provide a `InputFormat` and `OutputFormat` that can be referenced by a `HadoopGraph` instance as discussed
 in the link:http://tinkerpop.apache.org/docs/x.y.z/reference/#clonevertexprogram[Reference Documentation].
 


[15/41] tinkerpop git commit: Merge branch 'tp32' into tp33

Posted by dk...@apache.org.
Merge branch 'tp32' into tp33


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

Branch: refs/heads/TINKERPOP-1990
Commit: 3e308f5226e6254122f782cb55571e0103f9a9ff
Parents: b779a2a b98ff5e
Author: Robert Dale <ro...@gmail.com>
Authored: Sat Aug 4 16:44:41 2018 -0400
Committer: Robert Dale <ro...@gmail.com>
Committed: Sat Aug 4 16:44:41 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc     | 1 +
 gremlin-shaded/pom.xml | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3e308f52/CHANGELOG.asciidoc
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3e308f52/gremlin-shaded/pom.xml
----------------------------------------------------------------------


[18/41] tinkerpop git commit: Fix spelling mistake CTR

Posted by dk...@apache.org.
Fix spelling mistake CTR


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

Branch: refs/heads/TINKERPOP-1990
Commit: 72b264d0f5e4b8fca66ea77cde83982071f411b0
Parents: 18db9b8
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Mon Aug 6 07:40:30 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon Aug 6 07:40:30 2018 -0400

----------------------------------------------------------------------
 docs/src/upgrade/release-3.4.x.asciidoc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72b264d0/docs/src/upgrade/release-3.4.x.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.4.x.asciidoc b/docs/src/upgrade/release-3.4.x.asciidoc
index 9951024..587e761 100644
--- a/docs/src/upgrade/release-3.4.x.asciidoc
+++ b/docs/src/upgrade/release-3.4.x.asciidoc
@@ -85,7 +85,7 @@ While `io()`-step is still single-threaded for OLTP style loading, it can be uti
 internally uses `CloneVertexProgram` and therefore any graph `InputFormat` or `OutputFormat` can be configured in
 conjunction with this step for parallel loads of large datasets.
 
-It is also worth noting that the `io()`-step may be overriden by graph providers to utilize their native bulk-loading
+It is also worth noting that the `io()`-step may be overridden by graph providers to utilize their native bulk-loading
 features, so consult the documentation of the implementation being used to determine if there are any improved
 efficiencies there.
 


[03/41] tinkerpop git commit: TINKERPOP-2005 Encapsulate test eval timeout overrides in a method

Posted by dk...@apache.org.
TINKERPOP-2005 Encapsulate test eval timeout overrides in a method

This is to avoid directly exposing other settings whose changes may
not be effective until the server is restarted.


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

Branch: refs/heads/TINKERPOP-1990
Commit: 4ff4b88a5b663f86917299691edc6f84a6bd1c67
Parents: b7a4495
Author: Dmitri Bourlatchkov <dm...@datastax.com>
Authored: Mon Jul 30 15:57:14 2018 -0400
Committer: Dmitri Bourlatchkov <dm...@datastax.com>
Committed: Mon Jul 30 15:57:14 2018 -0400

----------------------------------------------------------------------
 .../server/AbstractGremlinServerIntegrationTest.java   | 13 ++++++++++++-
 .../gremlin/server/GremlinServerIntegrateTest.java     |  2 +-
 2 files changed, 13 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/4ff4b88a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java
index a8a8853..f11a045 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java
@@ -39,7 +39,7 @@ import static org.junit.Assume.assumeThat;
  */
 public abstract class AbstractGremlinServerIntegrationTest {
     protected GremlinServer server;
-    protected Settings overriddenSettings;
+    private Settings overriddenSettings;
     private final static String epollOption = "gremlin.server.epoll";
     private static final boolean GREMLIN_SERVER_EPOLL = "true".equalsIgnoreCase(System.getProperty(epollOption));
     private static final Logger logger = LoggerFactory.getLogger(AbstractGremlinServerIntegrationTest.class);
@@ -51,6 +51,17 @@ public abstract class AbstractGremlinServerIntegrationTest {
         return settings;
     }
 
+    /**
+     * This method may be called after {@link #startServer()} to (re-)set the script evaluation timeout in
+     * the running server.
+     * @param timeoutInMillis new script evaluation timeout
+     */
+    protected void overrideScriptEvaluationTimeout(final long timeoutInMillis) {
+        // Note: overriding settings in a running server is not guaranteed to work for all settings.
+        // It works for the evaluation timeout, though, because GremlinExecutor is re-created for each evaluation.
+        overriddenSettings.scriptEvaluationTimeout = timeoutInMillis;
+    }
+
     public InputStream getSettingsInputStream() {
         return AbstractGremlinServerIntegrationTest.class.getResourceAsStream("gremlin-server-integration.yaml");
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/4ff4b88a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
index 9256458..0867fd3 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
@@ -394,7 +394,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
         // Note: this test may have a false negative result, but a failure  would indicate a real problem.
         for(int i = 0; i < 30; i++) {
             int timeout = 1 + i;
-            overriddenSettings.scriptEvaluationTimeout = timeout;
+            overrideScriptEvaluationTimeout(timeout);
 
             try {
                 client.submit("x = 1 + 1").all().get().get(0).getInt();


[17/41] tinkerpop git commit: Added a note about versioning gremlin CTR

Posted by dk...@apache.org.
Added a note about versioning gremlin CTR


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

Branch: refs/heads/TINKERPOP-1990
Commit: 18db9b8159810d0d624944e169ccafdc868a3237
Parents: 891e7da
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Mon Aug 6 07:15:52 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon Aug 6 07:15:52 2018 -0400

----------------------------------------------------------------------
 docs/src/dev/future/index.asciidoc | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/18db9b81/docs/src/dev/future/index.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/dev/future/index.asciidoc b/docs/src/dev/future/index.asciidoc
index 6e41cf9..acf587e 100644
--- a/docs/src/dev/future/index.asciidoc
+++ b/docs/src/dev/future/index.asciidoc
@@ -53,6 +53,8 @@ TinkerPop 3.x. These items include:
 * The concept of `Traversal` as the sole means of interacting with the graph.
 ** The role of Blueprints should be significantly reduced.
 ** The role of Gremlin should be significantly increased.
+* Provide better methods of versioning Gremlin itself - being bound to JVM releases and forcing local and remote
+versions of Gremlin to be the same isn't ideal.
 
 == Hiding Blueprints
 


[14/41] tinkerpop git commit: Merge branch 'TINKERPOP-2016' into tp32

Posted by dk...@apache.org.
Merge branch 'TINKERPOP-2016' into tp32


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

Branch: refs/heads/TINKERPOP-1990
Commit: b98ff5e150c2da037780737c571c34215fe6c151
Parents: ce94738 1829318
Author: Robert Dale <ro...@gmail.com>
Authored: Sat Aug 4 16:44:00 2018 -0400
Committer: Robert Dale <ro...@gmail.com>
Committed: Sat Aug 4 16:44:00 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc     | 1 +
 gremlin-shaded/pom.xml | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------



[34/41] tinkerpop git commit: TINKERPOP-1976 Added GLV test for peerPressure()

Posted by dk...@apache.org.
TINKERPOP-1976 Added GLV test for peerPressure()


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

Branch: refs/heads/TINKERPOP-1990
Commit: 0a5d8ceb6931e3ab2165cba8cd8414e8f4575ce9
Parents: 85fbd7c
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Aug 7 13:45:39 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Aug 9 07:28:09 2018 -0400

----------------------------------------------------------------------
 .../ModernGraphTypeInformation.cs               |  1 +
 .../test/cucumber/feature-steps.js              |  3 +
 gremlin-test/features/map/PeerPressure.feature  | 60 ++++++++++++++++++++
 .../gremlin/process/FeatureCoverageTest.java    |  3 +-
 4 files changed, 66 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0a5d8ceb/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ModernGraphTypeInformation.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ModernGraphTypeInformation.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ModernGraphTypeInformation.cs
index 75dd37c..77ed4eb 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ModernGraphTypeInformation.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ModernGraphTypeInformation.cs
@@ -39,6 +39,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
             {"lang", typeof(string)},
             {"weight", typeof(float)},
             {"gremlin.pageRankVertexProgram.pageRank", typeof(double)},
+            {"gremlin.peerPressureVertexProgram.cluster", typeof(int)},
             {"friendRank", typeof(double)},
             {"pageRank", typeof(double)},
             {"foo", typeof(object)}, // used when for invalid property key lookups

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0a5d8ceb/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
index 3f76052..e585fcc 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
@@ -70,6 +70,9 @@ const ignoredScenarios = {
   'g_V_pageRank_byXpageRankX_asXaX_outXknowsX_pageRank_asXbX_selectXa_bX': new IgnoreError(ignoreReason.computerNotSupported),
   'g_V_hasLabelXsoftwareX_hasXname_rippleX_pageRankX1X_byXinEXcreatedXX_timesX1X_byXpriorsX_inXcreatedX_unionXboth__identityX_valueMapXname_priorsX': new IgnoreError(ignoreReason.computerNotSupported),
   'g_V_outXcreatedX_groupXmX_byXlabelX_pageRankX1X_byXpageRankX_byXinEX_timesX1X_inXcreatedX_groupXmX_byXpageRankX_capXmX': new IgnoreError(ignoreReason.computerNotSupported),
+  'g_V_peerPressure': new IgnoreError(ignoreReason.computerNotSupported),
+  'g_V_peerPressure_byXclusterX_byXoutEXknowsXX_pageRankX1X_byXrankX_byXoutEXknowsXX_timesX2X_group_byXclusterX_byXrank_sumX_limitX100X': new IgnoreError(ignoreReason.computerNotSupported),
+  'g_V_hasXname_rippleX_inXcreatedX_peerPressure_byXoutEX_byXclusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX': new IgnoreError(ignoreReason.computerNotSupported),
 };
 
 defineSupportCode(function(methods) {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0a5d8ceb/gremlin-test/features/map/PeerPressure.feature
----------------------------------------------------------------------
diff --git a/gremlin-test/features/map/PeerPressure.feature b/gremlin-test/features/map/PeerPressure.feature
new file mode 100644
index 0000000..d23fa31
--- /dev/null
+++ b/gremlin-test/features/map/PeerPressure.feature
@@ -0,0 +1,60 @@
+# 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.
+
+Feature: Step - peerPressure()
+                
+  Scenario: g_V_peerPressure
+    Given the modern graph
+    And the traversal of
+      """
+      g.withComputer().V().peerPressure()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | v[marko] |
+      | v[vadas] |
+      | v[lop] |
+      | v[josh] |
+      | v[ripple] |
+      | v[peter] |
+    And the graph should return 6 for count of "g.withComputer().V().peerPressure().has(\"gremlin.peerPressureVertexProgram.cluster\")"
+
+  Scenario: g_V_peerPressure_byXclusterX_byXoutEXknowsXX_pageRankX1X_byXrankX_byXoutEXknowsXX_timesX2X_group_byXclusterX_byXrank_sumX_limitX100X
+    Given an unsupported test
+    Then nothing should happen because
+      """
+      The result returned is not supported under GraphSON 2.x and therefore cannot be properly asserted. More
+      specifically it has long keys which basically get toString()'d under GraphSON 2.x. This test can be supported
+      with GraphSON 3.x.
+      """
+
+  Scenario: g_V_hasXname_rippleX_inXcreatedX_peerPressure_byXoutEX_byXclusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX
+    Given the modern graph
+    And the traversal of
+      """
+      g.withComputer().V().has("name", "ripple").in("created").peerPressure().by(__.outE()).by("cluster").repeat(__.union(__.identity(), __.both())).times(2).dedup().valueMap("name", "cluster")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | m[{"name": ["marko"], "cluster": [1]}] |
+      | m[{"name": ["vadas"], "cluster": [2]}] |
+      | m[{"name": ["lop"], "cluster": [4]}] |
+      | m[{"name": ["josh"], "cluster": [4]}] |
+      | m[{"name": ["ripple"], "cluster": [4]}] |
+      | m[{"name": ["peter"], "cluster": [6]}] |

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0a5d8ceb/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java b/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java
index 6a45d38..2cca50b 100644
--- a/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java
+++ b/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java
@@ -55,6 +55,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.MinTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PageRankTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PathTest;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.PeerPressureTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProjectTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.SelectTest;
@@ -143,7 +144,7 @@ public class FeatureCoverageTest {
                 OrderTest.class,
                 PageRankTest.class,
                 PathTest.class,
-                // PeerPressureTest.class,
+                PeerPressureTest.class,
                 // ProfileTest.class,
                 // ProgramTest.class,
                 ProjectTest.class,


[08/41] tinkerpop git commit: Added Huawei Graph Engine Service to listing - CTR

Posted by dk...@apache.org.
Added Huawei Graph Engine Service to listing - CTR


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

Branch: refs/heads/TINKERPOP-1990
Commit: 8f1fe6d8ebd753dc1fb708da53ba7a60354dbaf7
Parents: 69b6f96
Author: Robert Dale <ro...@gmail.com>
Authored: Wed Aug 1 22:33:57 2018 -0400
Committer: Robert Dale <ro...@gmail.com>
Committed: Wed Aug 1 22:33:57 2018 -0400

----------------------------------------------------------------------
 docs/site/home/index.html | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8f1fe6d8/docs/site/home/index.html
----------------------------------------------------------------------
diff --git a/docs/site/home/index.html b/docs/site/home/index.html
index 4ff692c..472e77a 100644
--- a/docs/site/home/index.html
+++ b/docs/site/home/index.html
@@ -224,6 +224,7 @@ limitations under the License.
             <li><a href="https://grakn.ai/">GRAKN.AI</a> - Distributed OLTP/OLAP knowledge graph system.</li>
             <li><a href="http://tinkerpop.apache.org/docs/current/reference/#sparkgraphcomputer">Hadoop (Spark)</a> - OLAP graph processor using Spark.</li>
             <li><a href="https://github.com/rayokota/hgraphdb">HGraphDB</a> - OLTP graph database running on Apache HBase.</li>
+            <li><a href="https://www.huaweicloud.com/en-us/product/ges.html">Huawei Graph Engine Service</a> - Fully-managed, distributed, at-scale graph query and analysis service that provides a visualized interactive analytics platform.</li>
             <li><a href="https://console.ng.bluemix.net/catalog/services/ibm-graph/">IBM Graph</a> - OLTP graph database as a service.</li>
             <li><a href="http://janusgraph.org/">JanusGraph</a> - Distributed OLTP and OLAP graph database with BerkeleyDB, Apache Cassandra and Apache HBase support.</li>
             <li><a href="https://github.com/awslabs/dynamodb-janusgraph-storage-backend//">JanusGraph (Amazon)</a> - The Amazon DynamoDB Storage Backend for JanusGraph.</li>


[20/41] tinkerpop git commit: Added a system error code for failed plugin installs to Gremlin Server CTR

Posted by dk...@apache.org.
Added a system error code for failed plugin installs to Gremlin Server CTR


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

Branch: refs/heads/TINKERPOP-1990
Commit: 2d315e828149a132ecabf406af91acc3caec064c
Parents: b98ff5e
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Aug 7 06:28:56 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Aug 7 06:30:08 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                                                | 1 +
 .../tinkerpop/gremlin/server/util/GremlinServerInstall.java       | 3 +++
 2 files changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2d315e82/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 8137b45..495abd7 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -23,6 +23,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 [[release-3-2-10]]
 === TinkerPop 3.2.10 (Release Date: NOT OFFICIALLY RELEASED YET)
 
+* Added an system error code for failed plugin installs for Gremlin Server `-i` option.
 * Match numbers in `choose()` options using `NumberHelper` (match values, ignore data type).
 * Added support for GraphSON serialization of `Date` in Javascript.
 * Fixed bug in Java driver where an disorderly shutdown of the server would cause the client to hang.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2d315e82/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/GremlinServerInstall.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/GremlinServerInstall.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/GremlinServerInstall.java
index 03317d3..58532a0 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/GremlinServerInstall.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/GremlinServerInstall.java
@@ -23,6 +23,8 @@ import org.apache.tinkerpop.gremlin.groovy.util.DependencyGrabber;
 import groovy.lang.GroovyClassLoader;
 
 /**
+ * Command line installer for plugins to Gremlin Server.
+ *
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public class GremlinServerInstall {
@@ -39,6 +41,7 @@ public class GremlinServerInstall {
             } catch (Exception iae) {
                 System.out.println(String.format("Could not install the dependency: %s", iae.getMessage()));
                 iae.printStackTrace();
+                System.exit(1);
             }
 
         }


[40/41] tinkerpop git commit: TINKERPOP-1990 Implemented `ShortestPathVertexProgram` and `ShortestPathVertexProgramStep`.

Posted by dk...@apache.org.
TINKERPOP-1990 Implemented `ShortestPathVertexProgram` and `ShortestPathVertexProgramStep`.


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

Branch: refs/heads/TINKERPOP-1990
Commit: 7389f019a91beb92499c81b8a7900ee7979ed2b6
Parents: f88ace1
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Wed May 23 08:46:34 2018 -0400
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Thu Aug 9 08:34:47 2018 -0700

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   1 +
 docs/src/recipes/shortest-path.asciidoc         |  62 ++
 docs/src/reference/the-graphcomputer.asciidoc   |  51 ++
 docs/src/reference/the-traversal.asciidoc       |  61 ++
 .../tinkerpop/gremlin/jsr223/CoreImports.java   |   4 +
 .../search/path/ShortestPathVertexProgram.java  | 611 +++++++++++++++++++
 .../traversal/step/map/ShortestPath.java        | 108 ++++
 .../step/map/ShortestPathVertexProgramStep.java | 185 ++++++
 .../gremlin/process/remote/RemoteGraph.java     |   4 +
 .../gremlin/process/traversal/Traversal.java    |  16 +-
 .../traversal/dsl/graph/GraphTraversal.java     |  20 +
 .../traversal/lambda/ColumnTraversal.java       |   8 +
 .../traversal/lambda/ConstantTraversal.java     |   9 +-
 .../traversal/lambda/ElementValueTraversal.java |  10 +-
 .../traversal/lambda/IdentityTraversal.java     |   7 +-
 .../process/traversal/lambda/LoopTraversal.java |   6 +
 .../traversal/lambda/TokenTraversal.java        |   8 +
 .../process/traversal/lambda/TrueTraversal.java |   5 +
 .../structure/io/graphson/GraphSONModule.java   |   2 +-
 .../gremlin/structure/io/gryo/GryoVersion.java  |  12 +-
 .../structure/io/gryo/UtilSerializers.java      |  15 +
 .../gremlin/structure/util/Attachable.java      |   3 +-
 .../traversal/dsl/graph/GraphTraversalTest.java |   2 +-
 .../Process/Traversal/GraphTraversal.cs         |   9 +
 .../lib/process/graph-traversal.js              |  10 +
 .../gremlin_python/process/graph_traversal.py   |   4 +
 .../tinkerpop/gremlin/AbstractGremlinTest.java  |   6 +-
 .../process/AbstractGremlinProcessTest.java     |   7 +-
 .../gremlin/process/ProcessComputerSuite.java   |   5 +
 .../search/path/ShortestPathTestHelper.java     | 100 +++
 .../path/ShortestPathVertexProgramTest.java     | 297 +++++++++
 .../traversal/step/map/ShortestPathTest.java    | 353 +++++++++++
 pom.xml                                         |   3 +
 33 files changed, 1981 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 303d963..f82727a 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -25,6 +25,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 
 This release also includes changes from <<release-3-3-3, 3.3.3>>.
 
+* Implemented `ShortestPathVertexProgram` and the `shortestPath()` step.
 * `AbstractGraphProvider` uses `g.io()` for loading test data.
 * Added the `io()` start step and `read()` and `write()` termination steps to the Gremlin language.
 * Added `GraphFeatures.supportsIoRead()` and `GraphFeatures.supportsIoWrite()`.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/docs/src/recipes/shortest-path.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/recipes/shortest-path.asciidoc b/docs/src/recipes/shortest-path.asciidoc
index 2e33055..04c542d 100644
--- a/docs/src/recipes/shortest-path.asciidoc
+++ b/docs/src/recipes/shortest-path.asciidoc
@@ -49,6 +49,16 @@ length three), but this example is not considering that.
 <2> It might be interesting to know the path lengths for all paths between vertex "1" and "5".
 <3> Alternatively, one might wish to do a path length distribution over all the paths.
 
+The following code block demonstrates how the shortest path from `v[1]` to `v[5]` can be queried in OLAP, using the `shortestPath()` step.
+
+[gremlin-groovy,existing]
+----
+g = g.withComputer()
+g.V(1).shortestPath().
+  with(ShortestPath.edges, Direction.OUT).
+  with(ShortestPath.target, hasId(5))
+----
+
 The previous example defines the length of the path by the number of vertices in the path, but the "path" might also
 be measured by data within the graph itself. The following example use the same graph structure as the previous example,
 but includes a "weight" on the edges, that will be used to help determine the "cost" of a particular path:
@@ -95,6 +105,17 @@ calculated cost. With some slight modifications given the use of `select` it bec
 the output. Note that the path with the lowest "cost" actually has a longer path length as determined by the graph
 structure.
 
+The next code block demonstrates how the `shortestPath()` step can be used in OLAP to determine the shortest weighted path.
+
+[gremlin-groovy,existing]
+----
+g = g.withComputer()
+g.V(1).shortestPath().
+  with(ShortestPath.edges, Direction.OUT).
+  with(ShortestPath.distance, 'weight').
+  with(ShortestPath.target, hasId(5))
+----
+
 The following query illustrates how `select(<traversal>)` can be used to find all shortest weighted undirected paths
 in the modern toy graph.
 
@@ -136,3 +157,44 @@ g.withSack(0.0).V().as("from").       <1>
 <7> Order the output by the start vertex id and then the end vertex id (for better readability).
 <8> Deduplicate vertex pairs (the shortest path from `v[1]` to `v[6]` is the same as the path from `v[6]` to `v[1]`).
 
+Again, this can be translated into an OLAP query using the `shortestPath()` step.
+
+[gremlin-groovy,existing]
+----
+result = g.withComputer().V().
+  shortestPath().
+    with(ShortestPath.distance, 'weight').
+    with(ShortestPath.includeEdges, true).
+  filter(count(local).is(gt(1))).
+  group().
+    by(project('from','to').
+         by(limit(local, 1)).
+         by(tail(local, 1))).
+  unfold().
+  order().
+    by(select(keys).select('from').id()).
+    by(select(keys).select('to').id()).toList()
+----
+
+The obvious difference in the result is the absence of property values in the OLAP result. Since OLAP traversers are not
+allowed to leave the local star graph, it's not possible to have the exact same result in an OLAP query. However, the determined
+shortest paths can be passed back into the OLTP `GraphTraversalSource`, which can then be used to query the values.
+
+[gremlin-groovy,existing]
+----
+g.withSideEffect('v', []).                            <1>
+  inject(result.toArray()).as('kv').select(values).
+  unfold().
+  map(unfold().as('v_or_e').
+      coalesce(V().where(eq('v_or_e')).store('v'),
+               select('v').tail(local, 1).bothE().where(eq('v_or_e'))).
+      values('name','weight').
+      fold()).
+  group().
+    by(select('kv').select(keys)).unfold().
+  order().
+    by(select(keys).select('from').id()).
+    by(select(keys).select('to').id()).toList()
+----
+
+<1> The side-effect `v` is used to keep track of the last processed vertex, hence it needs to be an order-preserving list. Without this explicit definition `v` would become a `BulkSet` which doesn't preserve the insert order.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/docs/src/reference/the-graphcomputer.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/the-graphcomputer.asciidoc b/docs/src/reference/the-graphcomputer.asciidoc
index 1d7586c..3d7ec00 100644
--- a/docs/src/reference/the-graphcomputer.asciidoc
+++ b/docs/src/reference/the-graphcomputer.asciidoc
@@ -403,6 +403,57 @@ g.V().peerPressure().by('cluster').valueMap()
 g.V().peerPressure().by(outE('knows')).by('cluster').valueMap()
 ----
 
+[[shortestpathvertexprogram]]
+=== ShortestPathVertexProgram
+
+The `ShortestPathVertexProram` provides an easy way to find shortest non-cyclic paths in the graph. It provides several options to configure
+the output format, the start- and end-vertices, the direction, a custom distance function, as well as a distance limitation. By default it just
+finds all undirected, shortest paths in the graph.
+
+[gremlin-groovy,modern]
+----
+spvp = ShortestPathVertexProgram.build().create() <1>
+result = graph.compute().program(spvp).submit().get() <2>
+result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS) <3>
+----
+
+<1> Create a `ShortestPathVertexProgram` with its default configuration.
+<2> Execute the `ShortestPathVertexProgram`.
+<3> Get all shortest paths from the results memory.
+
+[gremlin-groovy,modern]
+----
+spvp = ShortestPathVertexProgram.build().includeEdges(true).create() <1>
+result = graph.compute().program(spvp).submit().get() <2>
+result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS) <3>
+----
+
+<1> Create a `ShortestPathVertexProgram` as before, but configure it to include edges in the result.
+<2> Execute the `ShortestPathVertexProgram`.
+<3> Get all shortest paths from the results memory.
+
+The `ShortestPathVertexProgram.Builder` provides the following configuration methods:
+
+[width="100%",cols="3,15,5",options="header"]
+|=========================================================
+| Method | Description | Default
+| `source(Traversal)` | Sets a filter traversal for the start vertices (e.g. `__.has('name','marko')`). | all vertices (`__.identity()`)
+| `target(Traversal)` | Sets a filter traversal for the end vertices. | all vertices
+| `edgeDirection(Direction)` | Sets the direction to traverse during the shortest path discovery. | `Direction.BOTH`
+| `edgeTraversal(Traversal)` | Sets a traversal that emits the edges to traverse from the current vertex. | `__.bothE()`
+| `distanceProperty(String)` | Sets the edge property to use for the distance calculations. | none
+| `distanceTraversal(Traversal)` | Sets the traversal that calculates the distance for the current edge. | `__.constant(1)`
+| `maxDistance(Traversal)` | Limits the shortest path distance. | none
+| `includeEdges(Boolean)` | Whether to include edges in shortest paths or not. | `false`
+|=========================================================
+
+IMPORTANT: If a maximum distance is provided, the discovery process will only stop to follow a path at this distance if there was no
+custom distance property or traversal provided. Custom distances can be negative, hence exceeding the maximum distance doesn't mean that there
+can't be any more valid paths. However, paths will be filtered at the end, when no more non-cyclic paths can be found. The bottom line is that
+custom distance properties or traversals can lead to much longer runtimes and a much higher memory consumption.
+
+Note that `GraphTraversal` provides a <<shortestpath-step,`shortestPath()`>>-step.
+
 [[bulkdumpervertexprogram]]
 [[clonevertexprogram]]
 === CloneVertexProgram

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/docs/src/reference/the-traversal.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc
index 7d385c8..edc0645 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -2663,6 +2663,67 @@ link:++http://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/grem
 link:++http://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/structure/Column.html++[`Column`],
 link:++http://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Pop.html++[`Pop`]
 
+[[shortestpath-step]]
+=== ShortestPath step
+
+The `shortestPath()`-step provides an easy way to find shortest non-cyclic paths in a graph. It is configurable
+using the `with()`-modulator with the options given below.
+
+[width="100%",cols="3,3,15,5",options="header"]
+|=========================================================
+| Key | Type | Description | Default
+| `target` | `Traversal` | Sets a filter traversal for the end vertices (e.g. `__.has('name','marko')`). | all vertices (`__.identity()`)
+| `edges` | `Traversal` or `Direction` | Sets a `Traversal` that emits the edges to traverse from the current vertex or the `Direction` to traverse during the shortest path discovery. | `Direction.BOTH`
+| `distance` | `Traversal` or `String` | Sets the `Traversal` that calculates the distance for the current edge or the name of an edge property to use for the distance calculations. | `__.constant(1)`
+| `maxDistance` | `Number` | Sets the distance limit for all shortest paths. | none
+| `includeEdges` | `Boolean` | Whether to include edges in the result or not. | `false`
+|=========================================================
+
+[gremlin-groovy,modern]
+----
+g = g.withComputer()
+g.V().shortestPath() <1>
+g.V().has('person','name','marko').shortestPath() <2>
+g.V().shortestPath().with(ShortestPath.target, __.has('name','peter')) <3>
+g.V().shortestPath().
+        with(ShortestPath.edges, Direction.IN).
+        with(ShortestPath.target, __.has('name','josh')) <4>
+g.V().has('person','name','marko').
+      shortestPath().
+        with(ShortestPath.target, __.has('name','josh')) <5>
+g.V().has('person','name','marko').
+      shortestPath().
+        with(ShortestPath.target, __.has('name','josh')).
+        with(ShortestPath.distance, 'weight') <6>
+g.V().has('person','name','marko').
+      shortestPath().
+        with(ShortestPath.target, __.has('name','josh')).
+        with(ShortestPath.includeEdges, true) <7>
+----
+
+<1> Find all shortest paths.
+<2> Find all shortest paths from `marko`.
+<3> Find all shortest paths to `peter`.
+<4> Find all in-directed paths to `josh`.
+<5> Find all shortest paths from `marko` to `josh`.
+<6> Find all shortest paths from `marko` to `josh` using a custom distance property.
+<7> Find all shortest paths from `marko` to `josh` and include edges in the result.
+
+[gremlin-groovy,modern]
+----
+g.inject(g.withComputer().V().shortestPath().
+           with(ShortestPath.distance, 'weight').
+           with(ShortestPath.includeEdges, true).
+           with(ShortestPath.maxDistance, 1).toList().toArray()).
+  map(unfold().values('name','weight').fold()) <1>
+----
+
+<1> Find all shortest paths using a custom distance property and limit the distance to 1. Inject the result into a OLTP `GraphTraversal` in order to be able to select properties from all elements in all paths.
+
+*Additional References*
+
+link:++http://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#shortestPath--++[`shortestPath()`]
+
 [[simplepath-step]]
 === SimplePath Step
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreImports.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreImports.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreImports.java
index 72ad47a..9830cdd 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreImports.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreImports.java
@@ -47,10 +47,12 @@ import org.apache.tinkerpop.gremlin.process.computer.clustering.peerpressure.Clu
 import org.apache.tinkerpop.gremlin.process.computer.clustering.peerpressure.PeerPressureVertexProgram;
 import org.apache.tinkerpop.gremlin.process.computer.ranking.pagerank.PageRankMapReduce;
 import org.apache.tinkerpop.gremlin.process.computer.ranking.pagerank.PageRankVertexProgram;
+import org.apache.tinkerpop.gremlin.process.computer.search.path.ShortestPathVertexProgram;
 import org.apache.tinkerpop.gremlin.process.computer.traversal.MemoryTraversalSideEffects;
 import org.apache.tinkerpop.gremlin.process.computer.traversal.TraversalVertexProgram;
 import org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.PageRank;
 import org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.PeerPressure;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.ShortestPath;
 import org.apache.tinkerpop.gremlin.process.computer.traversal.strategy.decoration.VertexProgramStrategy;
 import org.apache.tinkerpop.gremlin.process.computer.traversal.strategy.optimization.GraphFilterStrategy;
 import org.apache.tinkerpop.gremlin.process.remote.RemoteConnection;
@@ -268,6 +270,8 @@ public final class CoreImports {
         CLASS_IMPORTS.add(PageRank.class);
         CLASS_IMPORTS.add(PageRankMapReduce.class);
         CLASS_IMPORTS.add(PageRankVertexProgram.class);
+        CLASS_IMPORTS.add(ShortestPath.class);
+        CLASS_IMPORTS.add(ShortestPathVertexProgram.class);
         CLASS_IMPORTS.add(GraphFilterStrategy.class);
         CLASS_IMPORTS.add(TraversalVertexProgram.class);
         CLASS_IMPORTS.add(VertexProgramStrategy.class);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/search/path/ShortestPathVertexProgram.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/search/path/ShortestPathVertexProgram.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/search/path/ShortestPathVertexProgram.java
new file mode 100644
index 0000000..1949c53
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/search/path/ShortestPathVertexProgram.java
@@ -0,0 +1,611 @@
+/*
+ * 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.process.computer.search.path;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.tinkerpop.gremlin.process.computer.GraphComputer;
+import org.apache.tinkerpop.gremlin.process.computer.Memory;
+import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
+import org.apache.tinkerpop.gremlin.process.computer.MessageScope;
+import org.apache.tinkerpop.gremlin.process.computer.Messenger;
+import org.apache.tinkerpop.gremlin.process.computer.VertexComputeKey;
+import org.apache.tinkerpop.gremlin.process.computer.VertexProgram;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.TraversalVertexProgram;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.ProgramVertexProgramStep;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.VertexProgramStep;
+import org.apache.tinkerpop.gremlin.process.computer.util.AbstractVertexProgramBuilder;
+import org.apache.tinkerpop.gremlin.process.traversal.Operator;
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ImmutablePath;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.IndexedTraverserSet;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
+import org.apache.tinkerpop.gremlin.process.traversal.util.PureTraversal;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Element;
+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.util.StringFactory;
+import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceFactory;
+import org.apache.tinkerpop.gremlin.util.NumberHelper;
+import org.javatuples.Pair;
+import org.javatuples.Triplet;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+
+/**
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public class ShortestPathVertexProgram implements VertexProgram<Triplet<Path, Edge, Number>> {
+
+    @SuppressWarnings("WeakerAccess")
+    public static final String SHORTEST_PATHS = "gremlin.shortestPathVertexProgram.shortestPaths";
+
+    private static final String SOURCE_VERTEX_FILTER = "gremlin.shortestPathVertexProgram.sourceVertexFilter";
+    private static final String TARGET_VERTEX_FILTER = "gremlin.shortestPathVertexProgram.targetVertexFilter";
+    private static final String EDGE_TRAVERSAL = "gremlin.shortestPathVertexProgram.edgeTraversal";
+    private static final String DISTANCE_TRAVERSAL = "gremlin.shortestPathVertexProgram.distanceTraversal";
+    private static final String MAX_DISTANCE = "gremlin.shortestPathVertexProgram.maxDistance";
+    private static final String INCLUDE_EDGES = "gremlin.shortestPathVertexProgram.includeEdges";
+
+    private static final String STATE = "gremlin.shortestPathVertexProgram.state";
+    private static final String PATHS = "gremlin.shortestPathVertexProgram.paths";
+    private static final String VOTE_TO_HALT = "gremlin.shortestPathVertexProgram.voteToHalt";
+
+    private static final int SEARCH = 0;
+    private static final int COLLECT_PATHS = 1;
+    private static final int UPDATE_HALTED_TRAVERSERS = 2;
+
+    public static final PureTraversal<Vertex, ?> DEFAULT_VERTEX_FILTER_TRAVERSAL = new PureTraversal<>(
+            __.<Vertex> identity().asAdmin()); // todo: new IdentityTraversal<>()
+    public static final PureTraversal<Vertex, Edge> DEFAULT_EDGE_TRAVERSAL = new PureTraversal<>(__.bothE().asAdmin());
+    public static final PureTraversal<Edge, Number> DEFAULT_DISTANCE_TRAVERSAL = new PureTraversal<>(
+            __.<Edge> start().<Number> constant(1).asAdmin()); // todo: new ConstantTraversal<>(1)
+
+    private TraverserSet<Vertex> haltedTraversers;
+    private IndexedTraverserSet<Vertex, Vertex> haltedTraversersIndex;
+    private PureTraversal<?, ?> traversal;
+    private PureTraversal<Vertex, ?> sourceVertexFilterTraversal = DEFAULT_VERTEX_FILTER_TRAVERSAL.clone();
+    private PureTraversal<Vertex, ?> targetVertexFilterTraversal = DEFAULT_VERTEX_FILTER_TRAVERSAL.clone();
+    private PureTraversal<Vertex, Edge> edgeTraversal = DEFAULT_EDGE_TRAVERSAL.clone();
+    private PureTraversal<Edge, Number> distanceTraversal = DEFAULT_DISTANCE_TRAVERSAL.clone();
+    private Step<Vertex, Path> programStep;
+    private Number maxDistance;
+    private boolean distanceEqualsNumberOfHops;
+    private boolean includeEdges;
+    private boolean standalone;
+
+    private static final Set<VertexComputeKey> VERTEX_COMPUTE_KEYS = new HashSet<>(Arrays.asList(
+            VertexComputeKey.of(PATHS, true),
+            VertexComputeKey.of(TraversalVertexProgram.HALTED_TRAVERSERS, false)));
+
+    private final Set<MemoryComputeKey> memoryComputeKeys = new HashSet<>(Arrays.asList(
+            MemoryComputeKey.of(VOTE_TO_HALT, Operator.and, false, true),
+            MemoryComputeKey.of(STATE, Operator.assign, true, true)));
+
+    private ShortestPathVertexProgram() {
+
+    }
+
+    @Override
+    public void loadState(final Graph graph, final Configuration configuration) {
+
+        if (configuration.containsKey(SOURCE_VERTEX_FILTER))
+            this.sourceVertexFilterTraversal = PureTraversal.loadState(configuration, SOURCE_VERTEX_FILTER, graph);
+
+        if (configuration.containsKey(TARGET_VERTEX_FILTER))
+            this.targetVertexFilterTraversal = PureTraversal.loadState(configuration, TARGET_VERTEX_FILTER, graph);
+
+        if (configuration.containsKey(EDGE_TRAVERSAL))
+            this.edgeTraversal = PureTraversal.loadState(configuration, EDGE_TRAVERSAL, graph);
+
+        if (configuration.containsKey(DISTANCE_TRAVERSAL))
+            this.distanceTraversal = PureTraversal.loadState(configuration, DISTANCE_TRAVERSAL, graph);
+
+        if (configuration.containsKey(MAX_DISTANCE))
+            this.maxDistance = (Number) configuration.getProperty(MAX_DISTANCE);
+
+        this.distanceEqualsNumberOfHops = this.distanceTraversal.equals(DEFAULT_DISTANCE_TRAVERSAL);
+        this.includeEdges = configuration.getBoolean(INCLUDE_EDGES, false);
+        this.standalone = !configuration.containsKey(VertexProgramStep.ROOT_TRAVERSAL);
+
+        if (!this.standalone) {
+            this.traversal = PureTraversal.loadState(configuration, VertexProgramStep.ROOT_TRAVERSAL, graph);
+            final String programStepId = configuration.getString(ProgramVertexProgramStep.STEP_ID);
+            for (final Step step : this.traversal.get().getSteps()) {
+                if (step.getId().equals(programStepId)) {
+                    //noinspection unchecked
+                    this.programStep = step;
+                    break;
+                }
+            }
+        }
+
+        // restore halted traversers from the configuration and build an index for direct access
+        this.haltedTraversers = TraversalVertexProgram.loadHaltedTraversers(configuration);
+        this.haltedTraversersIndex = new IndexedTraverserSet<>(v -> v);
+        for (final Traverser.Admin<Vertex> traverser : this.haltedTraversers) {
+            this.haltedTraversersIndex.add(traverser.split());
+        }
+        this.memoryComputeKeys.add(MemoryComputeKey.of(SHORTEST_PATHS, Operator.addAll, true, !standalone));
+    }
+
+    @Override
+    public void storeState(final Configuration configuration) {
+        VertexProgram.super.storeState(configuration);
+        this.sourceVertexFilterTraversal.storeState(configuration, SOURCE_VERTEX_FILTER);
+        this.targetVertexFilterTraversal.storeState(configuration, TARGET_VERTEX_FILTER);
+        this.edgeTraversal.storeState(configuration, EDGE_TRAVERSAL);
+        this.distanceTraversal.storeState(configuration, DISTANCE_TRAVERSAL);
+        configuration.setProperty(INCLUDE_EDGES, this.includeEdges);
+        if (this.maxDistance != null)
+            configuration.setProperty(MAX_DISTANCE, maxDistance);
+        if (this.traversal != null) {
+            this.traversal.storeState(configuration, ProgramVertexProgramStep.ROOT_TRAVERSAL);
+            configuration.setProperty(ProgramVertexProgramStep.STEP_ID, this.programStep.getId());
+        }
+        TraversalVertexProgram.storeHaltedTraversers(configuration, this.haltedTraversers);
+    }
+
+    @Override
+    public Set<VertexComputeKey> getVertexComputeKeys() {
+        return VERTEX_COMPUTE_KEYS;
+    }
+
+    @Override
+    public Set<MemoryComputeKey> getMemoryComputeKeys() {
+        return memoryComputeKeys;
+    }
+
+    @Override
+    public Set<MessageScope> getMessageScopes(final Memory memory) {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public VertexProgram<Triplet<Path, Edge, Number>> clone() {
+        try {
+            final ShortestPathVertexProgram clone = (ShortestPathVertexProgram) super.clone();
+            if (null != this.edgeTraversal)
+                clone.edgeTraversal = this.edgeTraversal.clone();
+            if (null != this.sourceVertexFilterTraversal)
+                clone.sourceVertexFilterTraversal = this.sourceVertexFilterTraversal.clone();
+            if (null != this.targetVertexFilterTraversal)
+                clone.targetVertexFilterTraversal = this.targetVertexFilterTraversal.clone();
+            if (null != this.distanceTraversal)
+                clone.distanceTraversal = this.distanceTraversal.clone();
+            if (null != this.traversal) {
+                clone.traversal = this.traversal.clone();
+                for (final Step step : clone.traversal.get().getSteps()) {
+                    if (step.getId().equals(this.programStep.getId())) {
+                        //noinspection unchecked
+                        clone.programStep = step;
+                        break;
+                    }
+                }
+            }
+            return clone;
+        } catch (final CloneNotSupportedException e) {
+            throw new IllegalStateException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public GraphComputer.ResultGraph getPreferredResultGraph() {
+        return GraphComputer.ResultGraph.ORIGINAL;
+    }
+
+    @Override
+    public GraphComputer.Persist getPreferredPersist() {
+        return GraphComputer.Persist.NOTHING;
+    }
+
+    @Override
+    public void setup(final Memory memory) {
+        memory.set(VOTE_TO_HALT, true);
+        memory.set(STATE, SEARCH);
+    }
+
+    @Override
+    public void execute(final Vertex vertex, final Messenger<Triplet<Path, Edge, Number>> messenger, final Memory memory) {
+
+        switch (memory.<Integer>get(STATE)) {
+
+            case COLLECT_PATHS:
+                collectShortestPaths(vertex, memory);
+                return;
+
+            case UPDATE_HALTED_TRAVERSERS:
+                updateHaltedTraversers(vertex, memory);
+                return;
+        }
+
+        boolean voteToHalt = true;
+
+        if (memory.isInitialIteration()) {
+
+            // Use the first iteration to copy halted traversers from the halted traverser index to the respective
+            // vertices. This way the rest of the code can be simplified and always expect the HALTED_TRAVERSERS
+            // property to be available (if halted traversers exist for this vertex).
+            copyHaltedTraversersFromMemory(vertex);
+
+            // ignore vertices that don't pass the start-vertex filter
+            if (!isStartVertex(vertex)) return;
+
+            // start to track paths for all valid start-vertices
+            final Map<Vertex, Pair<Number, Set<Path>>> paths = new HashMap<>();
+            final Path path;
+            final Set<Path> pathSet = new HashSet<>();
+
+            pathSet.add(path = makePath(vertex));
+            paths.put(vertex, Pair.with(0, pathSet));
+
+            vertex.property(VertexProperty.Cardinality.single, PATHS, paths);
+
+            // send messages to valid adjacent vertices
+            processEdges(vertex, path, 0, messenger);
+
+            voteToHalt = false;
+
+        } else {
+
+            // load existing paths to this vertex and extend them based on messages received from adjacent vertices
+            final Map<Vertex, Pair<Number, Set<Path>>> paths =
+                    vertex.<Map<Vertex, Pair<Number, Set<Path>>>>property(PATHS).orElseGet(HashMap::new);
+            final Iterator<Triplet<Path, Edge, Number>> iterator = messenger.receiveMessages();
+
+            while (iterator.hasNext()) {
+
+                final Triplet<Path, Edge, Number> triplet = iterator.next();
+                final Path sourcePath = triplet.getValue0();
+                final Number distance = triplet.getValue2();
+                final Vertex sourceVertex = sourcePath.get(0);
+
+                Path newPath = null;
+
+                // already know a path coming from this source vertex?
+                if (paths.containsKey(sourceVertex)) {
+
+                    final Number currentShortestDistance = paths.get(sourceVertex).getValue0();
+                    final int cmp = NumberHelper.compare(distance, currentShortestDistance);
+
+                    if (cmp <= 0) {
+                        newPath = extendPath(sourcePath, triplet.getValue1(), vertex);
+                        if (cmp < 0) {
+                            // if the path length is smaller than the current shortest path's length, replace the
+                            // current set of shortest paths
+                            final Set<Path> pathSet = new HashSet<>();
+                            pathSet.add(newPath);
+                            paths.put(sourceVertex, Pair.with(distance, pathSet));
+                        } else {
+                            // if the path length is equal to the current shortest path's length, add the new path
+                            // to the set of shortest paths
+                            paths.get(sourceVertex).getValue1().add(newPath);
+                        }
+                    }
+                } else if (!exceedsMaxDistance(distance)) {
+                    // store the new path as the shortest path from the source vertex to the current vertex
+                    final Set<Path> pathSet = new HashSet<>();
+                    pathSet.add(newPath = extendPath(sourcePath, triplet.getValue1(), vertex));
+                    paths.put(sourceVertex, Pair.with(distance, pathSet));
+                }
+
+                // if a new path was found, send messages to adjacent vertices, otherwise do nothing as there's no
+                // chance to find any new paths going forward
+                if (newPath != null) {
+                    vertex.property(VertexProperty.Cardinality.single, PATHS, paths);
+                    processEdges(vertex, newPath, distance, messenger);
+                    voteToHalt = false;
+                }
+            }
+        }
+
+        // VOTE_TO_HALT will be set to true if an iteration hasn't found any new paths
+        memory.add(VOTE_TO_HALT, voteToHalt);
+    }
+
+    @Override
+    public boolean terminate(final Memory memory) {
+        if (memory.isInitialIteration() && this.haltedTraversersIndex != null) {
+            this.haltedTraversersIndex.clear();
+        }
+        final boolean voteToHalt = memory.get(VOTE_TO_HALT);
+        if (voteToHalt) {
+            final int state = memory.get(STATE);
+            if (state == COLLECT_PATHS) {
+                // After paths were collected,
+                // a) the VP is done in standalone mode (paths will be in memory) or
+                // b) the halted traversers will be updated in order to have the paths available in the traversal
+                if (this.standalone) return true;
+                memory.set(STATE, UPDATE_HALTED_TRAVERSERS);
+                return false;
+            }
+            if (state == UPDATE_HALTED_TRAVERSERS) return true;
+            else memory.set(STATE, COLLECT_PATHS); // collect paths if no new paths were found
+            return false;
+        } else {
+            memory.set(VOTE_TO_HALT, true);
+            return false;
+        }
+    }
+
+    @Override
+    public String toString() {
+
+        final List<String> options = new ArrayList<>();
+        final Function<String, String> shortName = name -> name.substring(name.lastIndexOf(".") + 1);
+
+        if (!this.sourceVertexFilterTraversal.equals(DEFAULT_VERTEX_FILTER_TRAVERSAL)) {
+            options.add(shortName.apply(SOURCE_VERTEX_FILTER) + "=" + this.sourceVertexFilterTraversal.get());
+        }
+
+        if (!this.targetVertexFilterTraversal.equals(DEFAULT_VERTEX_FILTER_TRAVERSAL)) {
+            options.add(shortName.apply(TARGET_VERTEX_FILTER) + "=" + this.targetVertexFilterTraversal.get());
+        }
+
+        if (!this.edgeTraversal.equals(DEFAULT_EDGE_TRAVERSAL)) {
+            options.add(shortName.apply(EDGE_TRAVERSAL) + "=" + this.edgeTraversal.get());
+        }
+
+        if (!this.distanceTraversal.equals(DEFAULT_DISTANCE_TRAVERSAL)) {
+            options.add(shortName.apply(DISTANCE_TRAVERSAL) + "=" + this.distanceTraversal.get());
+        }
+
+        options.add(shortName.apply(INCLUDE_EDGES) + "=" + this.includeEdges);
+
+        return StringFactory.vertexProgramString(this, String.join(", ", options));
+    }
+
+    //////////////////////////////
+
+    private void copyHaltedTraversersFromMemory(final Vertex vertex) {
+        final Collection<Traverser.Admin<Vertex>> traversers = this.haltedTraversersIndex.get(vertex);
+        if (traversers != null) {
+            final TraverserSet<Vertex> newHaltedTraversers = new TraverserSet<>();
+            newHaltedTraversers.addAll(traversers);
+            vertex.property(VertexProperty.Cardinality.single, TraversalVertexProgram.HALTED_TRAVERSERS, newHaltedTraversers);
+        }
+    }
+
+
+    private static Path makePath(final Vertex newVertex) {
+        return extendPath(null, newVertex);
+    }
+
+    private static Path extendPath(final Path currentPath, final Element... elements) {
+        Path result = ImmutablePath.make();
+        if (currentPath != null) {
+            for (final Object o : currentPath.objects()) {
+                result = result.extend(o, Collections.emptySet());
+            }
+        }
+        for (final Element element : elements) {
+            if (element != null) {
+                result = result.extend(ReferenceFactory.detach(element), Collections.emptySet());
+            }
+        }
+        return result;
+    }
+
+    private boolean isStartVertex(final Vertex vertex) {
+        // use the sourceVertexFilterTraversal if the VP is running in standalone mode (not part of a traversal)
+        if (this.standalone) {
+            final Traversal.Admin<Vertex, ?> filterTraversal = this.sourceVertexFilterTraversal.getPure();
+            filterTraversal.addStart(filterTraversal.getTraverserGenerator().generate(vertex, filterTraversal.getStartStep(), 1));
+            return filterTraversal.hasNext();
+        }
+        // ...otherwise use halted traversers to determine whether this is a start vertex
+        return vertex.property(TraversalVertexProgram.HALTED_TRAVERSERS).isPresent();
+    }
+
+    private boolean isEndVertex(final Vertex vertex) {
+        final Traversal.Admin<Vertex, ?> filterTraversal = this.targetVertexFilterTraversal.getPure();
+        //noinspection unchecked
+        final Step<Vertex, Vertex> startStep = (Step<Vertex, Vertex>) filterTraversal.getStartStep();
+        filterTraversal.addStart(filterTraversal.getTraverserGenerator().generate(vertex, startStep, 1));
+        return filterTraversal.hasNext();
+    }
+
+    private void processEdges(final Vertex vertex, final Path currentPath, final Number currentDistance,
+                              final Messenger<Triplet<Path, Edge, Number>> messenger) {
+
+        final Traversal.Admin<Vertex, Edge> edgeTraversal = this.edgeTraversal.getPure();
+        edgeTraversal.addStart(edgeTraversal.getTraverserGenerator().generate(vertex, edgeTraversal.getStartStep(), 1));
+
+        while (edgeTraversal.hasNext()) {
+            final Edge edge = edgeTraversal.next();
+            final Number distance = getDistance(edge);
+
+            Vertex otherV = edge.inVertex();
+            if (otherV.equals(vertex))
+                otherV = edge.outVertex();
+
+            // only send message if the adjacent vertex is not yet part of the current path
+            if (!currentPath.objects().contains(otherV)) {
+                messenger.sendMessage(MessageScope.Global.of(otherV),
+                        Triplet.with(currentPath, this.includeEdges ? edge : null,
+                                NumberHelper.add(currentDistance, distance)));
+            }
+        }
+    }
+
+    private void updateHaltedTraversers(final Vertex vertex, final Memory memory) {
+        if (isStartVertex(vertex)) {
+            final List<Path> paths = memory.get(SHORTEST_PATHS);
+            if (vertex.property(TraversalVertexProgram.HALTED_TRAVERSERS).isPresent()) {
+                // replace the current set of halted traversers with new new traversers that hold the shortest paths
+                // found for this vertex
+                final TraverserSet<Vertex> haltedTraversers = vertex.value(TraversalVertexProgram.HALTED_TRAVERSERS);
+                final TraverserSet<Path> newHaltedTraversers = new TraverserSet<>();
+                for (final Traverser.Admin<Vertex> traverser : haltedTraversers) {
+                    final Vertex v = traverser.get();
+                    for (final Path path : paths) {
+                        if (path.get(0).equals(v)) {
+                            newHaltedTraversers.add(traverser.split(path, this.programStep));
+                        }
+                    }
+                }
+                vertex.property(VertexProperty.Cardinality.single, TraversalVertexProgram.HALTED_TRAVERSERS, newHaltedTraversers);
+            }
+        }
+    }
+
+    private Number getDistance(final Edge edge) {
+        if (this.distanceEqualsNumberOfHops) return 1;
+        final Traversal.Admin<Edge, Number> traversal = this.distanceTraversal.getPure();
+        traversal.addStart(traversal.getTraverserGenerator().generate(edge, traversal.getStartStep(), 1));
+        return traversal.tryNext().orElse(0);
+    }
+
+    private boolean exceedsMaxDistance(final Number distance) {
+        // This method is used to stop the message sending for paths that exceed the specified maximum distance. Since
+        // custom distances can be negative, this method should only return true if the distance is calculated based on
+        // the number of hops.
+        return this.distanceEqualsNumberOfHops && this.maxDistance != null
+                && NumberHelper.compare(distance, this.maxDistance) > 0;
+    }
+
+    /**
+     * Move any valid path into the VP's memory.
+     * @param vertex The current vertex.
+     * @param memory The VertexProgram's memory.
+     */
+    private void collectShortestPaths(final Vertex vertex, final Memory memory) {
+
+        final VertexProperty<Map<Vertex, Pair<Number, Set<Path>>>> pathProperty = vertex.property(PATHS);
+
+        if (pathProperty.isPresent()) {
+
+            final Map<Vertex, Pair<Number, Set<Path>>> paths = pathProperty.value();
+            final List<Path> result = new ArrayList<>();
+
+            for (final Pair<Number, Set<Path>> pair : paths.values()) {
+                for (final Path path : pair.getValue1()) {
+                    if (isEndVertex(vertex)) {
+                        if (this.distanceEqualsNumberOfHops ||
+                                this.maxDistance == null ||
+                                NumberHelper.compare(pair.getValue0(), this.maxDistance) <= 0) {
+                            result.add(path);
+                        }
+                    }
+                }
+            }
+
+            pathProperty.remove();
+
+            memory.add(SHORTEST_PATHS, result);
+        }
+    }
+
+    //////////////////////////////
+
+    public static Builder build() {
+        return new Builder();
+    }
+
+    @SuppressWarnings("WeakerAccess")
+    public static final class Builder extends AbstractVertexProgramBuilder<Builder> {
+
+
+        private Builder() {
+            super(ShortestPathVertexProgram.class);
+        }
+
+        public Builder source(final Traversal<Vertex, ?> sourceVertexFilter) {
+            if (null == sourceVertexFilter) throw Graph.Exceptions.argumentCanNotBeNull("sourceVertexFilter");
+            PureTraversal.storeState(this.configuration, SOURCE_VERTEX_FILTER, sourceVertexFilter.asAdmin());
+            return this;
+        }
+
+        public Builder target(final Traversal<Vertex, ?> targetVertexFilter) {
+            if (null == targetVertexFilter) throw Graph.Exceptions.argumentCanNotBeNull("targetVertexFilter");
+            PureTraversal.storeState(this.configuration, TARGET_VERTEX_FILTER, targetVertexFilter.asAdmin());
+            return this;
+        }
+
+        public Builder edgeDirection(final Direction direction) {
+            if (null == direction) throw Graph.Exceptions.argumentCanNotBeNull("direction");
+            return edgeTraversal(__.toE(direction));
+        }
+
+        public Builder edgeTraversal(final Traversal<Vertex, Edge> edgeTraversal) {
+            if (null == edgeTraversal) throw Graph.Exceptions.argumentCanNotBeNull("edgeTraversal");
+            PureTraversal.storeState(this.configuration, EDGE_TRAVERSAL, edgeTraversal.asAdmin());
+            return this;
+        }
+
+        public Builder distanceProperty(final String distance) {
+            //noinspection unchecked
+            return distance != null
+                    ? distanceTraversal(__.values(distance)) // todo: (Traversal) new ElementValueTraversal<>(distance)
+                    : distanceTraversal(DEFAULT_DISTANCE_TRAVERSAL.getPure());
+        }
+
+        public Builder distanceTraversal(final Traversal<Edge, Number> distanceTraversal) {
+            if (null == distanceTraversal) throw Graph.Exceptions.argumentCanNotBeNull("distanceTraversal");
+            PureTraversal.storeState(this.configuration, DISTANCE_TRAVERSAL, distanceTraversal.asAdmin());
+            return this;
+        }
+
+        public Builder maxDistance(final Number distance) {
+            if (null != distance)
+                this.configuration.setProperty(MAX_DISTANCE, distance);
+            else
+                this.configuration.clearProperty(MAX_DISTANCE);
+            return this;
+        }
+
+        public Builder includeEdges(final boolean include) {
+            this.configuration.setProperty(INCLUDE_EDGES, include);
+            return this;
+        }
+    }
+
+    ////////////////////////////
+
+    @Override
+    public Features getFeatures() {
+        return new Features() {
+            @Override
+            public boolean requiresGlobalMessageScopes() {
+                return true;
+            }
+
+            @Override
+            public boolean requiresVertexPropertyAddition() {
+                return true;
+            }
+        };
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/ShortestPath.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/ShortestPath.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/ShortestPath.java
new file mode 100644
index 0000000..b0d7815
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/ShortestPath.java
@@ -0,0 +1,108 @@
+/*
+ * 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.process.computer.traversal.step.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+
+/**
+ * Configuration options to be passed to the {@link GraphTraversal#with(String, Object)} step.
+ */
+public class ShortestPath {
+
+    /**
+     * Configures the traversal to use to filter the target vertices for all shortest paths.
+     */
+    public static final String target = Graph.Hidden.hide("tinkerpop.shortestPath.target");
+
+    /**
+     * Configures the direction or traversal to use to filter the edges traversed during the shortest path search phase.
+     */
+    public static final String edges = Graph.Hidden.hide("tinkerpop.shortestPath.edges");
+
+    /**
+     * Configures the edge property or traversal to use for shortest path distance calculations.
+     */
+    public static final String distance = Graph.Hidden.hide("tinkerpop.shortestPath.distance");
+
+    /**
+     * Configures the maximum distance for all shortest paths. Any path with a distance greater than the specified
+     * value will not be returned.
+     */
+    public static final String maxDistance = Graph.Hidden.hide("tinkerpop.shortestPath.maxDistance");
+
+    /**
+     * Configures the inclusion of edges in the shortest path computation result.
+     */
+    public static final String includeEdges = Graph.Hidden.hide("tinkerpop.shortestPath.includeEdges");
+
+    static boolean configure(final ShortestPathVertexProgramStep step, final String key, final Object value) {
+
+        if (target.equals(key)) {
+            if (value instanceof Traversal) {
+                step.setTargetVertexFilter((Traversal) value);
+                return true;
+            }
+            else throw new IllegalArgumentException("ShortestPath.target requires a Traversal as its argument");
+        }
+        else if (edges.equals(key)) {
+            if (value instanceof Traversal) {
+                step.setEdgeTraversal((Traversal) value);
+                return true;
+            }
+            else if (value instanceof Direction) {
+                step.setEdgeTraversal(__.toE((Direction) value));
+                return true;
+            }
+            else throw new IllegalArgumentException(
+                    "ShortestPath.edges requires a Traversal or a Direction as its argument");
+        }
+        else if (distance.equals(key)) {
+            if (value instanceof Traversal) {
+                step.setDistanceTraversal((Traversal) value);
+                return true;
+            }
+            else if (value instanceof String) {
+                // todo: new ElementValueTraversal((String) value)
+                step.setDistanceTraversal(__.values((String) value));
+                return true;
+            }
+            else throw new IllegalArgumentException(
+                    "ShortestPath.distance requires a Traversal or a property name as its argument");
+        }
+        else if (maxDistance.equals(key)) {
+            if (value instanceof Number) {
+                step.setMaxDistance((Number) value);
+                return true;
+            }
+            else throw new IllegalArgumentException("ShortestPath.maxDistance requires a Number as its argument");
+        }
+        else if (includeEdges.equals(key)) {
+            if (value instanceof Boolean) {
+                step.setIncludeEdges((Boolean) value);
+                return true;
+            }
+            else throw new IllegalArgumentException("ShortestPath.includeEdges requires a Boolean as its argument");
+        }
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/ShortestPathVertexProgramStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/ShortestPathVertexProgramStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/ShortestPathVertexProgramStep.java
new file mode 100644
index 0000000..e9a09e2
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/ShortestPathVertexProgramStep.java
@@ -0,0 +1,185 @@
+/*
+ * 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.process.computer.traversal.step.map;
+
+import org.apache.tinkerpop.gremlin.process.computer.ComputerResult;
+import org.apache.tinkerpop.gremlin.process.computer.GraphFilter;
+import org.apache.tinkerpop.gremlin.process.computer.Memory;
+import org.apache.tinkerpop.gremlin.process.computer.search.path.ShortestPathVertexProgram;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.TraversalVertexProgram;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Configuring;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Parameters;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
+import org.apache.tinkerpop.gremlin.process.traversal.util.PureTraversal;
+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.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.Serializer;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public final class ShortestPathVertexProgramStep extends VertexProgramStep implements TraversalParent, Configuring {
+
+    private Parameters parameters = new Parameters();
+    private PureTraversal<Vertex, ?> targetVertexFilter = ShortestPathVertexProgram.DEFAULT_VERTEX_FILTER_TRAVERSAL.clone();
+    private PureTraversal<Vertex, Edge> edgeTraversal = ShortestPathVertexProgram.DEFAULT_EDGE_TRAVERSAL.clone();
+    private PureTraversal<Edge, Number> distanceTraversal = ShortestPathVertexProgram.DEFAULT_DISTANCE_TRAVERSAL.clone();
+    private Number maxDistance;
+    private boolean includeEdges;
+
+    public ShortestPathVertexProgramStep(final Traversal.Admin<?, ?> traversal) {
+        super(traversal);
+    }
+
+    void setTargetVertexFilter(final Traversal filterTraversal) {
+        this.targetVertexFilter = new PureTraversal<>(this.integrateChild(filterTraversal.asAdmin()));
+    }
+
+    void setEdgeTraversal(final Traversal edgeTraversal) {
+        this.edgeTraversal = new PureTraversal<>(this.integrateChild(edgeTraversal.asAdmin()));
+    }
+
+    void setDistanceTraversal(final Traversal distanceTraversal) {
+        this.distanceTraversal = new PureTraversal<>(this.integrateChild(distanceTraversal.asAdmin()));
+    }
+
+    void setMaxDistance(final Number maxDistance) {
+        this.maxDistance = maxDistance;
+    }
+
+    void setIncludeEdges(final boolean includeEdges) {
+        this.includeEdges = includeEdges;
+    }
+
+    @Override
+    public void configure(final Object... keyValues) {
+        if (!ShortestPath.configure(this, (String) keyValues[0], keyValues[1])) {
+            this.parameters.set(this, keyValues);
+        }
+    }
+
+    @Override
+    public Parameters getParameters() {
+        return parameters;
+    }
+
+    @Override
+    protected Traverser.Admin<ComputerResult> processNextStart() throws NoSuchElementException {
+        return super.processNextStart();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public List<Traversal.Admin<?, ?>> getLocalChildren() {
+        return Arrays.asList(
+                this.targetVertexFilter.get(),
+                this.edgeTraversal.get(),
+                this.distanceTraversal.get());
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.stepString(this, this.targetVertexFilter.get(), this.edgeTraversal.get(),
+                this.distanceTraversal.get(), this.maxDistance, this.includeEdges, new GraphFilter(this.computer));
+    }
+
+    @Override
+    public ShortestPathVertexProgram generateProgram(final Graph graph, final Memory memory) {
+
+        final ShortestPathVertexProgram.Builder builder = ShortestPathVertexProgram.build()
+                .target(this.targetVertexFilter.getPure())
+                .edgeTraversal(this.edgeTraversal.getPure())
+                .distanceTraversal(this.distanceTraversal.getPure())
+                .maxDistance(this.maxDistance)
+                .includeEdges(this.includeEdges);
+
+        //noinspection unchecked
+        final PureTraversal pureRootTraversal = new PureTraversal<>(this.traversal);
+        Object rootTraversalValue;
+        try {
+            rootTraversalValue = Base64.getEncoder().encodeToString(Serializer.serializeObject(pureRootTraversal));
+        } catch (final IOException ignored) {
+            rootTraversalValue = pureRootTraversal;
+        }
+
+        builder.configure(
+                ProgramVertexProgramStep.ROOT_TRAVERSAL, rootTraversalValue,
+                ProgramVertexProgramStep.STEP_ID, this.id);
+
+        // There are two locations in which halted traversers can be stored: in memory or as vertex properties. In the
+        // former case they need to be copied to this VertexProgram's configuration as the VP won't have access to the
+        // previous VP's memory.
+        if (memory.exists(TraversalVertexProgram.HALTED_TRAVERSERS)) {
+            final TraverserSet<?> haltedTraversers = memory.get(TraversalVertexProgram.HALTED_TRAVERSERS);
+            if (!haltedTraversers.isEmpty()) {
+                Object haltedTraversersValue;
+                try {
+                    haltedTraversersValue = Base64.getEncoder().encodeToString(Serializer.serializeObject(haltedTraversers));
+                } catch (final IOException ignored) {
+                    haltedTraversersValue = haltedTraversers;
+                }
+                builder.configure(TraversalVertexProgram.HALTED_TRAVERSERS, haltedTraversersValue);
+            }
+        }
+
+        return builder.create(graph);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return TraversalParent.super.getSelfAndChildRequirements();
+    }
+
+    @Override
+    public ShortestPathVertexProgramStep clone() {
+        final ShortestPathVertexProgramStep clone = (ShortestPathVertexProgramStep) super.clone();
+        clone.targetVertexFilter = this.targetVertexFilter.clone();
+        clone.edgeTraversal = this.edgeTraversal.clone();
+        clone.distanceTraversal = this.distanceTraversal.clone();
+        return clone;
+    }
+
+    @Override
+    public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+        super.setTraversal(parentTraversal);
+        this.integrateChild(this.targetVertexFilter.get());
+        this.integrateChild(this.edgeTraversal.get());
+        this.integrateChild(this.distanceTraversal.get());
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode();
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
index f19d5fa..eaced7a 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
@@ -72,6 +72,10 @@ import java.util.Iterator;
         method = "*",
         reason = "RemoteGraph does not support direct Graph.compute() access")
 @Graph.OptOut(
+        test = "org.apache.tinkerpop.gremlin.process.computer.search.path.ShortestPathVertexProgramTest",
+        method = "*",
+        reason = "RemoteGraph does not support direct Graph.compute() access")
+@Graph.OptOut(
         test = "org.apache.tinkerpop.gremlin.process.computer.bulkloading.BulkLoaderVertexProgramTest",
         method = "*",
         reason = "RemoteGraph does not support direct Graph.compute() access")

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java
index 220c995..30435ab 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java
@@ -496,15 +496,17 @@ public interface Traversal<S, E> extends Iterator<E>, Serializable, Cloneable, A
         public void setGraph(final Graph graph);
 
         public default boolean equals(final Traversal.Admin<S, E> other) {
-            final List<Step> steps = this.getSteps();
-            final List<Step> otherSteps = other.getSteps();
-            if (steps.size() == otherSteps.size()) {
-                for (int i = 0; i < steps.size(); i++) {
-                    if (!steps.get(i).equals(otherSteps.get(i))) {
-                        return false;
+            if (this.getClass().equals(other.getClass())) {
+                final List<Step> steps = this.getSteps();
+                final List<Step> otherSteps = other.getSteps();
+                if (steps.size() == otherSteps.size()) {
+                    for (int i = 0; i < steps.size(); i++) {
+                        if (!steps.get(i).equals(otherSteps.get(i))) {
+                            return false;
+                        }
                     }
+                    return true;
                 }
-                return true;
             }
             return false;
         }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
index a675ad1..593323c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -22,6 +22,7 @@ import org.apache.tinkerpop.gremlin.process.computer.VertexProgram;
 import org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.PageRankVertexProgramStep;
 import org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.PeerPressureVertexProgramStep;
 import org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.ProgramVertexProgramStep;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.ShortestPathVertexProgramStep;
 import org.apache.tinkerpop.gremlin.process.traversal.Order;
 import org.apache.tinkerpop.gremlin.process.traversal.P;
 import org.apache.tinkerpop.gremlin.process.traversal.Path;
@@ -2452,6 +2453,24 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
     }
 
     /**
+     * Executes a Shortest Path algorithm over the graph.
+     *
+     * @return the traversal with the appended {@link ShortestPathVertexProgramStep}
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#shortestpath-step" target="_blank">Reference Documentation - ShortestPath Step</a>
+     */
+    public default GraphTraversal<S, Path> shortestPath() {
+        if (this.asAdmin().getEndStep() instanceof GraphStep) {
+            // This is very unfortunate, but I couldn't find another way to make it work. Without the additional
+            // IdentityStep, TraversalVertexProgram doesn't handle halted traversers as expected (it ignores both:
+            // HALTED_TRAVERSER stored in memory and stored as vertex properties); instead it just emits all vertices.
+            this.identity();
+        }
+        this.asAdmin().getBytecode().addStep(Symbols.shortestPath);
+        return (GraphTraversal<S, Path>) ((Traversal.Admin) this.asAdmin())
+                .addStep(new ShortestPathVertexProgramStep(this.asAdmin()));
+    }
+
+    /**
      * Executes an arbitrary {@link VertexProgram} over the graph.
      *
      * @return the traversal with the appended {@link ProgramVertexProgramStep}
@@ -2882,6 +2901,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
 
         public static final String pageRank = "pageRank";
         public static final String peerPressure = "peerPressure";
+        public static final String shortestPath = "shortestPath";
         public static final String program = "program";
 
         public static final String by = "by";

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ColumnTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ColumnTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ColumnTraversal.java
index 5023805..9e2f31c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ColumnTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ColumnTraversal.java
@@ -22,6 +22,8 @@ package org.apache.tinkerpop.gremlin.process.traversal.lambda;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.structure.Column;
 
+import java.util.Objects;
+
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
@@ -57,4 +59,10 @@ public final class ColumnTraversal extends AbstractLambdaTraversal {
     public int hashCode() {
         return this.getClass().hashCode() ^ this.column.hashCode();
     }
+
+    @Override
+    public boolean equals(final Object other) {
+        return other instanceof ColumnTraversal
+                && Objects.equals(((ColumnTraversal) other).column, this.column);
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ConstantTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ConstantTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ConstantTraversal.java
index 91973b9..bcf82d4 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ConstantTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ConstantTraversal.java
@@ -18,6 +18,8 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.lambda;
 
+import java.util.Objects;
+
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
@@ -43,5 +45,10 @@ public final class ConstantTraversal<S, E> extends AbstractLambdaTraversal<S, E>
     public int hashCode() {
         return this.getClass().hashCode() ^ this.end.hashCode();
     }
-}
 
+    @Override
+    public boolean equals(final Object other) {
+        return other instanceof ConstantTraversal
+                && Objects.equals(((ConstantTraversal) other).end, this.end);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ElementValueTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ElementValueTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ElementValueTraversal.java
index 2e9b26c..fbfff62 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ElementValueTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ElementValueTraversal.java
@@ -22,6 +22,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
 import org.apache.tinkerpop.gremlin.structure.Element;
 
+import java.util.Objects;
+
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
@@ -62,4 +64,10 @@ public final class ElementValueTraversal<V> extends AbstractLambdaTraversal<Elem
     public int hashCode() {
         return super.hashCode() ^ this.propertyKey.hashCode();
     }
-}
+
+    @Override
+    public boolean equals(final Object other) {
+        return other instanceof ElementValueTraversal
+                && Objects.equals(((ElementValueTraversal) other).propertyKey, this.propertyKey);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/IdentityTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/IdentityTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/IdentityTraversal.java
index 98f85c0..1ed5749 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/IdentityTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/IdentityTraversal.java
@@ -41,4 +41,9 @@ public final class IdentityTraversal<S> extends AbstractLambdaTraversal<S, S> {
     public String toString() {
         return "identity";
     }
-}
+
+    @Override
+    public boolean equals(final Object other) {
+        return other instanceof IdentityTraversal;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/LoopTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/LoopTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/LoopTraversal.java
index ae03c94..68b6b18 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/LoopTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/LoopTraversal.java
@@ -55,4 +55,10 @@ public final class LoopTraversal<S> extends AbstractLambdaTraversal<S, S> {
     public int hashCode() {
         return this.getClass().hashCode() ^ Long.hashCode(this.maxLoops);
     }
+
+    @Override
+    public boolean equals(final Object other) {
+        return other instanceof LoopTraversal
+                && ((LoopTraversal) other).maxLoops == this.maxLoops;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/TokenTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/TokenTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/TokenTraversal.java
index 4f98a54..d41c402 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/TokenTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/TokenTraversal.java
@@ -22,6 +22,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.structure.Element;
 import org.apache.tinkerpop.gremlin.structure.T;
 
+import java.util.Objects;
+
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
@@ -57,4 +59,10 @@ public final class TokenTraversal<S extends Element, E> extends AbstractLambdaTr
     public int hashCode() {
         return this.getClass().hashCode() ^ this.t.hashCode();
     }
+
+    @Override
+    public boolean equals(final Object other) {
+        return other instanceof TokenTraversal
+                && Objects.equals(((TokenTraversal) other).t, this.t);
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/TrueTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/TrueTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/TrueTraversal.java
index 84c0db6..71580ce 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/TrueTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/TrueTraversal.java
@@ -43,4 +43,9 @@ public final class TrueTraversal<S> extends AbstractLambdaTraversal<S, S> {
     public TrueTraversal<S> clone() {
         return INSTANCE;
     }
+
+    @Override
+    public boolean equals(final Object other) {
+        return other instanceof TrueTraversal;
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/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 2e795a5..1bccd7c 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
@@ -129,7 +129,7 @@ abstract class GraphSONModule extends TinkerPopJacksonModule {
                     put(List.class, "List");
                     put(Set.class, "Set");
 
-                    // Tinkerpop Graph objects
+                    // TinkerPop Graph objects
                     put(Lambda.class, "Lambda");
                     put(Vertex.class, "Vertex");
                     put(Edge.class, "Edge");

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java
index e7dfd93..6d55704 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java
@@ -114,10 +114,10 @@ import org.apache.tinkerpop.gremlin.util.function.MultiComparator;
 import org.apache.tinkerpop.shaded.kryo.ClassResolver;
 import org.apache.tinkerpop.shaded.kryo.KryoSerializable;
 import org.apache.tinkerpop.shaded.kryo.serializers.JavaSerializer;
-import org.javatuples.Pair;
 import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.LabelledCounter;
 import org.apache.commons.collections.map.ReferenceMap;
-import java.util.Stack;
+import org.javatuples.Pair;
+import org.javatuples.Triplet;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -154,6 +154,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Optional;
+import java.util.Stack;
 import java.util.TimeZone;
 import java.util.TreeMap;
 import java.util.TreeSet;
@@ -356,6 +357,7 @@ public enum GryoVersion {
             add(GryoTypeReg.of(MapReduce.NullObject.class, 74));
             add(GryoTypeReg.of(AtomicLong.class, 79));
             add(GryoTypeReg.of(Pair.class, 88, new UtilSerializers.PairSerializer()));
+            add(GryoTypeReg.of(Triplet.class, 183, new UtilSerializers.TripletSerializer()));                 // ***LAST ID***
             add(GryoTypeReg.of(TraversalExplanation.class, 106, new JavaSerializer()));
 
             add(GryoTypeReg.of(Duration.class, 93, new JavaTimeSerializers.DurationSerializer()));
@@ -393,8 +395,7 @@ public enum GryoVersion {
             add(GryoTypeReg.of(LP_NL_O_OB_P_S_SE_SL_Traverser.class, 179));
             add(GryoTypeReg.of(LabelledCounter.class, 180));
             add(GryoTypeReg.of(Stack.class, 181));
-            add(GryoTypeReg.of(ReferenceMap.class, 182));                        // ***LAST ID***
-
+            add(GryoTypeReg.of(ReferenceMap.class, 182));
 
             // placeholder serializers for classes that don't live here in core. this will allow them to be used if
             // present  or ignored if the class isn't available. either way the registration numbers are held as
@@ -520,6 +521,7 @@ public enum GryoVersion {
             add(GryoTypeReg.of(MapReduce.NullObject.class, 74));
             add(GryoTypeReg.of(AtomicLong.class, 79));
             add(GryoTypeReg.of(Pair.class, 88, new UtilSerializers.PairSerializer()));
+            add(GryoTypeReg.of(Triplet.class, 183, new UtilSerializers.TripletSerializer()));                 // ***LAST ID***
             add(GryoTypeReg.of(TraversalExplanation.class, 106, new JavaSerializer()));
 
             add(GryoTypeReg.of(Duration.class, 93, new JavaTimeSerializers.DurationSerializer()));
@@ -583,7 +585,7 @@ public enum GryoVersion {
             add(GryoTypeReg.of(LP_NL_O_OB_P_S_SE_SL_Traverser.class, 179));
             add(GryoTypeReg.of(LabelledCounter.class, 180));
             add(GryoTypeReg.of(Stack.class, 181));
-            add(GryoTypeReg.of(ReferenceMap.class, 182));                        // ***LAST ID***
+            add(GryoTypeReg.of(ReferenceMap.class, 182));
         }};
     }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/UtilSerializers.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/UtilSerializers.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/UtilSerializers.java
index 5182e6c..aff6059 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/UtilSerializers.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/UtilSerializers.java
@@ -28,6 +28,7 @@ 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.javatuples.Pair;
+import org.javatuples.Triplet;
 
 import java.net.InetAddress;
 import java.net.URI;
@@ -216,6 +217,20 @@ final class UtilSerializers {
         }
     }
 
+    static final class TripletSerializer implements SerializerShim<Triplet> {
+        @Override
+        public <O extends OutputShim> void write(final KryoShim<?, O> kryo, final O output, final Triplet triplet) {
+            kryo.writeClassAndObject(output, triplet.getValue0());
+            kryo.writeClassAndObject(output, triplet.getValue1());
+            kryo.writeClassAndObject(output, triplet.getValue2());
+        }
+
+        @Override
+        public <I extends InputShim> Triplet read(final KryoShim<I, ?> kryo, final I input, final Class<Triplet> tripletClass) {
+            return Triplet.with(kryo.readClassAndObject(input), kryo.readClassAndObject(input), kryo.readClassAndObject(input));
+        }
+    }
+
     static final class EntrySerializer extends Serializer<Map.Entry> {
         @Override
         public void write(final Kryo kryo, final Output output, final Map.Entry entry) {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/Attachable.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/Attachable.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/Attachable.java
index fa999aa..3cd76f2 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/Attachable.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/Attachable.java
@@ -26,6 +26,7 @@ import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
 
 import java.util.Iterator;
 import java.util.Optional;
@@ -70,7 +71,7 @@ public interface Attachable<V> {
      */
     public static class Method {
         public static <V> Function<Attachable<V>, V> get(final Host hostVertexOrGraph) {
-            return (Attachable<V> attachable) -> {
+            return hostVertexOrGraph instanceof EmptyGraph ? Attachable::get : (Attachable<V> attachable) -> {
                 final Object base = attachable.get();
                 if (base instanceof Vertex) {
                     final Optional<Vertex> optional = hostVertexOrGraph instanceof Graph ?

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java
index 3d9a549..d1da36d 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java
@@ -43,7 +43,7 @@ import static org.junit.Assert.assertEquals;
 public class GraphTraversalTest {
     private static final Logger logger = LoggerFactory.getLogger(GraphTraversalTest.class);
 
-    private static Set<String> NO_GRAPH = new HashSet<>(Arrays.asList("asAdmin", "by", "read", "write", "with", "option", "iterate", "to", "from", "profile", "pageRank", "peerPressure", "program", "none"));
+    private static Set<String> NO_GRAPH = new HashSet<>(Arrays.asList("asAdmin", "by", "read", "write", "with", "option", "iterate", "to", "from", "profile", "pageRank", "peerPressure", "shortestPath", "program", "none"));
     private static Set<String> NO_ANONYMOUS = new HashSet<>(Arrays.asList("start", "__"));
     private static Set<String> IGNORES_BYTECODE = new HashSet<>(Arrays.asList("asAdmin", "read", "write", "iterate", "mapValues", "mapKeys"));
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
index 361b246..af78f20 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
@@ -1386,6 +1386,15 @@ namespace Gremlin.Net.Process.Traversal
         }
 
         /// <summary>
+        ///     Adds the shortestPath step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<S, Path> ShortestPath ()
+        {
+            Bytecode.AddStep("shortestPath");
+            return Wrap<S, Path>(this);
+        }
+
+        /// <summary>
         ///     Adds the sideEffect step to this <see cref="GraphTraversal{SType, EType}" />.
         /// </summary>
         public GraphTraversal<S, E> SideEffect (IConsumer consumer)

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
index 4f39fa5..6479515 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
@@ -953,6 +953,16 @@ class GraphTraversal extends Traversal {
   }
   
   /**
+   * Graph traversal shortestPath method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  shortestPath(...args) {
+    this.bytecode.addStep('shortestPath', args);
+    return this;
+  }
+  
+  /**
    * Graph traversal sideEffect method.
    * @param {...Object} args
    * @returns {GraphTraversal}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py b/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
index f8b8285..a249e24 100644
--- a/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
+++ b/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
@@ -434,6 +434,10 @@ class GraphTraversal(Traversal):
         self.bytecode.add_step("select", *args)
         return self
 
+    def shortestPath(self, *args):
+        self.bytecode.add_step("shortestPath", *args)
+        return self
+
     def sideEffect(self, *args):
         self.bytecode.add_step("sideEffect", *args)
         return self


[10/41] tinkerpop git commit: Added entry for docker on website CTR

Posted by dk...@apache.org.
Added entry for docker on website CTR


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

Branch: refs/heads/TINKERPOP-1990
Commit: b63bacf4bbc04d220fb9cb7f6d2983fa4c10bea6
Parents: 665daa7
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Sat Aug 4 06:16:48 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Sat Aug 4 06:16:48 2018 -0400

----------------------------------------------------------------------
 docs/site/home/downloads.html | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b63bacf4/docs/site/home/downloads.html
----------------------------------------------------------------------
diff --git a/docs/site/home/downloads.html b/docs/site/home/downloads.html
index 24195bc..c6bdf72 100644
--- a/docs/site/home/downloads.html
+++ b/docs/site/home/downloads.html
@@ -24,10 +24,11 @@ limitations under the License.
     <p>
      As a convenience, TinkerPop also deploys packaged artifacts to:
      <ul>
+       <li><a href="https://hub.docker.com/u/tinkerpop/">Docker</a></li>
        <li><a href="http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.apache.tinkerpop%22">Maven Central</a></li>
        <li><a href="https://pypi.python.org/pypi/gremlinpython/">PyPI</a></li>
-       <li><a href="https://www.nuget.org/packages/Gremlin.Net/">NuGet</a></li>
        <li><a href="https://www.npmjs.com/package/gremlin">npm</a></li>
+       <li><a href="https://www.nuget.org/packages/Gremlin.Net/">NuGet</a></li>
      </ul>
     </p>
     <br/>


[04/41] tinkerpop git commit: TINKERPOP-2005 Expand .* imports in ResponseStatusCodeTest

Posted by dk...@apache.org.
TINKERPOP-2005 Expand .* imports in ResponseStatusCodeTest


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

Branch: refs/heads/TINKERPOP-1990
Commit: 63ae13c24a86f59f84a9b30189bb9a73e22fe50a
Parents: 4ff4b88
Author: Dmitri Bourlatchkov <dm...@datastax.com>
Authored: Tue Jul 31 10:25:01 2018 -0400
Committer: Dmitri Bourlatchkov <dm...@datastax.com>
Committed: Tue Jul 31 10:25:01 2018 -0400

----------------------------------------------------------------------
 .../tinkerpop/gremlin/driver/message/ResponseStatusCodeTest.java  | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/63ae13c2/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCodeTest.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCodeTest.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCodeTest.java
index a231489..3fc8a78 100644
--- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCodeTest.java
+++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCodeTest.java
@@ -21,7 +21,8 @@ package org.apache.tinkerpop.gremlin.driver.message;
 
 import org.junit.Test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 public class ResponseStatusCodeTest {
 


[41/41] tinkerpop git commit: added shortestPath() Gherkin tests

Posted by dk...@apache.org.
added shortestPath() Gherkin tests


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

Branch: refs/heads/TINKERPOP-1990
Commit: 91af0a2bfab6226a19c2da23bc5754de2d759a6f
Parents: 7389f01
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Thu Aug 9 10:27:10 2018 -0700
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Thu Aug 9 10:27:10 2018 -0700

----------------------------------------------------------------------
 gremlin-test/features/map/Path.feature          |   2 +-
 gremlin-test/features/map/ShortestPath.feature  | 353 +++++++++++++++++++
 .../traversal/step/map/ShortestPathTest.java    |   2 +-
 3 files changed, 355 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/91af0a2b/gremlin-test/features/map/Path.feature
----------------------------------------------------------------------
diff --git a/gremlin-test/features/map/Path.feature b/gremlin-test/features/map/Path.feature
index b0cb9dd..0bb7573 100644
--- a/gremlin-test/features/map/Path.feature
+++ b/gremlin-test/features/map/Path.feature
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
-Feature: Step - count()
+Feature: Step - path()
 
   Scenario: g_VX1X_name_path
     Given the modern graph

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/91af0a2b/gremlin-test/features/map/ShortestPath.feature
----------------------------------------------------------------------
diff --git a/gremlin-test/features/map/ShortestPath.feature b/gremlin-test/features/map/ShortestPath.feature
new file mode 100644
index 0000000..0029f9d
--- /dev/null
+++ b/gremlin-test/features/map/ShortestPath.feature
@@ -0,0 +1,353 @@
+# 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.
+
+Feature: Step - shortestPath()
+
+  Scenario: g_V_shortestPath
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().shortestPath()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                                    |
+      | p[v[josh], v[lop], v[peter]]              |
+      | p[v[josh], v[lop]]                        |
+      | p[v[josh], v[marko], v[vadas]]            |
+      | p[v[josh], v[marko]]                      |
+      | p[v[josh], v[ripple]]                     |
+      | p[v[josh]]                                |
+      | p[v[lop], v[josh], v[ripple]]             |
+      | p[v[lop], v[josh]]                        |
+      | p[v[lop], v[marko], v[vadas]]             |
+      | p[v[lop], v[marko]]                       |
+      | p[v[lop], v[peter]]                       |
+      | p[v[lop]]                                 |
+      | p[v[marko], v[josh], v[ripple]]           |
+      | p[v[marko], v[josh]]                      |
+      | p[v[marko], v[lop], v[peter]]             |
+      | p[v[marko], v[lop]]                       |
+      | p[v[marko], v[vadas]]                     |
+      | p[v[marko]]                               |
+      | p[v[peter], v[lop], v[josh], v[ripple]]   |
+      | p[v[peter], v[lop], v[josh]]              |
+      | p[v[peter], v[lop], v[marko], v[vadas]]   |
+      | p[v[peter], v[lop], v[marko]]             |
+      | p[v[peter], v[lop]]                       |
+      | p[v[peter]]                               |
+      | p[v[ripple], v[josh], v[lop], v[peter]]   |
+      | p[v[ripple], v[josh], v[lop]]             |
+      | p[v[ripple], v[josh], v[marko], v[vadas]] |
+      | p[v[ripple], v[josh], v[marko]]           |
+      | p[v[ripple], v[josh]]                     |
+      | p[v[ripple]]                              |
+      | p[v[vadas], v[marko], v[josh], v[ripple]] |
+      | p[v[vadas], v[marko], v[josh]]            |
+      | p[v[vadas], v[marko], v[lop], v[peter]]   |
+      | p[v[vadas], v[marko], v[lop]]             |
+      | p[v[vadas], v[marko]]                     |
+      | p[v[vadas]]                               |
+
+  Scenario: g_V_both_dedup_shortestPath
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().both().dedup().shortestPath()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                                    |
+      | p[v[josh], v[lop], v[peter]]              |
+      | p[v[josh], v[lop]]                        |
+      | p[v[josh], v[marko], v[vadas]]            |
+      | p[v[josh], v[marko]]                      |
+      | p[v[josh], v[ripple]]                     |
+      | p[v[josh]]                                |
+      | p[v[lop], v[josh], v[ripple]]             |
+      | p[v[lop], v[josh]]                        |
+      | p[v[lop], v[marko], v[vadas]]             |
+      | p[v[lop], v[marko]]                       |
+      | p[v[lop], v[peter]]                       |
+      | p[v[lop]]                                 |
+      | p[v[marko], v[josh], v[ripple]]           |
+      | p[v[marko], v[josh]]                      |
+      | p[v[marko], v[lop], v[peter]]             |
+      | p[v[marko], v[lop]]                       |
+      | p[v[marko], v[vadas]]                     |
+      | p[v[marko]]                               |
+      | p[v[peter], v[lop], v[josh], v[ripple]]   |
+      | p[v[peter], v[lop], v[josh]]              |
+      | p[v[peter], v[lop], v[marko], v[vadas]]   |
+      | p[v[peter], v[lop], v[marko]]             |
+      | p[v[peter], v[lop]]                       |
+      | p[v[peter]]                               |
+      | p[v[ripple], v[josh], v[lop], v[peter]]   |
+      | p[v[ripple], v[josh], v[lop]]             |
+      | p[v[ripple], v[josh], v[marko], v[vadas]] |
+      | p[v[ripple], v[josh], v[marko]]           |
+      | p[v[ripple], v[josh]]                     |
+      | p[v[ripple]]                              |
+      | p[v[vadas], v[marko], v[josh], v[ripple]] |
+      | p[v[vadas], v[marko], v[josh]]            |
+      | p[v[vadas], v[marko], v[lop], v[peter]]   |
+      | p[v[vadas], v[marko], v[lop]]             |
+      | p[v[vadas], v[marko]]                     |
+      | p[v[vadas]]                               |
+
+  Scenario: g_V_shortestPath_edgesIncluded
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().shortestPath().with(includeEdges, true)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                                                                                                          |
+      | p[v[josh], e[josh-created->lop], v[lop], e[peter-created->lop], v[peter]]                                       |
+      | p[v[josh], e[josh-created->lop], v[lop]]                                                                        |
+      | p[v[josh], e[josh-created->ripple], v[ripple]]                                                                  |
+      | p[v[josh], e[marko-knows->josh], v[marko], e[marko-knows->vadas], v[vadas]]                                     |
+      | p[v[josh], e[marko-knows->josh], v[marko]]                                                                      |
+      | p[v[josh]]                                                                                                      |
+      | p[v[lop], e[josh-created->lop], v[josh], e[josh-created->ripple], v[ripple]]                                    |
+      | p[v[lop], e[josh-created->lop], v[josh]]                                                                        |
+      | p[v[lop], e[marko-created->lop], v[marko], e[marko-knows->vadas], v[vadas]]                                     |
+      | p[v[lop], e[marko-created->lop], v[marko]]                                                                      |
+      | p[v[lop], e[peter-created->lop], v[peter]]                                                                      |
+      | p[v[lop]]                                                                                                       |
+      | p[v[marko], e[marko-created->lop], v[lop], e[peter-created->lop], v[peter]]                                     |
+      | p[v[marko], e[marko-created->lop], v[lop]]                                                                      |
+      | p[v[marko], e[marko-knows->josh], v[josh], e[josh-created->ripple], v[ripple]]                                  |
+      | p[v[marko], e[marko-knows->josh], v[josh]]                                                                      |
+      | p[v[marko], e[marko-knows->vadas], v[vadas]]                                                                    |
+      | p[v[marko]]                                                                                                     |
+      | p[v[peter], e[peter-created->lop], v[lop], e[josh-created->lop], v[josh], e[josh-created->ripple], v[ripple]]   |
+      | p[v[peter], e[peter-created->lop], v[lop], e[josh-created->lop], v[josh]]                                       |
+      | p[v[peter], e[peter-created->lop], v[lop], e[marko-created->lop], v[marko], e[marko-knows->vadas], v[vadas]]    |
+      | p[v[peter], e[peter-created->lop], v[lop], e[marko-created->lop], v[marko]]                                     |
+      | p[v[peter], e[peter-created->lop], v[lop]]                                                                      |
+      | p[v[peter]]                                                                                                     |
+      | p[v[ripple], e[josh-created->ripple], v[josh], e[josh-created->lop], v[lop], e[peter-created->lop], v[peter]]   |
+      | p[v[ripple], e[josh-created->ripple], v[josh], e[josh-created->lop], v[lop]]                                    |
+      | p[v[ripple], e[josh-created->ripple], v[josh], e[marko-knows->josh], v[marko], e[marko-knows->vadas], v[vadas]] |
+      | p[v[ripple], e[josh-created->ripple], v[josh], e[marko-knows->josh], v[marko]]                                  |
+      | p[v[ripple], e[josh-created->ripple], v[josh]]                                                                  |
+      | p[v[ripple]]                                                                                                    |
+      | p[v[vadas], e[marko-knows->vadas], v[marko], e[marko-created->lop], v[lop], e[peter-created->lop], v[peter]]    |
+      | p[v[vadas], e[marko-knows->vadas], v[marko], e[marko-created->lop], v[lop]]                                     |
+      | p[v[vadas], e[marko-knows->vadas], v[marko], e[marko-knows->josh], v[josh], e[josh-created->ripple], v[ripple]] |
+      | p[v[vadas], e[marko-knows->vadas], v[marko], e[marko-knows->josh], v[josh]]                                     |
+      | p[v[vadas], e[marko-knows->vadas], v[marko]]                                                                    |
+      | p[v[vadas]]                                                                                                     |
+
+  Scenario: g_V_shortestPath_directionXINX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().shortestPath().with(edges, Direction.IN)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                          |
+      | p[v[josh], v[marko]]            |
+      | p[v[josh]]                      |
+      | p[v[lop], v[josh]]              |
+      | p[v[lop], v[marko]]             |
+      | p[v[lop], v[peter]]             |
+      | p[v[lop]]                       |
+      | p[v[marko]]                     |
+      | p[v[peter]]                     |
+      | p[v[ripple], v[josh], v[marko]] |
+      | p[v[ripple], v[josh]]           |
+      | p[v[ripple]]                    |
+      | p[v[vadas], v[marko]]           |
+      | p[v[vadas]]                     |
+
+  Scenario: g_V_shortestPath_edgesXoutEX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().shortestPath().with(edges, __.outE())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                          |
+      | p[v[josh], v[lop]]              |
+      | p[v[josh], v[ripple]]           |
+      | p[v[josh]]                      |
+      | p[v[lop]]                       |
+      | p[v[marko], v[josh], v[ripple]] |
+      | p[v[marko], v[josh]]            |
+      | p[v[marko], v[lop]]             |
+      | p[v[marko], v[vadas]]           |
+      | p[v[marko]]                     |
+      | p[v[peter], v[lop]]             |
+      | p[v[peter]]                     |
+      | p[v[ripple]]                    |
+      | p[v[vadas]]                     |
+
+  Scenario: g_V_shortestPath_edgesIncluded_edgesXoutEX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().shortestPath().with(includeEdges, true).with(edges, __.outE())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                                                                         |
+      | p[v[josh], e[josh-created->lop], v[lop]]                                       |
+      | p[v[josh], e[josh-created->ripple], v[ripple]]                                 |
+      | p[v[josh]]                                                                     |
+      | p[v[lop]]                                                                      |
+      | p[v[marko], e[marko-created->lop], v[lop]]                                     |
+      | p[v[marko], e[marko-knows->josh], v[josh], e[josh-created->ripple], v[ripple]] |
+      | p[v[marko], e[marko-knows->josh], v[josh]]                                     |
+      | p[v[marko], e[marko-knows->vadas], v[vadas]]                                   |
+      | p[v[marko]]                                                                    |
+      | p[v[peter], e[peter-created->lop], v[lop]]                                     |
+      | p[v[peter]]                                                                    |
+      | p[v[ripple]]                                                                   |
+      | p[v[vadas]]                                                                    |
+
+  Scenario: g_V_hasXname_markoX_shortestPath
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().has("name", "marko").shortestPath()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                          |
+      | p[v[marko], v[josh], v[ripple]] |
+      | p[v[marko], v[josh]]            |
+      | p[v[marko], v[lop], v[peter]]   |
+      | p[v[marko], v[lop]]             |
+      | p[v[marko], v[vadas]]           |
+      | p[v[marko]]                     |
+
+  Scenario: g_V_shortestPath_targetXhasXname_markoXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().shortestPath().with(target, __.has("name", "marko"))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                          |
+      | p[v[josh], v[marko]]            |
+      | p[v[lop], v[marko]]             |
+      | p[v[marko]]                     |
+      | p[v[peter], v[lop], v[marko]]   |
+      | p[v[ripple], v[josh], v[marko]] |
+      | p[v[vadas], v[marko]]           |
+
+  Scenario: g_V_shortestPath_targetXvaluesXnameX_isXmarkoXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().shortestPath().with(target, __.values("name").is("marko"))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                          |
+      | p[v[josh], v[marko]]            |
+      | p[v[lop], v[marko]]             |
+      | p[v[marko]]                     |
+      | p[v[peter], v[lop], v[marko]]   |
+      | p[v[ripple], v[josh], v[marko]] |
+      | p[v[vadas], v[marko]]           |
+
+  Scenario: g_V_hasXname_markoX_shortestPath_targetXhasLabelXsoftwareXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().has("name", "marko").shortestPath().with(target, __.hasLabel("software"))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                          |
+      | p[v[marko], v[josh], v[ripple]] |
+      | p[v[marko], v[lop]]             |
+
+  Scenario: g_V_hasXname_markoX_shortestPath_targetXhasXname_joshXX_distanceXweightX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().has("name", "marko").shortestPath().with(target, __.has("name","josh")).with(distance, "weight")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                       |
+      | p[v[marko], v[lop], v[josh]] |
+
+  Scenario: g_V_hasXname_danielX_shortestPath_targetXhasXname_stephenXX_edgesXbothEXusesXX
+    Given the crew graph
+    And the traversal of
+      """
+      g.V().has("name", "daniel").shortestPath().with(target, __.has("name","stephen")).with(edges, __.bothE("uses"))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                                   |
+      | p[v[daniel], v[gremlin], v[stephen]]     |
+      | p[v[daniel], v[tinkergraph], v[stephen]] |
+
+  Scenario: g_V_hasXsong_name_MIGHT_AS_WELLX_shortestPath_targetXhasXsong_name_MAYBE_YOU_KNOW_HOW_I_FEELXX_edgesXoutEXfollowedByXX_distanceXweightX
+    Given the grateful dead graph
+    And the traversal of
+      """
+      g.V().has("song", "name", "MIGHT AS WELL").
+        shortestPath().
+          with(target, __.has("song", "name", "MAYBE YOU KNOW HOW I FEEL")).
+          with(edges, __.outE("followedBy")).
+          with(distance, "weight")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                                                              |
+      | p[v[MIGHT AS WELL], v[DRUMS], v[MAYBE YOU KNOW HOW I FEEL]]         |
+      | p[v[MIGHT AS WELL], v[SHIP OF FOOLS], v[MAYBE YOU KNOW HOW I FEEL]] |
+
+  Scenario: g_V_hasXname_markoX_shortestPath_maxDistanceX1X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().has("name", "marko").shortestPath().with(maxDistance, 1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                |
+      | p[v[marko], v[josh]]  |
+      | p[v[marko], v[lop]]   |
+      | p[v[marko], v[vadas]] |
+      | p[v[marko]]           |
+
+  Scenario: g_V_hasXname_vadasX_shortestPath_distanceXweightX_maxDistanceX1_3X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().has("name", "vadas").shortestPath().with(distance, "weight").with(maxDistance, 1.3)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result                                  |
+      | p[v[vadas], v[marko], v[lop], v[josh]]  |
+      | p[v[vadas], v[marko], v[lop], v[peter]] |
+      | p[v[vadas], v[marko], v[lop]]           |
+      | p[v[vadas], v[marko]]                   |
+      | p[v[vadas]]                             |

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/91af0a2b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ShortestPathTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ShortestPathTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ShortestPathTest.java
index bf4a5b7..a55215b 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ShortestPathTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ShortestPathTest.java
@@ -266,7 +266,7 @@ public abstract class ShortestPathTest extends AbstractGremlinProcessTest {
 
         @Override
         public Traversal<Vertex, Path> get_g_V_shortestPath() {
-            return g.V().shortestPath().dedup();
+            return g.V().shortestPath();
         }
 
         @Override


[27/41] tinkerpop git commit: Merge branch 'tp33'

Posted by dk...@apache.org.
Merge branch 'tp33'

Conflicts:
	gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java


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

Branch: refs/heads/TINKERPOP-1990
Commit: 9357d6a1fd91cac4bd7149b94ed757399aa810a4
Parents: 1e8baec fa7a7f6
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Aug 7 12:54:18 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Aug 7 12:54:18 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   1 +
 .../driver/message/ResponseStatusCode.java      |   7 +
 .../driver/message/ResponseStatusCodeTest.java  |  36 +++++
 .../gremlin/server/ResponseHandlerContext.java  |  85 +++++++++++
 .../server/op/AbstractEvalOpProcessor.java      |  38 ++++-
 .../gremlin/server/op/AbstractOpProcessor.java  |  34 ++++-
 .../AbstractGremlinServerIntegrationTest.java   |  20 ++-
 .../server/GremlinServerIntegrateTest.java      |  51 +++++++
 .../server/ResponseHandlerContextTest.java      | 143 +++++++++++++++++++
 .../server/op/AbstractEvalOpProcessorTest.java  |  62 ++++++++
 .../server/op/AbstractOpProcessorTest.java      |  53 +++++++
 11 files changed, 515 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/9357d6a1/CHANGELOG.asciidoc
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/9357d6a1/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
index bb368c5,38ca3e1..331b762
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
@@@ -66,8 -72,20 +67,20 @@@ public abstract class AbstractOpProcess
       *
       * @param context The Gremlin Server {@link Context} object containing settings, request message, etc.
       * @param itty The result to iterator
+      * @throws TimeoutException if the time taken to serialize the entire result set exceeds the allowable time.
+      * @see #handleIterator(ResponseHandlerContext, Iterator)
       */
 -    protected void handleIterator(final Context context, final Iterator itty) throws TimeoutException, InterruptedException {
 +    protected void handleIterator(final Context context, final Iterator itty) throws InterruptedException {
+         handleIterator(new ResponseHandlerContext(context), itty);
+     }
+ 
+     /**
+      * A variant of {@link #handleIterator(Context, Iterator)} that is suitable for use in situations when multiple
+      * threads may produce {@link ResponseStatusCode#isFinalResponse() final} response messages concurrently.
+      * @see #handleIterator(Context, Iterator)
+      */
 -    protected void handleIterator(final ResponseHandlerContext rhc, final Iterator itty) throws TimeoutException, InterruptedException {
++    protected void handleIterator(final ResponseHandlerContext rhc, final Iterator itty) throws InterruptedException {
+         final Context context = rhc.getContext();
          final ChannelHandlerContext ctx = context.getChannelHandlerContext();
          final RequestMessage msg = context.getRequestMessage();
          final Settings settings = context.getSettings();
@@@ -228,9 -261,32 +241,22 @@@
          return Collections.emptyMap();
      }
  
+     /**
 -     * @deprecated As of release 3.2.2, replaced by {@link #makeFrame(ChannelHandlerContext, RequestMessage, MessageSerializer, boolean, List, ResponseStatusCode, Map)}.
 -     */
 -    @Deprecated
 -    protected static Frame makeFrame(final ChannelHandlerContext ctx, final RequestMessage msg,
 -                                     final MessageSerializer serializer, final boolean useBinary, final List<Object> aggregate,
 -                                     final ResponseStatusCode code) throws Exception {
 -        return makeFrame(ctx, msg, serializer, useBinary, aggregate, code, Collections.emptyMap());
 -    }
 -
 -    /**
+      * Caution: {@link #makeFrame(ResponseHandlerContext, RequestMessage, MessageSerializer, boolean, List, ResponseStatusCode, Map)}
+      * should be used instead of this method whenever a {@link ResponseHandlerContext} is available.
+      */
      protected static Frame makeFrame(final ChannelHandlerContext ctx, final RequestMessage msg,
 -                                   final MessageSerializer serializer, final boolean useBinary, final List<Object> aggregate,
 -                                   final ResponseStatusCode code, final Map<String,Object> responseMetaData) throws Exception {
 +                                     final MessageSerializer serializer, final boolean useBinary, final List<Object> aggregate,
 +                                     final ResponseStatusCode code, final Map<String,Object> responseMetaData) throws Exception {
+         final Context context = new Context(msg, ctx, null, null, null, null); // dummy context, good only for writing response messages to the channel
+         final ResponseHandlerContext rhc = new ResponseHandlerContext(context);
+         return makeFrame(rhc, msg, serializer, useBinary, aggregate, code, responseMetaData);
+     }
+ 
+     protected static Frame makeFrame(final ResponseHandlerContext rhc, final RequestMessage msg,
 -                                   final MessageSerializer serializer, final boolean useBinary, final List<Object> aggregate,
 -                                   final ResponseStatusCode code, final Map<String,Object> responseMetaData) throws Exception {
++                                     final MessageSerializer serializer, final boolean useBinary, final List<Object> aggregate,
++                                     final ResponseStatusCode code, final Map<String,Object> responseMetaData) throws Exception {
+         final ChannelHandlerContext ctx = rhc.getContext().getChannelHandlerContext();
          try {
              if (useBinary) {
                  return new Frame(serializer.serializeResponseAsBinary(ResponseMessage.build(msg)

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/9357d6a1/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
index 08b8526,67ad021..f97fb1f
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
@@@ -69,7 -71,9 +70,8 @@@ import org.junit.Test
  
  import java.lang.reflect.Field;
  import java.nio.channels.ClosedChannelException;
 -import java.util.ArrayList;
  import java.util.HashMap;
+ import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/9357d6a1/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessorTest.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessorTest.java
index 0000000,a7cee1a..aba1603
mode 000000,100644..100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessorTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessorTest.java
@@@ -1,0 -1,73 +1,53 @@@
+ /*
+  * 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.server.op;
+ 
+ import io.netty.channel.ChannelHandlerContext;
+ 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.junit.Test;
+ import org.mockito.ArgumentCaptor;
+ import org.mockito.Mockito;
+ 
+ import static org.junit.Assert.assertEquals;
+ import static org.junit.Assert.fail;
+ 
+ public class AbstractOpProcessorTest {
+ 
+     @Test
 -    public void deprecatedMakeFrameMethodShouldRedirectCorrectly() throws Exception {
 -        final ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
 -        final RequestMessage request = RequestMessage.build("test").create();
 -        final ArgumentCaptor<ResponseMessage> responseCaptor = ArgumentCaptor.forClass(ResponseMessage.class);
 -
 -        try {
 -            // Induce a NullPointerException to validate error response message writing
 -            //noinspection deprecation
 -            AbstractOpProcessor.makeFrame(ctx, request, null, true, null, ResponseStatusCode.PARTIAL_CONTENT);
 -            fail("Expected a NullPointerException");
 -        } catch (NullPointerException expected) {
 -            // nop
 -        }
 -
 -        Mockito.verify(ctx, Mockito.times(1)).writeAndFlush(responseCaptor.capture());
 -        assertEquals(ResponseStatusCode.SERVER_ERROR_SERIALIZATION, responseCaptor.getValue().getStatus().getCode());
 -        assertEquals(request.getRequestId(), responseCaptor.getValue().getRequestId());
 -    }
 -
 -    @Test
+     public void alternativeMakeFrameMethodShouldRedirectCorrectly() throws Exception {
+         final ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
+         final RequestMessage request = RequestMessage.build("test").create();
+         final ArgumentCaptor<ResponseMessage> responseCaptor = ArgumentCaptor.forClass(ResponseMessage.class);
+ 
+         try {
+             // Induce a NullPointerException to validate error response message writing
+             AbstractOpProcessor.makeFrame(ctx, request, null, true, null, ResponseStatusCode.PARTIAL_CONTENT, null);
+             fail("Expected a NullPointerException");
+         } catch (NullPointerException expected) {
+             // nop
+         }
+ 
+         Mockito.verify(ctx, Mockito.times(1)).writeAndFlush(responseCaptor.capture());
+         assertEquals(ResponseStatusCode.SERVER_ERROR_SERIALIZATION, responseCaptor.getValue().getStatus().getCode());
+         assertEquals(request.getRequestId(), responseCaptor.getValue().getRequestId());
+     }
+ 
+ }


[38/41] tinkerpop git commit: Merge branch 'tp33'

Posted by dk...@apache.org.
Merge branch 'tp33'

Conflicts:
	gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java


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

Branch: refs/heads/TINKERPOP-1990
Commit: f88ace1420be0034108bf5f3c0c5c1d1973009c8
Parents: 9357d6a b12a3fd
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Aug 9 10:51:01 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Aug 9 10:51:01 2018 -0400

----------------------------------------------------------------------
 .../gremlin/process/remote/RemoteGraph.java     |  17 ---
 .../io/graphson/TraversalSerializersV2d0.java   |   4 -
 .../ModernGraphTypeInformation.cs               |   4 +
 .../DriverRemoteTraversalSideEffects.java       |   3 +-
 .../test/cucumber/feature-steps.js              |  15 ++-
 .../glv/GraphTraversalSource.template           |   2 +-
 .../gremlin_python/process/graph_traversal.py   |   2 +-
 .../RemoteGraphGroovyTranslatorProvider.java    |   3 +-
 gremlin-test/features/map/PageRank.feature      | 132 +++++++++++++++++++
 gremlin-test/features/map/PeerPressure.feature  |  77 +++++++++++
 .../process/AbstractGremlinProcessTest.java     |  26 ++--
 .../traversal/step/map/PageRankTest.java        |  37 +++---
 .../traversal/step/map/PeerPressureTest.java    |  24 ++--
 .../TranslationStrategyProcessTest.java         |   3 +
 .../gremlin/process/FeatureCoverageTest.java    |   6 +-
 15 files changed, 284 insertions(+), 71 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f88ace14/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
----------------------------------------------------------------------
diff --cc gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
index 83dfe22,0cddc02..96eeaaf
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
@@@ -62,7 -63,18 +63,19 @@@ const ignoreReason = 
  
  const ignoredScenarios = {
    // An associative array containing the scenario name as key, for example:
-   // 'g_V_asXa_bX_out_asXcX_path_selectXkeysX': new IgnoreError(ignoreReason.embeddedListAssertion),
+   'g_V_pageRank_hasXpageRankX': new IgnoreError(ignoreReason.computerNotSupported),
+   'g_V_outXcreatedX_pageRank_byXbothEX_byXprojectRankX_timesX0X_valueMapXname_projectRankX': new IgnoreError(ignoreReason.computerNotSupported),
+   'g_V_pageRank_order_byXpageRank_decrX_byXnameX_name': new IgnoreError(ignoreReason.computerNotSupported),
+   'g_V_pageRank_order_byXpageRank_decrX_name_limitX2X': new IgnoreError(ignoreReason.computerNotSupported),
+   'g_V_pageRank_byXoutEXknowsXX_byXfriendRankX_valueMapXname_friendRankX': new IgnoreError(ignoreReason.computerNotSupported),
+   'g_V_hasLabelXpersonX_pageRank_byXpageRankX_order_byXpageRankX_valueMapXname_pageRankX': new IgnoreError(ignoreReason.computerNotSupported),
+   'g_V_pageRank_byXpageRankX_asXaX_outXknowsX_pageRank_asXbX_selectXa_bX': new IgnoreError(ignoreReason.computerNotSupported),
+   'g_V_hasLabelXsoftwareX_hasXname_rippleX_pageRankX1X_byXinEXcreatedXX_timesX1X_byXpriorsX_inXcreatedX_unionXboth__identityX_valueMapXname_priorsX': new IgnoreError(ignoreReason.computerNotSupported),
+   'g_V_outXcreatedX_groupXmX_byXlabelX_pageRankX1X_byXpageRankX_byXinEX_timesX1X_inXcreatedX_groupXmX_byXpageRankX_capXmX': new IgnoreError(ignoreReason.computerNotSupported),
+   'g_V_peerPressure_hasXclusterX': new IgnoreError(ignoreReason.computerNotSupported),
+   'g_V_peerPressure_byXclusterX_byXoutEXknowsXX_pageRankX1X_byXrankX_byXoutEXknowsXX_timesX2X_group_byXclusterX_byXrank_sumX_limitX100X': new IgnoreError(ignoreReason.computerNotSupported),
+   'g_V_hasXname_rippleX_inXcreatedX_peerPressure_byXoutEX_byXclusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX': new IgnoreError(ignoreReason.computerNotSupported),
++  'g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXEDGES_outEX_withXPROPERTY_NAME_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX': new IgnoreError(ignoreReason.computerNotSupported),
  };
  
  defineSupportCode(function(methods) {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f88ace14/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f88ace14/gremlin-test/features/map/PeerPressure.feature
----------------------------------------------------------------------
diff --cc gremlin-test/features/map/PeerPressure.feature
index 0000000,83f5bb2..d7368e9
mode 000000,100644..100644
--- a/gremlin-test/features/map/PeerPressure.feature
+++ b/gremlin-test/features/map/PeerPressure.feature
@@@ -1,0 -1,60 +1,77 @@@
+ # 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.
+ 
+ Feature: Step - peerPressure()
+                 
+   Scenario: g_V_peerPressure_hasXclusterX
+     Given the modern graph
+     And the traversal of
+       """
+       g.withComputer().V().peerPressure().has("gremlin.peerPressureVertexProgram.cluster")
+       """
+     When iterated to list
+     Then the result should be unordered
+       | result |
+       | v[marko] |
+       | v[vadas] |
+       | v[lop] |
+       | v[josh] |
+       | v[ripple] |
+       | v[peter] |
+     And the graph should return 6 for count of "g.withComputer().V().peerPressure().has(\"gremlin.peerPressureVertexProgram.cluster\")"
+ 
+   Scenario: g_V_peerPressure_byXclusterX_byXoutEXknowsXX_pageRankX1X_byXrankX_byXoutEXknowsXX_timesX2X_group_byXclusterX_byXrank_sumX_limitX100X
+     Given an unsupported test
+     Then nothing should happen because
+       """
+       The result returned is not supported under GraphSON 2.x and therefore cannot be properly asserted. More
+       specifically it has long keys which basically get toString()'d under GraphSON 2.x. This test can be supported
+       with GraphSON 3.x.
+       """
+ 
+   Scenario: g_V_hasXname_rippleX_inXcreatedX_peerPressure_byXoutEX_byXclusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX
+     Given the modern graph
+     And the traversal of
+       """
+       g.withComputer().V().has("name", "ripple").in("created").peerPressure().by(__.outE()).by("cluster").repeat(__.union(__.identity(), __.both())).times(2).dedup().valueMap("name", "cluster")
+       """
+     When iterated to list
+     Then the result should be unordered
+       | result |
+       | m[{"name": ["marko"], "cluster": [1]}] |
+       | m[{"name": ["vadas"], "cluster": [2]}] |
+       | m[{"name": ["lop"], "cluster": [4]}] |
+       | m[{"name": ["josh"], "cluster": [4]}] |
+       | m[{"name": ["ripple"], "cluster": [4]}] |
+       | m[{"name": ["peter"], "cluster": [6]}] |
++
++  Scenario: g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXEDGES_outEX_withXPROPERTY_NAME_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX
++    Given the modern graph
++    And the traversal of
++      """
++      g.withComputer().V().has("name", "ripple").in("created").peerPressure().with("~tinkerpop.peerPressure.edges",__.outE()).with("~tinkerpop.peerPressure.propertyName", "cluster").repeat(__.union(__.identity(), __.both())).times(2).dedup().valueMap("name", "cluster")
++      """
++    When iterated to list
++    Then the result should be unordered
++      | result |
++      | m[{"name": ["marko"], "cluster": [1]}] |
++      | m[{"name": ["vadas"], "cluster": [2]}] |
++      | m[{"name": ["lop"], "cluster": [4]}] |
++      | m[{"name": ["josh"], "cluster": [4]}] |
++      | m[{"name": ["ripple"], "cluster": [4]}] |
++      | m[{"name": ["peter"], "cluster": [6]}] |
++

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f88ace14/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f88ace14/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
----------------------------------------------------------------------
diff --cc gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
index b70cb02,be4ce9a..d53ec3e
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
@@@ -22,8 -22,8 +22,9 @@@ package org.apache.tinkerpop.gremlin.pr
  import org.apache.tinkerpop.gremlin.LoadGraphWith;
  import org.apache.tinkerpop.gremlin.TestHelper;
  import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
+ import org.apache.tinkerpop.gremlin.process.GremlinProcessRunner;
  import org.apache.tinkerpop.gremlin.process.computer.clustering.peerpressure.PeerPressureVertexProgram;
 +import org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.PeerPressure;
  import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
  import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
  import org.apache.tinkerpop.gremlin.structure.Vertex;
@@@ -51,20 -54,12 +55,14 @@@ public abstract class PeerPressureTest 
  
      public abstract Traversal<Vertex, Map<String, List<Object>>> get_g_V_hasXname_rippleX_inXcreatedX_peerPressure_byXoutEX_byXclusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX();
  
 +    public abstract Traversal<Vertex, Map<String, List<Object>>> get_g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXedges_outEX_withXpropertyName_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX();
 +
      @Test
      @LoadGraphWith(MODERN)
-     public void g_V_peerPressure() {
-         final Traversal<Vertex, Vertex> traversal = get_g_V_peerPressure();
+     public void g_V_peerPressure_hasXclusterX() {
+         final Traversal<Vertex, Vertex> traversal = get_g_V_peerPressure_hasXclusterX();
          printTraversalForm(traversal);
-         int counter = 0;
-         while (traversal.hasNext()) {
-             final Vertex vertex = traversal.next();
-             counter++;
-             assertTrue(vertex.property(PeerPressureVertexProgram.CLUSTER).isPresent());
-         }
-         assertEquals(6, counter);
+         assertEquals(6, IteratorUtils.count(traversal));
      }
  
      @Test
@@@ -102,29 -97,7 +100,29 @@@
          assertTrue(ids.contains(convertToVertexId("josh")));
          assertTrue(ids.contains(convertToVertexId("peter")));
      }
 -    
 +
 +    @Test
 +    @LoadGraphWith(MODERN)
 +    public void g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXEDGES_outEX_withXPROPERTY_NAME_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX() {
 +        TestHelper.assumeNonDeterministic();
 +        final Traversal<Vertex, Map<String, List<Object>>> traversal = get_g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXedges_outEX_withXpropertyName_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX();
 +        printTraversalForm(traversal);
 +        final List<Map<String, List<Object>>> results = traversal.toList();
 +        assertEquals(6, results.size());
 +        final Map<String, Object> clusters = new HashMap<>();
 +        results.forEach(m -> clusters.put((String) m.get("name").get(0), m.get("cluster").get(0)));
 +        assertEquals(2, results.get(0).size());
 +        assertEquals(6, clusters.size());
 +        assertEquals(clusters.get("josh"), clusters.get("ripple"));
 +        assertEquals(clusters.get("josh"), clusters.get("lop"));
 +        final Set<Object> ids = new HashSet<>(clusters.values());
 +        assertEquals(4, ids.size());
 +        assertTrue(ids.contains(convertToVertexId("marko")));
 +        assertTrue(ids.contains(convertToVertexId("vadas")));
 +        assertTrue(ids.contains(convertToVertexId("josh")));
 +        assertTrue(ids.contains(convertToVertexId("peter")));
 +    }
-     
++
      public static class Traversals extends PeerPressureTest {
  
          @Override

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f88ace14/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java
----------------------------------------------------------------------
diff --cc gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java
index 5739629,2cca50b..e09156b
--- a/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java
+++ b/gremlin-test/src/test/java/org/apache/tinkerpop/gremlin/process/FeatureCoverageTest.java
@@@ -53,10 -53,11 +53,12 @@@ import org.apache.tinkerpop.gremlin.pro
  import org.apache.tinkerpop.gremlin.process.traversal.step.map.MeanTest;
  import org.apache.tinkerpop.gremlin.process.traversal.step.map.MinTest;
  import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderTest;
+ import org.apache.tinkerpop.gremlin.process.traversal.step.map.PageRankTest;
  import org.apache.tinkerpop.gremlin.process.traversal.step.map.PathTest;
+ import org.apache.tinkerpop.gremlin.process.traversal.step.map.PeerPressureTest;
  import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProjectTest;
  import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesTest;
 +import org.apache.tinkerpop.gremlin.process.traversal.step.map.ReadTest;
  import org.apache.tinkerpop.gremlin.process.traversal.step.map.SelectTest;
  import org.apache.tinkerpop.gremlin.process.traversal.step.map.SumTest;
  import org.apache.tinkerpop.gremlin.process.traversal.step.map.UnfoldTest;


[32/41] tinkerpop git commit: TINKERPOP-1976 Removed an OptOut from RemoteGraph

Posted by dk...@apache.org.
TINKERPOP-1976 Removed an OptOut from RemoteGraph

Carved out a special case for a behavior that is specific to remote operations around side-effects


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

Branch: refs/heads/TINKERPOP-1990
Commit: 682bdde6c58f992b20ad919279c7da691c1dc210
Parents: c03b575
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Mon Aug 6 15:10:52 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Aug 9 07:28:09 2018 -0400

----------------------------------------------------------------------
 .../tinkerpop/gremlin/process/remote/RemoteGraph.java     |  4 ----
 .../driver/remote/DriverRemoteTraversalSideEffects.java   |  3 ++-
 .../gremlin/process/AbstractGremlinProcessTest.java       | 10 +++++++++-
 3 files changed, 11 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/682bdde6/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
index 1ea7d42..3699fea 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
@@ -48,10 +48,6 @@ import java.util.Iterator;
 @Graph.OptIn(Graph.OptIn.SUITE_PROCESS_STANDARD)
 @Graph.OptIn(Graph.OptIn.SUITE_PROCESS_COMPUTER)
 @Graph.OptOut(
-        test = "org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupCountTest",
-        method = "g_V_hasXnoX_groupCountXaX_capXaX",
-        reason = "This test asserts an empty side-effect which reflects as a null rather than an \"empty\" and thus doesn't assert")
-@Graph.OptOut(
         test = "org.apache.tinkerpop.gremlin.process.traversal.CoreTraversalTest",
         method = "*",
         reason = "The test suite does not support profiling or lambdas and for groovy tests: 'Could not locate method: GraphTraversalSource.withStrategies([{traversalCategory=interface org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy$DecorationStrategy}])'")

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/682bdde6/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteTraversalSideEffects.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteTraversalSideEffects.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteTraversalSideEffects.java
index 4305567..791c70e 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteTraversalSideEffects.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteTraversalSideEffects.java
@@ -30,6 +30,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalSideEffects;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
@@ -88,7 +89,7 @@ public class DriverRemoteTraversalSideEffects extends AbstractRemoteTraversalSid
                 final Result result = client.submitAsync(msg).get().all().get().get(0);
                 sideEffects.put(key, null == result ? null : result.getObject());
             } catch (Exception ex) {
-                // we use to try to catch  "no found" situations returned from the server here and then null the
+                // we use to try to catch "no found" situations returned from the server here and then null the
                 // side-effect for the requested key. doesn't seem like there is a need for that now because calls
                 // to get() now initially trigger a call the keys() so you would know all of the keys available on
                 // the server and would validate them up front throwing sideEffectKeyDoesNotExist(key) which thus

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/682bdde6/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
index 96dee1d..c3f4dc2 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
@@ -20,6 +20,7 @@ package org.apache.tinkerpop.gremlin.process;
 
 import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
 import org.apache.tinkerpop.gremlin.GraphManager;
+import org.apache.tinkerpop.gremlin.process.remote.traversal.RemoteTraversalSideEffects;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalSideEffects;
@@ -96,8 +97,15 @@ public abstract class AbstractGremlinProcessTest extends AbstractGremlinTest {
             final Class clazz = (Class) keysClasses[i + 1];
             assertThat(sideEffects.keys().contains(key), is(true));
             assertThat(sideEffects.exists(key), is(true));
-            assertEquals(clazz, sideEffects.get((String) keysClasses[i]).getClass());
             assertThat(sideEffects.exists(UUID.randomUUID().toString()), is(false));
+
+            // there is slightly different behavior for remote side-effects so carving out a few asserts with that
+            // in mind. the client really doesnt' really have a way of knowing what type of object to create when it
+            // gets an empty iterator so it makes the result null and therefore we end up with a NPE if we try to
+            // access it. the rest of the behavior is solid so better to do this than OptOut I think
+            if (!(sideEffects instanceof RemoteTraversalSideEffects)) {
+                assertEquals(clazz, sideEffects.get((String) keysClasses[i]).getClass());
+            }
         }
         assertEquals(sideEffects.keys().size(), counter);
         assertThat(sideEffects.keys().contains(UUID.randomUUID().toString()), is(false));


[29/41] tinkerpop git commit: TINKERPOP-1976 Fixed up pageRank() groovy test

Posted by dk...@apache.org.
TINKERPOP-1976 Fixed up pageRank() groovy test


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

Branch: refs/heads/TINKERPOP-1990
Commit: 8c2313ed46d9a8683ff824d954038b9020097ae8
Parents: 5d9c3f1
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Aug 9 07:27:17 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Aug 9 07:28:09 2018 -0400

----------------------------------------------------------------------
 .../gremlin/process/traversal/step/map/GroovyPageRankTest.groovy   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8c2313ed/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
index 78671da..7554092 100644
--- a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
+++ b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
@@ -42,7 +42,7 @@ public abstract class GroovyPageRankTest {
 
         @Override
         public Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_decrX_byXnameX_name() {
-            new ScriptTraversal<>(g, "gremlin-groovy", "g.V.pageRank.order.by(PageRankVertexProgram.PAGE_RANK, decr).name")
+            new ScriptTraversal<>(g, "gremlin-groovy", "g.V.pageRank.order.by(PageRankVertexProgram.PAGE_RANK, decr).by('name').name")
         }
 
         @Override


[28/41] tinkerpop git commit: TINKERPOP-1976 Modified the nature of the pageRank() order() test

Posted by dk...@apache.org.
TINKERPOP-1976 Modified the nature of the pageRank() order() test

The GLV test language doesn't support the kind of asserts that the java test was doing. Change the nature of the java test a bit to ensure it could be tested properly. Made the java test more succinct in the process.


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

Branch: refs/heads/TINKERPOP-1990
Commit: 5d9c3f1335375caa1b4c0bd0cd97094f787e9dac
Parents: 13440d6
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Aug 8 12:06:43 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Aug 9 07:28:09 2018 -0400

----------------------------------------------------------------------
 .../traversal/step/map/GroovyPageRankTest.groovy  |  2 +-
 .../test/cucumber/feature-steps.js                |  2 +-
 gremlin-test/features/map/PageRank.feature        | 10 ++++------
 .../process/traversal/step/map/PageRankTest.java  | 18 +++++++++---------
 4 files changed, 15 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5d9c3f13/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
index 13787cc..78671da 100644
--- a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
+++ b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
@@ -41,7 +41,7 @@ public abstract class GroovyPageRankTest {
         }
 
         @Override
-        public Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_decrX_name() {
+        public Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_decrX_byXnameX_name() {
             new ScriptTraversal<>(g, "gremlin-groovy", "g.V.pageRank.order.by(PageRankVertexProgram.PAGE_RANK, decr).name")
         }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5d9c3f13/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
index e585fcc..fa609be 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
@@ -63,7 +63,7 @@ const ignoredScenarios = {
   // An associative array containing the scenario name as key, for example:
   'g_V_pageRank': new IgnoreError(ignoreReason.computerNotSupported),
   'g_V_outXcreatedX_pageRank_byXbothEX_byXprojectRankX_timesX0X_valueMapXname_projectRankX': new IgnoreError(ignoreReason.computerNotSupported),
-  'g_V_pageRank_order_byXpageRank_decrX_name': new IgnoreError(ignoreReason.computerNotSupported),
+  'g_V_pageRank_order_byXpageRank_decrX_byXnameX_name': new IgnoreError(ignoreReason.computerNotSupported),
   'g_V_pageRank_order_byXpageRank_decrX_name_limitX2X': new IgnoreError(ignoreReason.computerNotSupported),
   'g_V_pageRank_byXoutEXknowsXX_byXfriendRankX_valueMapXname_friendRankX': new IgnoreError(ignoreReason.computerNotSupported),
   'g_V_hasLabelXpersonX_pageRank_byXpageRankX_order_byXpageRankX_valueMapXname_pageRankX': new IgnoreError(ignoreReason.computerNotSupported),

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5d9c3f13/gremlin-test/features/map/PageRank.feature
----------------------------------------------------------------------
diff --git a/gremlin-test/features/map/PageRank.feature b/gremlin-test/features/map/PageRank.feature
index 049b8c2..ebf6489 100644
--- a/gremlin-test/features/map/PageRank.feature
+++ b/gremlin-test/features/map/PageRank.feature
@@ -48,21 +48,19 @@ Feature: Step - pageRank()
       | m[{"name": ["lop"], "projectRank": [3.0]}] |
       | m[{"name": ["ripple"], "projectRank": [1.0]}] |
 
-  # can't fully assert order here because some ranks are equivalent. the java test does an "or" type assert to deal
-  # with this, which we can't express here in these tests. should probably change the test or
-  Scenario: g_V_pageRank_order_byXpageRank_decrX_name
+  Scenario: g_V_pageRank_order_byXpageRank_decrX_byXnameX_name
     Given the modern graph
     And the traversal of
       """
-      g.withComputer().V().pageRank().order().by("gremlin.pageRankVertexProgram.pageRank", Order.decr).values("name")
+      g.withComputer().V().pageRank().order().by("gremlin.pageRankVertexProgram.pageRank", Order.decr).by("name").values("name")
       """
     When iterated to list
-    Then the result should be unordered
+    Then the result should be ordered
       | result |
       | lop    |
       | ripple |
-      | vadas  |
       | josh   |
+      | vadas  |
       | marko  |
       | peter  |
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5d9c3f13/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
index 57a3b3f..8846099 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
@@ -51,7 +51,7 @@ public abstract class PageRankTest extends AbstractGremlinProcessTest {
 
     public abstract Traversal<Vertex, Map<String, List<Object>>> get_g_V_outXcreatedX_pageRank_byXbothEX_byXprojectRankX_timesX0X_valueMapXname_projectRankX();
 
-    public abstract Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_decrX_name();
+    public abstract Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_decrX_byXnameX_name();
 
     public abstract Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_decrX_name_limitX2X();
 
@@ -99,17 +99,17 @@ public abstract class PageRankTest extends AbstractGremlinProcessTest {
 
     @Test
     @LoadGraphWith(MODERN)
-    public void g_V_pageRank_order_byXpageRank_decrX_name() {
-        final Traversal<Vertex, String> traversal = get_g_V_pageRank_order_byXpageRank_decrX_name();
+    public void g_V_pageRank_order_byXpageRank_decrX_byXnameX_name() {
+        final Traversal<Vertex, String> traversal = get_g_V_pageRank_order_byXpageRank_decrX_byXnameX_name();
         printTraversalForm(traversal);
         final List<String> names = traversal.toList();
         assertEquals(6, names.size());
         assertEquals("lop", names.get(0));
         assertEquals("ripple", names.get(1));
-        assertTrue(names.get(2).equals("josh") || names.get(2).equals("vadas"));
-        assertTrue(names.get(3).equals("josh") || names.get(3).equals("vadas"));
-        assertTrue(names.get(4).equals("marko") || names.get(4).equals("peter"));
-        assertTrue(names.get(5).equals("marko") || names.get(5).equals("peter"));
+        assertEquals("josh", names.get(2));
+        assertEquals("vadas", names.get(3));
+        assertEquals("marko", names.get(4));
+        assertEquals("peter", names.get(5));
     }
 
     @Test
@@ -256,8 +256,8 @@ public abstract class PageRankTest extends AbstractGremlinProcessTest {
         }
 
         @Override
-        public Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_decrX_name() {
-            return g.V().pageRank().order().by(PageRankVertexProgram.PAGE_RANK, Order.decr).values("name");
+        public Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_decrX_byXnameX_name() {
+            return g.V().pageRank().order().by(PageRankVertexProgram.PAGE_RANK, Order.decr).by("name").values("name");
         }
 
         @Override


[22/41] tinkerpop git commit: Merge branch 'tp33'

Posted by dk...@apache.org.
Merge branch 'tp33'


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

Branch: refs/heads/TINKERPOP-1990
Commit: 9b41f5a7f4b2b8bef226f5a62685bfdfd17c0feb
Parents: a5d1aa6 2cf551f
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Aug 7 06:30:35 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Aug 7 06:30:35 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                                                | 1 +
 .../tinkerpop/gremlin/server/util/GremlinServerInstall.java       | 3 +++
 2 files changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/9b41f5a7/CHANGELOG.asciidoc
----------------------------------------------------------------------


[36/41] tinkerpop git commit: TINKERPOP-1976 Changed the context of tests to be better suited to GLVs

Posted by dk...@apache.org.
TINKERPOP-1976 Changed the context of tests to be better suited to GLVs


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

Branch: refs/heads/TINKERPOP-1990
Commit: a533878cb71eef970bdca366ed1c4ae1e5d87f20
Parents: 8c2313e
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Aug 9 08:32:17 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Aug 9 08:32:17 2018 -0400

----------------------------------------------------------------------
 .../traversal/step/map/GroovyPageRankTest.groovy |  4 ++--
 .../step/map/GroovyPeerPressureTest.groovy       |  4 ++--
 .../test/cucumber/feature-steps.js               |  4 ++--
 gremlin-test/features/map/PageRank.feature       |  4 ++--
 gremlin-test/features/map/PeerPressure.feature   |  4 ++--
 .../process/traversal/step/map/PageRankTest.java | 19 +++++++------------
 .../traversal/step/map/PeerPressureTest.java     | 19 +++++++------------
 7 files changed, 24 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a533878c/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
index 7554092..6b8d7b2 100644
--- a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
+++ b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
@@ -31,8 +31,8 @@ public abstract class GroovyPageRankTest {
     public static class Traversals extends PageRankTest {
 
         @Override
-        public Traversal<Vertex, Vertex> get_g_V_pageRank() {
-            new ScriptTraversal<>(g, "gremlin-groovy", "g.V.pageRank")
+        public Traversal<Vertex, Vertex> get_g_V_pageRank_hasXpageRankX() {
+            new ScriptTraversal<>(g, "gremlin-groovy", "g.V.pageRank.has(PageRankVertexProgram.PAGE_RANK)")
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a533878c/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPeerPressureTest.groovy
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPeerPressureTest.groovy b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPeerPressureTest.groovy
index 6ec0750..cdd383c 100644
--- a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPeerPressureTest.groovy
+++ b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPeerPressureTest.groovy
@@ -31,8 +31,8 @@ public abstract class GroovyPeerPressureTest {
     public static class Traversals extends PeerPressureTest {
 
         @Override
-        public Traversal<Vertex, Vertex> get_g_V_peerPressure() {
-            new ScriptTraversal<>(g, "gremlin-groovy", "g.V.peerPressure")
+        public Traversal<Vertex, Vertex> get_g_V_peerPressure_hasXclusterX() {
+            new ScriptTraversal<>(g, "gremlin-groovy", "g.V.peerPressure.has(PeerPressureVertexProgram.CLUSTER)")
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a533878c/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
index fa609be..3e6824c 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
@@ -61,7 +61,7 @@ const ignoreReason = {
 
 const ignoredScenarios = {
   // An associative array containing the scenario name as key, for example:
-  'g_V_pageRank': new IgnoreError(ignoreReason.computerNotSupported),
+  'g_V_pageRank_hasXpageRankX': new IgnoreError(ignoreReason.computerNotSupported),
   'g_V_outXcreatedX_pageRank_byXbothEX_byXprojectRankX_timesX0X_valueMapXname_projectRankX': new IgnoreError(ignoreReason.computerNotSupported),
   'g_V_pageRank_order_byXpageRank_decrX_byXnameX_name': new IgnoreError(ignoreReason.computerNotSupported),
   'g_V_pageRank_order_byXpageRank_decrX_name_limitX2X': new IgnoreError(ignoreReason.computerNotSupported),
@@ -70,7 +70,7 @@ const ignoredScenarios = {
   'g_V_pageRank_byXpageRankX_asXaX_outXknowsX_pageRank_asXbX_selectXa_bX': new IgnoreError(ignoreReason.computerNotSupported),
   'g_V_hasLabelXsoftwareX_hasXname_rippleX_pageRankX1X_byXinEXcreatedXX_timesX1X_byXpriorsX_inXcreatedX_unionXboth__identityX_valueMapXname_priorsX': new IgnoreError(ignoreReason.computerNotSupported),
   'g_V_outXcreatedX_groupXmX_byXlabelX_pageRankX1X_byXpageRankX_byXinEX_timesX1X_inXcreatedX_groupXmX_byXpageRankX_capXmX': new IgnoreError(ignoreReason.computerNotSupported),
-  'g_V_peerPressure': new IgnoreError(ignoreReason.computerNotSupported),
+  'g_V_peerPressure_hasXclusterX': new IgnoreError(ignoreReason.computerNotSupported),
   'g_V_peerPressure_byXclusterX_byXoutEXknowsXX_pageRankX1X_byXrankX_byXoutEXknowsXX_timesX2X_group_byXclusterX_byXrank_sumX_limitX100X': new IgnoreError(ignoreReason.computerNotSupported),
   'g_V_hasXname_rippleX_inXcreatedX_peerPressure_byXoutEX_byXclusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX': new IgnoreError(ignoreReason.computerNotSupported),
 };

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a533878c/gremlin-test/features/map/PageRank.feature
----------------------------------------------------------------------
diff --git a/gremlin-test/features/map/PageRank.feature b/gremlin-test/features/map/PageRank.feature
index ebf6489..bf2ed26 100644
--- a/gremlin-test/features/map/PageRank.feature
+++ b/gremlin-test/features/map/PageRank.feature
@@ -17,11 +17,11 @@
 
 Feature: Step - pageRank()
                 
-  Scenario: g_V_pageRank
+  Scenario: g_V_pageRank_hasXpageRankX
     Given the modern graph
     And the traversal of
       """
-      g.withComputer().V().pageRank()
+      g.withComputer().V().pageRank().has("gremlin.pageRankVertexProgram.pageRank")
       """
     When iterated to list
     Then the result should be unordered

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a533878c/gremlin-test/features/map/PeerPressure.feature
----------------------------------------------------------------------
diff --git a/gremlin-test/features/map/PeerPressure.feature b/gremlin-test/features/map/PeerPressure.feature
index d23fa31..83f5bb2 100644
--- a/gremlin-test/features/map/PeerPressure.feature
+++ b/gremlin-test/features/map/PeerPressure.feature
@@ -17,11 +17,11 @@
 
 Feature: Step - peerPressure()
                 
-  Scenario: g_V_peerPressure
+  Scenario: g_V_peerPressure_hasXclusterX
     Given the modern graph
     And the traversal of
       """
-      g.withComputer().V().peerPressure()
+      g.withComputer().V().peerPressure().has("gremlin.peerPressureVertexProgram.cluster")
       """
     When iterated to list
     Then the result should be unordered

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a533878c/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
index 8846099..0c0a91d 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
@@ -28,6 +28,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -47,7 +48,7 @@ import static org.junit.Assert.fail;
 @RunWith(GremlinProcessRunner.class)
 public abstract class PageRankTest extends AbstractGremlinProcessTest {
 
-    public abstract Traversal<Vertex, Vertex> get_g_V_pageRank();
+    public abstract Traversal<Vertex, Vertex> get_g_V_pageRank_hasXpageRankX();
 
     public abstract Traversal<Vertex, Map<String, List<Object>>> get_g_V_outXcreatedX_pageRank_byXbothEX_byXprojectRankX_timesX0X_valueMapXname_projectRankX();
 
@@ -67,16 +68,10 @@ public abstract class PageRankTest extends AbstractGremlinProcessTest {
 
     @Test
     @LoadGraphWith(MODERN)
-    public void g_V_pageRank() {
-        final Traversal<Vertex, Vertex> traversal = get_g_V_pageRank();
+    public void g_V_pageRank_hasXpageRankX() {
+        final Traversal<Vertex, Vertex> traversal = get_g_V_pageRank_hasXpageRankX();
         printTraversalForm(traversal);
-        int counter = 0;
-        while (traversal.hasNext()) {
-            final Vertex vertex = traversal.next();
-            counter++;
-            assertTrue(vertex.property(PageRankVertexProgram.PAGE_RANK).isPresent());
-        }
-        assertEquals(6, counter);
+        assertEquals(6, IteratorUtils.count(traversal));
     }
 
     @Test
@@ -241,8 +236,8 @@ public abstract class PageRankTest extends AbstractGremlinProcessTest {
     public static class Traversals extends PageRankTest {
 
         @Override
-        public Traversal<Vertex, Vertex> get_g_V_pageRank() {
-            return g.V().pageRank();
+        public Traversal<Vertex, Vertex> get_g_V_pageRank_hasXpageRankX() {
+            return g.V().pageRank().has(PageRankVertexProgram.PAGE_RANK);
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a533878c/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
index 67ed267..e19f96d 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
@@ -27,6 +27,7 @@ import org.apache.tinkerpop.gremlin.process.computer.clustering.peerpressure.Pee
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -47,7 +48,7 @@ import static org.junit.Assert.assertTrue;
 @RunWith(GremlinProcessRunner.class)
 public abstract class PeerPressureTest extends AbstractGremlinProcessTest {
 
-    public abstract Traversal<Vertex, Vertex> get_g_V_peerPressure();
+    public abstract Traversal<Vertex, Vertex> get_g_V_peerPressure_hasXclusterX();
 
     public abstract Traversal<Vertex, Map<Object, Number>> get_g_V_peerPressure_byXclusterX_byXoutEXknowsXX_pageRankX1X_byXrankX_byXoutEXknowsXX_timesX2X_group_byXclusterX_byXrank_sumX_limitX100X();
 
@@ -55,16 +56,10 @@ public abstract class PeerPressureTest extends AbstractGremlinProcessTest {
 
     @Test
     @LoadGraphWith(MODERN)
-    public void g_V_peerPressure() {
-        final Traversal<Vertex, Vertex> traversal = get_g_V_peerPressure();
+    public void g_V_peerPressure_hasXclusterX() {
+        final Traversal<Vertex, Vertex> traversal = get_g_V_peerPressure_hasXclusterX();
         printTraversalForm(traversal);
-        int counter = 0;
-        while (traversal.hasNext()) {
-            final Vertex vertex = traversal.next();
-            counter++;
-            assertTrue(vertex.property(PeerPressureVertexProgram.CLUSTER).isPresent());
-        }
-        assertEquals(6, counter);
+        assertEquals(6, IteratorUtils.count(traversal));
     }
 
     @Test
@@ -106,8 +101,8 @@ public abstract class PeerPressureTest extends AbstractGremlinProcessTest {
     public static class Traversals extends PeerPressureTest {
 
         @Override
-        public Traversal<Vertex, Vertex> get_g_V_peerPressure() {
-            return g.V().peerPressure();
+        public Traversal<Vertex, Vertex> get_g_V_peerPressure_hasXclusterX() {
+            return g.V().peerPressure().has(PeerPressureVertexProgram.CLUSTER);
         }
 
         @Override


[02/41] tinkerpop git commit: TINKERPOP-2005 Handle evaluation excetions in AbstractEvalOpProcessor

Posted by dk...@apache.org.
TINKERPOP-2005 Handle evaluation excetions in AbstractEvalOpProcessor

Some script evaluation exceptions in AbstractEvalOpProcessor may occur
after the script has started executing. In this situation it it critical
to prevent potentially writing multiple final (e.g. error vs. success)
responses back to the client.

Exceptions that used to escape from evalOpInternal(...) would be
converted to error response messages by OpExecutorHandler, which could
coincide with a successful response from a quick script.

This change makes AbstractEvalOpProcessor do the error message
writing for the same type of exceptions that are handled by
OpExecutorHandler. However, AbstractEvalOpProcessor makes sure that
at most one final reponse message is sent by using
ResponseHandlerContext.

Also ResponseHandlerContext.writeAndFlush(...) methods will no longer
throw exceptions for attempts to send multiple final messages. This is
again to avoid multiple error response messages sent from
OpExecutorHandler.


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

Branch: refs/heads/TINKERPOP-1990
Commit: b7a44953c8ac62f308b78709ab2565a78eddb1af
Parents: f592e34
Author: Dmitri Bourlatchkov <dm...@datastax.com>
Authored: Mon Jul 30 12:38:21 2018 -0400
Committer: Dmitri Bourlatchkov <dm...@datastax.com>
Committed: Mon Jul 30 12:38:21 2018 -0400

----------------------------------------------------------------------
 .../gremlin/server/ResponseHandlerContext.java  | 19 +++---
 .../server/op/AbstractEvalOpProcessor.java      | 26 +++++++-
 .../gremlin/server/op/AbstractOpProcessor.java  |  2 +-
 .../server/ResponseHandlerContextTest.java      | 45 +++++++++++---
 .../server/op/AbstractEvalOpProcessorTest.java  | 62 ++++++++++++++++++++
 5 files changed, 135 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b7a44953/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContext.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContext.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContext.java
index fff4480..3c8c13c 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContext.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContext.java
@@ -20,6 +20,8 @@ package org.apache.tinkerpop.gremlin.server;
 
 import org.apache.tinkerpop.gremlin.driver.message.ResponseMessage;
 import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -27,7 +29,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
  * A context for asynchronously writing response messages related to a particular request.
  * <p>The "write" methods of this class ensure that at most one {@link ResponseStatusCode#isFinalResponse() final}
  * response message is written to the underlying channel. Attempts to write more than one final response message will
- * result in an {@link IllegalStateException}.</p>
+ * be ignored with a warning log message.</p>
  * <p>Note: an object of this class should be used instead of writing to the channel directly when multiple threads
  * are expected to produce final response messages concurrently. Callers must ensure that the same
  * {@link ResponseHandlerContext} is used by all threads writing response messages for the same request.</p>
@@ -35,6 +37,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
  * @author Dmitri Bourlatchkov
  */
 public class ResponseHandlerContext {
+    private static final Logger logger = LoggerFactory.getLogger(ResponseHandlerContext.class);
 
     private final Context context;
     private final AtomicBoolean finalResponseWritten = new AtomicBoolean();
@@ -52,7 +55,7 @@ public class ResponseHandlerContext {
      * {@link ResponseStatusCode#isFinalResponse() final} response is written.
      * <p>Note: this method should be used instead of writing to the channel directly when multiple threads
      * are expected to produce response messages concurrently.</p>
-     * <p>Attempts to write more than one final response message will result in an {@link IllegalStateException}.</p>
+     * <p>Attempts to write more than one final response message will be ignored.</p>
      * @see #writeAndFlush(ResponseStatusCode, Object)
      */
     public void writeAndFlush(ResponseMessage message) {
@@ -65,16 +68,18 @@ public class ResponseHandlerContext {
      * <p>The caller must make sure that the provided response status code matches the content of the message.</p>
      * <p>Note: this method should be used instead of writing to the channel directly when multiple threads
      * are expected to produce response messages concurrently.</p>
-     * <p>Attempts to write more than one final response message will result in an {@link IllegalStateException}.</p>
+     * <p>Attempts to write more than one final response message will be ignored.</p>
      * @see #writeAndFlush(ResponseMessage)
      */
     public void writeAndFlush(ResponseStatusCode code, Object responseMessage) {
         final boolean messageIsFinal = code.isFinalResponse();
-        if(!finalResponseWritten.compareAndSet(false, messageIsFinal)) {
-            final String errorMessage = String.format("Another final response message was already written for request %s", context.getRequestMessage().getRequestId());
-            throw new IllegalStateException(errorMessage);
+        if(finalResponseWritten.compareAndSet(false, messageIsFinal)) {
+            context.getChannelHandlerContext().writeAndFlush(responseMessage);
+        } else {
+            final String logMessage = String.format("Another final response message was already written for request %s, ignoring response code: %s",
+                    context.getRequestMessage().getRequestId(), code);
+            logger.warn(logMessage);
         }
 
-        context.getChannelHandlerContext().writeAndFlush(responseMessage);
     }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b7a44953/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
index 6ff0452..39168c2 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
@@ -223,9 +223,33 @@ public abstract class AbstractEvalOpProcessor extends AbstractOpProcessor {
      *                                script evaluation.
      * @param bindingsSupplier A function that returns the {@link Bindings} to provide to the
      *                         {@link GremlinExecutor#eval} method.
+     * @see #evalOpInternal(ResponseHandlerContext, Supplier, BindingSupplier)
      */
     protected void evalOpInternal(final Context context, final Supplier<GremlinExecutor> gremlinExecutorSupplier,
                                   final BindingSupplier bindingsSupplier) throws OpProcessorException {
+        ResponseHandlerContext rhc = new ResponseHandlerContext(context);
+        try {
+            evalOpInternal(rhc, gremlinExecutorSupplier, bindingsSupplier);
+        } catch (Exception ex) {
+            // Exceptions may occur on after the script started executing, therefore corresponding errors must be
+            // reported via the ResponseHandlerContext.
+            logger.warn("Unable to process script evaluation request: " + ex, ex);
+            rhc.writeAndFlush(ResponseMessage.build(context.getRequestMessage())
+                    .code(ResponseStatusCode.SERVER_ERROR)
+                    .statusAttributeException(ex)
+                    .statusMessage(ex.getMessage()).create());
+        }
+    }
+
+    /**
+     * A variant of {@link #evalOpInternal(Context, Supplier, BindingSupplier)} that is suitable for use in situations
+     * when multiple threads may produce {@link ResponseStatusCode#isFinalResponse() final} response messages
+     * concurrently.
+     * @see #evalOpInternal(Context, Supplier, BindingSupplier)
+     */
+    protected void evalOpInternal(final ResponseHandlerContext rhc, final Supplier<GremlinExecutor> gremlinExecutorSupplier,
+                                  final BindingSupplier bindingsSupplier) throws OpProcessorException {
+        final Context context = rhc.getContext();
         final Timer.Context timerContext = evalOpTimer.time();
         final ChannelHandlerContext ctx = context.getChannelHandlerContext();
         final RequestMessage msg = context.getRequestMessage();
@@ -246,8 +270,6 @@ public abstract class AbstractEvalOpProcessor extends AbstractOpProcessor {
         final long seto = args.containsKey(Tokens.ARGS_SCRIPT_EVAL_TIMEOUT) ?
                 Long.parseLong(args.get(Tokens.ARGS_SCRIPT_EVAL_TIMEOUT).toString()) : settings.scriptEvaluationTimeout;
 
-        ResponseHandlerContext rhc = new ResponseHandlerContext(context);
-
         final GremlinExecutor.LifeCycle lifeCycle = GremlinExecutor.LifeCycle.build()
                 .scriptEvaluationTimeoutOverride(seto)
                 .afterFailure((b,t) -> {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b7a44953/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
index 1263c81..c2b6f1f 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
@@ -80,7 +80,7 @@ public abstract class AbstractOpProcessor implements OpProcessor {
     }
 
     /**
-     * A variant of {@link #handleIterator(Context, Iterator)} that is suitable for use in situations when mutiple
+     * A variant of {@link #handleIterator(Context, Iterator)} that is suitable for use in situations when multiple
      * threads may produce {@link ResponseStatusCode#isFinalResponse() final} response messages concurrently.
      * @see #handleIterator(Context, Iterator)
      */

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b7a44953/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
index bea318b..6f15a33 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ResponseHandlerContextTest.java
@@ -19,10 +19,13 @@
 package org.apache.tinkerpop.gremlin.server;
 
 import io.netty.channel.ChannelHandlerContext;
+import org.apache.log4j.Logger;
 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.hamcrest.CoreMatchers;
+import org.apache.tinkerpop.gremlin.util.Log4jRecordingAppender;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -32,8 +35,7 @@ import java.util.Arrays;
 import java.util.UUID;
 import java.util.function.BiFunction;
 
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.assertTrue;
 
 @RunWith(Parameterized.class)
 public class ResponseHandlerContextTest {
@@ -45,6 +47,7 @@ public class ResponseHandlerContextTest {
     private final RequestMessage request = RequestMessage.build("test").create();
     private final Context context = new Context(request, ctx, null, null, null, null);
     private final ResponseHandlerContext rhc = new ResponseHandlerContext(context);
+    private final Log4jRecordingAppender recordingAppender = new Log4jRecordingAppender();
 
     @Parameterized.Parameters(name = "{0}")
     public static Iterable<Object[]> data() {
@@ -79,6 +82,18 @@ public class ResponseHandlerContextTest {
         });
     }
 
+    @Before
+    public void addRecordingAppender() {
+        final Logger rootLogger = Logger.getRootLogger();
+        rootLogger.addAppender(recordingAppender);
+    }
+
+    @After
+    public void removeRecordingAppender() {
+        final Logger rootLogger = Logger.getRootLogger();
+        rootLogger.removeAppender(recordingAppender);
+    }
+
     @Test
     public void shouldAllowMultipleNonFinalResponses() {
         writeInvoker.apply(rhc, ResponseStatusCode.AUTHENTICATE);
@@ -99,12 +114,24 @@ public class ResponseHandlerContextTest {
         writeInvoker.apply(rhc, ResponseStatusCode.SUCCESS);
         Mockito.verify(ctx, Mockito.times(2)).writeAndFlush(Mockito.any());
 
-        try {
-            writeInvoker.apply(rhc, ResponseStatusCode.SERVER_ERROR_TIMEOUT);
-            fail("Expected an IllegalStateException");
-        } catch (IllegalStateException ex) {
-            assertThat(ex.toString(), CoreMatchers.containsString(request.getRequestId().toString()));
-        }
+        writeInvoker.apply(rhc, ResponseStatusCode.SERVER_ERROR_TIMEOUT);
+        assertTrue(recordingAppender.logContainsAny(".*" + request.getRequestId() + ".*"));
+        assertTrue(recordingAppender.logContainsAny(".*" + ResponseStatusCode.SERVER_ERROR_TIMEOUT + "$"));
+
+        // ensure there were no other writes to the channel
         Mockito.verify(ctx, Mockito.times(2)).writeAndFlush(Mockito.any());
     }
+
+    @Test
+    public void shouldNotAllowNonFinalMessagesAfterFinalResponse() {
+        writeInvoker.apply(rhc, ResponseStatusCode.SERVER_ERROR_TIMEOUT);
+        Mockito.verify(ctx, Mockito.times(1)).writeAndFlush(Mockito.any());
+
+        writeInvoker.apply(rhc, ResponseStatusCode.PARTIAL_CONTENT);
+        assertTrue(recordingAppender.logContainsAny(".*" + request.getRequestId() + ".*"));
+        assertTrue(recordingAppender.logContainsAny(".*" + ResponseStatusCode.PARTIAL_CONTENT + "$"));
+
+        // ensure there were no other writes to the channel
+        Mockito.verify(ctx, Mockito.times(1)).writeAndFlush(Mockito.any());
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b7a44953/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessorTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessorTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessorTest.java
new file mode 100644
index 0000000..6f25e2e
--- /dev/null
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessorTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.server.op;
+
+import io.netty.channel.ChannelHandlerContext;
+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.groovy.engine.GremlinExecutor;
+import org.apache.tinkerpop.gremlin.server.Context;
+import org.apache.tinkerpop.gremlin.server.Settings;
+import org.apache.tinkerpop.gremlin.server.op.standard.StandardOpProcessor;
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
+import javax.script.SimpleBindings;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.anyString;
+
+public class AbstractEvalOpProcessorTest {
+
+    @Test
+    public void evalOpInternalShouldHandleAllEvaluationExceptions() throws OpProcessorException {
+        AbstractEvalOpProcessor processor = new StandardOpProcessor();
+        RequestMessage request = RequestMessage.build("test").create();
+        Settings settings = new Settings();
+        ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
+        ArgumentCaptor<ResponseMessage> responseCaptor = ArgumentCaptor.forClass(ResponseMessage.class);
+
+        GremlinExecutor gremlinExecutor = Mockito.mock(GremlinExecutor.class);
+        Mockito.when(gremlinExecutor.eval(anyString(), anyString(), Mockito.any(), Mockito.<GremlinExecutor.LifeCycle>any()))
+                .thenThrow(new IllegalStateException("test-exception"));
+
+        Context context = new Context(request, ctx, settings, null, gremlinExecutor, null);
+        processor.evalOpInternal(context, context::getGremlinExecutor, SimpleBindings::new);
+
+        Mockito.verify(ctx, Mockito.times(1)).writeAndFlush(responseCaptor.capture());
+        assertEquals(ResponseStatusCode.SERVER_ERROR, responseCaptor.getValue().getStatus().getCode());
+        assertEquals(request.getRequestId(), responseCaptor.getValue().getRequestId());
+        assertThat(responseCaptor.getValue().getStatus().getMessage(), CoreMatchers.containsString("test-exception"));
+    }
+}
\ No newline at end of file


[30/41] tinkerpop git commit: TINKERPOP-1976 Removed some OptOuts on RemoteGraph

Posted by dk...@apache.org.
TINKERPOP-1976 Removed some OptOuts on RemoteGraph

Some tests needed to use the "process" runner apparently


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

Branch: refs/heads/TINKERPOP-1990
Commit: f7ccb67b13547edba2986f53993d862576db59c4
Parents: 37476a2
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Aug 2 19:44:50 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Aug 9 07:28:09 2018 -0400

----------------------------------------------------------------------
 .../tinkerpop/gremlin/process/remote/RemoteGraph.java  | 13 -------------
 .../process/traversal/step/map/PeerPressureTest.java   |  6 ++++--
 .../decoration/TranslationStrategyProcessTest.java     |  3 +++
 3 files changed, 7 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f7ccb67b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
index 4b23475..1ea7d42 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
@@ -24,7 +24,6 @@ import org.apache.tinkerpop.gremlin.process.computer.GraphComputer;
 import org.apache.tinkerpop.gremlin.process.remote.traversal.strategy.decoration.RemoteStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
-import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.Transaction;
@@ -53,18 +52,6 @@ import java.util.Iterator;
         method = "g_V_hasXnoX_groupCountXaX_capXaX",
         reason = "This test asserts an empty side-effect which reflects as a null rather than an \"empty\" and thus doesn't assert")
 @Graph.OptOut(
-        test = "org.apache.tinkerpop.gremlin.process.traversal.step.map.PeerPressureTest",
-        method = "*",
-        reason = "https://issues.apache.org/jira/browse/TINKERPOP-1976")
-@Graph.OptOut(
-        test = "org.apache.tinkerpop.gremlin.process.traversal.step.map.PageRankTest",
-        method = "*",
-        reason = "https://issues.apache.org/jira/browse/TINKERPOP-1976")
-@Graph.OptOut(
-        test = "org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.TranslationStrategyProcessTest",
-        method = "*",
-        reason = "hmmmm")
-@Graph.OptOut(
         test = "org.apache.tinkerpop.gremlin.process.traversal.CoreTraversalTest",
         method = "*",
         reason = "The test suite does not support profiling or lambdas and for groovy tests: 'Could not locate method: GraphTraversalSource.withStrategies([{traversalCategory=interface org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy$DecorationStrategy}])'")

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f7ccb67b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
index 996be6d..67ed267 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
@@ -22,11 +22,13 @@ package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 import org.apache.tinkerpop.gremlin.LoadGraphWith;
 import org.apache.tinkerpop.gremlin.TestHelper;
 import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
+import org.apache.tinkerpop.gremlin.process.GremlinProcessRunner;
 import org.apache.tinkerpop.gremlin.process.computer.clustering.peerpressure.PeerPressureVertexProgram;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.HashMap;
 import java.util.HashSet;
@@ -42,6 +44,7 @@ import static org.junit.Assert.assertTrue;
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
+@RunWith(GremlinProcessRunner.class)
 public abstract class PeerPressureTest extends AbstractGremlinProcessTest {
 
     public abstract Traversal<Vertex, Vertex> get_g_V_peerPressure();
@@ -99,8 +102,7 @@ public abstract class PeerPressureTest extends AbstractGremlinProcessTest {
         assertTrue(ids.contains(convertToVertexId("josh")));
         assertTrue(ids.contains(convertToVertexId("peter")));
     }
-
-
+    
     public static class Traversals extends PeerPressureTest {
 
         @Override

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f7ccb67b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategyProcessTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategyProcessTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategyProcessTest.java
index a280a9c..0b81cce 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategyProcessTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategyProcessTest.java
@@ -21,9 +21,11 @@ package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
 
 import org.apache.tinkerpop.gremlin.LoadGraphWith;
 import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
+import org.apache.tinkerpop.gremlin.process.GremlinProcessRunner;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -33,6 +35,7 @@ import static org.junit.Assert.assertEquals;
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
+@RunWith(GremlinProcessRunner.class)
 public class TranslationStrategyProcessTest extends AbstractGremlinProcessTest {
     private static final Logger logger = LoggerFactory.getLogger(TranslationStrategyProcessTest.class);
 


[39/41] tinkerpop git commit: TINKERPOP-1990 Implemented `ShortestPathVertexProgram` and `ShortestPathVertexProgramStep`.

Posted by dk...@apache.org.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
index 7ca44ba..6a2b700 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
@@ -180,6 +180,10 @@ public abstract class AbstractGremlinTest {
         return convertToVertex(graph, vertexName).id();
     }
 
+    public Vertex convertToVertex(final String vertexName) {
+        return convertToVertex(graph, vertexName);
+    }
+
     public Vertex convertToVertex(final Graph graph, final String vertexName) {
         // all test graphs have "name" as a unique id which makes it easy to hardcode this...works for now
         return graph.traversal().V().has("name", vertexName).next();
@@ -249,7 +253,7 @@ public abstract class AbstractGremlinTest {
     public void printTraversalForm(final Traversal traversal) {
         logger.info(String.format("Testing: %s", name.getMethodName()));
         logger.info("   pre-strategy:" + traversal);
-        traversal.hasNext();
+        if (!traversal.asAdmin().isLocked()) traversal.asAdmin().applyStrategies();
         logger.info("  post-strategy:" + traversal);
         verifyUniqueStepIds(traversal.asAdmin());
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
index 4749e93..0a2a405 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
@@ -127,7 +127,7 @@ public abstract class AbstractGremlinProcessTest extends AbstractGremlinTest {
 
     public static <T> void checkResults(final List<T> expectedResults, final Traversal<?, T> traversal) {
         final List<T> results = traversal.toList();
-        assertFalse(traversal.hasNext());
+        assertThat(traversal.hasNext(), is(false));
         if (expectedResults.size() != results.size()) {
             logger.error("Expected results: " + expectedResults);
             logger.error("Actual results:   " + results);
@@ -145,11 +145,10 @@ public abstract class AbstractGremlinProcessTest extends AbstractGremlinTest {
         }
         final Map<T, Long> expectedResultsCount = new HashMap<>();
         final Map<T, Long> resultsCount = new HashMap<>();
+        expectedResults.forEach(t -> MapHelper.incr(expectedResultsCount, t, 1L));
+        results.forEach(t -> MapHelper.incr(resultsCount, t, 1L));
         assertEquals("Checking indexing is equivalent", expectedResultsCount.size(), resultsCount.size());
-        expectedResults.forEach(t -> MapHelper.incr(expectedResultsCount, t, 1l));
-        results.forEach(t -> MapHelper.incr(resultsCount, t, 1l));
         expectedResultsCount.forEach((k, v) -> assertEquals("Checking result group counts", v, resultsCount.get(k)));
-        assertThat(traversal.hasNext(), is(false));
     }
 
     public static <T> void checkResults(final Map<T, Long> expectedResults, final Traversal<?, T> traversal) {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java
index eab562d..857b3f0 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java
@@ -26,6 +26,7 @@ import org.apache.tinkerpop.gremlin.process.computer.bulkloading.BulkLoaderVerte
 import org.apache.tinkerpop.gremlin.process.computer.clone.CloneVertexProgramTest;
 import org.apache.tinkerpop.gremlin.process.computer.clustering.peerpressure.PeerPressureVertexProgramTest;
 import org.apache.tinkerpop.gremlin.process.computer.ranking.pagerank.PageRankVertexProgramTest;
+import org.apache.tinkerpop.gremlin.process.computer.search.path.ShortestPathVertexProgramTest;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionComputerTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.ComplexTest;
@@ -71,6 +72,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProgramTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProjectTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ReadTest;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.ShortestPathTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.SelectTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.SumTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.UnfoldTest;
@@ -166,6 +168,7 @@ public class ProcessComputerSuite extends AbstractGremlinSuite {
             ProgramTest.Traversals.class,
             PropertiesTest.Traversals.class,
             ReadTest.Traversals.class,
+            ShortestPathTest.Traversals.class,
             SelectTest.Traversals.class,
             UnfoldTest.Traversals.class,
             ValueMapTest.Traversals.class,
@@ -194,6 +197,7 @@ public class ProcessComputerSuite extends AbstractGremlinSuite {
             // algorithms
             PageRankVertexProgramTest.class,
             PeerPressureVertexProgramTest.class,
+            ShortestPathVertexProgramTest.class,
             BulkLoaderVertexProgramTest.class,
             BulkDumperVertexProgramTest.class,
             CloneVertexProgramTest.class,
@@ -258,6 +262,7 @@ public class ProcessComputerSuite extends AbstractGremlinSuite {
             ProjectTest.class,
             ProgramTest.class,
             PropertiesTest.class,
+            ShortestPathTest.class,
             SelectTest.class,
             UnfoldTest.class,
             ValueMapTest.class,

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/search/path/ShortestPathTestHelper.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/search/path/ShortestPathTestHelper.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/search/path/ShortestPathTestHelper.java
new file mode 100644
index 0000000..7f3aa63
--- /dev/null
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/search/path/ShortestPathTestHelper.java
@@ -0,0 +1,100 @@
+/*
+ * 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.process.computer.search.path;
+
+import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ImmutablePath;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.MapHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.MutablePath;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.hamcrest.Matchers;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+/**
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public class ShortestPathTestHelper {
+
+    private final AbstractGremlinProcessTest test;
+    private final GraphTraversalSource g;
+    private final Map<String, Vertex> vertexCache;
+    private final Map<Object, Map<Object, Edge>> edgeCache;
+
+    public ShortestPathTestHelper(final AbstractGremlinProcessTest test, final GraphTraversalSource g) {
+        this.test = test;
+        this.g = g;
+        this.vertexCache = new HashMap<>();
+        this.edgeCache = new HashMap<>();
+    }
+
+    public void checkResults(final List<Path> expected, final List<Path> actual) {
+        AbstractGremlinProcessTest.checkResults(expected, __.inject(actual.toArray(new Path[actual.size()])));
+    }
+
+    public Path makePath(final String... names) {
+        return makePath(false, names);
+    }
+
+    public Path makePath(final boolean includeEdges, final String... names) {
+        Path path = ImmutablePath.make();
+        boolean first = true;
+        for (final String name : names) {
+            final Vertex vertex = vertexCache.computeIfAbsent(name, test::convertToVertex);
+            if (!first) {
+                if (includeEdges) {
+                    final Object id1 = ((Vertex) path.get(path.size() - 1)).id();
+                    final Object id2 = vertex.id();
+                    final Edge edge;
+                    if (edgeCache.containsKey(id1)) {
+                        edge = edgeCache.get(id1).computeIfAbsent(id2, id -> getEdge(id1, id));
+                    } else if (edgeCache.containsKey(id2)) {
+                        edge = edgeCache.get(id2).computeIfAbsent(id1, id -> getEdge(id, id2));
+                    } else {
+                        edgeCache.put(id1, new HashMap<>());
+                        edgeCache.get(id1).put(id2, edge = getEdge(id1, id2));
+                    }
+                    path = path.extend(edge, Collections.emptySet());
+                }
+            }
+            path = path.extend(vertex, Collections.emptySet());
+            first = false;
+        }
+        return path;
+    }
+
+    private Edge getEdge(final Object id1, final Object id2) {
+        return g.V(id1)
+                .bothE().filter(__.otherV().hasId(id2))
+                .next();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/search/path/ShortestPathVertexProgramTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/search/path/ShortestPathVertexProgramTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/search/path/ShortestPathVertexProgramTest.java
new file mode 100644
index 0000000..303299d
--- /dev/null
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/search/path/ShortestPathVertexProgramTest.java
@@ -0,0 +1,297 @@
+/*
+ * 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.process.computer.search.path;
+
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
+import org.apache.tinkerpop.gremlin.process.computer.ComputerResult;
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.CREW;
+import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.GRATEFUL;
+import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public class ShortestPathVertexProgramTest extends AbstractGremlinProcessTest {
+
+    private ShortestPathTestHelper helper;
+
+    @Before
+    public void initializeHelper() throws Exception {
+        this.helper  = new ShortestPathTestHelper(this, g);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void shouldFindAllShortestPathsWithDefaultParameters() throws Exception {
+        final ComputerResult result = graph.compute(graphProvider.getGraphComputer(graph).getClass()).
+                program(ShortestPathVertexProgram.build().create(graph)).submit().get();
+        assertTrue(result.memory().exists(ShortestPathVertexProgram.SHORTEST_PATHS));
+        final List<Path> shortestPaths = result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS);
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS).map(helper::makePath).collect(Collectors.toList());
+        helper.checkResults(expected, shortestPaths);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void shouldFindAllShortestPathsWithEdgesIncluded() throws Exception {
+        final ComputerResult result = graph.compute(graphProvider.getGraphComputer(graph).getClass()).
+                program(ShortestPathVertexProgram.build().includeEdges(true).create(graph)).submit().get();
+        assertTrue(result.memory().exists(ShortestPathVertexProgram.SHORTEST_PATHS));
+        final List<Path> shortestPaths = result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS);
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS).map(p -> helper.makePath(true, p))
+                .collect(Collectors.toList());
+        helper.checkResults(expected, shortestPaths);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void shouldFindOutDirectedShortestPaths() throws Exception {
+        final List<ShortestPathVertexProgram> programs = Arrays.asList(
+                ShortestPathVertexProgram.build().edgeTraversal(__.outE()).create(graph),
+                ShortestPathVertexProgram.build().edgeDirection(Direction.OUT).create(graph));
+        for (final ShortestPathVertexProgram program : programs) {
+            final ComputerResult result = graph.compute(graphProvider.getGraphComputer(graph).getClass()).
+                    program(program).submit().get();
+            assertTrue(result.memory().exists(ShortestPathVertexProgram.SHORTEST_PATHS));
+            final List<Path> shortestPaths = result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS);
+            final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS)
+                    .filter(p -> (p[0].equals("marko") && !p[p.length - 1].equals("peter"))
+                            || (p[0].equals("vadas") && p.length == 1)
+                            || (p[0].equals("lop") && p.length == 1)
+                            || (p[0].equals("josh") && Arrays.asList("lop", "josh", "ripple").contains(p[p.length - 1]))
+                            || (p[0].equals("ripple") && p.length == 1)
+                            || (p[0].equals("peter") && Arrays.asList("lop", "peter").contains(p[p.length - 1])))
+                    .map(helper::makePath).collect(Collectors.toList());
+            helper.checkResults(expected, shortestPaths);
+        }
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void shouldFindInDirectedShortestPaths() throws Exception {
+        final List<ShortestPathVertexProgram> programs = Arrays.asList(
+                ShortestPathVertexProgram.build().edgeTraversal(__.inE()).create(graph),
+                ShortestPathVertexProgram.build().edgeDirection(Direction.IN).create(graph));
+        for (final ShortestPathVertexProgram program : programs) {
+            final ComputerResult result = graph.compute(graphProvider.getGraphComputer(graph).getClass()).
+                    program(program).submit().get();
+            assertTrue(result.memory().exists(ShortestPathVertexProgram.SHORTEST_PATHS));
+            final List<Path> shortestPaths = result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS);
+            final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS)
+                    .filter(p -> (p[0].equals("marko") && p.length == 1)
+                            || (p[0].equals("vadas") && Arrays.asList("marko", "vadas").contains(p[p.length - 1]))
+                            || (p[0].equals("lop") && Arrays.asList("marko", "lop", "josh", "peter").contains(p[p.length - 1]))
+                            || (p[0].equals("josh") && Arrays.asList("marko", "josh").contains(p[p.length - 1]))
+                            || (p[0].equals("ripple") && Arrays.asList("marko", "josh", "ripple").contains(p[p.length - 1]))
+                            || (p[0].equals("peter") && p.length == 1))
+                    .map(helper::makePath).collect(Collectors.toList());
+            helper.checkResults(expected, shortestPaths);
+        }
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void shouldFindDirectedShortestPathsWithEdgesIncluded() throws Exception {
+        final ComputerResult result = graph.compute(graphProvider.getGraphComputer(graph).getClass()).
+                program(ShortestPathVertexProgram.build().edgeTraversal(__.outE()).includeEdges(true).create(graph)).submit().get();
+        assertTrue(result.memory().exists(ShortestPathVertexProgram.SHORTEST_PATHS));
+        final List<Path> shortestPaths = result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS);
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS)
+                .filter(p -> (p[0].equals("marko") && !p[p.length - 1].equals("peter"))
+                        || (p[0].equals("vadas") && p.length == 1)
+                        || (p[0].equals("lop") && p.length == 1)
+                        || (p[0].equals("josh") && Arrays.asList("lop", "josh", "ripple").contains(p[p.length - 1]))
+                        || (p[0].equals("ripple") && p.length == 1)
+                        || (p[0].equals("peter") && Arrays.asList("lop", "peter").contains(p[p.length - 1])))
+                .map(p -> helper.makePath(true, p)).collect(Collectors.toList());
+        helper.checkResults(expected, shortestPaths);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void shouldFindShortestPathsWithStartVertexFilter() throws Exception {
+        final ComputerResult result = graph.compute(graphProvider.getGraphComputer(graph).getClass()).
+                program(ShortestPathVertexProgram.build().source(__.has("name", "marko")).create(graph)).submit().get();
+        assertTrue(result.memory().exists(ShortestPathVertexProgram.SHORTEST_PATHS));
+        final List<Path> shortestPaths = result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS);
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS)
+                .filter(p -> p[0].equals("marko")).map(helper::makePath).collect(Collectors.toList());
+        helper.checkResults(expected, shortestPaths);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void shouldFindShortestPathsWithEndVertexFilter() throws Exception {
+        final ComputerResult result = graph.compute(graphProvider.getGraphComputer(graph).getClass()).
+                program(ShortestPathVertexProgram.build().target(__.has("name", "marko")).create(graph)).submit().get();
+        assertTrue(result.memory().exists(ShortestPathVertexProgram.SHORTEST_PATHS));
+        final List<Path> shortestPaths = result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS);
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS)
+                .filter(p -> p[p.length - 1].equals("marko")).map(helper::makePath).collect(Collectors.toList());
+        helper.checkResults(expected, shortestPaths);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void shouldFindShortestPathsWithStartEndVertexFilter() throws Exception {
+        final ComputerResult result = graph.compute(graphProvider.getGraphComputer(graph).getClass()).
+                program(ShortestPathVertexProgram.build()
+                        .source(__.has("name", "marko"))
+                        .target(__.hasLabel("software")).create(graph)).submit().get();
+        assertTrue(result.memory().exists(ShortestPathVertexProgram.SHORTEST_PATHS));
+        final List<Path> shortestPaths = result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS);
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS)
+                .filter(p ->
+                        p[0].equals("marko") && Arrays.asList("lop", "ripple").contains(p[p.length - 1]))
+                .map(helper::makePath).collect(Collectors.toList());
+        helper.checkResults(expected, shortestPaths);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void shouldUseCustomDistanceProperty() throws Exception {
+        final ComputerResult result = graph.compute(graphProvider.getGraphComputer(graph).getClass()).
+                program(ShortestPathVertexProgram.build()
+                        .source(__.has("name", "marko"))
+                        .target(__.has("name", "josh"))
+                        .distanceProperty("weight").create(graph)).submit().get();
+        assertTrue(result.memory().exists(ShortestPathVertexProgram.SHORTEST_PATHS));
+        final List<Path> shortestPaths = result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS);
+        assertEquals(1, shortestPaths.size());
+        assertEquals(helper.makePath("marko", "lop", "josh"), shortestPaths.get(0));
+    }
+
+    @Test
+    @LoadGraphWith(CREW)
+    public void shouldFindEqualLengthPaths() throws Exception {
+        final ComputerResult result = graph.compute(graphProvider.getGraphComputer(graph).getClass()).
+                program(ShortestPathVertexProgram.build()
+                        .edgeTraversal(__.bothE("uses"))
+                        .source(__.has("name", "daniel"))
+                        .target(__.has("name", "stephen")).create(graph)).submit().get();
+        assertTrue(result.memory().exists(ShortestPathVertexProgram.SHORTEST_PATHS));
+        final List<Path> shortestPaths = result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS);
+        final List<Path> expected = Arrays.asList(
+                helper.makePath("daniel", "gremlin", "stephen"),
+                helper.makePath("daniel", "tinkergraph", "stephen"));
+        helper.checkResults(expected, shortestPaths);
+    }
+
+    @Test
+    @LoadGraphWith(GRATEFUL)
+    public void shouldFindEqualLengthPathsUsingDistanceProperty() throws Exception {
+        final ComputerResult result = graph.compute(graphProvider.getGraphComputer(graph).getClass()).
+                program(ShortestPathVertexProgram.build()
+                        .edgeTraversal(__.outE("followedBy"))
+                        .source(__.has("song", "name", "MIGHT AS WELL"))
+                        .target(__.has("song", "name", "MAYBE YOU KNOW HOW I FEEL"))
+                        .distanceProperty("weight")
+                        .create(graph)).submit().get();
+        assertTrue(result.memory().exists(ShortestPathVertexProgram.SHORTEST_PATHS));
+        final List<Path> shortestPaths = result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS);
+        final List<Path> expected = Arrays.asList(
+                helper.makePath("MIGHT AS WELL", "DRUMS", "MAYBE YOU KNOW HOW I FEEL"),
+                helper.makePath("MIGHT AS WELL", "SHIP OF FOOLS", "MAYBE YOU KNOW HOW I FEEL"));
+        helper.checkResults(expected, shortestPaths);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void shouldRespectMaxDistance() throws Exception {
+        final ComputerResult result = graph.compute(graphProvider.getGraphComputer(graph).getClass()).
+                program(ShortestPathVertexProgram.build()
+                        .source(__.has("name", "marko"))
+                        .maxDistance(1).create(graph)).submit().get();
+        assertTrue(result.memory().exists(ShortestPathVertexProgram.SHORTEST_PATHS));
+        final List<Path> shortestPaths = result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS);
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS)
+                .filter(p -> p[0].equals("marko") && p.length <= 2).map(helper::makePath).collect(Collectors.toList());
+        helper.checkResults(expected, shortestPaths);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void shouldRespectMaxCustomDistance() throws Exception {
+        final ComputerResult result = graph.compute(graphProvider.getGraphComputer(graph).getClass()).
+                program(ShortestPathVertexProgram.build()
+                        .source(__.has("name", "vadas"))
+                        .distanceProperty("weight").maxDistance(1.3).create(graph)).submit().get();
+        assertTrue(result.memory().exists(ShortestPathVertexProgram.SHORTEST_PATHS));
+        final List<Path> shortestPaths = result.memory().get(ShortestPathVertexProgram.SHORTEST_PATHS);
+        final List<Path> expected = Stream.concat(Arrays.stream(ALL_SHORTEST_PATHS)
+                        .filter(p -> p[0].equals("vadas") &&
+                                Arrays.asList("vadas", "marko", "lop", "peter").contains(p[p.length - 1]))
+                        .map(helper::makePath),
+                Stream.of(helper.makePath("vadas", "marko", "lop", "josh")))
+                .collect(Collectors.toList());
+        helper.checkResults(expected, shortestPaths);
+    }
+
+    public static String[][] ALL_SHORTEST_PATHS = new String[][]{
+            new String[]{"marko"},
+            new String[]{"marko", "vadas"},
+            new String[]{"marko", "lop"},
+            new String[]{"marko", "lop", "peter"},
+            new String[]{"marko", "josh"},
+            new String[]{"marko", "josh", "ripple"},
+            new String[]{"vadas"},
+            new String[]{"vadas", "marko"},
+            new String[]{"vadas", "marko", "lop"},
+            new String[]{"vadas", "marko", "lop", "peter"},
+            new String[]{"vadas", "marko", "josh", "ripple"},
+            new String[]{"vadas", "marko", "josh"},
+            new String[]{"lop"},
+            new String[]{"lop", "marko"},
+            new String[]{"lop", "marko", "vadas"},
+            new String[]{"lop", "josh"},
+            new String[]{"lop", "josh", "ripple"},
+            new String[]{"lop", "peter"},
+            new String[]{"josh"},
+            new String[]{"josh", "marko"},
+            new String[]{"josh", "marko", "vadas"},
+            new String[]{"josh", "lop"},
+            new String[]{"josh", "lop", "peter"},
+            new String[]{"josh", "ripple"},
+            new String[]{"ripple"},
+            new String[]{"ripple", "josh"},
+            new String[]{"ripple", "josh", "marko"},
+            new String[]{"ripple", "josh", "marko", "vadas"},
+            new String[]{"ripple", "josh", "lop"},
+            new String[]{"ripple", "josh", "lop", "peter"},
+            new String[]{"peter"},
+            new String[]{"peter", "lop"},
+            new String[]{"peter", "lop", "marko"},
+            new String[]{"peter", "lop", "marko", "vadas"},
+            new String[]{"peter", "lop", "josh"},
+            new String[]{"peter", "lop", "josh", "ripple"}
+    };
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ShortestPathTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ShortestPathTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ShortestPathTest.java
new file mode 100644
index 0000000..bf4a5b7
--- /dev/null
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ShortestPathTest.java
@@ -0,0 +1,353 @@
+/*
+ * 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.process.traversal.step.map;
+
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
+import org.apache.tinkerpop.gremlin.process.GremlinProcessRunner;
+import org.apache.tinkerpop.gremlin.process.computer.search.path.ShortestPathTestHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.CREW;
+import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.GRATEFUL;
+import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
+import static org.apache.tinkerpop.gremlin.process.computer.search.path.ShortestPathVertexProgramTest.ALL_SHORTEST_PATHS;
+import static org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.ShortestPath.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+@RunWith(GremlinProcessRunner.class)
+public abstract class ShortestPathTest extends AbstractGremlinProcessTest {
+
+    private ShortestPathTestHelper helper;
+
+    @Before
+    public void initializeHelper() throws Exception {
+        this.helper = new ShortestPathTestHelper(this, g);
+    }
+
+    public abstract Traversal<Vertex, Path> get_g_V_shortestPath();
+
+    public abstract Traversal<Vertex, Path> get_g_V_both_dedup_shortestPath();
+
+    public abstract Traversal<Vertex, Path> get_g_V_shortestPath_edgesIncluded();
+
+    public abstract Traversal<Vertex, Path> get_g_V_shortestPath_directionXINX();
+
+    public abstract Traversal<Vertex, Path> get_g_V_shortestPath_edgesXoutEX();
+
+    public abstract Traversal<Vertex, Path> get_g_V_shortestPath_edgesIncluded_edgesXoutEX();
+
+    public abstract Traversal<Vertex, Path> get_g_V_hasXname_markoX_shortestPath();
+
+    public abstract Traversal<Vertex, Path> get_g_V_shortestPath_targetXhasXname_markoXX();
+
+    public abstract Traversal<Vertex, Path> get_g_V_shortestPath_targetXvaluesXnameX_isXmarkoXX();
+
+    public abstract Traversal<Vertex, Path> get_g_V_hasXname_markoX_shortestPath_targetXhasLabelXsoftwareXX();
+
+    public abstract Traversal<Vertex, Path> get_g_V_hasXname_markoX_shortestPath_targetXhasXname_joshXX_distanceXweightX();
+
+    public abstract Traversal<Vertex, Path> get_g_V_hasXname_danielX_shortestPath_targetXhasXname_stephenXX_edgesXbothEXusesXX();
+
+    public abstract Traversal<Vertex, Path> get_g_V_hasXsong_name_MIGHT_AS_WELLX_shortestPath_targetXhasXsong_name_MAYBE_YOU_KNOW_HOW_I_FEELXX_edgesXoutEXfollowedByXX_distanceXweightX();
+
+    public abstract Traversal<Vertex, Path> get_g_V_hasXname_markoX_shortestPath_maxDistanceX1X();
+
+    public abstract Traversal<Vertex, Path> get_g_V_hasXname_vadasX_shortestPath_distanceXweightX_maxDistanceX1_3X();
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_shortestPath() {
+        final Traversal<Vertex, Path> traversal = get_g_V_shortestPath();
+        printTraversalForm(traversal);
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS).map(helper::makePath)
+                .collect(Collectors.toList());
+        checkResults(expected, traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_both_dedup_shortestPath() {
+        final Traversal<Vertex, Path> traversal = get_g_V_both_dedup_shortestPath();
+        printTraversalForm(traversal);
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS).map(helper::makePath)
+                .collect(Collectors.toList());
+        checkResults(expected, traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_shortestPath_edgesIncluded() {
+        final Traversal<Vertex, Path> traversal = get_g_V_shortestPath_edgesIncluded();
+        printTraversalForm(traversal);
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS).map(p -> helper.makePath(true, p))
+                .collect(Collectors.toList());
+        checkResults(expected, traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_shortestPath_directionXINX() {
+        final Traversal<Vertex, Path> traversal = get_g_V_shortestPath_directionXINX();
+        printTraversalForm(traversal);
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS)
+                .filter(p -> (p[0].equals("marko") && p.length == 1)
+                        || (p[0].equals("vadas") && Arrays.asList("marko", "vadas").contains(p[p.length - 1]))
+                        || (p[0].equals("lop") && Arrays.asList("marko", "lop", "josh", "peter").contains(p[p.length - 1]))
+                        || (p[0].equals("josh") && Arrays.asList("marko", "josh").contains(p[p.length - 1]))
+                        || (p[0].equals("ripple") && Arrays.asList("marko", "josh", "ripple").contains(p[p.length - 1]))
+                        || (p[0].equals("peter") && p.length == 1))
+                .map(helper::makePath).collect(Collectors.toList());
+        checkResults(expected, traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_shortestPath_edgesXoutEX() {
+        final Traversal<Vertex, Path> traversal = get_g_V_shortestPath_edgesXoutEX();
+        printTraversalForm(traversal);
+        checkOutDirectedPaths(false, traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_shortestPath_edgesIncluded_edgesXoutEX() {
+        final Traversal<Vertex, Path> traversal = get_g_V_shortestPath_edgesIncluded_edgesXoutEX();
+        printTraversalForm(traversal);
+        checkOutDirectedPaths(true, traversal);
+    }
+
+    private void checkOutDirectedPaths(final boolean includeEdges, final Traversal<Vertex, Path> traversal) {
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS)
+                .filter(p -> (p[0].equals("marko") && !p[p.length - 1].equals("peter"))
+                        || (p[0].equals("vadas") && p.length == 1)
+                        || (p[0].equals("lop") && p.length == 1)
+                        || (p[0].equals("josh") && Arrays.asList("lop", "josh", "ripple").contains(p[p.length - 1]))
+                        || (p[0].equals("ripple") && p.length == 1)
+                        || (p[0].equals("peter") && Arrays.asList("lop", "peter").contains(p[p.length - 1])))
+                .map(names -> helper.makePath(includeEdges, names)).collect(Collectors.toList());
+        checkResults(expected, traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_hasXname_markoX_shortestPath() {
+        final Traversal<Vertex, Path> traversal = get_g_V_hasXname_markoX_shortestPath();
+        printTraversalForm(traversal);
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS)
+                .filter(p -> p[0].equals("marko")).map(helper::makePath).collect(Collectors.toList());
+        checkResults(expected, traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_shortestPath_targetXhasXname_markoXX() {
+        final Traversal<Vertex, Path> traversal = get_g_V_shortestPath_targetXhasXname_markoXX();
+        printTraversalForm(traversal);
+        checkPathsToMarko(traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_shortestPath_targetXvaluesXnameX_isXmarkoXX() {
+        final Traversal<Vertex, Path> traversal = get_g_V_shortestPath_targetXvaluesXnameX_isXmarkoXX();
+        printTraversalForm(traversal);
+        checkPathsToMarko(traversal);
+    }
+
+    private void checkPathsToMarko(final Traversal<Vertex, Path> traversal) {
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS)
+                .filter(p -> p[p.length - 1].equals("marko")).map(helper::makePath).collect(Collectors.toList());
+        checkResults(expected, traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_hasXname_markoX_shortestPath_targetXhasLabelXsoftwareXX() {
+        final Traversal<Vertex, Path> traversal = get_g_V_hasXname_markoX_shortestPath_targetXhasLabelXsoftwareXX();
+        printTraversalForm(traversal);
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS)
+                .filter(p ->
+                        p[0].equals("marko") && Arrays.asList("lop", "ripple").contains(p[p.length - 1]))
+                .map(helper::makePath).collect(Collectors.toList());
+        checkResults(expected, traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_hasXname_markoX_shortestPath_targetXhasXname_joshXX_distanceXweightX() {
+        final Traversal<Vertex, Path> traversal = get_g_V_hasXname_markoX_shortestPath_targetXhasXname_joshXX_distanceXweightX();
+        printTraversalForm(traversal);
+        assertTrue(traversal.hasNext());
+        assertEquals(helper.makePath("marko", "lop", "josh"), traversal.next());
+        assertFalse(traversal.hasNext());
+    }
+
+    @Test
+    @LoadGraphWith(CREW)
+    public void g_V_hasXname_danielX_shortestPath_targetXhasXname_stephenXX_edgesXbothEXusesXX() {
+        final Traversal<Vertex, Path> traversal = get_g_V_hasXname_danielX_shortestPath_targetXhasXname_stephenXX_edgesXbothEXusesXX();
+        printTraversalForm(traversal);
+        final List<Path> expected = Arrays.asList(
+                helper.makePath("daniel", "gremlin", "stephen"),
+                helper.makePath("daniel", "tinkergraph", "stephen"));
+        checkResults(expected, traversal);
+    }
+
+    @Test
+    @LoadGraphWith(GRATEFUL)
+    public void g_V_hasXsong_name_MIGHT_AS_WELLX_shortestPath_targetXhasXsong_name_MAYBE_YOU_KNOW_HOW_I_FEELXX_edgesXoutEXfollowedByXX_distanceXweightX() {
+        final Traversal<Vertex, Path> traversal = get_g_V_hasXsong_name_MIGHT_AS_WELLX_shortestPath_targetXhasXsong_name_MAYBE_YOU_KNOW_HOW_I_FEELXX_edgesXoutEXfollowedByXX_distanceXweightX();
+        printTraversalForm(traversal);
+        final List<Path> expected = Arrays.asList(
+                helper.makePath("MIGHT AS WELL", "DRUMS", "MAYBE YOU KNOW HOW I FEEL"),
+                helper.makePath("MIGHT AS WELL", "SHIP OF FOOLS", "MAYBE YOU KNOW HOW I FEEL"));
+        checkResults(expected, traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_hasXname_markoX_shortestPath_maxDistanceX1X() {
+        final Traversal<Vertex, Path> traversal = get_g_V_hasXname_markoX_shortestPath_maxDistanceX1X();
+        printTraversalForm(traversal);
+        final List<Path> expected = Arrays.stream(ALL_SHORTEST_PATHS)
+                .filter(p -> p[0].equals("marko") && p.length <= 2).map(helper::makePath).collect(Collectors.toList());
+        checkResults(expected, traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_hasXname_vadasX_shortestPath_distanceXweightX_maxDistanceX1_3X() {
+        final Traversal<Vertex, Path> traversal = get_g_V_hasXname_vadasX_shortestPath_distanceXweightX_maxDistanceX1_3X();
+        printTraversalForm(traversal);
+        final List<Path> expected = Stream.concat(Arrays.stream(ALL_SHORTEST_PATHS)
+                        .filter(p -> p[0].equals("vadas") &&
+                                Arrays.asList("vadas", "marko", "lop", "peter").contains(p[p.length - 1]))
+                        .map(helper::makePath),
+                Stream.of(helper.makePath("vadas", "marko", "lop", "josh")))
+                .collect(Collectors.toList());
+        checkResults(expected, traversal);
+    }
+
+    public static class Traversals extends ShortestPathTest {
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_shortestPath() {
+            return g.V().shortestPath().dedup();
+        }
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_both_dedup_shortestPath() {
+            return g.V().both().dedup().shortestPath();
+        }
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_shortestPath_edgesIncluded() {
+            return g.V().shortestPath().with(includeEdges, true);
+        }
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_shortestPath_directionXINX() {
+            return g.V().shortestPath().with(edges, Direction.IN);
+        }
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_shortestPath_edgesXoutEX() {
+            return g.V().shortestPath().with(edges, __.outE());
+        }
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_shortestPath_edgesIncluded_edgesXoutEX() {
+            return g.V().shortestPath().with(includeEdges, true).with(edges, __.outE());
+        }
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_hasXname_markoX_shortestPath() {
+            return g.V().has("name", "marko").shortestPath();
+        }
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_shortestPath_targetXhasXname_markoXX() {
+            return g.V().shortestPath().with(target, __.has("name", "marko"));
+        }
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_shortestPath_targetXvaluesXnameX_isXmarkoXX() {
+            return g.V().shortestPath().with(target, __.<Vertex, String>values("name").is("marko"));
+        }
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_hasXname_markoX_shortestPath_targetXhasLabelXsoftwareXX() {
+            return g.V().has("name", "marko").shortestPath().with(target, __.hasLabel("software"));
+        }
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_hasXname_markoX_shortestPath_targetXhasXname_joshXX_distanceXweightX() {
+            return g.V().has("name", "marko").shortestPath()
+                    .with(target, __.has("name","josh"))
+                    .with(distance, "weight");
+        }
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_hasXname_danielX_shortestPath_targetXhasXname_stephenXX_edgesXbothEXusesXX() {
+            return g.V().has("name", "daniel").shortestPath()
+                    .with(target, __.has("name","stephen"))
+                    .with(edges, __.bothE("uses"));
+        }
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_hasXsong_name_MIGHT_AS_WELLX_shortestPath_targetXhasXsong_name_MAYBE_YOU_KNOW_HOW_I_FEELXX_edgesXoutEXfollowedByXX_distanceXweightX() {
+            return g.V().has("song", "name", "MIGHT AS WELL")
+                    .shortestPath().
+                            with(target, __.has("song", "name", "MAYBE YOU KNOW HOW I FEEL")).
+                            with(edges, __.outE("followedBy")).
+                            with(distance, "weight");
+        }
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_hasXname_markoX_shortestPath_maxDistanceX1X() {
+            return g.V().has("name", "marko").shortestPath()
+                    .with(maxDistance, 1);
+        }
+
+        @Override
+        public Traversal<Vertex, Path> get_g_V_hasXname_vadasX_shortestPath_distanceXweightX_maxDistanceX1_3X() {
+            return g.V().has("name", "vadas").shortestPath()
+                    .with(distance, "weight")
+                    .with(maxDistance, 1.3);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7389f019/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 4badaa1..9c9e27e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1268,6 +1268,9 @@ limitations under the License.
                                             org/apache/tinkerpop/gremlin/process/computer/ranking/pagerank/PageRankVertexProgram.java
                                         </include>
                                         <include>
+                                            org/apache/tinkerpop/gremlin/process/computer/search/path/ShortestPathVertexProgram.java
+                                        </include>
+                                        <include>
                                             org/apache/tinkerpop/gremlin/process/computer/traversal/TraversalVertexProgram.java
                                         </include>
                                         <!-- traversal -->


[26/41] tinkerpop git commit: Merge branch 'tp32' into tp33

Posted by dk...@apache.org.
Merge branch 'tp32' into tp33

Conflicts:
	gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java


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

Branch: refs/heads/TINKERPOP-1990
Commit: fa7a7f61308acc675e4a4c4a6dc863cf9818c3f9
Parents: 2cf551f 37476a2
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Aug 7 12:08:39 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Aug 7 12:08:39 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   1 +
 .../driver/message/ResponseStatusCode.java      |   7 +
 .../driver/message/ResponseStatusCodeTest.java  |  36 +++++
 .../gremlin/server/ResponseHandlerContext.java  |  85 +++++++++++
 .../server/op/AbstractEvalOpProcessor.java      |  38 ++++-
 .../gremlin/server/op/AbstractOpProcessor.java  |  34 ++++-
 .../AbstractGremlinServerIntegrationTest.java   |  20 ++-
 .../server/GremlinServerIntegrateTest.java      |  51 +++++++
 .../server/ResponseHandlerContextTest.java      | 143 +++++++++++++++++++
 .../server/op/AbstractEvalOpProcessorTest.java  |  62 ++++++++
 .../server/op/AbstractOpProcessorTest.java      |  73 ++++++++++
 11 files changed, 535 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fa7a7f61/CHANGELOG.asciidoc
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fa7a7f61/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
index 74e9478,ca1ee53..dbf7a44
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
@@@ -242,14 -287,9 +266,14 @@@ public abstract class AbstractEvalOpPro
                      final Iterator itty = IteratorUtils.asIterator(o);
  
                      logger.debug("Preparing to iterate results from - {} - in thread [{}]", msg, Thread.currentThread().getName());
 +                    if (settings.authentication.enableAuditLog) {
 +                        String address = context.getChannelHandlerContext().channel().remoteAddress().toString();
 +                        if (address.startsWith("/") && address.length() > 1) address = address.substring(1);
 +                        auditLogger.info("User with address {} requested: {}", address, script);
 +                    }
  
                      try {
-                         handleIterator(context, itty);
+                         handleIterator(rhc, itty);
                      } catch (Exception ex) {
                          if (managedTransactionsForRequest) attemptRollback(msg, context.getGraphManager(), settings.strictTransactionManagement);
  
@@@ -271,9 -311,16 +295,9 @@@
                      // occurs when the TimedInterruptCustomizerProvider is in play
                      final String errorMessage = String.format("A timeout occurred within the script during evaluation of [%s] - consider increasing the limit given to TimedInterruptCustomizerProvider", msg);
                      logger.warn(errorMessage);
-                     ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
+                     rhc.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
                              .statusMessage("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider")
                              .statusAttributeException(t).create());
 -                } else if (t instanceof org.apache.tinkerpop.gremlin.groovy.jsr223.TimedInterruptTimeoutException) {
 -                    // occurs when the TimedInterruptCustomizerProvider is in play
 -                    final String errorMessage = String.format("A timeout occurred within the script during evaluation of [%s] - consider increasing the limit given to TimedInterruptCustomizerProvider", msg);
 -                    logger.warn(errorMessage);
 -                    rhc.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
 -                            .statusMessage("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider")
 -                            .statusAttributeException(t).create());
                  } else if (t instanceof TimeoutException) {
                      final String errorMessage = String.format("Script evaluation exceeded the configured threshold for request [%s]", msg);
                      logger.warn(errorMessage, t);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fa7a7f61/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
index a1689e9,eb5def9..67ad021
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
@@@ -71,7 -74,9 +72,8 @@@ import org.junit.Test
  import java.lang.reflect.Field;
  import java.nio.channels.ClosedChannelException;
  import java.util.ArrayList;
 -import java.util.Collections;
  import java.util.HashMap;
+ import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;


[11/41] tinkerpop git commit: Added some javadoc CTR

Posted by dk...@apache.org.
Added some javadoc CTR


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

Branch: refs/heads/TINKERPOP-1990
Commit: ce947388e505436d97bcfb55de45d0a52bf8b075
Parents: 7fce137
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Sat Aug 4 06:27:46 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Sat Aug 4 06:27:46 2018 -0400

----------------------------------------------------------------------
 .../apache/tinkerpop/gremlin/driver/Client.java  | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ce947388/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java
index 3da8663..efbc844 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java
@@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.driver.message.RequestMessage;
 import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 import org.slf4j.Logger;
@@ -131,7 +132,10 @@ public abstract class Client {
     }
 
     /**
-     * Submit a {@link Traversal} to the server for remote execution.
+     * Submit a {@link Traversal} to the server for remote execution.Results are returned as {@link Traverser}
+     * instances and are therefore bulked, meaning that to properly iterate the contents of the result each
+     * {@link Traverser#bulk()} must be examined to determine the number of times that object should be presented in
+     * iteration.
      */
     public ResultSet submit(final Traversal traversal) {
         try {
@@ -144,14 +148,19 @@ public abstract class Client {
     }
 
     /**
-     * An asynchronous version of {@link #submit(Traversal)}.
+     * An asynchronous version of {@link #submit(Traversal)}. Results are returned as {@link Traverser} instances and
+     * are therefore bulked, meaning that to properly iterate the contents of the result each {@link Traverser#bulk()}
+     * must be examined to determine the number of times that object should be presented in iteration.
      */
     public CompletableFuture<ResultSet> submitAsync(final Traversal traversal) {
         throw new UnsupportedOperationException("This implementation does not support Traversal submission - use a sessionless Client created with from the alias() method");
     }
 
     /**
-     * Submit a {@link Bytecode} to the server for remote execution.
+     * Submit a {@link Bytecode} to the server for remote execution. Results are returned as {@link Traverser}
+     * instances and are therefore bulked, meaning that to properly iterate the contents of the result each
+     * {@link Traverser#bulk()} must be examined to determine the number of times that object should be presented in
+     * iteration.
      */
     public ResultSet submit(final Bytecode bytecode) {
         try {
@@ -164,7 +173,9 @@ public abstract class Client {
     }
 
     /**
-     * An asynchronous version of {@link #submit(Traversal)}.
+     * An asynchronous version of {@link #submit(Traversal)}. Results are returned as {@link Traverser} instances and
+     * are therefore bulked, meaning that to properly iterate the contents of the result each {@link Traverser#bulk()}
+     * must be examined to determine the number of times that object should be presented in iteration.
      */
     public CompletableFuture<ResultSet> submitAsync(final Bytecode bytecode) {
         throw new UnsupportedOperationException("This implementation does not support Traversal submission - use a sessionless Client created with from the alias() method");


[13/41] tinkerpop git commit: Merge branch 'tp33'

Posted by dk...@apache.org.
Merge branch 'tp33'


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

Branch: refs/heads/TINKERPOP-1990
Commit: 226ef6e4fbcecdc3a08b2ae55c15aca163efe412
Parents: b63bacf b779a2a
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Sat Aug 4 06:28:19 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Sat Aug 4 06:28:19 2018 -0400

----------------------------------------------------------------------
 .../apache/tinkerpop/gremlin/driver/Client.java  | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/226ef6e4/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java
----------------------------------------------------------------------