Repository: tinkerpop Updated Branches: refs/heads/tp32 bd4b98957 -> c30b378b3
[TINKERPOP-915]Add combined handler for Http and Websockets [TINKERPOP-915](https://issues.apache.org/jira/browse/TINKERPOP-915) Most of this is tests. I added an integration test that goes over the functionality of both the http and websocket channelizers using the new `WsAndHttpChannelizer`. I added an additional test on top of that to switch between using WebSockets and http. The change itself leverages the existing `WebSocketChannelizer` to provide the base pipeline setup. It has everything needed handler-wise to service both http and ws connections. The `WsAndHttpChannelizerHandler` then detects whether the incoming request is a plain http connection or a WebSockets connection. If it's an http connection, the channelizer handler swaps out the request handler appropriately for whether or not authentication has been enabled. Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/c2643905 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/c2643905 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/c2643905 Branch: refs/heads/tp32 Commit: c2643905ede89c2cb8580280dcf42ecfb4cdfe01 Parents: 402678b Author: Keith Lohnes <krloh...@us.ibm.com> Authored: Tue May 30 10:02:54 2017 -0400 Committer: Keith Lohnes <krloh...@us.ibm.com> Committed: Thu Jul 6 11:07:22 2017 -0400 ---------------------------------------------------------------------- CHANGELOG.asciidoc | 1 + .../src/reference/gremlin-applications.asciidoc | 7 +- .../upgrade/release-3.2.x-incubating.asciidoc | 9 + .../gremlin/server/AbstractChannelizer.java | 11 +- .../server/channel/WebSocketChannelizer.java | 7 +- .../server/channel/WsAndHttpChannelizer.java | 61 ++++ .../SaslAndHttpBasicAuthenticationHandler.java | 57 +++ .../server/handler/WebSocketHandlerUtil.java | 38 ++ .../handler/WsAndHttpChannelizerHandler.java | 87 +++++ .../AbstractGremlinServerIntegrationTest.java | 23 +- .../server/GremlinServerHttpIntegrateTest.java | 6 - .../server/GremlinServerIntegrateTest.java | 37 -- ...tGremlminServerChannelizerIntegrateTest.java | 346 +++++++++++++++++++ .../channel/HttpChannelizerIntegrateTest.java | 56 +++ .../channel/NioChannelizerIntegrateTest.java | 56 +++ .../WebSocketChannelizerIntegrateTest.java | 56 +++ .../WsAndHttpChannelizerIntegrateTest.java | 58 ++++ 17 files changed, 864 insertions(+), 52 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/CHANGELOG.asciidoc ---------------------------------------------------------------------- diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 96e79ab..b19b67e 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -38,6 +38,7 @@ This release also includes changes from <<release-3-1-8, 3.1.8>>. * Fixed `HADOOP_GREMLIN_LIBS` parsing for Windows. * Improved GraphSON serialization performance around `VertexProperty`. * Changed some tests in `EventStrategyProcessTest` which were enforcing some unintended semantics around transaction state. +* Added WsAndHttpChannelizer and SaslAndHttpBasicAuthenticationHandler to be allow for servicing Http and Websocket requests to the same server [[release-3-2-5]] TinkerPop 3.2.5 (Release Date: June 12, 2017) http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/docs/src/reference/gremlin-applications.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc index a936d3a..4e367e9 100644 --- a/docs/src/reference/gremlin-applications.asciidoc +++ b/docs/src/reference/gremlin-applications.asciidoc @@ -861,13 +861,16 @@ as the API for the endpoint is very similar to Rexster's link:https://github.com Gremlin Server provides for a single REST endpoint - a Gremlin evaluator - which allows the submission of a Gremlin script as a request. For each request, it returns a response containing the serialized results of that script. -To enable this endpoint, Gremlin Server needs to be configured with the `HttpChannelizer`, which replaces the default +To enable this endpoint, Gremlin Server needs to be configured with the `HttpChannelizer`, which replaces the default. The `WsAndHttpChannelizer` may also be configured to enable both WebSockets and the REST endpoint. `WebSocketChannelizer`, in the configuration file: [source,yaml] channelizer: org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer -This setting is already configured in the `gremlin-server-rest-modern.yaml` file that is packaged with the Gremlin +[source,yaml] +channelizer: org.apache.tinkerpop.gremlin.server.channel.WsAndHttpChannelizer + +The `HttpChannelizer` is already configured in the `gremlin-server-rest-modern.yaml` file that is packaged with the Gremlin Server distribution. To utilize it, start Gremlin Server as follows: [source,text] http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/docs/src/upgrade/release-3.2.x-incubating.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/upgrade/release-3.2.x-incubating.asciidoc b/docs/src/upgrade/release-3.2.x-incubating.asciidoc index aa98de4..b8348d3 100644 --- a/docs/src/upgrade/release-3.2.x-incubating.asciidoc +++ b/docs/src/upgrade/release-3.2.x-incubating.asciidoc @@ -39,6 +39,15 @@ it has not been promoted as the primary way to add `IoRegistry` instances to ser See: link:https://issues.apache.org/jira/browse/TINKERPOP-1694[TINKERPOP-1694] +WsAndHttpChannelizer +^^^^^^^^^^^^^^^^^^^^ + +The `WsAndHttpChannelizer` has been added to allow for processing both WebSocket and Http requests on the same +port and gremlin server. The `SaslAndHttpBasicAuthenticationHandler` has also been added to service +authentication for both protocols in conjunction with the `SimpleAuthenticator`. + +See: link:https://issues.apache.org/jira/browse/TINKERPOP-915[TINKERPOP-915] + Upgrading for Providers ~~~~~~~~~~~~~~~~~~~~~~~ http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/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 476cdd5..22bb1eb 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 @@ -85,11 +85,18 @@ public abstract class AbstractChannelizer extends ChannelInitializer<SocketChann protected ExecutorService gremlinExecutorService; protected ScheduledExecutorService scheduledExecutorService; + + public static final String PIPELINE_AUTHENTICATOR = "authenticator"; + public static final String PIPELINE_REQUEST_HANDLER = "request-handler"; + public static final String PIPELINE_HTTP_RESPONSE_ENCODER = "http-response-encoder"; + protected static final String PIPELINE_SSL = "ssl"; protected static final String PIPELINE_OP_SELECTOR = "op-selector"; protected static final String PIPELINE_RESULT_ITERATOR_HANDLER = "result-iterator-handler"; protected static final String PIPELINE_OP_EXECUTOR = "op-executor"; - protected static final String PIPELINE_AUTHENTICATOR = "authenticator"; + protected static final String PIPELINE_HTTP_REQUEST_DECODER = "http-request-decoder"; + + protected static final String GREMLIN_ENDPOINT = "/gremlin"; protected final Map<String, MessageSerializer> serializers = new HashMap<>(); @@ -272,8 +279,6 @@ public abstract class AbstractChannelizer extends ChannelInitializer<SocketChann builder = SslContextBuilder.forServer(keyCertChainFile, keyFile, sslSettings.keyPassword) .trustManager(trustCertChainFile); } - - builder.clientAuth(sslSettings.needClientAuth).sslProvider(provider); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/channel/WebSocketChannelizer.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/channel/WebSocketChannelizer.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/channel/WebSocketChannelizer.java index 1b613a1..af41cc6 100644 --- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/channel/WebSocketChannelizer.java +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/channel/WebSocketChannelizer.java @@ -79,7 +79,7 @@ public class WebSocketChannelizer extends AbstractChannelizer { logger.debug("HttpRequestDecoder settings - maxInitialLineLength={}, maxHeaderSize={}, maxChunkSize={}", settings.maxInitialLineLength, settings.maxHeaderSize, settings.maxChunkSize); - pipeline.addLast("http-request-decoder", new HttpRequestDecoder(settings.maxInitialLineLength, settings.maxHeaderSize, settings.maxChunkSize)); + pipeline.addLast(PIPELINE_HTTP_REQUEST_DECODER, new HttpRequestDecoder(settings.maxInitialLineLength, settings.maxHeaderSize, settings.maxChunkSize)); if (logger.isDebugEnabled()) pipeline.addLast(new LoggingHandler("log-decoder-aggregator", LogLevel.DEBUG)); @@ -93,8 +93,9 @@ public class WebSocketChannelizer extends AbstractChannelizer { if (logger.isDebugEnabled()) pipeline.addLast(new LoggingHandler("log-aggregator-encoder", LogLevel.DEBUG)); - pipeline.addLast("http-response-encoder", new HttpResponseEncoder()); - pipeline.addLast("request-handler", new WebSocketServerProtocolHandler("/gremlin", null, false, settings.maxContentLength)); + pipeline.addLast(PIPELINE_HTTP_RESPONSE_ENCODER, new HttpResponseEncoder()); + + pipeline.addLast(PIPELINE_REQUEST_HANDLER, new WebSocketServerProtocolHandler(GREMLIN_ENDPOINT, null, false, settings.maxContentLength)); if (logger.isDebugEnabled()) pipeline.addLast(new LoggingHandler("log-aggregator-encoder", LogLevel.DEBUG)); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/channel/WsAndHttpChannelizer.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/channel/WsAndHttpChannelizer.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/channel/WsAndHttpChannelizer.java new file mode 100644 index 0000000..58885fb --- /dev/null +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/channel/WsAndHttpChannelizer.java @@ -0,0 +1,61 @@ +/* + * 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.channel; + +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.EventLoopGroup; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; +import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; +import io.netty.handler.logging.LogLevel; +import io.netty.handler.logging.LoggingHandler; +import org.apache.tinkerpop.gremlin.server.AbstractChannelizer; +import org.apache.tinkerpop.gremlin.server.handler.HttpGremlinEndpointHandler; +import org.apache.tinkerpop.gremlin.server.handler.WsAndHttpChannelizerHandler; +import org.apache.tinkerpop.gremlin.server.util.ServerGremlinExecutor; +import org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *A channelizer for port unification with websockets and http + *@author Keith Lohnes lohn...@gmail.com + */ + +public class WsAndHttpChannelizer extends AbstractChannelizer { + + private static final Logger logger = LoggerFactory.getLogger(WsAndHttpChannelizer.class); + + private WsAndHttpChannelizerHandler handler; + + @Override + public void init(final ServerGremlinExecutor<EventLoopGroup> serverGremlinExecutor) { + super.init(serverGremlinExecutor); + handler = new WsAndHttpChannelizerHandler(); + handler.init(serverGremlinExecutor, new HttpGremlinEndpointHandler(serializers, gremlinExecutor, graphManager, settings)); + } + + @Override + public void configure(final ChannelPipeline pipeline) { + handler.configure(pipeline); + pipeline.addAfter(PIPELINE_HTTP_REQUEST_DECODER, "WsAndHttpChannelizerHandler", handler); + } +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/SaslAndHttpBasicAuthenticationHandler.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/SaslAndHttpBasicAuthenticationHandler.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/SaslAndHttpBasicAuthenticationHandler.java new file mode 100644 index 0000000..d3e4cfe --- /dev/null +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/SaslAndHttpBasicAuthenticationHandler.java @@ -0,0 +1,57 @@ +/* + * 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.handler; + +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPipeline; +import io.netty.handler.codec.http.HttpMessage; +import org.apache.tinkerpop.gremlin.server.auth.Authenticator; +import org.apache.tinkerpop.gremlin.server.handler.HttpBasicAuthenticationHandler; +import org.apache.tinkerpop.gremlin.server.handler.SaslAuthenticationHandler; +import org.apache.tinkerpop.gremlin.server.handler.WebSocketHandlerUtil; + +import static org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer.PIPELINE_AUTHENTICATOR; + +/** + *An Authentication Handler for doing WebSocket Sasl and Http Basic auth + */ +@ChannelHandler.Sharable +public class SaslAndHttpBasicAuthenticationHandler extends SaslAuthenticationHandler { + + private final String HTTP_AUTH = "http-authentication"; + + public SaslAndHttpBasicAuthenticationHandler(final Authenticator authenticator) { + super(authenticator); + } + + @Override + public void channelRead(final ChannelHandlerContext ctx, final Object obj) throws Exception { + if (obj instanceof HttpMessage && !WebSocketHandlerUtil.isWebSocket((HttpMessage)obj)) { + if (null == ctx.pipeline().get(HTTP_AUTH)) { + ctx.pipeline().addAfter(PIPELINE_AUTHENTICATOR, HTTP_AUTH, new HttpBasicAuthenticationHandler(authenticator)); + } + ctx.fireChannelRead(obj); + } else { + super.channelRead(ctx, obj); + } + } + +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WebSocketHandlerUtil.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WebSocketHandlerUtil.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WebSocketHandlerUtil.java new file mode 100644 index 0000000..2d571c0 --- /dev/null +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WebSocketHandlerUtil.java @@ -0,0 +1,38 @@ +/* + * 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.handler; + +import io.netty.handler.codec.http.HttpMessage; + +import static io.netty.handler.codec.http.HttpHeaders.Names.UPGRADE; +import static io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION; + +/** + * A class to handle common WebSocket operations + * @author Keith Lohnes lohn...@gmail.com + */ +final class WebSocketHandlerUtil { + + static boolean isWebSocket(final HttpMessage msg) { + final String connectionHeader = msg.headers().get(CONNECTION); + final String upgradeHeader = msg.headers().get(UPGRADE); + return (null != connectionHeader && connectionHeader.equalsIgnoreCase("Upgrade")) || + (null != upgradeHeader && upgradeHeader.equalsIgnoreCase("WebSocket")); + } +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsAndHttpChannelizerHandler.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsAndHttpChannelizerHandler.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsAndHttpChannelizerHandler.java new file mode 100644 index 0000000..328a34b --- /dev/null +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsAndHttpChannelizerHandler.java @@ -0,0 +1,87 @@ +/* + * 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.handler; + +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.EventLoopGroup; +import io.netty.handler.codec.http.HttpMessage; +import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; +import io.netty.handler.codec.http.HttpServerCodec; +import org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer; +import org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer; +import org.apache.tinkerpop.gremlin.server.handler.HttpGremlinEndpointHandler; +import org.apache.tinkerpop.gremlin.server.handler.WsAndHttpChannelizerHandler; +import org.apache.tinkerpop.gremlin.server.handler.WebSocketHandlerUtil; +import org.apache.tinkerpop.gremlin.server.util.ServerGremlinExecutor; + +import static io.netty.handler.codec.http.HttpHeaders.Names.UPGRADE; +import static io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION; +import static org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer.PIPELINE_AUTHENTICATOR; +import static org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer.PIPELINE_REQUEST_HANDLER; +import static org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer.PIPELINE_HTTP_RESPONSE_ENCODER; + +/* + * A ChannelInboundHandlerAdapter for use with {@link WsAndHttpChannelizer} that toggles between WebSockets + * and http + * @author Keith Lohnes lohn...@gmail.com + */ +@ChannelHandler.Sharable +public class WsAndHttpChannelizerHandler extends ChannelInboundHandlerAdapter { + + private final WebSocketChannelizer wsChannelizer = new WebSocketChannelizer(); + private HttpGremlinEndpointHandler httpGremlinEndpointHandler; + + public void init(final ServerGremlinExecutor<EventLoopGroup> serverGremlinExecutor, final HttpGremlinEndpointHandler httpGremlinEndpointHandler) { + //WebSocketChannelizer has everything needed for the http endpoint to work + wsChannelizer.init(serverGremlinExecutor); + this.httpGremlinEndpointHandler = httpGremlinEndpointHandler; + } + + public void configure(final ChannelPipeline pipeline) { + wsChannelizer.configure(pipeline); + } + + @Override + public void channelRead(final ChannelHandlerContext ctx, final Object obj) { + final ChannelPipeline pipeline = ctx.pipeline(); + if (obj instanceof HttpMessage && !WebSocketHandlerUtil.isWebSocket((HttpMessage)obj)) { + if (null != pipeline.get(PIPELINE_AUTHENTICATOR)) { + pipeline.remove(PIPELINE_REQUEST_HANDLER); + final ChannelHandler authenticator = pipeline.get(PIPELINE_AUTHENTICATOR); + pipeline.remove(PIPELINE_AUTHENTICATOR); + pipeline.addAfter(PIPELINE_HTTP_RESPONSE_ENCODER, PIPELINE_AUTHENTICATOR, authenticator); + pipeline.addAfter(PIPELINE_AUTHENTICATOR, PIPELINE_REQUEST_HANDLER, this.httpGremlinEndpointHandler); + } else { + pipeline.remove(PIPELINE_REQUEST_HANDLER); + pipeline.addAfter(PIPELINE_HTTP_RESPONSE_ENCODER, PIPELINE_REQUEST_HANDLER, this.httpGremlinEndpointHandler); + } + } + ctx.fireChannelRead(obj); + } + + @Override + public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) { + ctx.close(); + } + + +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/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 b8bf51f..7c124f0 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 @@ -62,6 +62,28 @@ public abstract class AbstractGremlinServerIntegrationTest { startServer(); } + public void setUp(final Settings settings) throws Exception { + logger.info("* Testing: " + name.getMethodName()); + logger.info("* Epoll option enabled:" + GREMLIN_SERVER_EPOLL); + + startServer(settings); + } + + public void startServer(final Settings settings) throws Exception { + if (null == settings) { + startServer(); + } else { + final Settings overridenSettings = overrideSettings(settings); + ServerTestHelper.rewritePathsInGremlinServerSettings(overridenSettings); + if (GREMLIN_SERVER_EPOLL) { + overridenSettings.useEpollEventLoop = true; + } + this.server = new GremlinServer(overridenSettings); + server.start().join(); + + } + } + public void startServer() throws Exception { final InputStream stream = getSettingsInputStream(); final Settings settings = Settings.read(stream); @@ -83,7 +105,6 @@ public abstract class AbstractGremlinServerIntegrationTest { public void stopServer() throws Exception { server.stop().join(); - // reset the OpLoader processors so that they can get reconfigured on startup - Settings may have changed // between tests OpLoader.reset(); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java index 769ee88..90017a9 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java @@ -96,12 +96,6 @@ public class GremlinServerHttpIntegrateTest extends AbstractGremlinServerIntegra case "should401OnGETWithInvalidPasswordAuthorizationHeader": case "should401OnPOSTWithInvalidPasswordAuthorizationHeader": case "should200OnGETWithAuthorizationHeader": - case "should200OnPOSTWithAuthorizationHeaderExplicitHandlerSetting": - configureForAuthenticationWithHandlerClass(settings); - break; - case "should200OnPOSTWithAuthorizationHeader": - configureForAuthentication(settings); - break; case "should401OnPOSTWithInvalidPasswordAuthorizationHeaderOld": case "should200OnPOSTWithAuthorizationHeaderOld": configureForAuthenticationOld(settings); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/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 96ec17c..aad8131 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 @@ -56,7 +56,6 @@ import org.apache.tinkerpop.gremlin.server.op.AbstractEvalOpProcessor; import org.apache.tinkerpop.gremlin.server.op.standard.StandardOpProcessor; import org.apache.tinkerpop.gremlin.structure.Graph; import org.apache.tinkerpop.gremlin.structure.T; -import org.apache.tinkerpop.gremlin.server.channel.NioChannelizer; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex; import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph; @@ -169,9 +168,6 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration case "shouldBatchResultsByTwos": settings.resultIterationBatchSize = 2; break; - case "shouldWorkOverNioTransport": - settings.channelizer = NioChannelizer.class.getName(); - break; case "shouldEnableSsl": case "shouldEnableSslButFailIfClientConnectsWithoutIt": settings.ssl = new Settings.SslSettings(); @@ -212,11 +208,6 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration // Trust ONLY the server cert settings.ssl.trustCertChainFile = SERVER_CRT; break; - case "shouldStartWithDefaultSettings": - // test with defaults exception for port because we want to keep testing off of 8182 - final Settings defaultSettings = new Settings(); - defaultSettings.port = TestClientFactory.PORT; - return settings; case "shouldUseSimpleSandbox": settings.scriptEngines.get("gremlin-groovy").config = getScriptEngineConfForSimpleSandbox(); break; @@ -370,20 +361,6 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration } @Test - public void shouldStartWithDefaultSettings() { - // just quickly validate that results are returning given defaults. no graphs are config'd with defaults - // so just eval a groovy script. - final Cluster cluster = TestClientFactory.open(); - final Client client = cluster.connect(); - - final ResultSet results = client.submit("[1,2,3,4,5,6,7,8,9]"); - final AtomicInteger counter = new AtomicInteger(0); - results.stream().map(i -> i.get(Integer.class) * 2).forEach(i -> assertEquals(counter.incrementAndGet() * 2, Integer.parseInt(i.toString()))); - - cluster.close(); - } - - @Test public void shouldEnableSsl() { final Cluster cluster = TestClientFactory.build().enableSsl(true).create(); final Client client = cluster.connect(); @@ -709,20 +686,6 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration } @Test - @SuppressWarnings("unchecked") - public void shouldWorkOverNioTransport() throws Exception { - try (SimpleClient client = TestClientFactory.createNioClient()) { - 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 = TestClientFactory.createWebSocketClient()){ // this should return "nothing" - there should be no exception http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/AbstractGremlminServerChannelizerIntegrateTest.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/AbstractGremlminServerChannelizerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/AbstractGremlminServerChannelizerIntegrateTest.java new file mode 100644 index 0000000..738ca89 --- /dev/null +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/AbstractGremlminServerChannelizerIntegrateTest.java @@ -0,0 +1,346 @@ +/* + * 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.channel; + +import org.apache.tinkerpop.gremlin.driver.AuthProperties; +import org.apache.tinkerpop.gremlin.driver.Client; +import org.apache.tinkerpop.gremlin.driver.Cluster; +import org.apache.tinkerpop.gremlin.driver.Client; +import org.apache.tinkerpop.gremlin.driver.simple.SimpleClient; +import org.apache.tinkerpop.gremlin.driver.Channelizer; +import org.apache.tinkerpop.gremlin.server.AbstractGremlinServerIntegrationTest; +import org.apache.tinkerpop.gremlin.server.channel.WsAndHttpChannelizer; +import org.apache.tinkerpop.gremlin.server.Settings; +import org.apache.tinkerpop.gremlin.server.TestClientFactory; + + +import org.apache.http.Consts; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.ssl.AllowAllHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLContextBuilder; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.conn.ssl.TrustStrategy; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.util.EntityUtils; +import org.apache.tinkerpop.shaded.jackson.databind.JsonNode; +import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.rules.ExternalResource; + +import java.io.File; +import java.io.InputStream; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Base64; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.apache.tinkerpop.gremlin.driver.AuthProperties.Property; + +abstract class AbstractGremlinServerChannelizerIntegrateTest extends AbstractGremlinServerIntegrationTest { + + private final ObjectMapper mapper = new ObjectMapper(); + private final Base64.Encoder encoder = Base64.getUrlEncoder(); + + protected static final String HTTP = "http"; + protected static final String WS = "ws"; + protected static final String HTTPS = "https"; + protected static final String WSS = "wss"; + protected static final String WS_AND_HTTP = "wsAndHttp"; + protected static final String WSS_AND_HTTPS = "wssAndHttps"; + protected static final String NIO = "nio"; + protected static final String NIO_SECURE = "nioSecure"; + + public abstract String getProtocol(); + public abstract String getSecureProtocol(); + public abstract String getChannelizer(); + public abstract Settings.AuthenticationSettings getAuthSettings(); + + /** + * Configure specific Gremlin Server settings for specific tests. + */ + @Override + public Settings overrideSettings(final Settings settings) { + settings.channelizer = getChannelizer(); + final String nameOfTest = name.getMethodName(); + Settings.AuthenticationSettings authSettings = getAuthSettings(); + switch (nameOfTest) { + case "shouldReturnResult": + break; + case "shouldWorkWithSSL": + settings.ssl = new Settings.SslSettings(); + settings.ssl.enabled = true; + break; + case "shouldWorkWithAuth": + if (authSettings != null) { + settings.authentication = getAuthSettings(); + } + break; + case "shouldWorkWithSSLAndAuth": + settings.ssl = new Settings.SslSettings(); + settings.ssl.enabled = true; + if (authSettings != null) { + settings.authentication = getAuthSettings(); + } + break; + } + return settings; + } + + @Test + public void shouldReturnResult() throws Exception { + final CombinedTestClient client = new CombinedTestClient(getProtocol()); + try { + client.sendAndAssert("2+2", 4); + } finally { + client.close(); + } + } + + @Test + public void shouldWorkWithSSL() throws Exception { + final CombinedTestClient client = new CombinedTestClient(getSecureProtocol()); + try { + client.sendAndAssert("2+2", 4); + } finally { + client.close(); + } + } + + @Test + public void shouldWorkWithAuth() throws Exception { + CombinedTestClient client = new CombinedTestClient(getProtocol()); + try { + client.sendAndAssertUnauthorized("2+2", "stephen", "notpassword"); + client.close(); + client = new CombinedTestClient(getProtocol()); + client.sendAndAssert("2+2", 4, "stephen", "password"); + client.close(); + } catch (Exception e) { + client.close(); + throw e; + } + } + + @Test + public void shouldWorkWithSSLAndAuth() throws Exception { + CombinedTestClient client = new CombinedTestClient(getSecureProtocol()); + try { + client.sendAndAssertUnauthorized("2+2", "stephen", "incorrect-password"); + client.close(); + client = new CombinedTestClient(getSecureProtocol()); + client.sendAndAssert("2+2", 4, "stephen", "password"); + client.close(); + } catch (Exception e) { + client.close(); + throw e; + } + } + + public class CombinedTestClient { + private CloseableHttpClient httpClient = null; + private Cluster wsCluster = null; + private Cluster.Builder wsBuilder = null; + private Cluster nioCluster = null; + private Cluster.Builder nioBuilder = null; + private Client wsClient = null; + private Client.ClusteredClient nioClient = null; + private boolean secure = false; + + + public CombinedTestClient(final String protocol) throws Exception { + switch (protocol) { + case HTTP: + httpClient = HttpClients.createDefault(); + break; + case HTTPS: + httpClient = createSslHttpClient(); + secure = true; + break; + case WS: + this.wsBuilder = TestClientFactory.build(); + break; + case WSS: + this.wsBuilder = TestClientFactory.build(); + secure = true; + break; + case WS_AND_HTTP: + httpClient = HttpClients.createDefault(); + this.wsBuilder = TestClientFactory.build(); + break; + case WSS_AND_HTTPS: + httpClient = createSslHttpClient(); + secure = true; + this.wsBuilder = TestClientFactory.build(); + break; + case NIO: + this.nioBuilder = TestClientFactory.build(); + break; + case NIO_SECURE: + this.nioBuilder = TestClientFactory.build(); + secure = true; + break; + } + } + + private CloseableHttpClient createSslHttpClient() throws Exception { + final SSLContextBuilder wsBuilder = new SSLContextBuilder(); + wsBuilder.loadTrustMaterial(null, new TrustStrategy() { + @Override + public boolean isTrusted(X509Certificate[] chain, + String authType) throws CertificateException { + return true; + } + }); + final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(wsBuilder.build(), + new AllowAllHostnameVerifier()); + //This winds up using a PoolingHttpClientConnectionManager so need to pass the + //RegistryBuilder + final Registry<ConnectionSocketFactory> registry = RegistryBuilder + .<ConnectionSocketFactory> create().register("https", sslsf) + .build(); + final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry); + return HttpClients + .custom() + .setConnectionManager(cm) + .build(); + + } + + public void sendAndAssert(final String gremlin, Object result) throws Exception { + sendAndAssert(gremlin, result, null, null); + } + + public void close() { + if (wsCluster != null) { + wsCluster.close(); + } + if (nioCluster != null) { + nioCluster.close(); + } + } + + public void sendAndAssertUnauthorized(final String gremlin, final String username, final String password) throws Exception { + if (httpClient != null) { + final HttpPost httpPost = createPost(gremlin, username, password); + try (final CloseableHttpResponse response = httpClient.execute(httpPost)) { + assertEquals(401, response.getStatusLine().getStatusCode()); + } + } + if (wsBuilder != null) { + setWsClient(username, password); + try { + wsClient.submit(gremlin).all().get(); + fail("Should not authorize on incorrect auth creds"); + } catch(Exception e) { + assertEquals("Username and/or password are incorrect", e.getCause().getMessage()); + } + } + if (nioBuilder != null) { + setNioClient(username, password); + try { + nioClient.submit(gremlin); + } catch(Exception e) { + assertEquals("Username and/or password are incorrect", e.getCause().getMessage()); + } + } + + } + + public void sendAndAssert(final String gremlin, final Object result, final String username, final String password) throws Exception { + if (httpClient != null) { + final HttpPost httpPost = createPost(gremlin, username, password); + try (final CloseableHttpResponse response = httpClient.execute(httpPost)) { + assertEquals(200, response.getStatusLine().getStatusCode()); + assertEquals("application/json", response.getEntity().getContentType().getValue()); + final String json = EntityUtils.toString(response.getEntity()); + final JsonNode node = mapper.readTree(json); + assertEquals(result, node.get("result").get("data").get(0).intValue()); + } + } + if (wsBuilder != null) { + setWsClient(username, password); + assertEquals(result, wsClient.submit(gremlin).all().get().get(0).getInt()); + } + if (nioClient != null) { + assertEquals(result, nioClient.submit(gremlin).all().get().get(0).getInt()); + } + } + + private void setNioClient(final String username, final String password) { + nioBuilder.channelizer(Channelizer.NioChannelizer.class.getName()); + if (username != null && password != null) { + final AuthProperties authProps = new AuthProperties() + .with(Property.USERNAME, username) + .with(Property.PASSWORD, password); + + nioCluster = nioBuilder.enableSsl(secure).authProperties(authProps).create(); + nioClient = nioCluster.connect(); + } else { + nioCluster = nioBuilder.enableSsl(secure).create(); + nioClient = nioCluster.connect(); + } + } + + private void setWsClient(final String username, final String password) { + if (username != null && password != null) { + final AuthProperties authProps = new AuthProperties() + .with(Property.USERNAME, username) + .with(Property.PASSWORD, password); + + wsCluster = wsBuilder.enableSsl(secure).authProperties(authProps).create(); + wsClient = wsCluster.connect(); + } else { + wsCluster = wsBuilder.enableSsl(secure).create(); + wsClient = wsCluster.connect(); + } + } + + private HttpPost createPost(final String gremlin, final String username, final String password) { + String urlString = TestClientFactory.createURLString(); + if (secure) { + urlString = urlString.replace("http", "https"); + } + final HttpPost httpPost = new HttpPost(urlString); + httpPost.addHeader("Content-Type", "application/json"); + if (username != null && password != null) { + final String auth = encoder.encodeToString((username + ":" + password).getBytes()); + httpPost.addHeader("Authorization", "Basic " + auth); + } + final String jsonBody = String.format("{\"gremlin\": \"%s\"}", gremlin); + httpPost.setEntity(new StringEntity(jsonBody, Consts.UTF_8)); + return httpPost; + } + } +} + http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/HttpChannelizerIntegrateTest.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/HttpChannelizerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/HttpChannelizerIntegrateTest.java new file mode 100644 index 0000000..22cb2da --- /dev/null +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/HttpChannelizerIntegrateTest.java @@ -0,0 +1,56 @@ +/* + * 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.channel; + + +import org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator; +import org.apache.tinkerpop.gremlin.server.Settings; + +import java.util.Map; +import java.util.HashMap; + +public class HttpChannelizerIntegrateTest extends AbstractGremlinServerChannelizerIntegrateTest { + + @Override + public String getProtocol() { + return HTTP; + } + + @Override + public String getSecureProtocol() { + return HTTPS; + } + + @Override + public String getChannelizer() { + return HttpChannelizer.class.getName(); + } + + @Override + public Settings.AuthenticationSettings getAuthSettings() { + final Settings.AuthenticationSettings authSettings = new Settings.AuthenticationSettings(); + final Map<String,Object> authConfig = new HashMap<>(); + authSettings.authenticator = SimpleAuthenticator.class.getName(); + authConfig.put(SimpleAuthenticator.CONFIG_CREDENTIALS_DB, "conf/tinkergraph-credentials.properties"); + authSettings.config = authConfig; + + return authSettings; + } + +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/NioChannelizerIntegrateTest.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/NioChannelizerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/NioChannelizerIntegrateTest.java new file mode 100644 index 0000000..8388b40 --- /dev/null +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/NioChannelizerIntegrateTest.java @@ -0,0 +1,56 @@ +/* + * 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.channel; + + +import org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator; +import org.apache.tinkerpop.gremlin.server.Settings; + +import java.util.Map; +import java.util.HashMap; + +public class NioChannelizerIntegrateTest extends AbstractGremlinServerChannelizerIntegrateTest { + + @Override + public String getProtocol() { + return NIO; + } + + @Override + public String getSecureProtocol() { + return NIO_SECURE; + } + + @Override + public String getChannelizer() { + return NioChannelizer.class.getName(); + } + + @Override + public Settings.AuthenticationSettings getAuthSettings() { + final Settings.AuthenticationSettings authSettings = new Settings.AuthenticationSettings(); + final Map<String,Object> authConfig = new HashMap<>(); + authSettings.authenticator = SimpleAuthenticator.class.getName(); + authConfig.put(SimpleAuthenticator.CONFIG_CREDENTIALS_DB, "conf/tinkergraph-credentials.properties"); + authSettings.config = authConfig; + + return authSettings; + } + +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/WebSocketChannelizerIntegrateTest.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/WebSocketChannelizerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/WebSocketChannelizerIntegrateTest.java new file mode 100644 index 0000000..9ae600e --- /dev/null +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/WebSocketChannelizerIntegrateTest.java @@ -0,0 +1,56 @@ +/* + * 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.channel; + + +import org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator; +import org.apache.tinkerpop.gremlin.server.Settings; + +import java.util.Map; +import java.util.HashMap; + +public class WebSocketChannelizerIntegrateTest extends AbstractGremlinServerChannelizerIntegrateTest { + + @Override + public String getProtocol() { + return WS; + } + + @Override + public String getSecureProtocol() { + return WSS; + } + + @Override + public String getChannelizer() { + return WebSocketChannelizer.class.getName(); + } + + @Override + public Settings.AuthenticationSettings getAuthSettings() { + final Settings.AuthenticationSettings authSettings = new Settings.AuthenticationSettings(); + final Map<String,Object> authConfig = new HashMap<>(); + authSettings.authenticator = SimpleAuthenticator.class.getName(); + authConfig.put(SimpleAuthenticator.CONFIG_CREDENTIALS_DB, "conf/tinkergraph-credentials.properties"); + authSettings.config = authConfig; + + return authSettings; + } + +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c2643905/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/WsAndHttpChannelizerIntegrateTest.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/WsAndHttpChannelizerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/WsAndHttpChannelizerIntegrateTest.java new file mode 100644 index 0000000..0bda809 --- /dev/null +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/WsAndHttpChannelizerIntegrateTest.java @@ -0,0 +1,58 @@ +/* + * 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.channel; + + +import org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator; +import org.apache.tinkerpop.gremlin.server.handler.SaslAndHttpBasicAuthenticationHandler; +import org.apache.tinkerpop.gremlin.server.Settings; + +import java.util.Map; +import java.util.HashMap; + +public class WsAndHttpChannelizerIntegrateTest extends AbstractGremlinServerChannelizerIntegrateTest { + + @Override + public String getProtocol() { + return WS_AND_HTTP; + } + + @Override + public String getSecureProtocol() { + return WSS_AND_HTTPS; + } + + @Override + public String getChannelizer() { + return WsAndHttpChannelizer.class.getName(); + } + + @Override + public Settings.AuthenticationSettings getAuthSettings() { + final Settings.AuthenticationSettings authSettings = new Settings.AuthenticationSettings(); + final Map<String,Object> authConfig = new HashMap<>(); + authSettings.authenticator = SimpleAuthenticator.class.getName(); + authSettings.authenticationHandler = SaslAndHttpBasicAuthenticationHandler.class.getName(); + authConfig.put(SimpleAuthenticator.CONFIG_CREDENTIALS_DB, "conf/tinkergraph-credentials.properties"); + authSettings.config = authConfig; + + return authSettings; + } + +}