JSR-356 - making ClientContainer a use jetty LifeCycle properly

This commit is contained in:
Joakim Erdfelt 2013-07-31 10:34:31 -07:00
parent 8a2ccdf8ae
commit 0fd0ecc887
8 changed files with 53 additions and 128 deletions

View File

@ -36,8 +36,7 @@ import javax.websocket.Extension;
import javax.websocket.Session; import javax.websocket.Session;
import javax.websocket.WebSocketContainer; import javax.websocket.WebSocketContainer;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.api.InvalidWebSocketException; import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory; import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
@ -58,10 +57,8 @@ import org.eclipse.jetty.websocket.jsr356.metadata.EndpointMetadata;
* <p> * <p>
* This should be specific to a JVM if run in a standalone mode. or specific to a WebAppContext if running on the Jetty server. * 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 implements WebSocketContainer public class ClientContainer extends ContainerLifeCycle implements WebSocketContainer
{ {
private static final Logger LOG = Log.getLogger(ClientContainer.class);
/** Tracking all primitive decoders for the container */ /** Tracking all primitive decoders for the container */
private final DecoderFactory decoderFactory; private final DecoderFactory decoderFactory;
/** Tracking all primitive encoders for the container */ /** Tracking all primitive encoders for the container */
@ -161,6 +158,16 @@ public class ClientContainer implements WebSocketContainer
return connect(instance,path); return connect(instance,path);
} }
@Override
protected void doStart() throws Exception
{
client = new WebSocketClient();
client.setEventDriverFactory(new JsrEventDriverFactory(client.getPolicy()));
client.setSessionFactory(new JsrSessionFactory(this));
addBean(client);
super.doStart();
}
public EndpointMetadata getClientEndpointMetadata(Class<?> endpoint) public EndpointMetadata getClientEndpointMetadata(Class<?> endpoint)
{ {
EndpointMetadata metadata = null; EndpointMetadata metadata = null;
@ -320,38 +327,4 @@ public class ClientContainer implements WebSocketContainer
client.getPolicy().setMaxTextMessageSize(max); client.getPolicy().setMaxTextMessageSize(max);
client.setMaxTextMessageBufferSize(max); client.setMaxTextMessageBufferSize(max);
} }
/**
* Start the container
*/
public void start()
{
client = new WebSocketClient();
client.setEventDriverFactory(new JsrEventDriverFactory(client.getPolicy()));
client.setSessionFactory(new JsrSessionFactory(this));
try
{
client.start();
}
catch (Exception e)
{
LOG.warn("Unable to start Jetty WebSocketClient instance",e);
}
}
/**
* Stop the container
*/
public void stop()
{
try
{
client.stop();
}
catch (Exception e)
{
LOG.warn("Unable to start Jetty WebSocketClient instance",e);
}
}
} }

View File

@ -30,7 +30,14 @@ public class JettyClientContainerProvider extends ContainerProvider
protected WebSocketContainer getContainer() protected WebSocketContainer getContainer()
{ {
ClientContainer container = new ClientContainer(); ClientContainer container = new ClientContainer();
try
{
container.start(); container.start();
return container; return container;
} }
catch (Exception e)
{
throw new RuntimeException("Unable to start Client Container",e);
}
}
} }

View File

