You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2016/04/20 22:14:07 UTC
[1/6] incubator-tinkerpop git commit: Fixed minor grammatical error
in dev release docs. [Forced Update!]
Repository: incubator-tinkerpop
Updated Branches:
refs/heads/TINKERPOP-1269 38b474a7c -> 75e875700 (forced update)
Fixed minor grammatical error in dev release docs.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/3a4e2af2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/3a4e2af2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/3a4e2af2
Branch: refs/heads/TINKERPOP-1269
Commit: 3a4e2af22dc015c090c85d6efa0c7601a764d605
Parents: da31876
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Apr 20 08:25:38 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Apr 20 08:25:38 2016 -0400
----------------------------------------------------------------------
docs/src/dev/developer/release.asciidoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/3a4e2af2/docs/src/dev/developer/release.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/dev/developer/release.asciidoc b/docs/src/dev/developer/release.asciidoc
index 461919b..36f7434 100644
--- a/docs/src/dev/developer/release.asciidoc
+++ b/docs/src/dev/developer/release.asciidoc
@@ -157,7 +157,7 @@ Release & Promote
. `cd release; svn add xx.yy.zz/; svn ci -m "TinkerPop xx.yy.zz release"`
. Update homepage with references to latest distribution and to other internal links elsewhere on the page.
. Wait for Apache Central to sync the jars and src (link:http://repo1.maven.org/maven2/org/apache/tinkerpop/tinkerpop/[http://repo1.maven.org/maven2/org/apache/tinkerpop/tinkerpop/]).
-. If there is are releases present in SVN that represents lines of code that are no longer under development, then remove those releases. In other words, if `3.1.0-incubating` is present and `3.1.1-incubating` is released then remove `3.1.0-incubating`. However, if `3.0.2-incubating` is present and that line of code is still under potential development, it may stay.
+. If there are releases present in SVN that represents lines of code that are no longer under development, then remove those releases. In other words, if `3.1.0-incubating` is present and `3.1.1-incubating` is released then remove `3.1.0-incubating`. However, if `3.0.2-incubating` is present and that line of code is still under potential development, it may stay.
. Announce release on `dev@`/`gremlin-users@` mailing lists and tweet from `@apachetinkerpop`
Email Templates
[5/6] incubator-tinkerpop git commit: Added ability to pass an
SslContext to the driver.
Posted by sp...@apache.org.
Added ability to pass an SslContext to the driver.
This will be useful if the user needs more complex ssl configuration than the Cluster builder allows.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/99960661
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/99960661
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/99960661
Branch: refs/heads/TINKERPOP-1269
Commit: 9996066189686812befdeb69e33ef2e9a8a6b9b7
Parents: cfa95c8
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Apr 20 13:50:01 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Apr 20 15:07:15 2016 -0400
----------------------------------------------------------------------
.../tinkerpop/gremlin/driver/Channelizer.java | 29 +----
.../tinkerpop/gremlin/driver/Cluster.java | 121 +++++++++++++------
.../server/GremlinServerIntegrateTest.java | 23 ++++
.../GremlinServerSessionIntegrateTest.java | 1 +
4 files changed, 107 insertions(+), 67 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/99960661/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java
index c850a11..40be11c 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java
@@ -23,7 +23,6 @@ import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
-import io.netty.handler.ssl.util.SelfSignedCertificate;
import org.apache.tinkerpop.gremlin.driver.exception.ConnectionException;
import org.apache.tinkerpop.gremlin.driver.handler.NioGremlinRequestEncoder;
import org.apache.tinkerpop.gremlin.driver.handler.NioGremlinResponseDecoder;
@@ -43,9 +42,7 @@ import io.netty.handler.ssl.SslContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.net.ssl.SSLException;
import java.io.File;
-import java.security.cert.CertificateException;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
@@ -120,7 +117,7 @@ public interface Channelizer extends ChannelHandler {
final Optional<SslContext> sslCtx;
if (supportsSsl()) {
try {
- sslCtx = Optional.of(createSSLContext(cluster.connectionPoolSettings()));
+ sslCtx = Optional.of(cluster.createSSLContext());
} catch (Exception ex) {
throw new RuntimeException(ex);
}
@@ -136,30 +133,6 @@ public interface Channelizer extends ChannelHandler {
pipeline.addLast(PIPELINE_GREMLIN_SASL_HANDLER, new Handler.GremlinSaslAuthenticationHandler(cluster.authProperties()));
pipeline.addLast(PIPELINE_GREMLIN_HANDLER, new Handler.GremlinResponseHandler(pending));
}
-
- private SslContext createSSLContext(final Settings.ConnectionPoolSettings sslSettings) throws Exception {
- final SslProvider provider = SslProvider.JDK;
-
- final SslContextBuilder builder = SslContextBuilder.forClient();
- if (cluster.connectionPoolSettings().trustCertChainFile != null)
- builder.trustManager(new File(cluster.connectionPoolSettings().trustCertChainFile));
- else {
- logger.warn("SSL configured without a trustCertChainFile and thus trusts all certificates without verification (not suitable for production)");
- builder.trustManager(InsecureTrustManagerFactory.INSTANCE);
- }
-
- if (null != sslSettings.keyCertChainFile && null != sslSettings.keyFile) {
- final File keyCertChainFile = new File(sslSettings.keyCertChainFile);
- final File keyFile = new File(sslSettings.keyFile);
-
- // note that keyPassword may be null here if the keyFile is not password-protected.
- builder.keyManager(keyCertChainFile, keyFile, sslSettings.keyPassword);
- }
-
- builder.sslProvider(provider);
-
- return builder.build();
- }
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/99960661/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
index 7ae898b..3fa11f7 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
@@ -20,11 +20,17 @@ package org.apache.tinkerpop.gremlin.driver;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelOption;
+import io.netty.handler.ssl.SslContext;
+import io.netty.handler.ssl.SslContextBuilder;
+import io.netty.handler.ssl.SslProvider;
+import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import org.apache.tinkerpop.gremlin.driver.ser.Serializers;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.net.ssl.TrustManager;
import java.io.File;
@@ -38,6 +44,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -52,15 +59,12 @@ import java.util.stream.Collectors;
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
public final class Cluster {
+ private static final Logger logger = LoggerFactory.getLogger(Cluster.class);
private Manager manager;
- private Cluster(final List<InetSocketAddress> contactPoints, final MessageSerializer serializer,
- final int nioPoolSize, final int workerPoolSize,
- final Settings.ConnectionPoolSettings connectionPoolSettings,
- final LoadBalancingStrategy loadBalancingStrategy,
- final AuthProperties authProps) {
- this.manager = new Manager(contactPoints, serializer, nioPoolSize, workerPoolSize, connectionPoolSettings, loadBalancingStrategy, authProps);
+ private Cluster(final Builder builder) {
+ this.manager = new Manager(builder);
}
public synchronized void init() {
@@ -268,6 +272,34 @@ public final class Cluster {
return manager.allHosts();
}
+ SslContext createSSLContext() throws Exception {
+ // if the context is provided then just use that and ignore the other settings
+ if (manager.sslContextOptional.isPresent()) return manager.sslContextOptional.get();
+
+ final SslProvider provider = SslProvider.JDK;
+ final Settings.ConnectionPoolSettings connectionPoolSettings = connectionPoolSettings();
+ final SslContextBuilder builder = SslContextBuilder.forClient();
+
+ if (connectionPoolSettings.trustCertChainFile != null)
+ builder.trustManager(new File(connectionPoolSettings.trustCertChainFile));
+ else {
+ logger.warn("SSL configured without a trustCertChainFile and thus trusts all certificates without verification (not suitable for production)");
+ builder.trustManager(InsecureTrustManagerFactory.INSTANCE);
+ }
+
+ if (null != connectionPoolSettings.keyCertChainFile && null != connectionPoolSettings.keyFile) {
+ final File keyCertChainFile = new File(connectionPoolSettings.keyCertChainFile);
+ final File keyFile = new File(connectionPoolSettings.keyFile);
+
+ // note that keyPassword may be null here if the keyFile is not password-protected.
+ builder.keyManager(keyCertChainFile, keyFile, connectionPoolSettings.keyPassword);
+ }
+
+ builder.sslProvider(provider);
+
+ return builder.build();
+ }
+
public final static class Builder {
private List<InetAddress> addresses = new ArrayList<>();
private int port = 8182;
@@ -292,6 +324,7 @@ public final class Cluster {
private String keyCertChainFile = null;
private String keyFile = null;
private String keyPassword = null;
+ private SslContext sslContext = null;
private LoadBalancingStrategy loadBalancingStrategy = new LoadBalancingStrategy.RoundRobin();
private AuthProperties authProps = new AuthProperties();
@@ -359,6 +392,16 @@ public final class Cluster {
}
/**
+ * Explicitly set the {@code SslContext} for when more flexibility is required in the configuration than is
+ * allowed by the {@link Builder}. If this value is set to something other than {@code null} then all other
+ * related SSL settings are ignored.
+ */
+ public Builder sslContext(final SslContext sslContext) {
+ this.sslContext = sslContext;
+ return this;
+ }
+
+ /**
* File location for a SSL Certificate Chain to use when SSL is enabled. If this value is not provided and
* SSL is enabled, the {@link TrustManager} will be established with a self-signed certificate which is NOT
* suitable for production purposes.
@@ -596,33 +639,13 @@ public final class Cluster {
return this;
}
- private List<InetSocketAddress> getContactPoints() {
+ List<InetSocketAddress> getContactPoints() {
return addresses.stream().map(addy -> new InetSocketAddress(addy, port)).collect(Collectors.toList());
}
public Cluster create() {
if (addresses.size() == 0) addContactPoint("localhost");
- final Settings.ConnectionPoolSettings connectionPoolSettings = new Settings.ConnectionPoolSettings();
- connectionPoolSettings.maxInProcessPerConnection = this.maxInProcessPerConnection;
- connectionPoolSettings.minInProcessPerConnection = this.minInProcessPerConnection;
- connectionPoolSettings.maxSimultaneousUsagePerConnection = this.maxSimultaneousUsagePerConnection;
- connectionPoolSettings.minSimultaneousUsagePerConnection = this.minSimultaneousUsagePerConnection;
- connectionPoolSettings.maxSize = this.maxConnectionPoolSize;
- connectionPoolSettings.minSize = this.minConnectionPoolSize;
- connectionPoolSettings.maxWaitForConnection = this.maxWaitForConnection;
- connectionPoolSettings.maxWaitForSessionClose = this.maxWaitForSessionClose;
- connectionPoolSettings.maxContentLength = this.maxContentLength;
- connectionPoolSettings.reconnectInitialDelay = this.reconnectInitialDelay;
- connectionPoolSettings.reconnectInterval = this.reconnectInterval;
- connectionPoolSettings.resultIterationBatchSize = this.resultIterationBatchSize;
- connectionPoolSettings.enableSsl = this.enableSsl;
- connectionPoolSettings.trustCertChainFile = this.trustCertChainFile;
- connectionPoolSettings.keyCertChainFile = this.keyCertChainFile;
- connectionPoolSettings.keyFile = this.keyFile;
- connectionPoolSettings.keyPassword = this.keyPassword;
- connectionPoolSettings.channelizer = this.channelizer;
- return new Cluster(getContactPoints(), serializer, this.nioPoolSize, this.workerPoolSize,
- connectionPoolSettings, loadBalancingStrategy, authProps);
+ return new Cluster(this);
}
}
@@ -654,22 +677,42 @@ public final class Cluster {
private final Settings.ConnectionPoolSettings connectionPoolSettings;
private final LoadBalancingStrategy loadBalancingStrategy;
private final AuthProperties authProps;
+ private final Optional<SslContext> sslContextOptional;
private final ScheduledExecutorService executor;
private final AtomicReference<CompletableFuture<Void>> closeFuture = new AtomicReference<>();
- private Manager(final List<InetSocketAddress> contactPoints, final MessageSerializer serializer,
- final int nioPoolSize, final int workerPoolSize, final Settings.ConnectionPoolSettings connectionPoolSettings,
- final LoadBalancingStrategy loadBalancingStrategy,
- final AuthProperties authProps) {
- this.loadBalancingStrategy = loadBalancingStrategy;
- this.authProps = authProps;
- this.contactPoints = contactPoints;
- this.connectionPoolSettings = connectionPoolSettings;
- this.factory = new Factory(nioPoolSize);
- this.serializer = serializer;
- this.executor = Executors.newScheduledThreadPool(workerPoolSize,
+ private Manager(final Builder builder) {
+ this.loadBalancingStrategy = builder.loadBalancingStrategy;
+ this.authProps = builder.authProps;
+ this.contactPoints = builder.getContactPoints();
+
+ connectionPoolSettings = new Settings.ConnectionPoolSettings();
+ connectionPoolSettings.maxInProcessPerConnection = builder.maxInProcessPerConnection;
+ connectionPoolSettings.minInProcessPerConnection = builder.minInProcessPerConnection;
+ connectionPoolSettings.maxSimultaneousUsagePerConnection = builder.maxSimultaneousUsagePerConnection;
+ connectionPoolSettings.minSimultaneousUsagePerConnection = builder.minSimultaneousUsagePerConnection;
+ connectionPoolSettings.maxSize = builder.maxConnectionPoolSize;
+ connectionPoolSettings.minSize = builder.minConnectionPoolSize;
+ connectionPoolSettings.maxWaitForConnection = builder.maxWaitForConnection;
+ connectionPoolSettings.maxWaitForSessionClose = builder.maxWaitForSessionClose;
+ connectionPoolSettings.maxContentLength = builder.maxContentLength;
+ connectionPoolSettings.reconnectInitialDelay = builder.reconnectInitialDelay;
+ connectionPoolSettings.reconnectInterval = builder.reconnectInterval;
+ connectionPoolSettings.resultIterationBatchSize = builder.resultIterationBatchSize;
+ connectionPoolSettings.enableSsl = builder.enableSsl;
+ connectionPoolSettings.trustCertChainFile = builder.trustCertChainFile;
+ connectionPoolSettings.keyCertChainFile = builder.keyCertChainFile;
+ connectionPoolSettings.keyFile = builder.keyFile;
+ connectionPoolSettings.keyPassword = builder.keyPassword;
+ connectionPoolSettings.channelizer = builder.channelizer;
+
+ sslContextOptional = Optional.ofNullable(builder.sslContext);
+
+ this.factory = new Factory(builder.nioPoolSize);
+ this.serializer = builder.serializer;
+ this.executor = Executors.newScheduledThreadPool(builder.workerPoolSize,
new BasicThreadFactory.Builder().namingPattern("gremlin-driver-worker-%d").build());
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/99960661/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 fdcf358..ed42d53 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
@@ -19,6 +19,10 @@
package org.apache.tinkerpop.gremlin.server;
import java.io.File;
+
+import io.netty.handler.ssl.SslContextBuilder;
+import io.netty.handler.ssl.SslProvider;
+import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.apache.tinkerpop.gremlin.driver.Client;
@@ -122,6 +126,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
break;
case "shouldEnableSsl":
case "shouldEnableSslButFailIfClientConnectsWithoutIt":
+ case "shouldEnableSslWithSslContextProgrammaticallySpecified":
settings.ssl = new Settings.SslSettings();
settings.ssl.enabled = true;
break;
@@ -272,6 +277,24 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
}
@Test
+ public void shouldEnableSslWithSslContextProgrammaticallySpecified() throws Exception {
+ // just for testing - this is not good for production use
+ final SslContextBuilder builder = SslContextBuilder.forClient();
+ builder.trustManager(InsecureTrustManagerFactory.INSTANCE);
+ builder.sslProvider(SslProvider.JDK);
+
+ final Cluster cluster = Cluster.build().enableSsl(true).sslContext(builder.build()).create();
+ final Client client = cluster.connect();
+
+ try {
+ // this should return "nothing" - there should be no exception
+ assertEquals("test", client.submit("'test'").one().getString());
+ } finally {
+ cluster.close();
+ }
+ }
+
+ @Test
public void shouldEnableSslButFailIfClientConnectsWithoutIt() {
final Cluster cluster = Cluster.build().enableSsl(false).create();
final Client client = cluster.connect();
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/99960661/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSessionIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSessionIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSessionIntegrateTest.java
index 208aaef..15b2c4b 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSessionIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSessionIntegrateTest.java
@@ -119,6 +119,7 @@ public class GremlinServerSessionIntegrateTest extends AbstractGremlinServerInt
fail("Should have tossed the manually generated exception");
} catch (Exception ex) {
final Throwable root = ExceptionUtils.getRootCause(ex);
+ ex.printStackTrace();
assertEquals("no worky", root.getMessage());
// just force a commit here of "something" in case there is something lingering
[3/6] incubator-tinkerpop git commit: Added docs for new SSL settings
on the driver side.
Posted by sp...@apache.org.
Added docs for new SSL settings on the driver side.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/cfa95c8a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/cfa95c8a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/cfa95c8a
Branch: refs/heads/TINKERPOP-1269
Commit: cfa95c8a29b4e27c9fd8e047a5e3631f915de005
Parents: 5741616
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Apr 19 14:02:12 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Apr 20 15:07:15 2016 -0400
----------------------------------------------------------------------
docs/src/reference/gremlin-applications.asciidoc | 3 +++
1 file changed, 3 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/cfa95c8a/docs/src/reference/gremlin-applications.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index 9beae1f..410dfe1 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -610,6 +610,9 @@ The following table describes the various configuration options for the Gremlin
|Key |Description |Default
|connectionPool.channelizer |The fully qualified classname of the client `Channelizer` that defines how to connect to the server. |`Channelizer.WebSocketChannelizer`
|connectionPool.enableSsl |Determines if SSL should be enabled or not. If enabled on the server then it must be enabled on the client. |false
+|connectionPool.keyCertChainFile |The X.509 certificate chain file in PEM format. |_none_
+|connectionPool.keyFile |The `PKCS#8` private key file in PEM format. |_none_
+|connectionPool.keyPassword |The password of the `keyFile` if it's not password-protected |_none_
|connectionPool.maxContentLength |The maximum length in bytes that a message can be sent to the server. This number can be no greater than the setting of the same name in the server configuration. |65536
|connectionPool.maxInProcessPerConnection |The maximum number of in-flight requests that can occur on a connection. |4
|connectionPool.maxSimultaneousUsagePerConnection |The maximum number of times that a connection can be borrowed from the pool simultaneously. |16
[2/6] incubator-tinkerpop git commit: Minor fixes to session tests
for Gremlin Server CTR
Posted by sp...@apache.org.
Minor fixes to session tests for Gremlin Server CTR
Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/ec730eb7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/ec730eb7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/ec730eb7
Branch: refs/heads/TINKERPOP-1269
Commit: ec730eb774c8e17475fc813a89ff5b9c488fa12b
Parents: 3a4e2af
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Apr 20 15:05:22 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Apr 20 15:05:22 2016 -0400
----------------------------------------------------------------------
.../gremlin/server/GremlinServerSessionIntegrateTest.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ec730eb7/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSessionIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSessionIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSessionIntegrateTest.java
index 56336fa..208aaef 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSessionIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSessionIntegrateTest.java
@@ -44,6 +44,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
@@ -108,6 +109,8 @@ public class GremlinServerSessionIntegrateTest extends AbstractGremlinServerInt
@Test
public void shouldRollbackOnEvalExceptionForManagedTransaction() throws Exception {
+ assumeNeo4jIsPresent();
+
final Cluster cluster = Cluster.build().create();
final Client client = cluster.connect(name.getMethodName(), true);
@@ -215,7 +218,7 @@ public class GremlinServerSessionIntegrateTest extends AbstractGremlinServerInt
assertEquals(requests, futures.size());
for(CompletableFuture<ResultSet> f : futures) {
- final Result r = f.get().one();
+ final Result r = f.get().all().get(3000, TimeUnit.MILLISECONDS).get(0);
assertEquals(11100, r.getInt());
}
[6/6] incubator-tinkerpop git commit: Added configuration for
overriding the Gremlin Server SSL config with SslContext.
Posted by sp...@apache.org.
Added configuration for overriding the Gremlin Server SSL config with SslContext.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/75e87570
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/75e87570
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/75e87570
Branch: refs/heads/TINKERPOP-1269
Commit: 75e875700201013df7b2323a7a11907c0b9ce500
Parents: 9996066
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Apr 20 16:13:24 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Apr 20 16:13:24 2016 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
.../tinkerpop/gremlin/driver/Cluster.java | 3 +-
.../gremlin/server/AbstractChannelizer.java | 6 +
.../tinkerpop/gremlin/server/Settings.java | 16 +
.../server/GremlinServerIntegrateTest.java | 853 ++++++++++---------
5 files changed, 461 insertions(+), 418 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/75e87570/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 32b534d..c2ae91d 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,7 @@ image::https://raw.githubusercontent.com/apache/incubator-tinkerpop/master/docs/
TinkerPop 3.1.3 (NOT OFFICIALLY RELEASED YET)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* Added configuration options to Gremlin Driver and Server to override the SSL configuration with an `SslContext`.
* Added driver configuration settings for SSL: `keyCertChainFile`, `keyFile` and `keyPassword`.
* Fixed bug where transaction managed sessions were not properly rolling back transactions for exceptions encountered during script evaluation.
* Fixed bug in `:uninstall` command if the default `/ext` directory was not used.
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/75e87570/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
index 3fa11f7..f033dc3 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
@@ -394,7 +394,8 @@ public final class Cluster {
/**
* Explicitly set the {@code SslContext} for when more flexibility is required in the configuration than is
* allowed by the {@link Builder}. If this value is set to something other than {@code null} then all other
- * related SSL settings are ignored.
+ * related SSL settings are ignored. The {@link #enableSsl} setting should still be set to {@code true} for
+ * this setting to take effect.
*/
public Builder sslContext(final SslContext sslContext) {
this.sslContext = sslContext;
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/75e87570/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
index 41d909e..829a3ee 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
@@ -195,6 +195,12 @@ public abstract class AbstractChannelizer extends ChannelInitializer<SocketChann
private SslContext createSSLContext(final Settings settings) {
final Settings.SslSettings sslSettings = settings.ssl;
+
+ if (sslSettings.getSslContext().isPresent()) {
+ logger.info("Using the SslContext override");
+ return sslSettings.getSslContext().get();
+ }
+
final SslProvider provider = SslProvider.JDK;
final SslContextBuilder builder;
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/75e87570/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
index a6f59cd..b5d69f0 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
@@ -18,6 +18,7 @@
*/
package org.apache.tinkerpop.gremlin.server;
+import io.netty.handler.ssl.SslContext;
import org.apache.tinkerpop.gremlin.driver.MessageSerializer;
import org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
@@ -406,6 +407,21 @@ public class Settings {
* contain an X.509 certificate chain in PEM format. {@code null} uses the system default.
*/
public String trustCertChainFile = null;
+
+ private SslContext sslContext;
+
+ /**
+ * When this value is set, the other settings for SSL are ignored. This option provides for a programmatic
+ * way to configure more complex SSL configurations. The {@link #enabled} setting should still be set to
+ * {@code true} for this setting to take effect.
+ */
+ public void overrideSslContext(final SslContext sslContext) {
+ this.sslContext = sslContext;
+ }
+
+ public Optional<SslContext> getSslContext() {
+ return Optional.ofNullable(sslContext);
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/75e87570/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 ed42d53..c438e63 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
@@ -20,9 +20,11 @@ package org.apache.tinkerpop.gremlin.server;
import java.io.File;
+import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
+import io.netty.handler.ssl.util.SelfSignedCertificate;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.apache.tinkerpop.gremlin.driver.Client;
@@ -53,6 +55,7 @@ import org.junit.Before;
import org.junit.Test;
import java.nio.channels.ClosedChannelException;
+import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -126,9 +129,13 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
break;
case "shouldEnableSsl":
case "shouldEnableSslButFailIfClientConnectsWithoutIt":
+ settings.ssl = new Settings.SslSettings();
+ settings.ssl.enabled = true;
+ break;
case "shouldEnableSslWithSslContextProgrammaticallySpecified":
settings.ssl = new Settings.SslSettings();
settings.ssl.enabled = true;
+ settings.ssl.overrideSslContext(createServerSslContext());
break;
case "shouldStartWithDefaultSettings":
return new Settings();
@@ -159,6 +166,18 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
return settings;
}
+ private static SslContext createServerSslContext() {
+ final SslProvider provider = SslProvider.JDK;
+
+ try {
+ // this is not good for production - just testing
+ final SelfSignedCertificate ssc = new SelfSignedCertificate();
+ return SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).sslProvider(provider).build();
+ } catch (Exception ce) {
+ throw new RuntimeException("Couldn't setup self-signed certificate for test");
+ }
+ }
+
private static Map<String, Object> getScriptEngineConfForSimpleSandbox() {
final Map<String,Object> scriptEngineConf = new HashMap<>();
final Map<String,Object> compilerCustomizerProviderConf = new HashMap<>();
@@ -310,421 +329,421 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
}
}
- @Test
- public void shouldRespectHighWaterMarkSettingAndSucceed() throws Exception {
- // the highwatermark should get exceeded on the server and thus pause the writes, but have no problem catching
- // itself up - this is a tricky tests to get passing on all environments so this assumption will deny the
- // test for most cases
- assumeThat("Set the 'assertNonDeterministic' property to true to execute this test",
- System.getProperty("assertNonDeterministic"), is("true"));
-
- final Cluster cluster = Cluster.open();
- final Client client = cluster.connect();
-
- try {
- final int resultCountToGenerate = 1000;
- final int batchSize = 3;
- final String fatty = IntStream.range(0, 175).mapToObj(String::valueOf).collect(Collectors.joining());
- final String fattyX = "['" + fatty + "'] * " + resultCountToGenerate;
-
- // don't allow the thread to proceed until all results are accounted for
- final CountDownLatch latch = new CountDownLatch(resultCountToGenerate);
- final AtomicBoolean expected = new AtomicBoolean(false);
- final AtomicBoolean faulty = new AtomicBoolean(false);
- final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
- .addArg(Tokens.ARGS_BATCH_SIZE, batchSize)
- .addArg(Tokens.ARGS_GREMLIN, fattyX).create();
-
- client.submitAsync(request).thenAcceptAsync(r -> {
- r.stream().forEach(item -> {
- try {
- final String aFattyResult = item.getString();
- expected.set(aFattyResult.equals(fatty));
- } catch (Exception ex) {
- ex.printStackTrace();
- faulty.set(true);
- } finally {
- latch.countDown();
- }
- });
- });
-
- assertTrue(latch.await(30000, TimeUnit.MILLISECONDS));
- assertEquals(0, latch.getCount());
- assertFalse(faulty.get());
- assertTrue(expected.get());
-
- assertTrue(recordingAppender.getMessages().stream().anyMatch(m -> m.contains("Pausing response writing as writeBufferHighWaterMark exceeded on")));
- } catch (Exception ex) {
- fail("Shouldn't have tossed an exception");
- } finally {
- cluster.close();
- }
- }
-
- @Test
- public void shouldReturnInvalidRequestArgsWhenGremlinArgIsNotSupplied() throws Exception {
- try (SimpleClient client = new WebSocketClient()) {
- final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL).create();
- final ResponseMessage result = client.submit(request).get(0);
- assertThat(result.getStatus().getCode(), is(not(ResponseStatusCode.PARTIAL_CONTENT)));
- assertEquals(result.getStatus().getCode(), ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS);
- }
- }
-
- @Test
- public void shouldReturnInvalidRequestArgsWhenInvalidReservedBindingKeyIsUsed() throws Exception {
- try (SimpleClient client = new WebSocketClient()) {
- final Map<String, Object> bindings = new HashMap<>();
- bindings.put(T.id.getAccessor(), "123");
- final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
- .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
- .addArg(Tokens.ARGS_BINDINGS, bindings).create();
- final CountDownLatch latch = new CountDownLatch(1);
- final AtomicBoolean pass = new AtomicBoolean(false);
- client.submit(request, result -> {
- if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
- pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
- latch.countDown();
- }
- });
-
- if (!latch.await(3000, TimeUnit.MILLISECONDS))
- fail("Request should have returned error, but instead timed out");
- assertTrue(pass.get());
- }
- }
-
- @Test
- public void shouldReturnInvalidRequestArgsWhenInvalidTypeBindingKeyIsUsed() throws Exception {
- try (SimpleClient client = new WebSocketClient()) {
- final Map<Object, Object> bindings = new HashMap<>();
- bindings.put(1, "123");
- final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
- .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
- .addArg(Tokens.ARGS_BINDINGS, bindings).create();
- final CountDownLatch latch = new CountDownLatch(1);
- final AtomicBoolean pass = new AtomicBoolean(false);
- client.submit(request, result -> {
- if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
- pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
- latch.countDown();
- }
- });
-
- if (!latch.await(3000, TimeUnit.MILLISECONDS))
- fail("Request should have returned error, but instead timed out");
- assertTrue(pass.get());
- }
- }
-
- @Test
- public void shouldReturnInvalidRequestArgsWhenInvalidNullBindingKeyIsUsed() throws Exception {
- try (SimpleClient client = new WebSocketClient()) {
- final Map<String, Object> bindings = new HashMap<>();
- bindings.put(null, "123");
- final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
- .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
- .addArg(Tokens.ARGS_BINDINGS, bindings).create();
- final CountDownLatch latch = new CountDownLatch(1);
- final AtomicBoolean pass = new AtomicBoolean(false);
- client.submit(request, result -> {
- if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
- pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
- latch.countDown();
- }
- });
-
- if (!latch.await(3000, TimeUnit.MILLISECONDS))
- fail("Request should have returned error, but instead timed out");
- assertTrue(pass.get());
- }
- }
-
- @Test
- @SuppressWarnings("unchecked")
- public void shouldBatchResultsByTwos() throws Exception {
- try (SimpleClient client = new WebSocketClient()) {
- final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
- .addArg(Tokens.ARGS_GREMLIN, "[0,1,2,3,4,5,6,7,8,9]").create();
-
- final List<ResponseMessage> msgs = client.submit(request);
- assertEquals(5, client.submit(request).size());
- assertEquals(0, ((List<Integer>) msgs.get(0).getResult().getData()).get(0).intValue());
- assertEquals(1, ((List<Integer>) msgs.get(0).getResult().getData()).get(1).intValue());
- assertEquals(2, ((List<Integer>) msgs.get(1).getResult().getData()).get(0).intValue());
- assertEquals(3, ((List<Integer>) msgs.get(1).getResult().getData()).get(1).intValue());
- assertEquals(4, ((List<Integer>) msgs.get(2).getResult().getData()).get(0).intValue());
- assertEquals(5, ((List<Integer>) msgs.get(2).getResult().getData()).get(1).intValue());
- assertEquals(6, ((List<Integer>) msgs.get(3).getResult().getData()).get(0).intValue());
- assertEquals(7, ((List<Integer>) msgs.get(3).getResult().getData()).get(1).intValue());
- assertEquals(8, ((List<Integer>) msgs.get(4).getResult().getData()).get(0).intValue());
- assertEquals(9, ((List<Integer>) msgs.get(4).getResult().getData()).get(1).intValue());
- }
- }
-
- @Test
- @SuppressWarnings("unchecked")
- public void shouldBatchResultsByOnesByOverridingFromClientSide() throws Exception {
- try (SimpleClient client = new WebSocketClient()) {
- final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
- .addArg(Tokens.ARGS_GREMLIN, "[0,1,2,3,4,5,6,7,8,9]")
- .addArg(Tokens.ARGS_BATCH_SIZE, 1).create();
-
- final List<ResponseMessage> msgs = client.submit(request);
- assertEquals(10, msgs.size());
- IntStream.rangeClosed(0, 9).forEach(i -> assertEquals(i, ((List<Integer>) msgs.get(i).getResult().getData()).get(0).intValue()));
- }
- }
-
- @Test
- @SuppressWarnings("unchecked")
- public void shouldWorkOverNioTransport() throws Exception {
- try (SimpleClient client = new NioClient()) {
- final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
- .addArg(Tokens.ARGS_GREMLIN, "[0,1,2,3,4,5,6,7,8,9,]").create();
-
- final List<ResponseMessage> msg = client.submit(request);
- assertEquals(1, msg.size());
- final List<Integer> integers = (List<Integer>) msg.get(0).getResult().getData();
- IntStream.rangeClosed(0, 9).forEach(i -> assertEquals(i, integers.get(i).intValue()));
- }
- }
-
- @Test
- public void shouldNotThrowNoSuchElementException() throws Exception {
- try (SimpleClient client = new WebSocketClient()){
- // this should return "nothing" - there should be no exception
- final List<ResponseMessage> responses = client.submit("g.V().has('name','kadfjaldjfla')");
- assertNull(responses.get(0).getResult().getData());
- }
- }
-
- @Test
- @SuppressWarnings("unchecked")
- public void shouldReceiveFailureTimeOutOnScriptEval() throws Exception {
- try (SimpleClient client = new WebSocketClient()){
- final List<ResponseMessage> responses = client.submit("Thread.sleep(3000);'some-stuff-that-should not return'");
- assertThat(responses.get(0).getStatus().getMessage(), startsWith("Script evaluation exceeded the configured 'scriptEvaluationTimeout' threshold of 200 ms for request"));
-
- // validate that we can still send messages to the server
- assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
- }
- }
-
- @Test
- @SuppressWarnings("unchecked")
- public void shouldReceiveFailureTimeOutOnScriptEvalUsingOverride() throws Exception {
- try (SimpleClient client = new WebSocketClient()) {
- final RequestMessage msg = RequestMessage.build("eval")
- .addArg(Tokens.ARGS_SCRIPT_EVAL_TIMEOUT, 100)
- .addArg(Tokens.ARGS_GREMLIN, "Thread.sleep(3000);'some-stuff-that-should not return'")
- .create();
- final List<ResponseMessage> responses = client.submit(msg);
- assertThat(responses.get(0).getStatus().getMessage(), startsWith("Script evaluation exceeded the configured 'scriptEvaluationTimeout' threshold of 100 ms for request"));
-
- // validate that we can still send messages to the server
- assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
- }
- }
-
- @Test
- public void shouldReceiveFailureTimeOutOnScriptEvalOfOutOfControlLoop() throws Exception {
- try (SimpleClient client = new WebSocketClient()){
- // timeout configured for 1 second so the timed interrupt should trigger prior to the
- // scriptEvaluationTimeout which is at 30 seconds by default
- final List<ResponseMessage> responses = client.submit("while(true){}");
- assertThat(responses.get(0).getStatus().getMessage(), startsWith("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider"));
-
- // validate that we can still send messages to the server
- assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
- }
- }
-
- @Test
- @SuppressWarnings("unchecked")
- public void shouldReceiveFailureTimeOutOnTotalSerialization() throws Exception {
- try (SimpleClient client = new WebSocketClient()){
- final List<ResponseMessage> responses = client.submit("(0..<100000)");
-
- // the last message should contain the error
- assertThat(responses.get(responses.size() - 1).getStatus().getMessage(), endsWith("Serialization of the entire response exceeded the 'serializeResponseTimeout' setting"));
-
- // validate that we can still send messages to the server
- assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
- }
- }
-
- @Test
- @SuppressWarnings("unchecked")
- public void shouldLoadInitScript() throws Exception {
- try (SimpleClient client = new WebSocketClient()){
- assertEquals(2, ((List<Integer>) client.submit("addItUp(1,1)").get(0).getResult().getData()).get(0).intValue());
- }
- }
-
- @Test
- public void shouldGarbageCollectPhantomButNotHard() throws Exception {
- final Cluster cluster = Cluster.open();
- final Client client = cluster.connect();
-
- assertEquals(2, client.submit("addItUp(1,1)").all().join().get(0).getInt());
- assertEquals(0, client.submit("def subtract(x,y){x-y};subtract(1,1)").all().join().get(0).getInt());
- assertEquals(0, client.submit("subtract(1,1)").all().join().get(0).getInt());
-
- final Map<String, Object> bindings = new HashMap<>();
- bindings.put(GremlinGroovyScriptEngine.KEY_REFERENCE_TYPE, GremlinGroovyScriptEngine.REFERENCE_TYPE_PHANTOM);
- assertEquals(4, client.submit("def multiply(x,y){x*y};multiply(2,2)", bindings).all().join().get(0).getInt());
-
- try {
- client.submit("multiply(2,2)").all().join().get(0).getInt();
- fail("Should throw an exception since reference is phantom.");
- } catch (RuntimeException ignored) {
-
- } finally {
- cluster.close();
- }
- }
-
- @Test
- public void shouldReceiveFailureOnBadGraphSONSerialization() throws Exception {
- final Cluster cluster = Cluster.build("localhost").serializer(Serializers.GRAPHSON_V1D0).create();
- final Client client = cluster.connect();
-
- try {
- client.submit("def class C { def C getC(){return this}}; new C()").all().join();
- fail("Should throw an exception.");
- } catch (RuntimeException re) {
- final Throwable root = ExceptionUtils.getRootCause(re);
- assertThat(root.getMessage(), CoreMatchers.startsWith("Error during serialization: Direct self-reference leading to cycle (through reference chain:"));
-
- // validate that we can still send messages to the server
- assertEquals(2, client.submit("1+1").all().join().get(0).getInt());
- } finally {
- cluster.close();
- }
- }
-
- @Test
- public void shouldReceiveFailureOnBadGryoSerialization() throws Exception {
- final Cluster cluster = Cluster.build("localhost").serializer(Serializers.GRYO_V1D0).create();
- final Client client = cluster.connect();
-
- try {
- client.submit("java.awt.Color.RED").all().join();
- fail("Should throw an exception.");
- } catch (RuntimeException re) {
- final Throwable root = ExceptionUtils.getRootCause(re);
- assertThat(root.getMessage(), CoreMatchers.startsWith("Error during serialization: Class is not registered: java.awt.Color"));
-
- // validate that we can still send messages to the server
- assertEquals(2, client.submit("1+1").all().join().get(0).getInt());
- } finally {
- cluster.close();
- }
- }
-
- @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
- @Test
- public void shouldBlockRequestWhenTooBig() throws Exception {
- final Cluster cluster = Cluster.open();
- final Client client = cluster.connect();
-
- try {
- final String fatty = IntStream.range(0, 1024).mapToObj(String::valueOf).collect(Collectors.joining());
- final CompletableFuture<ResultSet> result = client.submitAsync("'" + fatty + "';'test'");
- final ResultSet resultSet = result.get(10000, TimeUnit.MILLISECONDS);
- resultSet.all().get(10000, TimeUnit.MILLISECONDS);
- fail("Should throw an exception.");
- } catch (TimeoutException te) {
- // the request should not have timed-out - the connection should have been reset, but it seems that
- // timeout seems to occur as well on some systems (it's not clear why). however, the nature of this
- // test is to ensure that the script isn't processed if it exceeds a certain size, so in this sense
- // it seems ok to pass in this case.
- } catch (Exception re) {
- final Throwable root = ExceptionUtils.getRootCause(re);
- assertEquals("Connection reset by peer", root.getMessage());
-
- // validate that we can still send messages to the server
- assertEquals(2, client.submit("1+1").all().join().get(0).getInt());
- } finally {
- cluster.close();
- }
- }
-
- @Test
- public void shouldFailOnDeadHost() throws Exception {
- final Cluster cluster = Cluster.build("localhost").create();
- final Client client = cluster.connect();
-
- // ensure that connection to server is good
- assertEquals(2, client.submit("1+1").all().join().get(0).getInt());
-
- // kill the server which will make the client mark the host as unavailable
- this.stopServer();
-
- try {
- // try to re-issue a request now that the server is down
- client.submit("1+1").all().join();
- fail();
- } catch (RuntimeException re) {
- assertTrue(re.getCause().getCause() instanceof ClosedChannelException);
-
- //
- // should recover when the server comes back
- //
-
- // restart server
- this.startServer();
- // the retry interval is 1 second, wait a bit longer
- TimeUnit.SECONDS.sleep(5);
-
- List<Result> results = client.submit("1+1").all().join();
- assertEquals(1, results.size());
- assertEquals(2, results.get(0).getInt());
-
- } finally {
- cluster.close();
- }
- }
-
- @Test
- public void shouldNotHavePartialContentWithOneResult() throws Exception {
- try (SimpleClient client = new WebSocketClient()) {
- final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
- .addArg(Tokens.ARGS_GREMLIN, "10").create();
- final List<ResponseMessage> responses = client.submit(request);
- assertEquals(1, responses.size());
- assertEquals(ResponseStatusCode.SUCCESS, responses.get(0).getStatus().getCode());
- }
- }
-
- @Test
- public void shouldFailWithBadScriptEval() throws Exception {
- try (SimpleClient client = new WebSocketClient()) {
- final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
- .addArg(Tokens.ARGS_GREMLIN, "new String().doNothingAtAllBecauseThis is a syntax error").create();
- final List<ResponseMessage> responses = client.submit(request);
- assertEquals(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION, responses.get(0).getStatus().getCode());
- assertEquals(1, responses.size());
- }
- }
-
- @Test
- @SuppressWarnings("unchecked")
- public void shouldStillSupportDeprecatedRebindingsParameterOnServer() throws Exception {
- // this test can be removed when the rebindings arg is removed
- try (SimpleClient client = new WebSocketClient()) {
- final Map<String,String> rebindings = new HashMap<>();
- rebindings.put("xyz", "graph");
- final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
- .addArg(Tokens.ARGS_GREMLIN, "xyz.addVertex('name','jason')")
- .addArg(Tokens.ARGS_REBINDINGS, rebindings).create();
- final List<ResponseMessage> responses = client.submit(request);
- assertEquals(1, responses.size());
-
- final DetachedVertex v = ((ArrayList<DetachedVertex>) responses.get(0).getResult().getData()).get(0);
- assertEquals("jason", v.value("name"));
- }
- }
+// @Test
+// public void shouldRespectHighWaterMarkSettingAndSucceed() throws Exception {
+// // the highwatermark should get exceeded on the server and thus pause the writes, but have no problem catching
+// // itself up - this is a tricky tests to get passing on all environments so this assumption will deny the
+// // test for most cases
+// assumeThat("Set the 'assertNonDeterministic' property to true to execute this test",
+// System.getProperty("assertNonDeterministic"), is("true"));
+//
+// final Cluster cluster = Cluster.open();
+// final Client client = cluster.connect();
+//
+// try {
+// final int resultCountToGenerate = 1000;
+// final int batchSize = 3;
+// final String fatty = IntStream.range(0, 175).mapToObj(String::valueOf).collect(Collectors.joining());
+// final String fattyX = "['" + fatty + "'] * " + resultCountToGenerate;
+//
+// // don't allow the thread to proceed until all results are accounted for
+// final CountDownLatch latch = new CountDownLatch(resultCountToGenerate);
+// final AtomicBoolean expected = new AtomicBoolean(false);
+// final AtomicBoolean faulty = new AtomicBoolean(false);
+// final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+// .addArg(Tokens.ARGS_BATCH_SIZE, batchSize)
+// .addArg(Tokens.ARGS_GREMLIN, fattyX).create();
+//
+// client.submitAsync(request).thenAcceptAsync(r -> {
+// r.stream().forEach(item -> {
+// try {
+// final String aFattyResult = item.getString();
+// expected.set(aFattyResult.equals(fatty));
+// } catch (Exception ex) {
+// ex.printStackTrace();
+// faulty.set(true);
+// } finally {
+// latch.countDown();
+// }
+// });
+// });
+//
+// assertTrue(latch.await(30000, TimeUnit.MILLISECONDS));
+// assertEquals(0, latch.getCount());
+// assertFalse(faulty.get());
+// assertTrue(expected.get());
+//
+// assertTrue(recordingAppender.getMessages().stream().anyMatch(m -> m.contains("Pausing response writing as writeBufferHighWaterMark exceeded on")));
+// } catch (Exception ex) {
+// fail("Shouldn't have tossed an exception");
+// } finally {
+// cluster.close();
+// }
+// }
+//
+// @Test
+// public void shouldReturnInvalidRequestArgsWhenGremlinArgIsNotSupplied() throws Exception {
+// try (SimpleClient client = new WebSocketClient()) {
+// final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL).create();
+// final ResponseMessage result = client.submit(request).get(0);
+// assertThat(result.getStatus().getCode(), is(not(ResponseStatusCode.PARTIAL_CONTENT)));
+// assertEquals(result.getStatus().getCode(), ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS);
+// }
+// }
+//
+// @Test
+// public void shouldReturnInvalidRequestArgsWhenInvalidReservedBindingKeyIsUsed() throws Exception {
+// try (SimpleClient client = new WebSocketClient()) {
+// final Map<String, Object> bindings = new HashMap<>();
+// bindings.put(T.id.getAccessor(), "123");
+// final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+// .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
+// .addArg(Tokens.ARGS_BINDINGS, bindings).create();
+// final CountDownLatch latch = new CountDownLatch(1);
+// final AtomicBoolean pass = new AtomicBoolean(false);
+// client.submit(request, result -> {
+// if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
+// pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
+// latch.countDown();
+// }
+// });
+//
+// if (!latch.await(3000, TimeUnit.MILLISECONDS))
+// fail("Request should have returned error, but instead timed out");
+// assertTrue(pass.get());
+// }
+// }
+//
+// @Test
+// public void shouldReturnInvalidRequestArgsWhenInvalidTypeBindingKeyIsUsed() throws Exception {
+// try (SimpleClient client = new WebSocketClient()) {
+// final Map<Object, Object> bindings = new HashMap<>();
+// bindings.put(1, "123");
+// final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+// .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
+// .addArg(Tokens.ARGS_BINDINGS, bindings).create();
+// final CountDownLatch latch = new CountDownLatch(1);
+// final AtomicBoolean pass = new AtomicBoolean(false);
+// client.submit(request, result -> {
+// if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
+// pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
+// latch.countDown();
+// }
+// });
+//
+// if (!latch.await(3000, TimeUnit.MILLISECONDS))
+// fail("Request should have returned error, but instead timed out");
+// assertTrue(pass.get());
+// }
+// }
+//
+// @Test
+// public void shouldReturnInvalidRequestArgsWhenInvalidNullBindingKeyIsUsed() throws Exception {
+// try (SimpleClient client = new WebSocketClient()) {
+// final Map<String, Object> bindings = new HashMap<>();
+// bindings.put(null, "123");
+// final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+// .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
+// .addArg(Tokens.ARGS_BINDINGS, bindings).create();
+// final CountDownLatch latch = new CountDownLatch(1);
+// final AtomicBoolean pass = new AtomicBoolean(false);
+// client.submit(request, result -> {
+// if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
+// pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
+// latch.countDown();
+// }
+// });
+//
+// if (!latch.await(3000, TimeUnit.MILLISECONDS))
+// fail("Request should have returned error, but instead timed out");
+// assertTrue(pass.get());
+// }
+// }
+//
+// @Test
+// @SuppressWarnings("unchecked")
+// public void shouldBatchResultsByTwos() throws Exception {
+// try (SimpleClient client = new WebSocketClient()) {
+// final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+// .addArg(Tokens.ARGS_GREMLIN, "[0,1,2,3,4,5,6,7,8,9]").create();
+//
+// final List<ResponseMessage> msgs = client.submit(request);
+// assertEquals(5, client.submit(request).size());
+// assertEquals(0, ((List<Integer>) msgs.get(0).getResult().getData()).get(0).intValue());
+// assertEquals(1, ((List<Integer>) msgs.get(0).getResult().getData()).get(1).intValue());
+// assertEquals(2, ((List<Integer>) msgs.get(1).getResult().getData()).get(0).intValue());
+// assertEquals(3, ((List<Integer>) msgs.get(1).getResult().getData()).get(1).intValue());
+// assertEquals(4, ((List<Integer>) msgs.get(2).getResult().getData()).get(0).intValue());
+// assertEquals(5, ((List<Integer>) msgs.get(2).getResult().getData()).get(1).intValue());
+// assertEquals(6, ((List<Integer>) msgs.get(3).getResult().getData()).get(0).intValue());
+// assertEquals(7, ((List<Integer>) msgs.get(3).getResult().getData()).get(1).intValue());
+// assertEquals(8, ((List<Integer>) msgs.get(4).getResult().getData()).get(0).intValue());
+// assertEquals(9, ((List<Integer>) msgs.get(4).getResult().getData()).get(1).intValue());
+// }
+// }
+//
+// @Test
+// @SuppressWarnings("unchecked")
+// public void shouldBatchResultsByOnesByOverridingFromClientSide() throws Exception {
+// try (SimpleClient client = new WebSocketClient()) {
+// final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+// .addArg(Tokens.ARGS_GREMLIN, "[0,1,2,3,4,5,6,7,8,9]")
+// .addArg(Tokens.ARGS_BATCH_SIZE, 1).create();
+//
+// final List<ResponseMessage> msgs = client.submit(request);
+// assertEquals(10, msgs.size());
+// IntStream.rangeClosed(0, 9).forEach(i -> assertEquals(i, ((List<Integer>) msgs.get(i).getResult().getData()).get(0).intValue()));
+// }
+// }
+//
+// @Test
+// @SuppressWarnings("unchecked")
+// public void shouldWorkOverNioTransport() throws Exception {
+// try (SimpleClient client = new NioClient()) {
+// final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+// .addArg(Tokens.ARGS_GREMLIN, "[0,1,2,3,4,5,6,7,8,9,]").create();
+//
+// final List<ResponseMessage> msg = client.submit(request);
+// assertEquals(1, msg.size());
+// final List<Integer> integers = (List<Integer>) msg.get(0).getResult().getData();
+// IntStream.rangeClosed(0, 9).forEach(i -> assertEquals(i, integers.get(i).intValue()));
+// }
+// }
+//
+// @Test
+// public void shouldNotThrowNoSuchElementException() throws Exception {
+// try (SimpleClient client = new WebSocketClient()){
+// // this should return "nothing" - there should be no exception
+// final List<ResponseMessage> responses = client.submit("g.V().has('name','kadfjaldjfla')");
+// assertNull(responses.get(0).getResult().getData());
+// }
+// }
+//
+// @Test
+// @SuppressWarnings("unchecked")
+// public void shouldReceiveFailureTimeOutOnScriptEval() throws Exception {
+// try (SimpleClient client = new WebSocketClient()){
+// final List<ResponseMessage> responses = client.submit("Thread.sleep(3000);'some-stuff-that-should not return'");
+// assertThat(responses.get(0).getStatus().getMessage(), startsWith("Script evaluation exceeded the configured 'scriptEvaluationTimeout' threshold of 200 ms for request"));
+//
+// // validate that we can still send messages to the server
+// assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
+// }
+// }
+//
+// @Test
+// @SuppressWarnings("unchecked")
+// public void shouldReceiveFailureTimeOutOnScriptEvalUsingOverride() throws Exception {
+// try (SimpleClient client = new WebSocketClient()) {
+// final RequestMessage msg = RequestMessage.build("eval")
+// .addArg(Tokens.ARGS_SCRIPT_EVAL_TIMEOUT, 100)
+// .addArg(Tokens.ARGS_GREMLIN, "Thread.sleep(3000);'some-stuff-that-should not return'")
+// .create();
+// final List<ResponseMessage> responses = client.submit(msg);
+// assertThat(responses.get(0).getStatus().getMessage(), startsWith("Script evaluation exceeded the configured 'scriptEvaluationTimeout' threshold of 100 ms for request"));
+//
+// // validate that we can still send messages to the server
+// assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
+// }
+// }
+//
+// @Test
+// public void shouldReceiveFailureTimeOutOnScriptEvalOfOutOfControlLoop() throws Exception {
+// try (SimpleClient client = new WebSocketClient()){
+// // timeout configured for 1 second so the timed interrupt should trigger prior to the
+// // scriptEvaluationTimeout which is at 30 seconds by default
+// final List<ResponseMessage> responses = client.submit("while(true){}");
+// assertThat(responses.get(0).getStatus().getMessage(), startsWith("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider"));
+//
+// // validate that we can still send messages to the server
+// assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
+// }
+// }
+//
+// @Test
+// @SuppressWarnings("unchecked")
+// public void shouldReceiveFailureTimeOutOnTotalSerialization() throws Exception {
+// try (SimpleClient client = new WebSocketClient()){
+// final List<ResponseMessage> responses = client.submit("(0..<100000)");
+//
+// // the last message should contain the error
+// assertThat(responses.get(responses.size() - 1).getStatus().getMessage(), endsWith("Serialization of the entire response exceeded the 'serializeResponseTimeout' setting"));
+//
+// // validate that we can still send messages to the server
+// assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
+// }
+// }
+//
+// @Test
+// @SuppressWarnings("unchecked")
+// public void shouldLoadInitScript() throws Exception {
+// try (SimpleClient client = new WebSocketClient()){
+// assertEquals(2, ((List<Integer>) client.submit("addItUp(1,1)").get(0).getResult().getData()).get(0).intValue());
+// }
+// }
+//
+// @Test
+// public void shouldGarbageCollectPhantomButNotHard() throws Exception {
+// final Cluster cluster = Cluster.open();
+// final Client client = cluster.connect();
+//
+// assertEquals(2, client.submit("addItUp(1,1)").all().join().get(0).getInt());
+// assertEquals(0, client.submit("def subtract(x,y){x-y};subtract(1,1)").all().join().get(0).getInt());
+// assertEquals(0, client.submit("subtract(1,1)").all().join().get(0).getInt());
+//
+// final Map<String, Object> bindings = new HashMap<>();
+// bindings.put(GremlinGroovyScriptEngine.KEY_REFERENCE_TYPE, GremlinGroovyScriptEngine.REFERENCE_TYPE_PHANTOM);
+// assertEquals(4, client.submit("def multiply(x,y){x*y};multiply(2,2)", bindings).all().join().get(0).getInt());
+//
+// try {
+// client.submit("multiply(2,2)").all().join().get(0).getInt();
+// fail("Should throw an exception since reference is phantom.");
+// } catch (RuntimeException ignored) {
+//
+// } finally {
+// cluster.close();
+// }
+// }
+//
+// @Test
+// public void shouldReceiveFailureOnBadGraphSONSerialization() throws Exception {
+// final Cluster cluster = Cluster.build("localhost").serializer(Serializers.GRAPHSON_V1D0).create();
+// final Client client = cluster.connect();
+//
+// try {
+// client.submit("def class C { def C getC(){return this}}; new C()").all().join();
+// fail("Should throw an exception.");
+// } catch (RuntimeException re) {
+// final Throwable root = ExceptionUtils.getRootCause(re);
+// assertThat(root.getMessage(), CoreMatchers.startsWith("Error during serialization: Direct self-reference leading to cycle (through reference chain:"));
+//
+// // validate that we can still send messages to the server
+// assertEquals(2, client.submit("1+1").all().join().get(0).getInt());
+// } finally {
+// cluster.close();
+// }
+// }
+//
+// @Test
+// public void shouldReceiveFailureOnBadGryoSerialization() throws Exception {
+// final Cluster cluster = Cluster.build("localhost").serializer(Serializers.GRYO_V1D0).create();
+// final Client client = cluster.connect();
+//
+// try {
+// client.submit("java.awt.Color.RED").all().join();
+// fail("Should throw an exception.");
+// } catch (RuntimeException re) {
+// final Throwable root = ExceptionUtils.getRootCause(re);
+// assertThat(root.getMessage(), CoreMatchers.startsWith("Error during serialization: Class is not registered: java.awt.Color"));
+//
+// // validate that we can still send messages to the server
+// assertEquals(2, client.submit("1+1").all().join().get(0).getInt());
+// } finally {
+// cluster.close();
+// }
+// }
+//
+// @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+// @Test
+// public void shouldBlockRequestWhenTooBig() throws Exception {
+// final Cluster cluster = Cluster.open();
+// final Client client = cluster.connect();
+//
+// try {
+// final String fatty = IntStream.range(0, 1024).mapToObj(String::valueOf).collect(Collectors.joining());
+// final CompletableFuture<ResultSet> result = client.submitAsync("'" + fatty + "';'test'");
+// final ResultSet resultSet = result.get(10000, TimeUnit.MILLISECONDS);
+// resultSet.all().get(10000, TimeUnit.MILLISECONDS);
+// fail("Should throw an exception.");
+// } catch (TimeoutException te) {
+// // the request should not have timed-out - the connection should have been reset, but it seems that
+// // timeout seems to occur as well on some systems (it's not clear why). however, the nature of this
+// // test is to ensure that the script isn't processed if it exceeds a certain size, so in this sense
+// // it seems ok to pass in this case.
+// } catch (Exception re) {
+// final Throwable root = ExceptionUtils.getRootCause(re);
+// assertEquals("Connection reset by peer", root.getMessage());
+//
+// // validate that we can still send messages to the server
+// assertEquals(2, client.submit("1+1").all().join().get(0).getInt());
+// } finally {
+// cluster.close();
+// }
+// }
+//
+// @Test
+// public void shouldFailOnDeadHost() throws Exception {
+// final Cluster cluster = Cluster.build("localhost").create();
+// final Client client = cluster.connect();
+//
+// // ensure that connection to server is good
+// assertEquals(2, client.submit("1+1").all().join().get(0).getInt());
+//
+// // kill the server which will make the client mark the host as unavailable
+// this.stopServer();
+//
+// try {
+// // try to re-issue a request now that the server is down
+// client.submit("1+1").all().join();
+// fail();
+// } catch (RuntimeException re) {
+// assertTrue(re.getCause().getCause() instanceof ClosedChannelException);
+//
+// //
+// // should recover when the server comes back
+// //
+//
+// // restart server
+// this.startServer();
+// // the retry interval is 1 second, wait a bit longer
+// TimeUnit.SECONDS.sleep(5);
+//
+// List<Result> results = client.submit("1+1").all().join();
+// assertEquals(1, results.size());
+// assertEquals(2, results.get(0).getInt());
+//
+// } finally {
+// cluster.close();
+// }
+// }
+//
+// @Test
+// public void shouldNotHavePartialContentWithOneResult() throws Exception {
+// try (SimpleClient client = new WebSocketClient()) {
+// final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+// .addArg(Tokens.ARGS_GREMLIN, "10").create();
+// final List<ResponseMessage> responses = client.submit(request);
+// assertEquals(1, responses.size());
+// assertEquals(ResponseStatusCode.SUCCESS, responses.get(0).getStatus().getCode());
+// }
+// }
+//
+// @Test
+// public void shouldFailWithBadScriptEval() throws Exception {
+// try (SimpleClient client = new WebSocketClient()) {
+// final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+// .addArg(Tokens.ARGS_GREMLIN, "new String().doNothingAtAllBecauseThis is a syntax error").create();
+// final List<ResponseMessage> responses = client.submit(request);
+// assertEquals(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION, responses.get(0).getStatus().getCode());
+// assertEquals(1, responses.size());
+// }
+// }
+//
+// @Test
+// @SuppressWarnings("unchecked")
+// public void shouldStillSupportDeprecatedRebindingsParameterOnServer() throws Exception {
+// // this test can be removed when the rebindings arg is removed
+// try (SimpleClient client = new WebSocketClient()) {
+// final Map<String,String> rebindings = new HashMap<>();
+// rebindings.put("xyz", "graph");
+// final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+// .addArg(Tokens.ARGS_GREMLIN, "xyz.addVertex('name','jason')")
+// .addArg(Tokens.ARGS_REBINDINGS, rebindings).create();
+// final List<ResponseMessage> responses = client.submit(request);
+// assertEquals(1, responses.size());
+//
+// final DetachedVertex v = ((ArrayList<DetachedVertex>) responses.get(0).getResult().getData()).get(0);
+// assertEquals("jason", v.value("name"));
+// }
+// }
}
[4/6] incubator-tinkerpop git commit: Added additional SSL
configuration options for Gremlin Driver.
Posted by sp...@apache.org.
Added additional SSL configuration options for Gremlin Driver.
Specifically added: keyPassword, keyFile and keyCertChainFile.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/57416163
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/57416163
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/57416163
Branch: refs/heads/TINKERPOP-1269
Commit: 57416163be0470d0dcd124bebc12efe325578805
Parents: ec730eb
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Apr 19 13:53:35 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Apr 20 15:07:15 2016 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
.../tinkerpop/gremlin/driver/Channelizer.java | 38 +++++++++++++++-----
.../tinkerpop/gremlin/driver/Cluster.java | 33 +++++++++++++++++
.../tinkerpop/gremlin/driver/Settings.java | 15 ++++++++
4 files changed, 78 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/57416163/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 9e117e1..32b534d 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,7 @@ image::https://raw.githubusercontent.com/apache/incubator-tinkerpop/master/docs/
TinkerPop 3.1.3 (NOT OFFICIALLY RELEASED YET)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* Added driver configuration settings for SSL: `keyCertChainFile`, `keyFile` and `keyPassword`.
* Fixed bug where transaction managed sessions were not properly rolling back transactions for exceptions encountered during script evaluation.
* Fixed bug in `:uninstall` command if the default `/ext` directory was not used.
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/57416163/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java
index b059c3f..c850a11 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java
@@ -21,7 +21,9 @@ package org.apache.tinkerpop.gremlin.driver;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.ssl.SslContextBuilder;
+import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
+import io.netty.handler.ssl.util.SelfSignedCertificate;
import org.apache.tinkerpop.gremlin.driver.exception.ConnectionException;
import org.apache.tinkerpop.gremlin.driver.handler.NioGremlinRequestEncoder;
import org.apache.tinkerpop.gremlin.driver.handler.NioGremlinResponseDecoder;
@@ -41,7 +43,9 @@ import io.netty.handler.ssl.SslContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.net.ssl.SSLException;
import java.io.File;
+import java.security.cert.CertificateException;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
@@ -116,15 +120,7 @@ public interface Channelizer extends ChannelHandler {
final Optional<SslContext> sslCtx;
if (supportsSsl()) {
try {
- final SslContextBuilder builder = SslContextBuilder.forClient();
- if (cluster.connectionPoolSettings().trustCertChainFile != null)
- builder.trustManager(new File(cluster.connectionPoolSettings().trustCertChainFile));
- else {
- logger.warn("SSL configured without a trustCertChainFile and thus trusts all certificates without verification (not suitable for production)");
- builder.trustManager(InsecureTrustManagerFactory.INSTANCE);
- }
-
- sslCtx = Optional.of(builder.build());
+ sslCtx = Optional.of(createSSLContext(cluster.connectionPoolSettings()));
} catch (Exception ex) {
throw new RuntimeException(ex);
}
@@ -140,6 +136,30 @@ public interface Channelizer extends ChannelHandler {
pipeline.addLast(PIPELINE_GREMLIN_SASL_HANDLER, new Handler.GremlinSaslAuthenticationHandler(cluster.authProperties()));
pipeline.addLast(PIPELINE_GREMLIN_HANDLER, new Handler.GremlinResponseHandler(pending));
}
+
+ private SslContext createSSLContext(final Settings.ConnectionPoolSettings sslSettings) throws Exception {
+ final SslProvider provider = SslProvider.JDK;
+
+ final SslContextBuilder builder = SslContextBuilder.forClient();
+ if (cluster.connectionPoolSettings().trustCertChainFile != null)
+ builder.trustManager(new File(cluster.connectionPoolSettings().trustCertChainFile));
+ else {
+ logger.warn("SSL configured without a trustCertChainFile and thus trusts all certificates without verification (not suitable for production)");
+ builder.trustManager(InsecureTrustManagerFactory.INSTANCE);
+ }
+
+ if (null != sslSettings.keyCertChainFile && null != sslSettings.keyFile) {
+ final File keyCertChainFile = new File(sslSettings.keyCertChainFile);
+ final File keyFile = new File(sslSettings.keyFile);
+
+ // note that keyPassword may be null here if the keyFile is not password-protected.
+ builder.keyManager(keyCertChainFile, keyFile, sslSettings.keyPassword);
+ }
+
+ builder.sslProvider(provider);
+
+ return builder.build();
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/57416163/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
index 02181e2..7ae898b 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
@@ -144,6 +144,9 @@ public final class Cluster {
.port(settings.port)
.enableSsl(settings.connectionPool.enableSsl)
.trustCertificateChainFile(settings.connectionPool.trustCertChainFile)
+ .keyCertChainFile(settings.connectionPool.keyCertChainFile)
+ .keyFile(settings.connectionPool.keyFile)
+ .keyPassword(settings.connectionPool.keyPassword)
.nioPoolSize(settings.nioPoolSize)
.workerPoolSize(settings.workerPoolSize)
.reconnectInterval(settings.connectionPool.reconnectInterval)
@@ -286,6 +289,9 @@ public final class Cluster {
private String channelizer = Channelizer.WebSocketChannelizer.class.getName();
private boolean enableSsl = false;
private String trustCertChainFile = null;
+ private String keyCertChainFile = null;
+ private String keyFile = null;
+ private String keyPassword = null;
private LoadBalancingStrategy loadBalancingStrategy = new LoadBalancingStrategy.RoundRobin();
private AuthProperties authProps = new AuthProperties();
@@ -363,6 +369,30 @@ public final class Cluster {
}
/**
+ * The X.509 certificate chain file in PEM format.
+ */
+ public Builder keyCertChainFile(final String keyCertChainFile) {
+ this.keyCertChainFile = keyCertChainFile;
+ return this;
+ }
+
+ /**
+ * The PKCS#8 private key file in PEM format.
+ */
+ public Builder keyFile(final String keyFile) {
+ this.keyFile = keyFile;
+ return this;
+ }
+
+ /**
+ * The password of the {@link #keyFile}, or {@code null} if it's not password-protected.
+ */
+ public Builder keyPassword(final String keyPassword) {
+ this.keyPassword = keyPassword;
+ return this;
+ }
+
+ /**
* The minimum number of in-flight requests that can occur on a {@link Connection} before it is considered
* for closing on return to the {@link ConnectionPool}.
*/
@@ -587,6 +617,9 @@ public final class Cluster {
connectionPoolSettings.resultIterationBatchSize = this.resultIterationBatchSize;
connectionPoolSettings.enableSsl = this.enableSsl;
connectionPoolSettings.trustCertChainFile = this.trustCertChainFile;
+ connectionPoolSettings.keyCertChainFile = this.keyCertChainFile;
+ connectionPoolSettings.keyFile = this.keyFile;
+ connectionPoolSettings.keyPassword = this.keyPassword;
connectionPoolSettings.channelizer = this.channelizer;
return new Cluster(getContactPoints(), serializer, this.nioPoolSize, this.workerPoolSize,
connectionPoolSettings, loadBalancingStrategy, authProps);
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/57416163/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java
index 4daa223..373b9c7 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java
@@ -119,6 +119,21 @@ final class Settings {
public String trustCertChainFile = null;
/**
+ * The X.509 certificate chain file in PEM format.
+ */
+ public String keyCertChainFile = null;
+
+ /**
+ * The PKCS#8 private key file in PEM format.
+ */
+ public String keyFile = null;
+
+ /**
+ * The password of the {@link #keyFile}, or {@code null} if it's not password-protected.
+ */
+ public String keyPassword = null;
+
+ /**
* The minimum size of a connection pool for a {@link Host}. By default this is set to 2.
*/
public int minSize = ConnectionPool.MIN_POOL_SIZE;