From 1f3097ff162ea4198f9979fed09b19ef49f69572 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 19 Dec 2014 13:54:34 -0700 Subject: [PATCH] 453834 - CDI Support for WebSocket + Adding scopes to websocket to help with CDI integration --- .../websocket/jsr356/ClientContainer.java | 62 ++++++--- .../websocket/jsr356/DecoderFactory.java | 19 ++- .../websocket/jsr356/EncoderFactory.java | 18 ++- .../jetty/websocket/jsr356/JsrSession.java | 9 +- .../websocket/jsr356/JsrSessionFactory.java | 11 +- .../websocket/jsr356/DecoderFactoryTest.java | 12 +- .../websocket/jsr356/EncoderFactoryTest.java | 10 +- .../websocket/jsr356/JsrSessionTest.java | 9 +- .../jsr356/MessageHandlerFactoryTest.java | 12 +- .../server/AnnotatedServerEndpointConfig.java | 20 ++- .../AnnotatedServerEndpointMetadata.java | 8 +- .../server/BasicServerEndpointConfig.java | 18 ++- .../BasicServerEndpointConfigurator.java | 87 ++---------- .../server/ContainerDefaultConfigurator.java | 127 ++++++++++++++++++ .../websocket/jsr356/server/JsrCreator.java | 12 +- .../server/PathParamServerEndpointConfig.java | 6 +- .../jsr356/server/ServerContainer.java | 8 +- .../WebSocketServerContainerInitializer.java | 2 - ...t.server.ServerEndpointConfig$Configurator | 2 +- .../JettyServerEndpointConfiguratorTest.java | 2 +- .../jsr356/server/OnPartialTest.java | 16 +-- ...tedEndpointScanner_GoodSignaturesTest.java | 9 +- ...EndpointScanner_InvalidSignaturesTest.java | 11 +- .../websocket/api/extensions/Extension.java | 5 - .../websocket/client/WebSocketClient.java | 50 +++++-- .../jetty/websocket/client/SessionTest.java | 6 +- .../websocket/common/SessionFactory.java | 3 - .../websocket/common/WebSocketSession.java | 28 +++- .../common/WebSocketSessionFactory.java | 32 +++-- .../common/extensions/AbstractExtension.java | 9 +- .../extensions/WebSocketExtensionFactory.java | 23 +--- .../common/scopes/SimpleContainerScope.java | 95 +++++++++++++ .../scopes/WebSocketContainerScope.java | 67 +++++++++ .../scopes/WebSocketHandshakeScope.java | 36 +++++ .../common/scopes/WebSocketSessionScope.java | 31 +++++ .../common/events/EventDriverTest.java | 22 ++- .../common/extensions/ExtensionStackTest.java | 7 +- .../common/extensions/ExtensionTool.java | 7 +- .../common/io/LocalWebSocketSession.java | 7 +- .../message/MessageOutputStreamTest.java | 6 +- .../common/message/MessageWriterTest.java | 6 +- .../common/test/BlockheadClient.java | 5 +- .../common/test/BlockheadServer.java | 3 +- .../server/WebSocketServerFactory.java | 89 ++++++------ .../server/WebSocketUpgradeFilter.java | 1 - 45 files changed, 717 insertions(+), 311 deletions(-) create mode 100644 jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ContainerDefaultConfigurator.java create mode 100644 jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java create mode 100644 jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketContainerScope.java create mode 100644 jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketHandshakeScope.java create mode 100644 jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketSessionScope.java 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 8ed51dc15d5..eff027094bb 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 @@ -40,6 +40,7 @@ import javax.websocket.Extension; import javax.websocket.Session; import javax.websocket.WebSocketContainer; +import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.log.Log; @@ -47,6 +48,7 @@ import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.ShutdownThread; import org.eclipse.jetty.websocket.api.InvalidWebSocketException; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory; import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.client.WebSocketClient; @@ -54,6 +56,8 @@ import org.eclipse.jetty.websocket.client.io.UpgradeListener; import org.eclipse.jetty.websocket.common.SessionFactory; import org.eclipse.jetty.websocket.common.SessionListener; import org.eclipse.jetty.websocket.common.WebSocketSession; +import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner; import org.eclipse.jetty.websocket.jsr356.client.AnnotatedClientEndpointMetadata; import org.eclipse.jetty.websocket.jsr356.client.EmptyClientEndpointConfig; @@ -69,7 +73,7 @@ import org.eclipse.jetty.websocket.jsr356.metadata.EndpointMetadata; *

* This should be specific to a JVM if run in a standalone mode. or specific to a WebAppContext if running on the Jetty server. */ -public class ClientContainer extends ContainerLifeCycle implements WebSocketContainer, SessionListener +public class ClientContainer extends ContainerLifeCycle implements WebSocketContainer, WebSocketContainerScope, SessionListener { private static final Logger LOG = Log.getLogger(ClientContainer.class); @@ -90,30 +94,28 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont public ClientContainer() { // This constructor is used with Standalone JSR Client usage. - this(null,new DecoratedObjectFactory()); + this(new SimpleContainerScope(WebSocketPolicy.newClientPolicy())); client.setDaemon(true); } - public ClientContainer(Executor executor, DecoratedObjectFactory objectFactory) + public ClientContainer(WebSocketContainerScope scope) { - this.objectFactory = objectFactory; + boolean trustAll = Boolean.getBoolean("org.eclipse.jetty.websocket.jsr356.ssl-trust-all"); + + client = new WebSocketClient(scope, new SslContextFactory(trustAll)); + client.setEventDriverFactory(new JsrEventDriverFactory(client.getPolicy())); + SessionFactory sessionFactory = new JsrSessionFactory(this,this,client); + client.setSessionFactory(sessionFactory); + addBean(client); + this.endpointClientMetadataCache = new ConcurrentHashMap<>(); - this.decoderFactory = new DecoderFactory(PrimitiveDecoderMetadataSet.INSTANCE,null,objectFactory); - this.encoderFactory = new EncoderFactory(PrimitiveEncoderMetadataSet.INSTANCE,null,objectFactory); + this.decoderFactory = new DecoderFactory(this,PrimitiveDecoderMetadataSet.INSTANCE); + this.encoderFactory = new EncoderFactory(this,PrimitiveEncoderMetadataSet.INSTANCE); EmptyClientEndpointConfig empty = new EmptyClientEndpointConfig(); this.decoderFactory.init(empty); this.encoderFactory.init(empty); - boolean trustAll = Boolean.getBoolean("org.eclipse.jetty.websocket.jsr356.ssl-trust-all"); - - client = new WebSocketClient(new SslContextFactory(trustAll), executor); - client.setEventDriverFactory(new JsrEventDriverFactory(client.getPolicy())); - SessionFactory sessionFactory = new JsrSessionFactory(this,this,client); - sessionFactory.setEnhancedInstantiator(objectFactory); - client.setSessionFactory(sessionFactory); - addBean(client); - ShutdownThread.register(this); } @@ -203,6 +205,12 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont super.doStop(); } + @Override + public ByteBufferPool getBufferPool() + { + return client.getBufferPool(); + } + public WebSocketClient getClient() { return client; @@ -286,6 +294,12 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont return encoderFactory; } + @Override + public Executor getExecutor() + { + return client.getExecutor(); + } + @Override public Set getInstalledExtensions() { @@ -300,6 +314,12 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont return ret; } + @Override + public DecoratedObjectFactory getObjectFactory() + { + return client.getObjectFactory(); + } + /** * Used in {@link Session#getOpenSessions()} */ @@ -308,6 +328,18 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont return Collections.unmodifiableSet(this.openSessions); } + @Override + public WebSocketPolicy getPolicy() + { + return client.getPolicy(); + } + + @Override + public SslContextFactory getSslContextFactory() + { + return client.getSslContextFactory(); + } + private EndpointInstance newClientEndpointInstance(Class endpointClass, ClientEndpointConfig config) { try diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/DecoderFactory.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/DecoderFactory.java index 755b3671c8a..1459eda4dcd 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/DecoderFactory.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/DecoderFactory.java @@ -28,6 +28,8 @@ import javax.websocket.EndpointConfig; import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; +import org.eclipse.jetty.websocket.common.scopes.WebSocketSessionScope; import org.eclipse.jetty.websocket.jsr356.metadata.DecoderMetadata; import org.eclipse.jetty.websocket.jsr356.metadata.DecoderMetadataSet; @@ -78,19 +80,23 @@ public class DecoderFactory implements Configurable private DecoderFactory parentFactory; private Map, Wrapper> activeWrappers; - public DecoderFactory(DecoderMetadataSet metadatas) + public DecoderFactory(WebSocketContainerScope containerScope, DecoderMetadataSet metadatas) { - this(metadatas, null, new DecoratedObjectFactory()); + this(containerScope,metadatas,null); + } + + public DecoderFactory(WebSocketSessionScope sessionScope, DecoderMetadataSet metadatas, DecoderFactory parentFactory) + { + this(sessionScope.getContainerScope(),metadatas,parentFactory); } - public DecoderFactory(DecoderMetadataSet metadatas, DecoderFactory parentFactory, DecoratedObjectFactory objectFactory) + protected DecoderFactory(WebSocketContainerScope containerScope, DecoderMetadataSet metadatas, DecoderFactory parentFactory) { + Objects.requireNonNull(containerScope,"Container Scope cannot be null"); + this.objectFactory = containerScope.getObjectFactory(); this.metadatas = metadatas; this.activeWrappers = new ConcurrentHashMap<>(); this.parentFactory = parentFactory; - - Objects.requireNonNull(objectFactory,"EnhancedInitiator cannot be null"); - this.objectFactory = objectFactory; } public Decoder getDecoderFor(Class type) @@ -109,6 +115,7 @@ public class DecoderFactory implements Configurable { LOG.debug("getMetadataFor({})",type); } + DecoderMetadata metadata = metadatas.getMetadataByType(type); if (metadata != null) diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/EncoderFactory.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/EncoderFactory.java index 1f34452517f..4e18662b2b3 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/EncoderFactory.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/EncoderFactory.java @@ -28,6 +28,8 @@ import javax.websocket.EndpointConfig; import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; +import org.eclipse.jetty.websocket.common.scopes.WebSocketSessionScope; import org.eclipse.jetty.websocket.jsr356.metadata.EncoderMetadata; import org.eclipse.jetty.websocket.jsr356.metadata.EncoderMetadataSet; @@ -71,19 +73,23 @@ public class EncoderFactory implements Configurable private EncoderFactory parentFactory; private Map, Wrapper> activeWrappers; - public EncoderFactory(EncoderMetadataSet metadatas) + public EncoderFactory(WebSocketContainerScope containerScope, EncoderMetadataSet metadatas) { - this(metadatas,null,new DecoratedObjectFactory()); + this(containerScope,metadatas,null); } - public EncoderFactory(EncoderMetadataSet metadatas, EncoderFactory parentFactory, DecoratedObjectFactory objectFactory) + public EncoderFactory(WebSocketSessionScope sessionScope, EncoderMetadataSet metadatas, EncoderFactory parentFactory) { + this(sessionScope.getContainerScope(),metadatas,parentFactory); + } + + protected EncoderFactory(WebSocketContainerScope containerScope, EncoderMetadataSet metadatas, EncoderFactory parentFactory) + { + Objects.requireNonNull(containerScope,"Container Scope cannot be null"); + this.objectFactory = containerScope.getObjectFactory(); this.metadatas = metadatas; this.activeWrappers = new ConcurrentHashMap<>(); this.parentFactory = parentFactory; - - Objects.requireNonNull(objectFactory,"EnhancedInitiator cannot be null"); - this.objectFactory = objectFactory; } public Encoder getEncoderFor(Class type) diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSession.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSession.java index e887ee1c138..c1fa532a8f8 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSession.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSession.java @@ -39,7 +39,6 @@ import javax.websocket.RemoteEndpoint.Basic; import javax.websocket.Session; import javax.websocket.WebSocketContainer; -import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.BatchMode; @@ -75,9 +74,9 @@ public class JsrSession extends WebSocketSession implements javax.websocket.Sess private JsrAsyncRemote asyncRemote; private JsrBasicRemote basicRemote; - public JsrSession(URI requestURI, EventDriver websocket, LogicalConnection connection, ClientContainer container, String id, DecoratedObjectFactory objectFactory, SessionListener... sessionListeners) + public JsrSession(ClientContainer container, String id, URI requestURI, EventDriver websocket, LogicalConnection connection, SessionListener... sessionListeners) { - super(requestURI, websocket, connection, sessionListeners); + super(container, requestURI, websocket, connection, sessionListeners); if (!(websocket instanceof AbstractJsrEventDriver)) { throw new IllegalArgumentException("Cannot use, not a JSR WebSocket: " + websocket); @@ -87,8 +86,8 @@ public class JsrSession extends WebSocketSession implements javax.websocket.Sess this.metadata = jsr.getMetadata(); this.container = container; this.id = id; - this.decoderFactory = new DecoderFactory(metadata.getDecoders(),container.getDecoderFactory(),objectFactory); - this.encoderFactory = new EncoderFactory(metadata.getEncoders(),container.getEncoderFactory(),objectFactory); + this.decoderFactory = new DecoderFactory(this,metadata.getDecoders(),container.getDecoderFactory()); + this.encoderFactory = new EncoderFactory(this,metadata.getEncoders(),container.getEncoderFactory()); this.messageHandlerFactory = new MessageHandlerFactory(); this.wrappers = new MessageHandlerWrapper[MessageType.values().length]; this.messageHandlerSet = new HashSet<>(); diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSessionFactory.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSessionFactory.java index 5fd8c02537c..26e0c8683f3 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSessionFactory.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSessionFactory.java @@ -21,7 +21,6 @@ package org.eclipse.jetty.websocket.jsr356; import java.net.URI; import java.util.concurrent.atomic.AtomicLong; -import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.websocket.common.LogicalConnection; import org.eclipse.jetty.websocket.common.SessionFactory; import org.eclipse.jetty.websocket.common.SessionListener; @@ -32,7 +31,6 @@ import org.eclipse.jetty.websocket.jsr356.endpoints.AbstractJsrEventDriver; public class JsrSessionFactory implements SessionFactory { private AtomicLong idgen = new AtomicLong(0); - private DecoratedObjectFactory objectFactory; private final ClientContainer container; private final SessionListener[] listeners; @@ -40,13 +38,12 @@ public class JsrSessionFactory implements SessionFactory { this.container = container; this.listeners = sessionListeners; - this.objectFactory = new DecoratedObjectFactory(); } @Override public WebSocketSession createSession(URI requestURI, EventDriver websocket, LogicalConnection connection) { - return new JsrSession(requestURI,websocket,connection,container,getNextId(),objectFactory,listeners); + return new JsrSession(container,getNextId(),requestURI,websocket,connection,listeners); } public String getNextId() @@ -59,10 +56,4 @@ public class JsrSessionFactory implements SessionFactory { return (websocket instanceof AbstractJsrEventDriver); } - - @Override - public void setEnhancedInstantiator(DecoratedObjectFactory objectFactory) - { - this.objectFactory = objectFactory; - } } diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderFactoryTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderFactoryTest.java index 733dd08f6eb..0aa8ee6e84a 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderFactoryTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderFactoryTest.java @@ -18,14 +18,16 @@ package org.eclipse.jetty.websocket.jsr356; -import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.*; import java.nio.ByteBuffer; import java.util.Date; import javax.websocket.Decoder; -import org.eclipse.jetty.util.DecoratedObjectFactory; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.websocket.jsr356.decoders.ByteArrayDecoder; import org.eclipse.jetty.websocket.jsr356.decoders.ByteBufferDecoder; import org.eclipse.jetty.websocket.jsr356.decoders.DateDecoder; @@ -57,9 +59,11 @@ public class DecoderFactoryTest @Before public void initDecoderFactory() { - DecoderFactory primitivesFactory = new DecoderFactory(PrimitiveDecoderMetadataSet.INSTANCE); + WebSocketContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy()); + + DecoderFactory primitivesFactory = new DecoderFactory(containerScope,PrimitiveDecoderMetadataSet.INSTANCE); metadatas = new DecoderMetadataSet(); - factory = new DecoderFactory(metadatas,primitivesFactory,new DecoratedObjectFactory()); + factory = new DecoderFactory(containerScope,metadatas,primitivesFactory); } @Test diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderFactoryTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderFactoryTest.java index 204b0dfe030..1ce98feb740 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderFactoryTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderFactoryTest.java @@ -22,7 +22,9 @@ import static org.hamcrest.Matchers.*; import javax.websocket.Encoder; -import org.eclipse.jetty.util.DecoratedObjectFactory; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.websocket.jsr356.encoders.IntegerEncoder; import org.eclipse.jetty.websocket.jsr356.encoders.LongEncoder; import org.eclipse.jetty.websocket.jsr356.encoders.PrimitiveEncoderMetadataSet; @@ -54,9 +56,11 @@ public class EncoderFactoryTest @Before public void initEncoderFactory() { - EncoderFactory primitivesFactory = new EncoderFactory(PrimitiveEncoderMetadataSet.INSTANCE); + WebSocketContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy()); + + EncoderFactory primitivesFactory = new EncoderFactory(containerScope,PrimitiveEncoderMetadataSet.INSTANCE); metadatas = new EncoderMetadataSet(); - factory = new EncoderFactory(metadatas,primitivesFactory,new DecoratedObjectFactory()); + factory = new EncoderFactory(containerScope,metadatas,primitivesFactory); } @Test diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/JsrSessionTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/JsrSessionTest.java index 07eae55b967..f17d6267a4d 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/JsrSessionTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/JsrSessionTest.java @@ -18,6 +18,8 @@ package org.eclipse.jetty.websocket.jsr356; +import static org.hamcrest.Matchers.*; + import java.net.URI; import java.nio.ByteBuffer; @@ -25,7 +27,6 @@ import javax.websocket.ClientEndpointConfig; import javax.websocket.DeploymentException; import javax.websocket.MessageHandler; -import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.common.events.EventDriver; import org.eclipse.jetty.websocket.jsr356.client.EmptyClientEndpointConfig; @@ -42,8 +43,6 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import static org.hamcrest.Matchers.instanceOf; - public class JsrSessionTest { private ClientContainer container; @@ -62,10 +61,10 @@ public class JsrSessionTest // Executor executor = null; EndpointInstance ei = new EndpointInstance(websocket,config,metadata); - + EventDriver driver = new JsrEndpointEventDriver(policy,ei); DummyConnection connection = new DummyConnection(); - session = new JsrSession(requestURI,driver,connection,container,id, new DecoratedObjectFactory()); + session = new JsrSession(container,id,requestURI,driver,connection); } @Test diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/MessageHandlerFactoryTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/MessageHandlerFactoryTest.java index 15630540d75..3df787953b1 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/MessageHandlerFactoryTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/MessageHandlerFactoryTest.java @@ -18,14 +18,16 @@ package org.eclipse.jetty.websocket.jsr356; -import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.*; import java.lang.reflect.Type; import java.util.List; import javax.websocket.DeploymentException; -import org.eclipse.jetty.util.DecoratedObjectFactory; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.websocket.jsr356.decoders.PrimitiveDecoderMetadataSet; import org.eclipse.jetty.websocket.jsr356.handlers.ByteArrayPartialHandler; import org.eclipse.jetty.websocket.jsr356.handlers.StringPartialHandler; @@ -45,9 +47,11 @@ public class MessageHandlerFactoryTest @Before public void init() throws DeploymentException { - DecoderFactory primitivesFactory = new DecoderFactory(PrimitiveDecoderMetadataSet.INSTANCE); + WebSocketContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy()); + + DecoderFactory primitivesFactory = new DecoderFactory(containerScope,PrimitiveDecoderMetadataSet.INSTANCE); metadatas = new DecoderMetadataSet(); - decoders = new DecoderFactory(metadatas,primitivesFactory,new DecoratedObjectFactory()); + decoders = new DecoderFactory(containerScope,metadatas,primitivesFactory); factory = new MessageHandlerFactory(); } diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointConfig.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointConfig.java index 3b0be7492e4..f6ae65b3e3f 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointConfig.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointConfig.java @@ -32,7 +32,7 @@ import javax.websocket.Extension; import javax.websocket.server.ServerEndpoint; import javax.websocket.server.ServerEndpointConfig; -import org.eclipse.jetty.util.DecoratedObjectFactory; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; public class AnnotatedServerEndpointConfig implements ServerEndpointConfig { @@ -46,12 +46,12 @@ public class AnnotatedServerEndpointConfig implements ServerEndpointConfig private Map userProperties; private List extensions; - public AnnotatedServerEndpointConfig(Class endpointClass, ServerEndpoint anno, DecoratedObjectFactory objectFactory) throws DeploymentException + public AnnotatedServerEndpointConfig(WebSocketContainerScope containerScope, Class endpointClass, ServerEndpoint anno) throws DeploymentException { - this(endpointClass,anno,objectFactory,null); + this(containerScope,endpointClass,anno,null); } - public AnnotatedServerEndpointConfig(Class endpointClass, ServerEndpoint anno, DecoratedObjectFactory objectFactory, ServerEndpointConfig baseConfig) throws DeploymentException + public AnnotatedServerEndpointConfig(WebSocketContainerScope containerScope, Class endpointClass, ServerEndpoint anno, ServerEndpointConfig baseConfig) throws DeploymentException { ServerEndpointConfig.Configurator configr = null; @@ -111,23 +111,25 @@ public class AnnotatedServerEndpointConfig implements ServerEndpointConfig { userProperties.putAll(baseConfig.getUserProperties()); } + + ServerEndpointConfig.Configurator cfgr; if (anno.configurator() == ServerEndpointConfig.Configurator.class) { if (configr != null) { - this.configurator = configr; + cfgr = configr; } else { - this.configurator = new BasicServerEndpointConfigurator(objectFactory); + cfgr = new BasicServerEndpointConfigurator(containerScope); } } else { try { - this.configurator = anno.configurator().newInstance(); + cfgr = anno.configurator().newInstance(); } catch (InstantiationException | IllegalAccessException e) { @@ -139,6 +141,10 @@ public class AnnotatedServerEndpointConfig implements ServerEndpointConfig throw new DeploymentException(err.toString(),e); } } + + // Make sure all Configurators obtained are decorated + this.configurator = containerScope.getObjectFactory().decorate(cfgr); + } @Override diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointMetadata.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointMetadata.java index e980e48b906..5e0f82b9a7c 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointMetadata.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointMetadata.java @@ -24,8 +24,8 @@ import javax.websocket.DeploymentException; import javax.websocket.server.ServerEndpoint; import javax.websocket.server.ServerEndpointConfig; -import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.websocket.api.InvalidWebSocketException; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointMetadata; import org.eclipse.jetty.websocket.jsr356.annotations.IJsrParamId; @@ -34,7 +34,7 @@ public class AnnotatedServerEndpointMetadata extends AnnotatedEndpointMetadata websocket, ServerEndpointConfig baseConfig, DecoratedObjectFactory objectFactory) throws DeploymentException + protected AnnotatedServerEndpointMetadata(WebSocketContainerScope containerScope, Class websocket, ServerEndpointConfig baseConfig) throws DeploymentException { super(websocket); @@ -45,9 +45,9 @@ public class AnnotatedServerEndpointMetadata extends AnnotatedEndpointMetadata userProperties; - public BasicServerEndpointConfig(Class endpointClass, String path, DecoratedObjectFactory objectFactory) + public BasicServerEndpointConfig(WebSocketContainerScope containerScope, Class endpointClass, String path) { this.endpointClass = endpointClass; this.path = path; @@ -51,10 +51,10 @@ public class BasicServerEndpointConfig implements ServerEndpointConfig this.subprotocols = new ArrayList<>(); this.extensions = new ArrayList<>(); this.userProperties = new HashMap<>(); - this.configurator = new BasicServerEndpointConfigurator(objectFactory); + this.configurator = new BasicServerEndpointConfigurator(containerScope); } - public BasicServerEndpointConfig(ServerEndpointConfig copy, DecoratedObjectFactory objectFactory) + public BasicServerEndpointConfig(WebSocketContainerScope containerScope, ServerEndpointConfig copy) { // immutable concepts this.endpointClass = copy.getEndpointClass(); @@ -64,15 +64,21 @@ public class BasicServerEndpointConfig implements ServerEndpointConfig this.encoders = copy.getEncoders(); this.subprotocols = copy.getSubprotocols(); this.extensions = copy.getExtensions(); + + ServerEndpointConfig.Configurator cfgr; + if (copy.getConfigurator() != null) { - this.configurator = copy.getConfigurator(); + cfgr = copy.getConfigurator(); } else { - this.configurator = new BasicServerEndpointConfigurator(objectFactory); + cfgr = new BasicServerEndpointConfigurator(containerScope); } + // Make sure all Configurators obtained are decorated + this.configurator = containerScope.getObjectFactory().decorate(cfgr); + // mutable concepts this.userProperties = new HashMap<>(copy.getUserProperties()); } diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/BasicServerEndpointConfigurator.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/BasicServerEndpointConfigurator.java index 43e1a016f10..71000af8fd0 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/BasicServerEndpointConfigurator.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/BasicServerEndpointConfigurator.java @@ -18,45 +18,23 @@ package org.eclipse.jetty.websocket.jsr356.server; -import java.util.List; -import java.util.Objects; - -import javax.websocket.Extension; -import javax.websocket.HandshakeResponse; -import javax.websocket.server.HandshakeRequest; -import javax.websocket.server.ServerEndpointConfig; - import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.api.util.QuoteUtil; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; -public class BasicServerEndpointConfigurator extends ServerEndpointConfig.Configurator +/** + * The Basic Configurator + */ +public class BasicServerEndpointConfigurator extends ContainerDefaultConfigurator { private static final Logger LOG = Log.getLogger(BasicServerEndpointConfigurator.class); - private static final String NO_SUBPROTOCOL = ""; private final DecoratedObjectFactory objectFactory; - /** - * Default Constructor required, as - * javax.websocket.server.ServerEndpointConfig$Configurator.fetchContainerDefaultConfigurator() - * will be the one that instantiates this class in most cases. - */ - public BasicServerEndpointConfigurator() + public BasicServerEndpointConfigurator(WebSocketContainerScope containerScope) { - this(DecoratedObjectFactory.getCurrentInstantiator()); - } - - public BasicServerEndpointConfigurator(DecoratedObjectFactory objectFactory) - { - Objects.requireNonNull(objectFactory,"DecoratedObjectFactory cannot be null"); - this.objectFactory = objectFactory; - } - - @Override - public boolean checkOrigin(String originHeaderValue) - { - return true; + super(); + this.objectFactory = containerScope.getObjectFactory(); } @Override @@ -76,53 +54,4 @@ public class BasicServerEndpointConfigurator extends ServerEndpointConfig.Config throw new InstantiationException(String.format("%s: %s",e.getClass().getName(),e.getMessage())); } } - - @Override - public List getNegotiatedExtensions(List installed, List requested) - { - return requested; - } - - @Override - public String getNegotiatedSubprotocol(List supported, List requested) - { - if ((requested == null) || (requested.size() == 0)) - { - // nothing requested, don't return anything - return NO_SUBPROTOCOL; - } - - // Nothing specifically called out as being supported by the endpoint - if ((supported == null) || (supported.isEmpty())) - { - // Just return the first hit in this case - LOG.warn("Client requested Subprotocols on endpoint with none supported: {}",QuoteUtil.join(requested,",")); - return NO_SUBPROTOCOL; - } - - // Return the first matching hit from the list of supported protocols. - for (String possible : requested) - { - if (possible == null) - { - // skip null - continue; - } - - if (supported.contains(possible)) - { - return possible; - } - } - - LOG.warn("Client requested subprotocols {} do not match any endpoint supported subprotocols {}",QuoteUtil.join(requested,","), - QuoteUtil.join(supported,",")); - return NO_SUBPROTOCOL; - } - - @Override - public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) - { - /* do nothing */ - } } \ No newline at end of file diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ContainerDefaultConfigurator.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ContainerDefaultConfigurator.java new file mode 100644 index 00000000000..7fc5f955056 --- /dev/null +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ContainerDefaultConfigurator.java @@ -0,0 +1,127 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.jsr356.server; + +import java.util.List; + +import javax.websocket.Extension; +import javax.websocket.HandshakeResponse; +import javax.websocket.server.HandshakeRequest; +import javax.websocket.server.ServerEndpointConfig; +import javax.websocket.server.ServerEndpointConfig.Configurator; + +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.util.QuoteUtil; + +/** + * The "Container Default Configurator" per the JSR-356 spec. + * + * @see ServiceLoader behavior of {@link ServerEndpointConfig.Configurator} + */ +public class ContainerDefaultConfigurator extends Configurator +{ + private static final Logger LOG = Log.getLogger(ContainerDefaultConfigurator.class); + private static final String NO_SUBPROTOCOL = ""; + + /** + * Default Constructor required, as + * javax.websocket.server.ServerEndpointConfig$Configurator.fetchContainerDefaultConfigurator() + * will be the one that instantiates this class in most cases. + */ + public ContainerDefaultConfigurator() + { + super(); + } + + @Override + public boolean checkOrigin(String originHeaderValue) + { + return true; + } + + @Override + public T getEndpointInstance(Class endpointClass) throws InstantiationException + { + if (LOG.isDebugEnabled()) + { + LOG.debug(".getEndpointInstance({})",endpointClass); + } + + try + { + // Since this is started via a ServiceLoader, this class has no Scope or context + // that can be used to obtain a ObjectFactory from. + return endpointClass.newInstance(); + } + catch (IllegalAccessException e) + { + throw new InstantiationException(String.format("%s: %s",e.getClass().getName(),e.getMessage())); + } + } + + @Override + public List getNegotiatedExtensions(List installed, List requested) + { + return requested; + } + + @Override + public String getNegotiatedSubprotocol(List supported, List requested) + { + if ((requested == null) || (requested.size() == 0)) + { + // nothing requested, don't return anything + return NO_SUBPROTOCOL; + } + + // Nothing specifically called out as being supported by the endpoint + if ((supported == null) || (supported.isEmpty())) + { + // Just return the first hit in this case + LOG.warn("Client requested Subprotocols on endpoint with none supported: {}",QuoteUtil.join(requested,",")); + return NO_SUBPROTOCOL; + } + + // Return the first matching hit from the list of supported protocols. + for (String possible : requested) + { + if (possible == null) + { + // skip null + continue; + } + + if (supported.contains(possible)) + { + return possible; + } + } + + LOG.warn("Client requested subprotocols {} do not match any endpoint supported subprotocols {}",QuoteUtil.join(requested,","), + QuoteUtil.join(supported,",")); + return NO_SUBPROTOCOL; + } + + @Override + public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) + { + /* do nothing */ + } +} diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrCreator.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrCreator.java index eda968b25d7..93d6659771b 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrCreator.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrCreator.java @@ -26,12 +26,12 @@ import javax.websocket.Extension; import javax.websocket.Extension.Parameter; import javax.websocket.server.ServerEndpointConfig; -import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.websocket.jsr356.JsrExtension; import org.eclipse.jetty.websocket.jsr356.endpoints.EndpointInstance; import org.eclipse.jetty.websocket.jsr356.server.pathmap.WebSocketPathSpec; @@ -45,15 +45,15 @@ public class JsrCreator implements WebSocketCreator public static final String PROP_REMOTE_ADDRESS = "javax.websocket.endpoint.remoteAddress"; public static final String PROP_LOCAL_ADDRESS = "javax.websocket.endpoint.localAddress"; private static final Logger LOG = Log.getLogger(JsrCreator.class); + private final WebSocketContainerScope containerScope; private final ServerEndpointMetadata metadata; private final ExtensionFactory extensionFactory; - private final DecoratedObjectFactory objectFactory; - public JsrCreator(ServerEndpointMetadata metadata, ExtensionFactory extensionFactory, DecoratedObjectFactory objectFactory) + public JsrCreator(WebSocketContainerScope containerScope, ServerEndpointMetadata metadata, ExtensionFactory extensionFactory) { + this.containerScope = containerScope; this.metadata = metadata; this.extensionFactory = extensionFactory; - this.objectFactory = objectFactory; } @Override @@ -67,7 +67,7 @@ public class JsrCreator implements WebSocketCreator // Establish a copy of the config, so that the UserProperties are unique // per upgrade request. - config = new BasicServerEndpointConfig(config, objectFactory); + config = new BasicServerEndpointConfig(containerScope, config); // Bug 444617 - Expose localAddress and remoteAddress for jsr modify handshake to use // This is being implemented as an optional set of userProperties so that @@ -145,7 +145,7 @@ public class JsrCreator implements WebSocketCreator WebSocketPathSpec wspathSpec = (WebSocketPathSpec)pathSpec; String requestPath = req.getRequestPath(); // Wrap the config with the path spec information - config = new PathParamServerEndpointConfig(config,objectFactory,wspathSpec,requestPath); + config = new PathParamServerEndpointConfig(containerScope,config,wspathSpec,requestPath); } return new EndpointInstance(endpoint,config,metadata); } diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/PathParamServerEndpointConfig.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/PathParamServerEndpointConfig.java index 1ff43b4cbc0..d709a0039a0 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/PathParamServerEndpointConfig.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/PathParamServerEndpointConfig.java @@ -23,7 +23,7 @@ import java.util.Map; import javax.websocket.server.ServerEndpointConfig; -import org.eclipse.jetty.util.DecoratedObjectFactory; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.websocket.jsr356.server.pathmap.WebSocketPathSpec; /** @@ -33,9 +33,9 @@ public class PathParamServerEndpointConfig extends BasicServerEndpointConfig imp { private final Map pathParamMap; - public PathParamServerEndpointConfig(ServerEndpointConfig config, DecoratedObjectFactory objectFactory, WebSocketPathSpec pathSpec, String requestPath) + public PathParamServerEndpointConfig(WebSocketContainerScope containerScope, ServerEndpointConfig config, WebSocketPathSpec pathSpec, String requestPath) { - super(config, objectFactory); + super(containerScope, config); Map pathMap = pathSpec.getPathParams(requestPath); pathParamMap = new HashMap(); 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 10383ec4345..6955bef201e 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 @@ -46,7 +46,7 @@ public class ServerContainer extends ClientContainer implements javax.websocket. public ServerContainer(MappedWebSocketCreator creator, WebSocketServerFactory factory, Executor executor) { - super(executor, factory.getEnhancedInstantiator()); + super(); this.mappedCreator = creator; this.webSocketServerFactory = factory; EventDriverFactory eventDriverFactory = this.webSocketServerFactory.getEventDriverFactory(); @@ -67,7 +67,7 @@ public class ServerContainer extends ClientContainer implements javax.websocket. } else { - cec = new BasicServerEndpointConfig(endpoint.getClass(),path,objectFactory); + cec = new BasicServerEndpointConfig(this,endpoint.getClass(),path); } } return new EndpointInstance(endpoint,cec,metadata); @@ -82,7 +82,7 @@ public class ServerContainer extends ClientContainer implements javax.websocket. public void addEndpoint(ServerEndpointMetadata metadata) throws DeploymentException { - JsrCreator creator = new JsrCreator(metadata,webSocketServerFactory.getExtensionFactory(),objectFactory); + JsrCreator creator = new JsrCreator(this,metadata,webSocketServerFactory.getExtensionFactory()); mappedCreator.addMapping(new WebSocketPathSpec(metadata.getPath()),creator); } @@ -105,7 +105,7 @@ public class ServerContainer extends ClientContainer implements javax.websocket. if (anno != null) { // Annotated takes precedence here - AnnotatedServerEndpointMetadata ametadata = new AnnotatedServerEndpointMetadata(endpoint,config,objectFactory); + AnnotatedServerEndpointMetadata ametadata = new AnnotatedServerEndpointMetadata(this,endpoint,config); AnnotatedEndpointScanner scanner = new AnnotatedEndpointScanner<>(ametadata); metadata = ametadata; scanner.scan(); 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 311ea7c6e08..b389ab0f277 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 @@ -177,8 +177,6 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit instantiator = new DecoratedObjectFactory(); } - DecoratedObjectFactory.setCurrentInstantiator(instantiator); - if (LOG.isDebugEnabled()) { LOG.debug("Found {} classes",c.size()); diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/resources/META-INF/services/javax.websocket.server.ServerEndpointConfig$Configurator b/jetty-websocket/javax-websocket-server-impl/src/main/resources/META-INF/services/javax.websocket.server.ServerEndpointConfig$Configurator index 57e3ef37cba..7f67aa0a84f 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/resources/META-INF/services/javax.websocket.server.ServerEndpointConfig$Configurator +++ b/jetty-websocket/javax-websocket-server-impl/src/main/resources/META-INF/services/javax.websocket.server.ServerEndpointConfig$Configurator @@ -1 +1 @@ -org.eclipse.jetty.websocket.jsr356.server.BasicServerEndpointConfigurator \ No newline at end of file +org.eclipse.jetty.websocket.jsr356.server.ContainerDefaultConfigurator \ No newline at end of file diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/JettyServerEndpointConfiguratorTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/JettyServerEndpointConfiguratorTest.java index 2f1dba9f011..189052437b5 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/JettyServerEndpointConfiguratorTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/JettyServerEndpointConfiguratorTest.java @@ -48,6 +48,6 @@ public class JettyServerEndpointConfiguratorTest ServerEndpointConfig.Configurator configr = iter.next(); assertThat("Configurator",configr,notNullValue()); - assertThat("COnfigurator type",configr,instanceOf(BasicServerEndpointConfigurator.class)); + assertThat("Configurator type",configr,instanceOf(ContainerDefaultConfigurator.class)); } } diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/OnPartialTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/OnPartialTest.java index ef759c506e2..3846cc20689 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/OnPartialTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/OnPartialTest.java @@ -18,6 +18,8 @@ package org.eclipse.jetty.websocket.jsr356.server; +import static org.hamcrest.Matchers.*; + import java.net.URI; import java.util.ArrayList; import java.util.List; @@ -25,7 +27,6 @@ import java.util.List; import javax.websocket.server.ServerEndpoint; import javax.websocket.server.ServerEndpointConfig; -import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.events.EventDriver; @@ -33,6 +34,8 @@ import org.eclipse.jetty.websocket.common.events.EventDriverFactory; import org.eclipse.jetty.websocket.common.events.EventDriverImpl; import org.eclipse.jetty.websocket.common.frames.ContinuationFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; +import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.websocket.jsr356.ClientContainer; import org.eclipse.jetty.websocket.jsr356.JsrSession; import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner; @@ -43,9 +46,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; - public class OnPartialTest { @Rule @@ -68,10 +68,10 @@ public class OnPartialTest ServerEndpoint anno = endpoint.getAnnotation(ServerEndpoint.class); Assert.assertThat("Endpoint: " + endpoint + " should be annotated with @ServerEndpoint",anno,notNullValue()); - DecoratedObjectFactory instantiator = new DecoratedObjectFactory(); + WebSocketContainerScope containerScope = new SimpleContainerScope(policy); - ServerEndpointConfig config = new BasicServerEndpointConfig(endpoint,"/",instantiator); - AnnotatedServerEndpointMetadata metadata = new AnnotatedServerEndpointMetadata(endpoint,config,instantiator); + ServerEndpointConfig config = new BasicServerEndpointConfig(containerScope,endpoint,"/"); + AnnotatedServerEndpointMetadata metadata = new AnnotatedServerEndpointMetadata(containerScope,endpoint,config); AnnotatedEndpointScanner scanner = new AnnotatedEndpointScanner<>(metadata); scanner.scan(); EndpointInstance ei = new EndpointInstance(websocket,config,metadata); @@ -84,7 +84,7 @@ public class OnPartialTest DummyConnection connection = new DummyConnection(); ClientContainer container = new ClientContainer(); @SuppressWarnings("resource") - JsrSession session = new JsrSession(requestURI,driver,connection,container,id, new DecoratedObjectFactory()); + JsrSession session = new JsrSession(container,id,requestURI,driver,connection); session.setPolicy(policy); session.open(); return driver; diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_GoodSignaturesTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_GoodSignaturesTest.java index be957b51bf5..1bec47ece46 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_GoodSignaturesTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_GoodSignaturesTest.java @@ -18,7 +18,7 @@ package org.eclipse.jetty.websocket.jsr356.server; -import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.*; import java.io.Reader; import java.lang.reflect.Field; @@ -34,7 +34,9 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import javax.websocket.server.ServerEndpointConfig; -import org.eclipse.jetty.util.DecoratedObjectFactory; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner; import org.eclipse.jetty.websocket.jsr356.annotations.JsrCallable; import org.eclipse.jetty.websocket.jsr356.server.samples.BasicBinaryMessageByteBufferSocket; @@ -183,7 +185,8 @@ public class ServerAnnotatedEndpointScanner_GoodSignaturesTest @Test public void testScan_Basic() throws Exception { - AnnotatedServerEndpointMetadata metadata = new AnnotatedServerEndpointMetadata(testcase.pojo,null,new DecoratedObjectFactory()); + WebSocketContainerScope container = new SimpleContainerScope(WebSocketPolicy.newClientPolicy()); + AnnotatedServerEndpointMetadata metadata = new AnnotatedServerEndpointMetadata(container,testcase.pojo,null); AnnotatedEndpointScanner scanner = new AnnotatedEndpointScanner<>(metadata); scanner.scan(); diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_InvalidSignaturesTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_InvalidSignaturesTest.java index 08d029931f7..6ed6b1716bb 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_InvalidSignaturesTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_InvalidSignaturesTest.java @@ -18,6 +18,8 @@ package org.eclipse.jetty.websocket.jsr356.server; +import static org.hamcrest.Matchers.*; + import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collection; @@ -30,10 +32,12 @@ import javax.websocket.OnOpen; import javax.websocket.server.ServerEndpoint; import javax.websocket.server.ServerEndpointConfig; -import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.common.events.annotated.InvalidSignatureException; +import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner; import org.eclipse.jetty.websocket.jsr356.server.samples.InvalidCloseIntSocket; import org.eclipse.jetty.websocket.jsr356.server.samples.InvalidErrorErrorSocket; @@ -48,8 +52,6 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; -import static org.hamcrest.Matchers.containsString; - /** * Test {@link AnnotatedEndpointScanner} against various simple, 1 method {@link ServerEndpoint} annotated classes with invalid signatures. */ @@ -95,7 +97,8 @@ public class ServerAnnotatedEndpointScanner_InvalidSignaturesTest @Test public void testScan_InvalidSignature() throws DeploymentException { - AnnotatedServerEndpointMetadata metadata = new AnnotatedServerEndpointMetadata(pojo,null,new DecoratedObjectFactory()); + WebSocketContainerScope container = new SimpleContainerScope(WebSocketPolicy.newClientPolicy()); + AnnotatedServerEndpointMetadata metadata = new AnnotatedServerEndpointMetadata(container,pojo,null); AnnotatedEndpointScanner scanner = new AnnotatedEndpointScanner<>(metadata); try diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Extension.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Extension.java index ebcb7dab1d8..c19a3e0df65 100644 --- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Extension.java +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Extension.java @@ -81,9 +81,4 @@ public interface Extension extends IncomingFrames, OutgoingFrames * the next outgoing extension */ public void setNextOutgoingFrames(OutgoingFrames nextOutgoing); - - // TODO: Extension should indicate if it requires boundary of fragments to be preserved - - // TODO: Extension should indicate if it uses the Extension data field of frame for its own reasons. - } 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 74a759fb38d..e9f192689f2 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 @@ -22,6 +22,7 @@ import java.io.IOException; import java.net.CookieStore; import java.net.SocketAddress; import java.net.URI; +import java.util.Collections; import java.util.HashSet; import java.util.Locale; import java.util.Set; @@ -31,6 +32,7 @@ import java.util.concurrent.Future; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.io.SelectorManager; +import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.HttpCookieStore; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.component.ContainerLifeCycle; @@ -57,15 +59,16 @@ import org.eclipse.jetty.websocket.common.WebSocketSessionFactory; import org.eclipse.jetty.websocket.common.events.EventDriver; import org.eclipse.jetty.websocket.common.events.EventDriverFactory; import org.eclipse.jetty.websocket.common.extensions.WebSocketExtensionFactory; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; /** * WebSocketClient provides a means of establishing connections to remote websocket endpoints. */ -public class WebSocketClient extends ContainerLifeCycle implements SessionListener +public class WebSocketClient extends ContainerLifeCycle implements SessionListener, WebSocketContainerScope { private static final Logger LOG = Log.getLogger(WebSocketClient.class); - private final WebSocketPolicy policy; + private final WebSocketPolicy policy = WebSocketPolicy.newClientPolicy(); private final SslContextFactory sslContextFactory; private final WebSocketExtensionFactory extensionRegistry; private boolean daemon = false; @@ -73,6 +76,7 @@ public class WebSocketClient extends ContainerLifeCycle implements SessionListen private SessionFactory sessionFactory; private ByteBufferPool bufferPool; private Executor executor; + private DecoratedObjectFactory objectFactory; private Scheduler scheduler; private CookieStore cookieStore; private ConnectionManager connectionManager; @@ -83,9 +87,9 @@ public class WebSocketClient extends ContainerLifeCycle implements SessionListen public WebSocketClient() { - this(null,null); + this((SslContextFactory)null,null); } - + public WebSocketClient(Executor executor) { this(null,executor); @@ -106,13 +110,28 @@ public class WebSocketClient extends ContainerLifeCycle implements SessionListen this(sslContextFactory,executor,new MappedByteBufferPool()); } + public WebSocketClient(WebSocketContainerScope scope) + { + this(scope.getSslContextFactory(), scope.getExecutor(), scope.getBufferPool(), scope.getObjectFactory()); + } + + public WebSocketClient(WebSocketContainerScope scope, SslContextFactory sslContextFactory) + { + this(sslContextFactory, scope.getExecutor(), scope.getBufferPool(), scope.getObjectFactory()); + } + public WebSocketClient(SslContextFactory sslContextFactory, Executor executor, ByteBufferPool bufferPool) + { + this(sslContextFactory, executor, bufferPool, new DecoratedObjectFactory()); + } + + public WebSocketClient(SslContextFactory sslContextFactory, Executor executor, ByteBufferPool bufferPool, DecoratedObjectFactory objectFactory) { this.executor = executor; this.sslContextFactory = sslContextFactory; - this.policy = WebSocketPolicy.newClientPolicy(); this.bufferPool = bufferPool; - this.extensionRegistry = new WebSocketExtensionFactory(policy,bufferPool); + this.objectFactory = objectFactory; + this.extensionRegistry = new WebSocketExtensionFactory(this); // Bug #431459 - unregistering compression extensions till they are more stable this.extensionRegistry.unregister("deflate-frame"); @@ -121,7 +140,6 @@ public class WebSocketClient extends ContainerLifeCycle implements SessionListen this.masker = new RandomMasker(); this.eventDriverFactory = new EventDriverFactory(policy); - this.sessionFactory = new WebSocketSessionFactory(this); addBean(this.executor); addBean(this.sslContextFactory); @@ -251,6 +269,16 @@ public class WebSocketClient extends ContainerLifeCycle implements SessionListen cookieStore = new HttpCookieStore.Empty(); } + if(this.sessionFactory == null) + { + this.sessionFactory = new WebSocketSessionFactory(this); + } + + if(this.objectFactory == null) + { + this.objectFactory = new DecoratedObjectFactory(); + } + super.doStart(); if (LOG.isDebugEnabled()) @@ -390,9 +418,15 @@ public class WebSocketClient extends ContainerLifeCycle implements SessionListen return this.policy.getMaxTextMessageSize(); } + @Override + public DecoratedObjectFactory getObjectFactory() + { + return this.objectFactory; + } + public Set getOpenSessions() { - return new HashSet<>(getBeans(WebSocketSession.class)); + return Collections.unmodifiableSet(new HashSet<>(getBeans(WebSocketSession.class))); } public WebSocketPolicy getPolicy() diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SessionTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SessionTest.java index 011dc0b1aee..170c28bb1dd 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SessionTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SessionTest.java @@ -87,13 +87,15 @@ public class SessionTest RemoteEndpoint remote = cliSock.getSession().getRemote(); remote.sendStringByFuture("Hello World!"); if (remote.getBatchMode() == BatchMode.ON) + { remote.flush(); + } srvSock.echoMessage(1,500,TimeUnit.MILLISECONDS); // wait for response from server cliSock.waitForMessage(500,TimeUnit.MILLISECONDS); Set open = client.getOpenSessions(); - Assert.assertThat("Open Sessions.size", open.size(), is(1)); + Assert.assertThat("(Before Close) Open Sessions.size", open.size(), is(1)); cliSock.assertMessage("Hello World!"); cliSock.close(); @@ -101,7 +103,7 @@ public class SessionTest cliSock.waitForClose(500,TimeUnit.MILLISECONDS); open = client.getOpenSessions(); - Assert.assertThat("Open Sessions.size", open.size(), is(0)); + Assert.assertThat("(After Close) Open Sessions.size", open.size(), is(0)); } finally { diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionFactory.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionFactory.java index b4d73fb147c..acedb57fb42 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionFactory.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionFactory.java @@ -20,7 +20,6 @@ package org.eclipse.jetty.websocket.common; import java.net.URI; -import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.websocket.common.events.EventDriver; /** @@ -31,6 +30,4 @@ public interface SessionFactory public boolean supports(EventDriver websocket); public WebSocketSession createSession(URI requestURI, EventDriver websocket, LogicalConnection connection); - - public void setEnhancedInstantiator(DecoratedObjectFactory objectFactory); } diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java index 56883d3b33f..93b2899572b 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java @@ -24,6 +24,7 @@ import java.net.URI; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.Executor; import org.eclipse.jetty.io.ByteBufferPool; @@ -51,11 +52,14 @@ import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames; import org.eclipse.jetty.websocket.common.events.EventDriver; import org.eclipse.jetty.websocket.common.io.IOState; import org.eclipse.jetty.websocket.common.io.IOState.ConnectionStateListener; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; +import org.eclipse.jetty.websocket.common.scopes.WebSocketSessionScope; @ManagedObject("A Jetty WebSocket Session") -public class WebSocketSession extends ContainerLifeCycle implements Session, IncomingFrames, ConnectionStateListener +public class WebSocketSession extends ContainerLifeCycle implements Session, WebSocketSessionScope, IncomingFrames, ConnectionStateListener { private static final Logger LOG = Log.getLogger(WebSocketSession.class); + private final WebSocketContainerScope containerScope; private final URI requestURI; private final EventDriver websocket; private final LogicalConnection connection; @@ -72,14 +76,13 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Inc private UpgradeRequest upgradeRequest; private UpgradeResponse upgradeResponse; - public WebSocketSession(URI requestURI, EventDriver websocket, LogicalConnection connection, SessionListener... sessionListeners) + public WebSocketSession(WebSocketContainerScope containerScope, URI requestURI, EventDriver websocket, LogicalConnection connection, SessionListener... sessionListeners) { - if (requestURI == null) - { - throw new RuntimeException("Request URI cannot be null"); - } + Objects.requireNonNull(containerScope,"Container Scope cannot be null"); + Objects.requireNonNull(requestURI,"Request URI cannot be null"); this.classLoader = Thread.currentThread().getContextClassLoader(); + this.containerScope = containerScope; this.requestURI = requestURI; this.websocket = websocket; this.connection = connection; @@ -195,6 +198,12 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Inc return connection; } + @Override + public WebSocketContainerScope getContainerScope() + { + return this.containerScope; + } + public ExtensionFactory getExtensionFactory() { return extensionFactory; @@ -274,6 +283,13 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Inc { return this.upgradeResponse; } + + + @Override + public WebSocketSession getWebSocketSession() + { + return this; + } @Override public int hashCode() diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSessionFactory.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSessionFactory.java index 22443a24264..1f9b0268006 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSessionFactory.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSessionFactory.java @@ -20,22 +20,38 @@ package org.eclipse.jetty.websocket.common; import java.net.URI; -import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.websocket.common.events.EventDriver; import org.eclipse.jetty.websocket.common.events.JettyAnnotatedEventDriver; import org.eclipse.jetty.websocket.common.events.JettyListenerEventDriver; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; /** * Default Session factory, creating WebSocketSession objects. */ public class WebSocketSessionFactory implements SessionFactory { + private final WebSocketContainerScope containerScope; private final SessionListener[] listeners; - public WebSocketSessionFactory(SessionListener... sessionListeners) + public WebSocketSessionFactory(WebSocketContainerScope containerScope, SessionListener... sessionListeners) { - listeners = sessionListeners; - } + this.containerScope = containerScope; + if ((sessionListeners != null) && (sessionListeners.length > 0)) + { + this.listeners = sessionListeners; + } + else + { + if (this.containerScope instanceof SessionListener) + { + this.listeners = new SessionListener[] { (SessionListener)containerScope }; + } + else + { + this.listeners = new SessionListener[0]; + } + } + } @Override public boolean supports(EventDriver websocket) @@ -46,12 +62,6 @@ public class WebSocketSessionFactory implements SessionFactory @Override public WebSocketSession createSession(URI requestURI, EventDriver websocket, LogicalConnection connection) { - return new WebSocketSession(requestURI,websocket,connection,listeners); - } - - @Override - public void setEnhancedInstantiator(DecoratedObjectFactory objectFactory) - { - /* does nothing here */ + return new WebSocketSession(containerScope, requestURI,websocket,connection,listeners); } } diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/AbstractExtension.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/AbstractExtension.java index c35fe8f8187..93519e6c6f1 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/AbstractExtension.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/AbstractExtension.java @@ -35,6 +35,7 @@ import org.eclipse.jetty.websocket.api.extensions.Frame; import org.eclipse.jetty.websocket.api.extensions.IncomingFrames; import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames; import org.eclipse.jetty.websocket.common.LogicalConnection; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; @ManagedObject("Abstract Extension") public abstract class AbstractExtension extends ContainerLifeCycle implements Extension @@ -67,6 +68,12 @@ public abstract class AbstractExtension extends ContainerLifeCycle implements Ex out.append(heading).append(" : "); out.append(bean.toString()); } + + public void init(WebSocketContainerScope container) + { + this.policy = container.getPolicy(); + this.bufferPool = container.getBufferPool(); + } public ByteBufferPool getBufferPool() { @@ -183,7 +190,7 @@ public abstract class AbstractExtension extends ContainerLifeCycle implements Ex { this.connection = connection; } - + @Override public void setNextIncomingFrames(IncomingFrames nextIncoming) { diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/WebSocketExtensionFactory.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/WebSocketExtensionFactory.java index c8db08e0406..0b2d8a8fe3e 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/WebSocketExtensionFactory.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/WebSocketExtensionFactory.java @@ -18,26 +18,21 @@ package org.eclipse.jetty.websocket.common.extensions; -import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.websocket.api.WebSocketException; -import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.api.extensions.Extension; import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; public class WebSocketExtensionFactory extends ExtensionFactory { - private WebSocketPolicy policy; - private ByteBufferPool bufferPool; - private DecoratedObjectFactory objectFactory; + private WebSocketContainerScope container; - public WebSocketExtensionFactory(WebSocketPolicy policy, ByteBufferPool bufferPool) + public WebSocketExtensionFactory(WebSocketContainerScope container) { super(); - this.policy = policy; - this.bufferPool = bufferPool; + this.container = container; } @Override @@ -62,12 +57,11 @@ public class WebSocketExtensionFactory extends ExtensionFactory try { - Extension ext = objectFactory.createInstance(extClass); + Extension ext = container.getObjectFactory().createInstance(extClass); if (ext instanceof AbstractExtension) { AbstractExtension aext = (AbstractExtension)ext; - aext.setPolicy(policy); - aext.setBufferPool(bufferPool); + aext.init(container); aext.setConfig(config); } return ext; @@ -77,9 +71,4 @@ public class WebSocketExtensionFactory extends ExtensionFactory throw new WebSocketException("Cannot instantiate extension: " + extClass,e); } } - - public void setEnhancedInstantiator(DecoratedObjectFactory objectFactory) - { - this.objectFactory = objectFactory; - } } diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java new file mode 100644 index 00000000000..b255c6ac686 --- /dev/null +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java @@ -0,0 +1,95 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.common.scopes; + +import java.util.concurrent.Executor; + +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.MappedByteBufferPool; +import org.eclipse.jetty.util.DecoratedObjectFactory; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; + +public class SimpleContainerScope implements WebSocketContainerScope +{ + private final ByteBufferPool bufferPool; + private final DecoratedObjectFactory objectFactory; + private final WebSocketPolicy policy; + private Executor executor; + private SslContextFactory sslContextFactory; + + public SimpleContainerScope(WebSocketPolicy policy) + { + this(policy,new MappedByteBufferPool(),new DecoratedObjectFactory()); + } + + public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool) + { + this(policy,bufferPool,new DecoratedObjectFactory()); + } + + public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool, DecoratedObjectFactory objectFactory) + { + this.policy = policy; + this.bufferPool = bufferPool; + this.objectFactory = objectFactory; + + QueuedThreadPool threadPool = new QueuedThreadPool(); + String name = "WebSocketSimpleContainer@" + hashCode(); + threadPool.setName(name); + threadPool.setDaemon(true); + this.executor = threadPool; + } + + @Override + public ByteBufferPool getBufferPool() + { + return this.bufferPool; + } + + @Override + public Executor getExecutor() + { + return this.executor; + } + + @Override + public DecoratedObjectFactory getObjectFactory() + { + return this.objectFactory; + } + + @Override + public WebSocketPolicy getPolicy() + { + return this.policy; + } + + @Override + public SslContextFactory getSslContextFactory() + { + return this.sslContextFactory; + } + + public void setSslContextFactory(SslContextFactory sslContextFactory) + { + this.sslContextFactory = sslContextFactory; + } +} diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketContainerScope.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketContainerScope.java new file mode 100644 index 00000000000..546a4ea9eb3 --- /dev/null +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketContainerScope.java @@ -0,0 +1,67 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.common.scopes; + +import java.util.concurrent.Executor; + +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.util.DecoratedObjectFactory; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; + +/** + * Defined Scope for a WebSocketContainer. + */ +public interface WebSocketContainerScope +{ + /** + * The configured Container Buffer Pool. + * + * @return the buffer pool (never null) + */ + public ByteBufferPool getBufferPool(); + + /** + * Executor in use by the container. + * + * @return the Executor in use by the container. + */ + public Executor getExecutor(); + + /** + * Object Factory used to create objects. + * + * @return Object Factory used to create instances of objects. + */ + public DecoratedObjectFactory getObjectFactory(); + + /** + * The policy the container is running on. + * + * @return the websocket policy + */ + public WebSocketPolicy getPolicy(); + + /** + * The SslContextFactory in use by the container. + * + * @return the SslContextFactory in use by the container (can be null if no SSL context is defined) + */ + public SslContextFactory getSslContextFactory(); +} diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketHandshakeScope.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketHandshakeScope.java new file mode 100644 index 00000000000..86bafce6598 --- /dev/null +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketHandshakeScope.java @@ -0,0 +1,36 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.common.scopes; + +import org.eclipse.jetty.websocket.api.UpgradeRequest; +import org.eclipse.jetty.websocket.api.UpgradeResponse; + +/** + * Defined Scope for a WebSocket Handshake/Upgrade + */ +public interface WebSocketHandshakeScope +{ + Class getPotentialEndpointClass(); + + UpgradeRequest getHandshakeRequest(); + + UpgradeResponse getHandshakeResponse(); + + WebSocketContainerScope getContainerScope(); +} diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketSessionScope.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketSessionScope.java new file mode 100644 index 00000000000..860ebdef53a --- /dev/null +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketSessionScope.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.common.scopes; + +import org.eclipse.jetty.websocket.common.WebSocketSession; + +/** + * Defined Scope for a WebSocketSession (active connection) + */ +public interface WebSocketSessionScope +{ + WebSocketSession getWebSocketSession(); + + WebSocketContainerScope getContainerScope(); +} diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventDriverTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventDriverTest.java index e0276144697..deb18096893 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventDriverTest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventDriverTest.java @@ -31,6 +31,8 @@ import org.eclipse.jetty.websocket.common.frames.PingFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.io.LocalWebSocketSession; import org.eclipse.jetty.websocket.common.test.LeakTrackingBufferPoolRule; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; @@ -49,6 +51,14 @@ public class EventDriverTest @Rule public LeakTrackingBufferPoolRule bufferPool = new LeakTrackingBufferPoolRule("Test"); + + private WebSocketContainerScope container; + + @Before + public void initContainer() + { + this.container = new SimpleContainerScope(WebSocketPolicy.newClientPolicy()); + } private Frame makeBinaryFrame(String content, boolean fin) { @@ -61,7 +71,7 @@ public class EventDriverTest AdapterConnectCloseSocket socket = new AdapterConnectCloseSocket(); EventDriver driver = wrap(socket); - try (LocalWebSocketSession conn = new LocalWebSocketSession(testname,driver,bufferPool)) + try (LocalWebSocketSession conn = new LocalWebSocketSession(container,testname,driver)) { conn.open(); driver.incomingFrame(new CloseInfo(StatusCode.NORMAL).asFrame()); @@ -78,7 +88,7 @@ public class EventDriverTest AnnotatedBinaryArraySocket socket = new AnnotatedBinaryArraySocket(); EventDriver driver = wrap(socket); - try (LocalWebSocketSession conn = new LocalWebSocketSession(testname,driver,bufferPool)) + try (LocalWebSocketSession conn = new LocalWebSocketSession(container,testname,driver)) { conn.open(); driver.incomingFrame(makeBinaryFrame("Hello World",true)); @@ -97,7 +107,7 @@ public class EventDriverTest AnnotatedTextSocket socket = new AnnotatedTextSocket(); EventDriver driver = wrap(socket); - try (LocalWebSocketSession conn = new LocalWebSocketSession(testname,driver,bufferPool)) + try (LocalWebSocketSession conn = new LocalWebSocketSession(container,testname,driver)) { conn.open(); driver.incomingError(new WebSocketException("oof")); @@ -116,7 +126,7 @@ public class EventDriverTest AnnotatedFramesSocket socket = new AnnotatedFramesSocket(); EventDriver driver = wrap(socket); - try (LocalWebSocketSession conn = new LocalWebSocketSession(testname,driver,bufferPool)) + try (LocalWebSocketSession conn = new LocalWebSocketSession(container,testname,driver)) { conn.open(); driver.incomingFrame(new PingFrame().setPayload("PING")); @@ -140,7 +150,7 @@ public class EventDriverTest AnnotatedBinaryStreamSocket socket = new AnnotatedBinaryStreamSocket(); EventDriver driver = wrap(socket); - try (LocalWebSocketSession conn = new LocalWebSocketSession(testname,driver,bufferPool)) + try (LocalWebSocketSession conn = new LocalWebSocketSession(container,testname,driver)) { conn.open(); driver.incomingFrame(makeBinaryFrame("Hello World",true)); @@ -159,7 +169,7 @@ public class EventDriverTest ListenerBasicSocket socket = new ListenerBasicSocket(); EventDriver driver = wrap(socket); - try (LocalWebSocketSession conn = new LocalWebSocketSession(testname,driver,bufferPool)) + try (LocalWebSocketSession conn = new LocalWebSocketSession(container,testname,driver)) { conn.start(); conn.open(); diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStackTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStackTest.java index 67838a09207..05555eb45e0 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStackTest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStackTest.java @@ -23,7 +23,6 @@ import static org.hamcrest.Matchers.*; import java.util.ArrayList; import java.util.List; -import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.WebSocketPolicy; @@ -31,6 +30,7 @@ import org.eclipse.jetty.websocket.api.extensions.Extension; import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; import org.eclipse.jetty.websocket.common.extensions.identity.IdentityExtension; import org.eclipse.jetty.websocket.common.test.LeakTrackingBufferPoolRule; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; @@ -56,8 +56,9 @@ public class ExtensionStackTest private ExtensionStack createExtensionStack() { WebSocketPolicy policy = WebSocketPolicy.newClientPolicy(); - WebSocketExtensionFactory factory = new WebSocketExtensionFactory(policy,bufferPool); - factory.setEnhancedInstantiator(new DecoratedObjectFactory()); + WebSocketContainerScope container = new SimpleContainerScope(policy,bufferPool); + + WebSocketExtensionFactory factory = new WebSocketExtensionFactory(container); return new ExtensionStack(factory); } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/ExtensionTool.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/ExtensionTool.java index 89c4558e656..38c0849ae63 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/ExtensionTool.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/ExtensionTool.java @@ -24,7 +24,6 @@ import java.nio.ByteBuffer; import java.util.Collections; import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.api.extensions.Extension; @@ -34,6 +33,8 @@ import org.eclipse.jetty.websocket.api.extensions.Frame; import org.eclipse.jetty.websocket.common.Parser; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; +import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.websocket.common.test.ByteBufferAssert; import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture; import org.eclipse.jetty.websocket.common.test.UnitParser; @@ -127,8 +128,8 @@ public class ExtensionTool public ExtensionTool(WebSocketPolicy policy, ByteBufferPool bufferPool) { this.policy = policy; - WebSocketExtensionFactory extFactory = new WebSocketExtensionFactory(policy,bufferPool); - extFactory.setEnhancedInstantiator(new DecoratedObjectFactory()); + WebSocketContainerScope container = new SimpleContainerScope(policy, bufferPool); + WebSocketExtensionFactory extFactory = new WebSocketExtensionFactory(container); this.factory = extFactory; } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/LocalWebSocketSession.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/LocalWebSocketSession.java index 843c64e6d5d..18f49f3ee35 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/LocalWebSocketSession.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/LocalWebSocketSession.java @@ -20,9 +20,9 @@ package org.eclipse.jetty.websocket.common.io; import java.net.URI; -import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.events.EventDriver; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.websocket.common.test.OutgoingFramesCapture; import org.junit.rules.TestName; @@ -31,9 +31,10 @@ public class LocalWebSocketSession extends WebSocketSession private String id; private OutgoingFramesCapture outgoingCapture; - public LocalWebSocketSession(TestName testname, EventDriver driver, ByteBufferPool bufferPool) + public LocalWebSocketSession(WebSocketContainerScope containerScope, TestName testname, EventDriver driver) { - super(URI.create("ws://localhost/LocalWebSocketSesssion/" + testname.getMethodName()),driver,new LocalWebSocketConnection(testname,bufferPool)); + super(containerScope,URI.create("ws://localhost/LocalWebSocketSesssion/" + testname.getMethodName()),driver, + new LocalWebSocketConnection(testname,containerScope.getBufferPool())); this.id = testname.getMethodName(); outgoingCapture = new OutgoingFramesCapture(); setOutgoingHandler(outgoingCapture); diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java index 868a20d9f41..a05412230c2 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java @@ -34,6 +34,7 @@ import org.eclipse.jetty.websocket.common.events.EventDriverFactory; import org.eclipse.jetty.websocket.common.io.FramePipes; import org.eclipse.jetty.websocket.common.io.LocalWebSocketSession; import org.eclipse.jetty.websocket.common.test.LeakTrackingBufferPoolRule; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -73,6 +74,9 @@ public class MessageOutputStreamTest // Event Driver factory EventDriverFactory factory = new EventDriverFactory(policy); + + // Container + WebSocketContainerScope containerScope = new SimpleContainerScope(policy,bufferPool); // local socket EventDriver driver = factory.wrap(new TrackingSocket("local")); @@ -81,7 +85,7 @@ public class MessageOutputStreamTest socket = new TrackingSocket("remote"); OutgoingFrames socketPipe = FramePipes.to(factory.wrap(socket)); - session = new LocalWebSocketSession(testname,driver,bufferPool); + session = new LocalWebSocketSession(containerScope,testname,driver); session.setPolicy(policy); // talk to our remote socket diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageWriterTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageWriterTest.java index 7b0dac0a47f..12420cc0bca 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageWriterTest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageWriterTest.java @@ -30,6 +30,7 @@ import org.eclipse.jetty.websocket.common.events.EventDriverFactory; import org.eclipse.jetty.websocket.common.io.FramePipes; import org.eclipse.jetty.websocket.common.io.LocalWebSocketSession; import org.eclipse.jetty.websocket.common.test.LeakTrackingBufferPoolRule; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -72,6 +73,9 @@ public class MessageWriterTest // Event Driver factory EventDriverFactory factory = new EventDriverFactory(policy); + // Container + WebSocketContainerScope containerScope = new SimpleContainerScope(policy,bufferPool); + // local socket EventDriver driver = factory.wrap(new TrackingSocket("local")); @@ -79,7 +83,7 @@ public class MessageWriterTest socket = new TrackingSocket("remote"); OutgoingFrames socketPipe = FramePipes.to(factory.wrap(socket)); - session = new LocalWebSocketSession(testname,driver,bufferPool); + session = new LocalWebSocketSession(containerScope,testname,driver); session.setPolicy(policy); // talk to our remote socket diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java index 504990079f1..b4ebcb0f377 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java @@ -44,7 +44,6 @@ import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; @@ -69,6 +68,7 @@ import org.eclipse.jetty.websocket.common.extensions.WebSocketExtensionFactory; import org.eclipse.jetty.websocket.common.io.IOState; import org.eclipse.jetty.websocket.common.io.IOState.ConnectionStateListener; import org.eclipse.jetty.websocket.common.io.http.HttpResponseHeaderParser; +import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; import org.junit.Assert; /** @@ -228,8 +228,7 @@ public class BlockheadClient implements OutgoingFrames, ConnectionStateListener, this.generator = new Generator(policy,bufferPool); this.parser = new Parser(policy,bufferPool); - this.extensionFactory = new WebSocketExtensionFactory(policy,bufferPool); - this.extensionFactory.setEnhancedInstantiator(new DecoratedObjectFactory()); + this.extensionFactory = new WebSocketExtensionFactory(new SimpleContainerScope(policy,bufferPool)); this.ioState = new IOState(); this.ioState.addListener(this); } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java index 7a2c32da350..4fe8f298b5a 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java @@ -66,6 +66,7 @@ import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.extensions.ExtensionStack; import org.eclipse.jetty.websocket.common.extensions.WebSocketExtensionFactory; import org.eclipse.jetty.websocket.common.frames.CloseFrame; +import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; import org.junit.Assert; /** @@ -109,7 +110,7 @@ public class BlockheadServer this.parser = new Parser(policy,bufferPool); this.parseCount = new AtomicInteger(0); this.generator = new Generator(policy,bufferPool,false); - this.extensionRegistry = new WebSocketExtensionFactory(policy,bufferPool); + this.extensionRegistry = new WebSocketExtensionFactory(new SimpleContainerScope(policy,bufferPool)); } /** diff --git a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java index f0ee9cdca75..018c2079b5f 100644 --- a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java +++ b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java @@ -41,11 +41,13 @@ import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.server.HttpConnection; +import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.websocket.api.InvalidWebSocketException; @@ -63,6 +65,7 @@ import org.eclipse.jetty.websocket.common.events.EventDriver; import org.eclipse.jetty.websocket.common.events.EventDriverFactory; import org.eclipse.jetty.websocket.common.extensions.ExtensionStack; import org.eclipse.jetty.websocket.common.extensions.WebSocketExtensionFactory; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; import org.eclipse.jetty.websocket.servlet.WebSocketCreator; @@ -71,7 +74,7 @@ import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; /** * Factory to create WebSocket connections */ -public class WebSocketServerFactory extends ContainerLifeCycle implements WebSocketCreator, WebSocketServletFactory, SessionListener +public class WebSocketServerFactory extends ContainerLifeCycle implements WebSocketCreator, WebSocketContainerScope, WebSocketServletFactory, SessionListener { private static final Logger LOG = Log.getLogger(WebSocketServerFactory.class); @@ -86,6 +89,7 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc private final EventDriverFactory eventDriverFactory; private final ByteBufferPool bufferPool; private final WebSocketExtensionFactory extensionFactory; + private Executor executor; private List sessionFactories; private Set openSessions = new CopyOnWriteArraySet<>(); private WebSocketCreator creator; @@ -121,7 +125,7 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc this.defaultPolicy = policy; this.eventDriverFactory = new EventDriverFactory(defaultPolicy); this.bufferPool = bufferPool; - this.extensionFactory = new WebSocketExtensionFactory(defaultPolicy, this.bufferPool); + this.extensionFactory = new WebSocketExtensionFactory(this); // Bug #431459 - unregistering compression extensions till they are more stable this.extensionFactory.unregister("deflate-frame"); @@ -165,16 +169,12 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc { Thread.currentThread().setContextClassLoader(contextClassloader); - // Establish the DecoratedObjectFactory thread local - // for various ServiceLoader initiated components to use. - DecoratedObjectFactory.setCurrentInstantiator(getEnhancedInstantiator(request)); - // Create Servlet Specific Upgrade Request/Response objects ServletUpgradeRequest sockreq = new ServletUpgradeRequest(request); ServletUpgradeResponse sockresp = new ServletUpgradeResponse(response); Object websocketPojo = creator.createWebSocket(sockreq, sockresp); - websocketPojo = objectFactory.decorate(websocketPojo); + websocketPojo = getObjectFactory().decorate(websocketPojo); // Handle response forbidden (and similar paths) if (sockresp.isCommitted()) @@ -315,12 +315,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc this.objectFactory = new DecoratedObjectFactory(); } - this.extensionFactory.setEnhancedInstantiator(this.objectFactory); - for(SessionFactory sessionFactory: this.sessionFactories) - { - sessionFactory.setEnhancedInstantiator(this.objectFactory); - } - super.doStart(); } @@ -331,53 +325,26 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc super.doStop(); } + @Override + public ByteBufferPool getBufferPool() + { + return this.bufferPool; + } + @Override public WebSocketCreator getCreator() { return this.creator; } - public DecoratedObjectFactory getEnhancedInstantiator() + @Override + public Executor getExecutor() { - return objectFactory; + return this.executor; } - public DecoratedObjectFactory getEnhancedInstantiator(HttpServletRequest request) + public DecoratedObjectFactory getObjectFactory() { - if (objectFactory != null) - { - return objectFactory; - } - - if (request == null) - { - LOG.debug("Using default DecoratedObjectFactory (HttpServletRequest is null)"); - return new DecoratedObjectFactory(); - } - - return getEnhancedInstantiator(request.getServletContext()); - } - - public DecoratedObjectFactory getEnhancedInstantiator(ServletContext context) - { - if (objectFactory != null) - { - return objectFactory; - } - - if (context == null) - { - LOG.debug("Using default DecoratedObjectFactory (ServletContext is null)"); - return new DecoratedObjectFactory(); - } - - objectFactory = (DecoratedObjectFactory)context.getAttribute(DecoratedObjectFactory.ATTR); - if (objectFactory == null) - { - LOG.debug("Using default DecoratedObjectFactory (ServletContext attribute is null)"); - objectFactory = new DecoratedObjectFactory(); - } - return objectFactory; } @@ -403,6 +370,15 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc return defaultPolicy; } + @Override + public SslContextFactory getSslContextFactory() + { + /* Not relevant for a Server, as this is defined in the + * Connector configuration + */ + return null; + } + public void init(ServletContextHandler context) throws ServletException { this.objectFactory = (DecoratedObjectFactory)context.getAttribute(DecoratedObjectFactory.ATTR); @@ -410,6 +386,8 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc { this.objectFactory = new DecoratedObjectFactory(); } + + this.executor = context.getServer().getThreadPool(); } @Override @@ -420,6 +398,17 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc { this.objectFactory = new DecoratedObjectFactory(); } + + + ContextHandler handler = ContextHandler.getContextHandler(context); + + if (handler == null) + { + throw new ServletException("Not running on Jetty, WebSocket support unavailable"); + } + + this.executor = handler.getServer().getThreadPool(); + try { // start lifecycle diff --git a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilter.java b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilter.java index cf5fa14003d..f41e06260e4 100644 --- a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilter.java +++ b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilter.java @@ -259,7 +259,6 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter { factory.init(config.getServletContext()); WebSocketPolicy policy = factory.getPolicy(); - String max = config.getInitParameter("maxIdleTime"); if (max != null)