@ -38,20 +38,24 @@ import org.eclipse.jetty.websocket.jsr356.metadata.EndpointMetadata;
import org.eclipse.jetty.websocket.jsr356.server.pathmap.WebSocketPathSpec; import org.eclipse.jetty.websocket.jsr356.server.pathmap.WebSocketPathSpec;
import org.eclipse.jetty.websocket.server.MappedWebSocketCreator; import org.eclipse.jetty.websocket.server.MappedWebSocketCreator;
import org.eclipse.jetty.websocket.server.WebSocketServerFactory; import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
public class ServerContainer extends ClientContainer implements javax.websocket.server.ServerContainer, WebSocketServerFactory.Listener public class ServerContainer extends ClientContainer implements javax.websocket.server.ServerContainer
{ {
private static final Logger LOG = Log.getLogger(ServerContainer.class); private static final Logger LOG = Log.getLogger(ServerContainer.class);
private final MappedWebSocketCreator mappedCreator; private final MappedWebSocketCreator mappedCreator;
private WebSocketServerFactory webSocketServletFactory; private final WebSocketServerFactory webSocketServerFactory;
private Map<Class<?>, ServerEndpointMetadata> endpointServerMetadataCache = new ConcurrentHashMap<>(); private Map<Class<?>, ServerEndpointMetadata> endpointServerMetadataCache = new ConcurrentHashMap<>();
public ServerContainer(MappedWebSocketCreator creator) public ServerContainer(MappedWebSocketCreator creator, WebSocketServerFactory factory)
{ {
super(); super();
this.mappedCreator = creator; this.mappedCreator = creator;
this.webSocketServerFactory = factory;
EventDriverFactory eventDriverFactory = this.webSocketServerFactory.getEventDriverFactory();
eventDriverFactory.addImplementation(new JsrServerEndpointImpl());
eventDriverFactory.addImplementation(new JsrEndpointImpl());
this.webSocketServerFactory.addSessionFactory(new JsrSessionFactory(this));
} }
public EndpointInstance newClientEndpointInstance(Object endpoint, ServerEndpointConfig config, String path) public EndpointInstance newClientEndpointInstance(Object endpoint, ServerEndpointConfig config, String path)
@ -134,25 +138,4 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
return metadata; return metadata;
} }
} }
public WebSocketServletFactory getWebSocketServletFactory()
{
return webSocketServletFactory;
}
@Override
public void onWebSocketServerFactoryStarted(WebSocketServerFactory factory)
{
this.webSocketServletFactory = factory;
EventDriverFactory eventDriverFactory = this.webSocketServletFactory.getEventDriverFactory();
eventDriverFactory.addImplementation(new JsrServerEndpointImpl());
eventDriverFactory.addImplementation(new JsrEndpointImpl());
this.webSocketServletFactory.addSessionFactory(new JsrSessionFactory(this));
}
@Override
public void onWebSocketServerFactoryStopped(WebSocketServerFactory factory)
{
/* do nothing */
}
} }

View File

@ -54,17 +54,16 @@ public class WebSocketConfiguration extends AbstractConfiguration
// Store reference to the WebSocketUpgradeFilter // Store reference to the WebSocketUpgradeFilter
context.setAttribute(WebSocketUpgradeFilter.class.getName(),filter); context.setAttribute(WebSocketUpgradeFilter.class.getName(),filter);
// Store reference to DiscoveredEndpoints
context.setAttribute(DiscoveredEndpoints.class.getName(),new DiscoveredEndpoints());
// Create the Jetty ServerContainer implementation // Create the Jetty ServerContainer implementation
ServerContainer jettyContainer = new ServerContainer(filter); ServerContainer jettyContainer = new ServerContainer(filter,filter.getFactory());
filter.setWebSocketServerFactoryListener(jettyContainer); context.addBean(jettyContainer);
context.addBean(jettyContainer,true);
// Store a reference to the ServerContainer per javax.websocket spec 1.0 final section 6.4 Programmatic Server Deployment // Store a reference to the ServerContainer per javax.websocket spec 1.0 final section 6.4 Programmatic Server Deployment
context.setAttribute(javax.websocket.server.ServerContainer.class.getName(),jettyContainer); context.setAttribute(javax.websocket.server.ServerContainer.class.getName(),jettyContainer);
// Store reference to DiscoveredEndpoints
context.setAttribute(DiscoveredEndpoints.class.getName(),new DiscoveredEndpoints());
return jettyContainer; return jettyContainer;
} }

View File

@ -68,6 +68,7 @@ import org.eclipse.jetty.websocket.jsr356.server.samples.primitives.ShortObjectT
import org.eclipse.jetty.websocket.jsr356.server.samples.primitives.ShortTextSocket; import org.eclipse.jetty.websocket.jsr356.server.samples.primitives.ShortTextSocket;
import org.eclipse.jetty.websocket.jsr356.server.samples.streaming.ReaderParamSocket; import org.eclipse.jetty.websocket.jsr356.server.samples.streaming.ReaderParamSocket;
import org.eclipse.jetty.websocket.jsr356.server.samples.streaming.StringReturnReaderParamSocket; import org.eclipse.jetty.websocket.jsr356.server.samples.streaming.StringReturnReaderParamSocket;
import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -103,7 +104,7 @@ public class ServerAnnotatedEndpointScanner_GoodSignaturesTest
} }
} }
private static ServerContainer container = new ServerContainer(new DummyCreator()); private static ServerContainer container = new ServerContainer(new DummyCreator(), new WebSocketServerFactory());
@Parameters @Parameters
public static Collection<Case[]> data() throws Exception public static Collection<Case[]> data() throws Exception

View File

@ -43,6 +43,7 @@ import org.eclipse.jetty.websocket.jsr356.server.samples.InvalidErrorIntSocket;
import org.eclipse.jetty.websocket.jsr356.server.samples.InvalidOpenCloseReasonSocket; import org.eclipse.jetty.websocket.jsr356.server.samples.InvalidOpenCloseReasonSocket;
import org.eclipse.jetty.websocket.jsr356.server.samples.InvalidOpenIntSocket; import org.eclipse.jetty.websocket.jsr356.server.samples.InvalidOpenIntSocket;
import org.eclipse.jetty.websocket.jsr356.server.samples.InvalidOpenSessionIntSocket; import org.eclipse.jetty.websocket.jsr356.server.samples.InvalidOpenSessionIntSocket;
import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -57,7 +58,7 @@ public class ServerAnnotatedEndpointScanner_InvalidSignaturesTest
{ {
private static final Logger LOG = Log.getLogger(ServerAnnotatedEndpointScanner_InvalidSignaturesTest.class); private static final Logger LOG = Log.getLogger(ServerAnnotatedEndpointScanner_InvalidSignaturesTest.class);
private static ServerContainer container = new ServerContainer(new DummyCreator()); private static ServerContainer container = new ServerContainer(new DummyCreator(), new WebSocketServerFactory());
@Parameters @Parameters
public static Collection<Class<?>[]> data() public static Collection<Class<?>[]> data()

View File

@ -22,7 +22,6 @@ import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -66,13 +65,6 @@ import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
*/ */
public class WebSocketServerFactory extends ContainerLifeCycle implements WebSocketCreator, WebSocketServletFactory public class WebSocketServerFactory extends ContainerLifeCycle implements WebSocketCreator, WebSocketServletFactory
{ {
public static interface Listener
{
void onWebSocketServerFactoryStarted(WebSocketServerFactory factory);
void onWebSocketServerFactoryStopped(WebSocketServerFactory factory);
}
private static final Logger LOG = Log.getLogger(WebSocketServerFactory.class); private static final Logger LOG = Log.getLogger(WebSocketServerFactory.class);
private static final ThreadLocal<UpgradeContext> ACTIVE_CONTEXT = new ThreadLocal<>(); private static final ThreadLocal<UpgradeContext> ACTIVE_CONTEXT = new ThreadLocal<>();
@ -100,7 +92,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
private final WebSocketPolicy basePolicy; private final WebSocketPolicy basePolicy;
private final EventDriverFactory eventDriverFactory; private final EventDriverFactory eventDriverFactory;
private final WebSocketExtensionFactory extensionFactory; private final WebSocketExtensionFactory extensionFactory;
private List<WebSocketServerFactory.Listener> listeners = new ArrayList<>();
private List<SessionFactory> sessionFactories; private List<SessionFactory> sessionFactories;
private WebSocketCreator creator; private WebSocketCreator creator;
private List<Class<?>> registeredSocketClasses; private List<Class<?>> registeredSocketClasses;
@ -197,11 +188,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
} }
} }
public void addListener(WebSocketServerFactory.Listener listener)
{
listeners.add(listener);
}
public void addSessionFactory(SessionFactory sessionFactory) public void addSessionFactory(SessionFactory sessionFactory)
{ {
if (sessionFactories.contains(sessionFactory)) if (sessionFactories.contains(sessionFactory))
@ -291,24 +277,10 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
} }
} }
@Override
protected void doStart() throws Exception
{
for (WebSocketServerFactory.Listener listener : listeners)
{
listener.onWebSocketServerFactoryStarted(this);
}
super.doStart();
}
@Override @Override
protected void doStop() throws Exception protected void doStop() throws Exception
{ {
closeAllConnections(); closeAllConnections();
for (WebSocketServerFactory.Listener listener : listeners)
{
listener.onWebSocketServerFactoryStopped(this);
}
super.doStop(); super.doStop();
} }
@ -329,11 +301,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
return extensionFactory; return extensionFactory;
} }
public Collection<WebSocketServerFactory.Listener> getListeners()
{
return listeners;
}
@Override @Override
public WebSocketPolicy getPolicy() public WebSocketPolicy getPolicy()
{ {
@ -343,7 +310,7 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
@Override @Override
public void init() throws Exception public void init() throws Exception
{ {
start(); start(); // start lifecycle
} }
@Override @Override
@ -415,11 +382,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
registeredSocketClasses.add(websocketPojo); registeredSocketClasses.add(websocketPojo);
} }
public void removeListener(WebSocketServerFactory.Listener listener)
{
listeners.remove(listener);
}
public boolean sessionClosed(WebSocketSession session) public boolean sessionClosed(WebSocketSession session)
{ {
return isRunning() && sessions.remove(session); return isRunning() && sessions.remove(session);

View File

@ -46,12 +46,18 @@ import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
* Inline Servlet Filter to capture WebSocket upgrade requests and perform path mappings to {@link WebSocketCreator} objects. * Inline Servlet Filter to capture WebSocket upgrade requests and perform path mappings to {@link WebSocketCreator} objects.
*/ */
@ManagedObject("WebSocket Upgrade Filter") @ManagedObject("WebSocket Upgrade Filter")
public class WebSocketUpgradeFilter implements Filter, MappedWebSocketCreator, Dumpable public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter, MappedWebSocketCreator, Dumpable
{ {
private static final Logger LOG = Log.getLogger(WebSocketUpgradeFilter.class); private static final Logger LOG = Log.getLogger(WebSocketUpgradeFilter.class);
private final WebSocketServerFactory factory;
private PathMappings<WebSocketCreator> pathmap = new PathMappings<>(); private PathMappings<WebSocketCreator> pathmap = new PathMappings<>();
private WebSocketServerFactory factory;
private WebSocketServerFactory.Listener listener; public WebSocketUpgradeFilter()
{
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
factory = new WebSocketServerFactory(policy);
addBean(factory,true);
}
@Override @Override
public void addMapping(PathSpec spec, WebSocketCreator creator) public void addMapping(PathSpec spec, WebSocketCreator creator)
@ -153,7 +159,7 @@ public class WebSocketUpgradeFilter implements Filter, MappedWebSocketCreator, D
{ {
try try
{ {
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER); WebSocketPolicy policy = factory.getPolicy();
String max = config.getInitParameter("maxIdleTime"); String max = config.getInitParameter("maxIdleTime");
if (max != null) if (max != null)
@ -179,9 +185,7 @@ public class WebSocketUpgradeFilter implements Filter, MappedWebSocketCreator, D
policy.setInputBufferSize(Integer.parseInt(max)); policy.setInputBufferSize(Integer.parseInt(max));
} }
factory = new WebSocketServerFactory(policy); factory.start();
factory.addListener(this.listener);
factory.init();
} }
catch (Exception x) catch (Exception x)
{ {
@ -189,11 +193,6 @@ public class WebSocketUpgradeFilter implements Filter, MappedWebSocketCreator, D
} }
} }
public void setWebSocketServerFactoryListener(WebSocketServerFactory.Listener listener)
{
this.listener = listener;
}
@Override @Override
public String toString() public String toString()
{ {