store shared websocket components as attributes and not beans

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan Roberts 2019-05-21 18:56:53 +10:00
parent e31009cb06
commit 5f62e0f2db
6 changed files with 16 additions and 72 deletions

View File

@ -26,7 +26,6 @@ import java.util.function.Supplier;
import javax.servlet.ServletContext;
import javax.websocket.DeploymentException;
import javax.websocket.EndpointConfig;
import javax.websocket.WebSocketContainer;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpoint;
import javax.websocket.server.ServerEndpointConfig;
@ -50,46 +49,23 @@ import org.eclipse.jetty.websocket.javax.server.internal.UndefinedServerEndpoint
import org.eclipse.jetty.websocket.servlet.WebSocketMapping;
@ManagedObject("JSR356 Server Container")
public class JavaxWebSocketServerContainer
extends JavaxWebSocketClientContainer
implements javax.websocket.server.ServerContainer, LifeCycle.Listener
public class JavaxWebSocketServerContainer extends JavaxWebSocketClientContainer implements javax.websocket.server.ServerContainer, LifeCycle.Listener
{
public static final String JAVAX_WEBSOCKET_CONTAINER_ATTRIBUTE = ServerContainer.class.getName();
private static final Logger LOG = Log.getLogger(JavaxWebSocketServerContainer.class);
/**
* Get the WebSocketContainer out of the current ThreadLocal reference
* of the active ContextHandler.
*
* @return the WebSocketContainer if found, null if not found.
*/
public static WebSocketContainer getWebSocketContainer()
{
ContextHandler.Context context = ContextHandler.getCurrentContext();
if (context == null)
return null;
ContextHandler handler = ContextHandler.getContextHandler(context);
if (handler == null)
return null;
if (!(handler instanceof ServletContextHandler))
return null;
return (javax.websocket.WebSocketContainer)handler.getServletContext().getAttribute("javax.websocket.server.ServerContainer");
}
public static JavaxWebSocketServerContainer ensureContainer(ServletContext servletContext)
{
ContextHandler contextHandler = ServletContextHandler.getServletContextHandler(servletContext, "Javax Websocket");
if (contextHandler.getServer() == null)
throw new IllegalStateException("Server has not been set on the ServletContextHandler");
JavaxWebSocketServerContainer container = contextHandler.getBean(JavaxWebSocketServerContainer.class);
JavaxWebSocketServerContainer container = (JavaxWebSocketServerContainer)servletContext.getAttribute(JAVAX_WEBSOCKET_CONTAINER_ATTRIBUTE);
if (container==null)
{
Supplier<WebSocketCoreClient> coreClientSupplier = () ->
{
WebSocketCoreClient coreClient = contextHandler.getBean(WebSocketCoreClient.class);
WebSocketCoreClient coreClient = (WebSocketCoreClient)servletContext.getAttribute(WebSocketCoreClient.WEBSOCKET_CORECLIENT_ATTRIBUTE);
if (coreClient == null)
{
// Find Pre-Existing (Shared?) HttpClient and/or executor
@ -111,6 +87,7 @@ public class JavaxWebSocketServerContainer
coreClient.getHttpClient().setName("Javax-WebSocketClient@" + Integer.toHexString(coreClient.getHttpClient().hashCode()));
if (executor != null && httpClient == null)
coreClient.getHttpClient().setExecutor(executor);
servletContext.setAttribute(WebSocketCoreClient.WEBSOCKET_CORECLIENT_ATTRIBUTE, coreClient);
}
return coreClient;
};
@ -124,7 +101,7 @@ public class JavaxWebSocketServerContainer
contextHandler.addLifeCycleListener(container);
}
// Store a reference to the ServerContainer per - javax.websocket spec 1.0 final - section 6.4: Programmatic Server Deployment
servletContext.setAttribute(ServerContainer.class.getName(), container);
servletContext.setAttribute(JAVAX_WEBSOCKET_CONTAINER_ATTRIBUTE, container);
return container;
}

View File

@ -48,7 +48,6 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServerContainer;
import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer;
import org.eclipse.jetty.websocket.javax.tests.WSURI;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer.HTTPCLIENT_ATTRIBUTE;
@ -207,37 +206,6 @@ public class WebSocketServerContainerExecutorTest
}
}
@Disabled //TODO: the ContextHandler executor attribute is overwritten on ContextHandler.doStart() now we do attribute lookup lazily
@Test
public void testContextExecutor() throws Exception
{
Server server = new Server(0);
ServletContextHandler contextHandler = new ServletContextHandler();
server.setHandler(contextHandler);
//Executor to use
Executor executor = new QueuedThreadPool();
contextHandler.setAttribute("org.eclipse.jetty.server.Executor", executor);
// Using JSR356 Server Techniques to connectToServer()
contextHandler.addServlet(ServerConnectServlet.class, "/connect");
JavaxWebSocketServerContainer container = JavaxWebSocketServletContainerInitializer.configureContext(contextHandler);
container.addEndpoint(EchoSocket.class);
try
{
server.start();
String response = GET(server.getURI().resolve("/connect"));
assertThat("Response", response, startsWith("Connected to ws://"));
Executor containerExecutor = container.getExecutor();
assertThat(containerExecutor, sameInstance(executor));
}
finally
{
server.stop();
}
}
private String GET(URI destURI) throws IOException
{
HttpURLConnection http = (HttpURLConnection)destURI.toURL().openConnection();

View File

@ -47,6 +47,7 @@ import org.eclipse.jetty.websocket.servlet.WebSocketMapping;
public class JettyWebSocketServerContainer extends ContainerLifeCycle implements WebSocketContainer, WebSocketPolicy, LifeCycle.Listener
{
public static final String JETTY_WEBSOCKET_CONTAINER_ATTRIBUTE = WebSocketContainer.class.getName();
public static JettyWebSocketServerContainer ensureContainer(ServletContext servletContext)
{
@ -54,7 +55,7 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements
if (contextHandler.getServer() == null)
throw new IllegalStateException("Server has not been set on the ServletContextHandler");
JettyWebSocketServerContainer container = contextHandler.getBean(JettyWebSocketServerContainer.class);
JettyWebSocketServerContainer container = (JettyWebSocketServerContainer)servletContext.getAttribute(JETTY_WEBSOCKET_CONTAINER_ATTRIBUTE);
if (container == null)
{
// Find Pre-Existing executor
@ -67,7 +68,7 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements
contextHandler,
WebSocketMapping.ensureMapping(servletContext, WebSocketMapping.DEFAULT_KEY),
WebSocketComponents.ensureWebSocketComponents(servletContext), executor);
servletContext.setAttribute(WebSocketContainer.class.getName(), container);
servletContext.setAttribute(JETTY_WEBSOCKET_CONTAINER_ATTRIBUTE, container);
contextHandler.addManaged(container);
contextHandler.addLifeCycleListener(container);
}

View File

@ -22,7 +22,6 @@ import javax.servlet.ServletContext;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.DecoratedObjectFactory;
/**
@ -34,16 +33,16 @@ import org.eclipse.jetty.util.DecoratedObjectFactory;
*/
public class WebSocketComponents
{
public static final String WEBSOCKET_COMPONENTS_ATTRIBUTE = WebSocketComponents.class.getName();
public static WebSocketComponents ensureWebSocketComponents(ServletContext servletContext)
{
ContextHandler contextHandler = ContextHandler.getContextHandler(servletContext);
// Ensure a mapping exists
WebSocketComponents components = contextHandler.getBean(WebSocketComponents.class);
WebSocketComponents components = (WebSocketComponents)servletContext.getAttribute(WEBSOCKET_COMPONENTS_ATTRIBUTE);
if (components == null)
{
components = new WebSocketComponents();
contextHandler.addBean(components);
servletContext.setAttribute(WEBSOCKET_COMPONENTS_ATTRIBUTE, components);
}
return components;

View File

@ -36,6 +36,7 @@ import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry;
public class WebSocketCoreClient extends ContainerLifeCycle
{
public static final String WEBSOCKET_CORECLIENT_ATTRIBUTE = WebSocketCoreClient.class.getName();
private static final Logger LOG = Log.getLogger(WebSocketCoreClient.class);
private final HttpClient httpClient;

View File

@ -61,8 +61,7 @@ public class WebSocketMapping implements Dumpable, LifeCycle.Listener
public static WebSocketMapping getMapping(ServletContext servletContext, String mappingKey)
{
ContextHandler contextHandler = ContextHandler.getContextHandler(servletContext);
Object mappingObject = contextHandler.getAttribute(mappingKey);
Object mappingObject = servletContext.getAttribute(mappingKey);
if (mappingObject!=null)
{
@ -79,13 +78,12 @@ public class WebSocketMapping implements Dumpable, LifeCycle.Listener
public static WebSocketMapping ensureMapping(ServletContext servletContext, String mappingKey)
{
ContextHandler contextHandler = ContextHandler.getContextHandler(servletContext);
WebSocketMapping mapping = getMapping(servletContext, mappingKey);
if (mapping == null)
{
mapping = new WebSocketMapping(WebSocketComponents.ensureWebSocketComponents(servletContext));
contextHandler.setAttribute(mappingKey, mapping);
servletContext.setAttribute(mappingKey, mapping);
}
return mapping;