From e001fe03552887d889b53b4b25111d8cb3c3bf18 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 19 May 2017 08:27:53 -0700 Subject: [PATCH] Issue #1528 - pull preconfigured HttpClient from attributes + Search ServletContext attributes first + Search Server attributes next --- .../websocket/jsr356/ClientContainer.java | 25 ++++++++++++--- .../jsr356/server/ServerContainer.java | 19 ++++++++++-- .../WebSocketServerContainerInitializer.java | 11 ++++++- .../websocket/client/WebSocketClient.java | 31 ++++++++++++++++--- 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java index a5b705d13da..573f6b7e47f 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java @@ -38,6 +38,7 @@ import javax.websocket.Extension; import javax.websocket.Session; import javax.websocket.WebSocketContainer; +import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.component.ContainerLifeCycle; @@ -104,8 +105,19 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont */ public ClientContainer(final WebSocketContainerScope scope) { - String jsr356TrustAll = System.getProperty("org.eclipse.jetty.websocket.jsr356.ssl-trust-all"); + this(scope, null); + } + /** + * This is the entry point for ServerContainer, via ServletContext.getAttribute(ServerContainer.class.getName()) + * + * @param scope the scope of the ServerContainer + * @param httpClient the HttpClient instance to use + */ + protected ClientContainer(final WebSocketContainerScope scope, final HttpClient httpClient) + { + String jsr356TrustAll = System.getProperty("org.eclipse.jetty.websocket.jsr356.ssl-trust-all"); + WebSocketContainerScope clientScope; if (scope.getPolicy().getBehavior() == WebSocketBehavior.CLIENT) { @@ -120,19 +132,22 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont this.scopeDelegate = clientScope; this.client = new WebSocketClient(scopeDelegate, new JsrEventDriverFactory(scopeDelegate), - new JsrSessionFactory(this)); - this.internalClient = true; - + new JsrSessionFactory(this), + httpClient); + this.client.addBean(httpClient); + if(jsr356TrustAll != null) { boolean trustAll = Boolean.parseBoolean(jsr356TrustAll); client.getSslContextFactory().setTrustAll(trustAll); } + this.internalClient = true; + this.endpointClientMetadataCache = new ConcurrentHashMap<>(); this.decoderFactory = new DecoderFactory(this,PrimitiveDecoderMetadataSet.INSTANCE); this.encoderFactory = new EncoderFactory(this,PrimitiveEncoderMetadataSet.INSTANCE); - + ShutdownThread.register(this); } diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java index a6a130a7964..6ac98ca30f2 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java @@ -27,9 +27,13 @@ import java.util.concurrent.Executor; import javax.websocket.DeploymentException; import javax.websocket.Endpoint; import javax.websocket.Session; +import javax.websocket.WebSocketContainer; import javax.websocket.server.ServerEndpoint; import javax.websocket.server.ServerEndpointConfig; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.common.WebSocketSession; @@ -45,14 +49,23 @@ import org.eclipse.jetty.websocket.server.WebSocketServerFactory; public class ServerContainer extends ClientContainer implements javax.websocket.server.ServerContainer { private static final Logger LOG = Log.getLogger(ServerContainer.class); - + private final NativeWebSocketConfiguration configuration; private List> deferredEndpointClasses; private List deferredEndpointConfigs; - + + /** + * @deprecated use {@code ServerContainer(NativeWebSocketConfiguration, HttpClient)} instead + */ + @Deprecated public ServerContainer(NativeWebSocketConfiguration configuration, Executor executor) { - super(configuration.getFactory()); + this(configuration, (HttpClient) null); + } + + public ServerContainer(NativeWebSocketConfiguration configuration, HttpClient httpClient) + { + super(configuration.getFactory(), httpClient); this.configuration = configuration; EventDriverFactory eventDriverFactory = this.configuration.getFactory().getEventDriverFactory(); eventDriverFactory.addImplementation(new JsrServerEndpointImpl()); diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/deploy/WebSocketServerContainerInitializer.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/deploy/WebSocketServerContainerInitializer.java index d02ae1d30f3..33632837621 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/deploy/WebSocketServerContainerInitializer.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/deploy/WebSocketServerContainerInitializer.java @@ -33,6 +33,7 @@ import javax.websocket.server.ServerApplicationConfig; import javax.websocket.server.ServerEndpoint; import javax.websocket.server.ServerEndpointConfig; +import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.util.TypeUtil; @@ -51,6 +52,7 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit public static final String ENABLE_KEY = "org.eclipse.jetty.websocket.jsr356"; public static final String ADD_DYNAMIC_FILTER_KEY = "org.eclipse.jetty.websocket.jsr356.addDynamicFilter"; private static final Logger LOG = Log.getLogger(WebSocketServerContainerInitializer.class); + public static final String HTTPCLIENT_ATTRIBUTE = "org.eclipse.jetty.websocket.jsr356.HttpClient"; /** * DestroyListener @@ -136,8 +138,15 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit // Create Basic components NativeWebSocketConfiguration nativeWebSocketConfiguration = NativeWebSocketServletContainerInitializer.getDefaultFrom(context.getServletContext()); + // Build HttpClient + HttpClient httpClient = (HttpClient) context.getServletContext().getAttribute(HTTPCLIENT_ATTRIBUTE); + if(httpClient == null) + { + httpClient = (HttpClient) context.getServer().getAttribute(HTTPCLIENT_ATTRIBUTE); + } + // Create the Jetty ServerContainer implementation - ServerContainer jettyContainer = new ServerContainer(nativeWebSocketConfiguration, context.getServer().getThreadPool()); + ServerContainer jettyContainer = new ServerContainer(nativeWebSocketConfiguration, httpClient); context.addBean(jettyContainer); // Store a reference to the ServerContainer per javax.websocket spec 1.0 final section 6.4 Programmatic Server Deployment diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java index fc68ea00146..04d6e64a543 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java @@ -248,6 +248,22 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont * the SessionFactory to use */ public WebSocketClient(final WebSocketContainerScope scope, EventDriverFactory eventDriverFactory, SessionFactory sessionFactory) + { + this(scope, eventDriverFactory, sessionFactory, null); + } + + /** + * Create WebSocketClient based on pre-existing Container Scope, to allow sharing of + * internal features like Executor, ByteBufferPool, SSLContextFactory, etc. + * + * @param scope + * the Container Scope + * @param eventDriverFactory + * the EventDriver Factory to use + * @param sessionFactory + * the SessionFactory to use + */ + public WebSocketClient(final WebSocketContainerScope scope, EventDriverFactory eventDriverFactory, SessionFactory sessionFactory, HttpClient httpClient) { WebSocketContainerScope clientScope; if (scope.getPolicy().getBehavior() == WebSocketBehavior.CLIENT) @@ -262,11 +278,18 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont this.containerScope = clientScope; - this.httpClient = HttpClientProvider.get(scope); - addBean(this.httpClient); - + if(httpClient == null) + { + this.httpClient = HttpClientProvider.get(scope); + addBean(this.httpClient); + } + else + { + this.httpClient = httpClient; + } + this.extensionRegistry = new WebSocketExtensionFactory(containerScope); - + this.eventDriverFactory = eventDriverFactory; this.sessionFactory = sessionFactory; }