Using Jetty component listeners for CDI
This commit is contained in:
parent
31ee46d482
commit
dc81cda742
|
@ -57,8 +57,6 @@ public class JettyWeldInitializer
|
|||
|
||||
public static void initContext(ContextHandler handler) throws NamingException
|
||||
{
|
||||
// TODO: handler.addLifeCycleListener(new WebSocketServerLifecycleListener(handler));
|
||||
|
||||
// Add context specific weld container reference.
|
||||
// See https://issues.jboss.org/browse/WELD-1710
|
||||
// and https://github.com/weld/core/blob/2.2.5.Final/environments/servlet/core/src/main/java/org/jboss/weld/environment/servlet/WeldServletLifecycle.java#L244-L253
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2015 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.cdi.websocket;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletContainerInitializer;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.websocket.common.util.ThreadClassLoaderScope;
|
||||
|
||||
public class WebSocketCdiInitializer implements ServletContainerInitializer
|
||||
{
|
||||
public static void configureContext(ServletContextHandler context) throws ServletException
|
||||
{
|
||||
try (ThreadClassLoaderScope scope = new ThreadClassLoaderScope(context.getClassLoader()))
|
||||
{
|
||||
addListeners(context);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartup(Set<Class<?>> c, ServletContext context) throws ServletException
|
||||
{
|
||||
ContextHandler handler = ContextHandler.getContextHandler(context);
|
||||
|
||||
if (handler == null)
|
||||
{
|
||||
throw new ServletException("Not running on Jetty, WebSocket+CDI support unavailable");
|
||||
}
|
||||
|
||||
if (!(handler instanceof ServletContextHandler))
|
||||
{
|
||||
throw new ServletException("Not running in Jetty ServletContextHandler, WebSocket+CDI support unavailable");
|
||||
}
|
||||
|
||||
ServletContextHandler jettyContext = (ServletContextHandler)handler;
|
||||
try (ThreadClassLoaderScope scope = new ThreadClassLoaderScope(context.getClassLoader()))
|
||||
{
|
||||
addListeners(jettyContext);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addListeners(ContainerLifeCycle container)
|
||||
{
|
||||
WebSocketCdiListener listener = new WebSocketCdiListener(container);
|
||||
|
||||
if (listener != null)
|
||||
{
|
||||
container.addLifeCycleListener(listener);
|
||||
container.addEventListener(listener);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
package org.eclipse.jetty.cdi.websocket;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.enterprise.inject.spi.Bean;
|
||||
import javax.enterprise.inject.spi.BeanManager;
|
||||
import javax.enterprise.inject.spi.CDI;
|
||||
|
||||
import org.eclipse.jetty.cdi.core.AnyLiteral;
|
||||
import org.eclipse.jetty.cdi.core.ScopedInstance;
|
||||
import org.eclipse.jetty.util.component.Container;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketSessionScope;
|
||||
|
||||
public class WebSocketCdiListener implements LifeCycle.Listener, Container.InheritedListener
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(WebSocketCdiListener.class);
|
||||
private final ContainerLifeCycle container;
|
||||
|
||||
public WebSocketCdiListener(ContainerLifeCycle container)
|
||||
{
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public static <T> ScopedInstance<T> newInstance(Class<T> clazz)
|
||||
{
|
||||
BeanManager bm = CDI.current().getBeanManager();
|
||||
|
||||
ScopedInstance sbean = new ScopedInstance();
|
||||
Set<Bean<?>> beans = bm.getBeans(clazz,AnyLiteral.INSTANCE);
|
||||
if (beans.size() > 0)
|
||||
{
|
||||
sbean.bean = beans.iterator().next();
|
||||
sbean.creationalContext = bm.createCreationalContext(sbean.bean);
|
||||
sbean.instance = bm.getReference(sbean.bean,clazz,sbean.creationalContext);
|
||||
return sbean;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException(String.format("Can't find class %s",clazz));
|
||||
}
|
||||
}
|
||||
|
||||
private ScopedInstance<WebSocketScopeContext> wsScope;
|
||||
|
||||
private synchronized ScopedInstance<WebSocketScopeContext> getWebSocketScope()
|
||||
{
|
||||
if (wsScope == null)
|
||||
{
|
||||
wsScope = newInstance(WebSocketScopeContext.class);
|
||||
}
|
||||
return wsScope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lifeCycleStarting(LifeCycle event)
|
||||
{
|
||||
if (event instanceof WebSocketContainerScope)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("starting websocket container [{}]", event);
|
||||
}
|
||||
getWebSocketScope().instance.begin();
|
||||
}
|
||||
else if (event instanceof WebSocketSessionScope)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("starting websocket session [{}]", event);
|
||||
}
|
||||
getWebSocketScope().instance.setSession((Session)event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lifeCycleStarted(LifeCycle event)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lifeCycleFailure(LifeCycle event, Throwable cause)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lifeCycleStopping(LifeCycle event)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lifeCycleStopped(LifeCycle event)
|
||||
{
|
||||
if (event instanceof WebSocketContainerScope)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("stopped websocket container [{}]", event);
|
||||
}
|
||||
getWebSocketScope().instance.end();
|
||||
}
|
||||
else if (event == container)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("stopped parent container [{}]", event);
|
||||
}
|
||||
if (wsScope != null)
|
||||
{
|
||||
wsScope.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beanAdded(Container parent, Object child)
|
||||
{
|
||||
if (child instanceof LifeCycle)
|
||||
{
|
||||
((LifeCycle)child).addLifeCycleListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beanRemoved(Container parent, Object child)
|
||||
{
|
||||
if (child instanceof LifeCycle)
|
||||
{
|
||||
((LifeCycle)child).removeLifeCycleListener(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -52,7 +52,7 @@ public class WebSocketScopeContext
|
|||
|
||||
public void begin()
|
||||
{
|
||||
LOG.debug("begin()");
|
||||
LOG.debug("begin()", new Throwable("Trace"));
|
||||
if (state.get() != null)
|
||||
{
|
||||
throw new IllegalAccessError("Already in WebSocketScope");
|
||||
|
@ -102,7 +102,7 @@ public class WebSocketScopeContext
|
|||
|
||||
public void setSession(Session sess)
|
||||
{
|
||||
LOG.debug("setSession()");
|
||||
LOG.debug("setSession({})",sess);
|
||||
jettySessionProducer.setSession(sess);
|
||||
if(sess instanceof javax.websocket.Session)
|
||||
{
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
org.eclipse.jetty.cdi.websocket.WebSocketCdiInitializer
|
|
@ -49,6 +49,7 @@ public class BasicAppTest
|
|||
private static final Logger LOG = Log.getLogger(BasicAppTest.class);
|
||||
|
||||
private static Server server;
|
||||
@SuppressWarnings("unused")
|
||||
private static URI serverHttpURI;
|
||||
private static URI serverWebsocketURI;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import javax.websocket.server.ServerContainer;
|
|||
|
||||
import org.eclipse.jetty.cdi.servlet.EmbeddedCdiHandler;
|
||||
import org.eclipse.jetty.cdi.websocket.CheckSocket;
|
||||
import org.eclipse.jetty.cdi.websocket.WebSocketCdiInitializer;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
|
@ -60,6 +61,7 @@ public class CdiAppTest
|
|||
server.addConnector(connector);
|
||||
|
||||
EmbeddedCdiHandler context = new EmbeddedCdiHandler();
|
||||
WebSocketCdiInitializer.configureContext(context);
|
||||
|
||||
File baseDir = MavenTestingUtils.getTestResourcesDir();
|
||||
|
||||
|
@ -69,6 +71,7 @@ public class CdiAppTest
|
|||
|
||||
// Add some websockets
|
||||
ServerContainer container = WebSocketServerContainerInitializer.configureContext(context);
|
||||
container.addEndpoint(EchoSocket.class);
|
||||
container.addEndpoint(InfoSocket.class);
|
||||
|
||||
server.start();
|
||||
|
@ -120,7 +123,7 @@ public class CdiAppTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testWebSocketInfo() throws Exception
|
||||
public void testWebSocket_Info_FieldPresence() throws Exception
|
||||
{
|
||||
WebSocketClient client = new WebSocketClient();
|
||||
try
|
||||
|
@ -150,4 +153,31 @@ public class CdiAppTest
|
|||
client.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWebSocket_Info_DataFromCdi() throws Exception
|
||||
{
|
||||
WebSocketClient client = new WebSocketClient();
|
||||
try
|
||||
{
|
||||
client.start();
|
||||
CheckSocket socket = new CheckSocket();
|
||||
client.connect(socket,serverWebsocketURI.resolve("/cdi-info"));
|
||||
|
||||
socket.awaitOpen(2,TimeUnit.SECONDS);
|
||||
socket.sendText("data|stuff");
|
||||
socket.close(StatusCode.NORMAL,"Test complete");
|
||||
socket.awaitClose(2,TimeUnit.SECONDS);
|
||||
|
||||
assertThat("Messages received",socket.getTextMessages().size(),is(1));
|
||||
String response = socket.getTextMessages().poll();
|
||||
System.err.println(response);
|
||||
|
||||
assertThat("Message[0]",response,containsString("Hello there data"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,15 +20,22 @@ package org.eclipse.jetty.cdi.websocket.cdiapp;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
|
||||
public class DataMaker
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(DataMaker.class);
|
||||
|
||||
@Inject
|
||||
private Session session;
|
||||
|
||||
public void processMessage(String msg)
|
||||
{
|
||||
LOG.debug(".processMessage({})",msg);
|
||||
LOG.debug("session = {}",session);
|
||||
|
||||
session.getRemote().sendStringByFuture("Hello there " + msg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2015 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.cdi.websocket.cdiapp;
|
||||
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.OnClose;
|
||||
import javax.websocket.OnMessage;
|
||||
import javax.websocket.OnOpen;
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.server.ServerEndpoint;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
@ServerEndpoint("/echo")
|
||||
public class EchoSocket
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(EchoSocket.class);
|
||||
@SuppressWarnings("unused")
|
||||
private Session session;
|
||||
|
||||
@OnOpen
|
||||
public void onOpen(Session session)
|
||||
{
|
||||
LOG.debug("onOpen(): {}",session);
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
@OnClose
|
||||
public void onClose(CloseReason close)
|
||||
{
|
||||
LOG.debug("onClose(): {}",close);
|
||||
this.session = null;
|
||||
}
|
||||
|
||||
@OnMessage
|
||||
public String onMessage(String msg)
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
}
|
|
@ -69,8 +69,10 @@ public class InfoSocket
|
|||
{
|
||||
StringWriter str = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(str);
|
||||
|
||||
String args[] = msg.split("\\|");
|
||||
|
||||
switch (msg)
|
||||
switch (args[0])
|
||||
{
|
||||
case "info":
|
||||
out.printf("websocketSession is %s%n",asPresent(session));
|
||||
|
@ -78,7 +80,7 @@ public class InfoSocket
|
|||
out.printf("servletContext is %s%n",asPresent(servletContext));
|
||||
break;
|
||||
case "data":
|
||||
dataMaker.processMessage(msg);
|
||||
dataMaker.processMessage(args[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ import java.io.IOException;
|
|||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
@ -59,8 +58,6 @@ 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.common.scopes.WebSocketScopeEvents;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketScopeListener;
|
||||
import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner;
|
||||
import org.eclipse.jetty.websocket.jsr356.client.AnnotatedClientEndpointMetadata;
|
||||
import org.eclipse.jetty.websocket.jsr356.client.EmptyClientEndpointConfig;
|
||||
|
@ -119,12 +116,6 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
|||
ShutdownThread.register(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScopeListener(WebSocketScopeListener listener)
|
||||
{
|
||||
this.scopeDelegate.addScopeListener(listener);
|
||||
}
|
||||
|
||||
private Session connect(EndpointInstance instance, URI path) throws IOException
|
||||
{
|
||||
Objects.requireNonNull(instance,"EndpointInstance cannot be null");
|
||||
|
@ -351,17 +342,6 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
|||
return scopeDelegate.getPolicy();
|
||||
}
|
||||
|
||||
public WebSocketScopeEvents getScopeEvents()
|
||||
{
|
||||
return scopeDelegate.getScopeEvents();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WebSocketScopeListener> getScopeListeners()
|
||||
{
|
||||
return scopeDelegate.getScopeListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SslContextFactory getSslContextFactory()
|
||||
{
|
||||
|
@ -426,12 +406,6 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeScopeListener(WebSocketScopeListener listener)
|
||||
{
|
||||
scopeDelegate.removeScopeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAsyncSendTimeout(long ms)
|
||||
{
|
||||
|
|
|
@ -148,6 +148,7 @@ public class JsrEvents<T extends Annotation, C extends EndpointConfig>
|
|||
{
|
||||
if (onError == null)
|
||||
{
|
||||
LOG.warn("Unable to report throwable to websocket (no @OnError handler declared): " + websocket.getClass().getName(), cause);
|
||||
return;
|
||||
}
|
||||
onError.call(websocket,cause);
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.net.SocketAddress;
|
|||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
|
@ -61,8 +60,6 @@ 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;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketScopeEvents;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketScopeListener;
|
||||
|
||||
/**
|
||||
* WebSocketClient provides a means of establishing connections to remote websocket endpoints.
|
||||
|
@ -74,7 +71,6 @@ public class WebSocketClient extends ContainerLifeCycle implements SessionListen
|
|||
private final WebSocketPolicy policy = WebSocketPolicy.newClientPolicy();
|
||||
private final SslContextFactory sslContextFactory;
|
||||
private final WebSocketExtensionFactory extensionRegistry;
|
||||
private WebSocketScopeEvents scopeEvents = new WebSocketScopeEvents();
|
||||
private boolean daemon = false;
|
||||
private EventDriverFactory eventDriverFactory;
|
||||
private SessionFactory sessionFactory;
|
||||
|
@ -150,12 +146,6 @@ public class WebSocketClient extends ContainerLifeCycle implements SessionListen
|
|||
addBean(this.bufferPool);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScopeListener(WebSocketScopeListener listener)
|
||||
{
|
||||
this.scopeEvents.addScopeListener(listener);
|
||||
}
|
||||
|
||||
public Future<Session> connect(Object websocket, URI toUri) throws IOException
|
||||
{
|
||||
ClientUpgradeRequest request = new ClientUpgradeRequest(toUri);
|
||||
|
@ -291,8 +281,6 @@ public class WebSocketClient extends ContainerLifeCycle implements SessionListen
|
|||
|
||||
super.doStart();
|
||||
|
||||
scopeEvents.fireContainerActivated(this);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Started {}",this);
|
||||
}
|
||||
|
@ -316,8 +304,6 @@ public class WebSocketClient extends ContainerLifeCycle implements SessionListen
|
|||
|
||||
super.doStop();
|
||||
|
||||
scopeEvents.fireContainerDeactivated(this);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Stopped {}",this);
|
||||
}
|
||||
|
@ -453,17 +439,6 @@ public class WebSocketClient extends ContainerLifeCycle implements SessionListen
|
|||
return scheduler;
|
||||
}
|
||||
|
||||
public WebSocketScopeEvents getScopeEvents()
|
||||
{
|
||||
return scopeEvents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WebSocketScopeListener> getScopeListeners()
|
||||
{
|
||||
return this.scopeEvents.getScopeListeners();
|
||||
}
|
||||
|
||||
public SessionFactory getSessionFactory()
|
||||
{
|
||||
return sessionFactory;
|
||||
|
@ -531,12 +506,6 @@ public class WebSocketClient extends ContainerLifeCycle implements SessionListen
|
|||
LOG.debug("Session Opened: {}",session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeScopeListener(WebSocketScopeListener listener)
|
||||
{
|
||||
this.scopeEvents.removeScopeListener(listener);
|
||||
}
|
||||
|
||||
public void setAsyncWriteTimeout(long ms)
|
||||
{
|
||||
this.policy.setAsyncWriteTimeout(ms);
|
||||
|
|
|
@ -275,7 +275,9 @@ public class UpgradeConnection extends AbstractConnection
|
|||
// Validate Response Status Code
|
||||
if (response.getStatusCode() != SWITCHING_PROTOCOLS)
|
||||
{
|
||||
throw new UpgradeException(request.getRequestURI(),response.getStatusCode(),"Didn't switch protocols");
|
||||
// TODO: use jetty-http and org.eclipse.jetty.http.HttpStatus for more meaningful exception messages
|
||||
throw new UpgradeException(request.getRequestURI(),response.getStatusCode(),"Didn't switch protocols, expected status <" + SWITCHING_PROTOCOLS
|
||||
+ ">, but got <" + response.getStatusCode() + ">");
|
||||
}
|
||||
|
||||
// Validate Connection header
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.common.scopes;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
|
@ -36,7 +35,6 @@ public class SimpleContainerScope extends ContainerLifeCycle implements WebSocke
|
|||
private final WebSocketPolicy policy;
|
||||
private Executor executor;
|
||||
private SslContextFactory sslContextFactory;
|
||||
private WebSocketScopeEvents scopeEvents = new WebSocketScopeEvents();
|
||||
|
||||
public SimpleContainerScope(WebSocketPolicy policy)
|
||||
{
|
||||
|
@ -65,14 +63,12 @@ public class SimpleContainerScope extends ContainerLifeCycle implements WebSocke
|
|||
protected void doStart() throws Exception
|
||||
{
|
||||
super.doStart();
|
||||
scopeEvents.fireContainerActivated(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
super.doStop();
|
||||
scopeEvents.fireContainerDeactivated(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -109,27 +105,4 @@ public class SimpleContainerScope extends ContainerLifeCycle implements WebSocke
|
|||
{
|
||||
this.sslContextFactory = sslContextFactory;
|
||||
}
|
||||
|
||||
public WebSocketScopeEvents getScopeEvents()
|
||||
{
|
||||
return scopeEvents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScopeListener(WebSocketScopeListener listener)
|
||||
{
|
||||
this.scopeEvents.addScopeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeScopeListener(WebSocketScopeListener listener)
|
||||
{
|
||||
this.scopeEvents.removeScopeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WebSocketScopeListener> getScopeListeners()
|
||||
{
|
||||
return this.scopeEvents.getScopeListeners();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.common.scopes;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
|
@ -31,32 +30,6 @@ import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
|||
*/
|
||||
public interface WebSocketContainerScope
|
||||
{
|
||||
/**
|
||||
* Add a {@link WebSocketScopeListener} for this container.
|
||||
*
|
||||
* @param listener
|
||||
* the listener to receive container scope events
|
||||
*/
|
||||
public void addScopeListener(WebSocketScopeListener listener);
|
||||
|
||||
/**
|
||||
* Remove a {@link WebSocketScopeListener} from this container
|
||||
*
|
||||
* @param listener
|
||||
* the listener to receive websocket scope events
|
||||
*/
|
||||
public void removeScopeListener(WebSocketScopeListener listener);
|
||||
|
||||
/**
|
||||
* Get the current list of {@link WebSocketScopeListener}s for this container
|
||||
*/
|
||||
public List<WebSocketScopeListener> getScopeListeners();
|
||||
|
||||
/**
|
||||
* Get the WebSocketScopeEvents handler, for firing {@link WebSocketScopeListener} events.
|
||||
*/
|
||||
public WebSocketScopeEvents getScopeEvents();
|
||||
|
||||
/**
|
||||
* The configured Container Buffer Pool.
|
||||
*
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2015 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.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class WebSocketScopeEvents
|
||||
{
|
||||
private List<WebSocketScopeListener> scopeListeners;
|
||||
|
||||
public void addScopeListener(WebSocketScopeListener listener)
|
||||
{
|
||||
if (scopeListeners == null)
|
||||
{
|
||||
scopeListeners = new ArrayList<>();
|
||||
}
|
||||
scopeListeners.add(listener);
|
||||
}
|
||||
|
||||
public void fireContainerActivated(WebSocketContainerScope container)
|
||||
{
|
||||
if (scopeListeners != null)
|
||||
{
|
||||
for (WebSocketScopeListener listener : scopeListeners)
|
||||
{
|
||||
listener.onWebSocketContainerActivated(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void fireContainerDeactivated(WebSocketContainerScope container)
|
||||
{
|
||||
if (scopeListeners != null)
|
||||
{
|
||||
for (WebSocketScopeListener listener : scopeListeners)
|
||||
{
|
||||
listener.onWebSocketContainerDeactivated(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void fireSessionActivated(WebSocketSessionScope session)
|
||||
{
|
||||
if (scopeListeners != null)
|
||||
{
|
||||
for (WebSocketScopeListener listener : scopeListeners)
|
||||
{
|
||||
listener.onWebSocketSessionActivated(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void fireSessionDeactivated(WebSocketSessionScope session)
|
||||
{
|
||||
if (scopeListeners != null)
|
||||
{
|
||||
for (WebSocketScopeListener listener : scopeListeners)
|
||||
{
|
||||
listener.onWebSocketSessionDeactivated(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<WebSocketScopeListener> getScopeListeners()
|
||||
{
|
||||
if (scopeListeners == null)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.unmodifiableList(scopeListeners);
|
||||
}
|
||||
|
||||
public void removeScopeListener(WebSocketScopeListener listener)
|
||||
{
|
||||
if (scopeListeners == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
scopeListeners.remove(listener);
|
||||
}
|
||||
}
|
|
@ -16,27 +16,30 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.common.scopes;
|
||||
package org.eclipse.jetty.websocket.common.util;
|
||||
|
||||
public interface WebSocketScopeListener
|
||||
import java.io.Closeable;
|
||||
|
||||
public class ThreadClassLoaderScope implements Closeable
|
||||
{
|
||||
/**
|
||||
* A WebSocket Container scope was created / activated
|
||||
*/
|
||||
void onWebSocketContainerActivated(WebSocketContainerScope scope);
|
||||
private final ClassLoader old;
|
||||
private final ClassLoader scopedClassLoader;
|
||||
|
||||
/**
|
||||
* A WebSocket Container scope was stopped / deactivated
|
||||
*/
|
||||
void onWebSocketContainerDeactivated(WebSocketContainerScope scope);
|
||||
public ThreadClassLoaderScope(ClassLoader cl)
|
||||
{
|
||||
old = Thread.currentThread().getContextClassLoader();
|
||||
scopedClassLoader = cl;
|
||||
Thread.currentThread().setContextClassLoader(scopedClassLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* A WebSocket Session scope was created / activated
|
||||
*/
|
||||
void onWebSocketSessionActivated(WebSocketSessionScope scope);
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
|
||||
/**
|
||||
* A WebSocket Session scope was stopped / deactivated
|
||||
*/
|
||||
void onWebSocketSessionDeactivated(WebSocketSessionScope scope);
|
||||
public ClassLoader getScopedClassLoader()
|
||||
{
|
||||
return scopedClassLoader;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2015 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.util;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class ThreadClassLoaderScopeTest
|
||||
{
|
||||
private static class ClassLoaderFoo extends URLClassLoader
|
||||
{
|
||||
public ClassLoaderFoo()
|
||||
{
|
||||
super(new URL[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ClassLoaderBar extends URLClassLoader
|
||||
{
|
||||
public ClassLoaderBar()
|
||||
{
|
||||
super(new URL[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormal()
|
||||
{
|
||||
try (ThreadClassLoaderScope scope = new ThreadClassLoaderScope(new ClassLoaderFoo()))
|
||||
{
|
||||
assertThat("ClassLoader in scope",Thread.currentThread().getContextClassLoader(),instanceOf(ClassLoaderFoo.class));
|
||||
assertThat("Scoped ClassLoader",scope.getScopedClassLoader(),instanceOf(ClassLoaderFoo.class));
|
||||
}
|
||||
assertThat("ClassLoader after scope",Thread.currentThread().getContextClassLoader(),not(instanceOf(ClassLoaderFoo.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithException()
|
||||
{
|
||||
try (ThreadClassLoaderScope scope = new ThreadClassLoaderScope(new ClassLoaderBar()))
|
||||
{
|
||||
assertThat("ClassLoader in 'scope'",Thread.currentThread().getContextClassLoader(),instanceOf(ClassLoaderBar.class));
|
||||
assertThat("Scoped ClassLoader",scope.getScopedClassLoader(),instanceOf(ClassLoaderBar.class));
|
||||
try (ThreadClassLoaderScope inner = new ThreadClassLoaderScope(new ClassLoaderFoo()))
|
||||
{
|
||||
assertThat("ClassLoader in 'inner'",Thread.currentThread().getContextClassLoader(),instanceOf(ClassLoaderFoo.class));
|
||||
assertThat("Scoped ClassLoader",scope.getScopedClassLoader(),instanceOf(ClassLoaderFoo.class));
|
||||
throw new RuntimeException("Intention exception");
|
||||
}
|
||||
}
|
||||
catch (Throwable ignore)
|
||||
{
|
||||
/* ignore */
|
||||
}
|
||||
assertThat("ClassLoader after 'scope'",Thread.currentThread().getContextClassLoader(),not(instanceOf(ClassLoaderBar.class)));
|
||||
}
|
||||
}
|
|
@ -66,8 +66,6 @@ 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.common.scopes.WebSocketScopeEvents;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketScopeListener;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||
|
@ -97,7 +95,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
private WebSocketCreator creator;
|
||||
private List<Class<?>> registeredSocketClasses;
|
||||
private DecoratedObjectFactory objectFactory;
|
||||
private WebSocketScopeEvents scopeEvents = new WebSocketScopeEvents();
|
||||
|
||||
public WebSocketServerFactory()
|
||||
{
|
||||
|
@ -209,12 +206,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScopeListener(WebSocketScopeListener listener)
|
||||
{
|
||||
this.scopeEvents.addScopeListener(listener);
|
||||
}
|
||||
|
||||
public void addSessionFactory(SessionFactory sessionFactory)
|
||||
{
|
||||
if (sessionFactories.contains(sessionFactory))
|
||||
|
@ -325,8 +316,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
}
|
||||
|
||||
super.doStart();
|
||||
|
||||
scopeEvents.fireContainerActivated(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -334,8 +323,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
{
|
||||
shutdownAllConnections();
|
||||
super.doStop();
|
||||
|
||||
scopeEvents.fireContainerDeactivated(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -383,17 +370,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
return defaultPolicy;
|
||||
}
|
||||
|
||||
public WebSocketScopeEvents getScopeEvents()
|
||||
{
|
||||
return scopeEvents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WebSocketScopeListener> getScopeListeners()
|
||||
{
|
||||
return this.scopeEvents.getScopeListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SslContextFactory getSslContextFactory()
|
||||
{
|
||||
|
@ -540,12 +516,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
registeredSocketClasses.add(websocketPojo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeScopeListener(WebSocketScopeListener listener)
|
||||
{
|
||||
this.scopeEvents.removeScopeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreator(WebSocketCreator creator)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue