WebSocketMapping refactor changes from review

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan Roberts 2019-01-25 17:11:27 +11:00
parent 0c85b3138f
commit aa1d6ff9cd
5 changed files with 17 additions and 221 deletions

View File

@ -1,71 +0,0 @@
package org.eclipse.jetty.websocket.core;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
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;
public class SharedResources
{
public static SharedResources ensureSharedResources(ServletContext servletContext) throws ServletException
{
ContextHandler contextHandler = ContextHandler.getContextHandler(servletContext);
// Ensure a mapping exists
SharedResources resources = contextHandler.getBean(SharedResources.class);
if (resources == null)
{
resources = new SharedResources();
resources.setContextClassLoader(servletContext.getClassLoader());
contextHandler.addBean(resources);
}
return resources;
}
public SharedResources()
{
this(new WebSocketExtensionRegistry(), new DecoratedObjectFactory(), new MappedByteBufferPool());
}
public SharedResources(WebSocketExtensionRegistry extensionRegistry, DecoratedObjectFactory objectFactory, ByteBufferPool bufferPool)
{
this.extensionRegistry = extensionRegistry;
this.objectFactory = objectFactory;
this.bufferPool = bufferPool;
}
private DecoratedObjectFactory objectFactory;
private ClassLoader contextClassLoader;
private WebSocketExtensionRegistry extensionRegistry;
private ByteBufferPool bufferPool;
public ByteBufferPool getBufferPool()
{
return bufferPool;
}
public void setContextClassLoader(ClassLoader classLoader)
{
contextClassLoader = classLoader;
}
public ClassLoader getContextClassloader()
{
return contextClassLoader;
}
public WebSocketExtensionRegistry getExtensionRegistry()
{
return extensionRegistry;
}
public DecoratedObjectFactory getObjectFactory()
{
return objectFactory;
}
}

View File

@ -67,10 +67,12 @@ public class WebSocketMapping implements Dumpable, LifeCycle.Listener
Object mappingObject = contextHandler.getAttribute(mappingKey);
if (mappingObject!=null)
{
if (WebSocketMapping.class.isAssignableFrom(mappingObject.getClass()))
if (WebSocketMapping.class.isInstance(mappingObject.getClass()))
return (WebSocketMapping)mappingObject;
else
throw new IllegalStateException("WebSocketMapping attribute already in use");
throw new IllegalStateException(
String.format("ContextHandler attribute %s is not of type WebSocketMapping: {%s}",
mappingKey, mappingObject.toString()));
}
else
{
@ -80,7 +82,7 @@ public class WebSocketMapping implements Dumpable, LifeCycle.Listener
}
}
public static final String DEFAULT_KEY = "org.eclipse.jetty.websocket.WebSocketMapping";
public static final String DEFAULT_KEY = "org.eclipse.jetty.websocket.servlet.WebSocketMapping";
private final PathMappings<Negotiator> mappings = new PathMappings<>();
private final WebSocketComponents components;
@ -266,8 +268,11 @@ public class WebSocketMapping implements Dumpable, LifeCycle.Listener
@Override
public FrameHandler negotiate(Negotiation negotiation)
{
//TODO what about a null context
ClassLoader loader = negotiation.getRequest().getServletContext().getClassLoader();
ServletContext servletContext = negotiation.getRequest().getServletContext();
if (servletContext == null)
throw new IllegalStateException("null servletContext from request");
ClassLoader loader = servletContext.getClassLoader();
ClassLoader old = Thread.currentThread().getContextClassLoader();
try

View File

@ -82,12 +82,8 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
for (FilterHolder holder : servletHandler.getFilters())
{
if (holder.getClassName().equals(WebSocketUpgradeFilter.class.getName()) ||
(holder.getHeldClass() != null && WebSocketUpgradeFilter.class.isAssignableFrom(holder.getHeldClass())))
{
if (holder.getInitParameter("javaxWebSocketMapping") != null)
return holder;
}
if (holder.getInitParameter(MAPPING_INIT_PARAM) != null)
return holder;
}
return null;
@ -104,7 +100,7 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST);
FilterHolder holder = new FilterHolder(new WebSocketUpgradeFilter());
holder.setName(name);
holder.setInitParameter("javaxWebSocketMapping", WebSocketMapping.DEFAULT_KEY);
holder.setInitParameter(MAPPING_INIT_PARAM, WebSocketMapping.DEFAULT_KEY);
holder.setAsyncSupported(true);
ServletHandler servletHandler = ContextHandler.getContextHandler(servletContext).getChildHandlerByClass(ServletHandler.class);
@ -114,6 +110,8 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
return holder;
}
public final static String MAPPING_INIT_PARAM = "org.eclipse.jetty.websocket.servlet.WebSocketMapping.key";
private final FrameHandler.ConfigurationCustomizer defaultCustomizer = new FrameHandler.ConfigurationCustomizer();
private WebSocketMapping mapping;
@ -159,7 +157,7 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
{
final ServletContext context = config.getServletContext();
String mappingKey = config.getInitParameter("javaxWebSocketMapping");
String mappingKey = config.getInitParameter(MAPPING_INIT_PARAM);
if (mappingKey != null)
mapping = WebSocketMapping.ensureMapping(context, mappingKey);
else

View File

@ -8,7 +8,7 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>websocket-tests</artifactId>
<artifactId>jetty-websocket-tests</artifactId>
<name>Jetty :: Websocket :: Tests</name>
<properties>
@ -16,48 +16,25 @@
</properties>
<dependencies>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>jetty-websocket-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>javax-websocket-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-server</artifactId>
<version>10.0.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -1,113 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2019 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.tests;
import java.net.URI;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer;
import org.junit.jupiter.api.Test;
public class JavaxWebsocketTest
{
@ClientEndpoint
@ServerEndpoint("/path")
public static class EventSocket
{
CountDownLatch closed = new CountDownLatch(1);
@OnOpen
public void onOpen(Session sess)
{
System.out.println("Socket Connected: " + sess);
}
@OnMessage
public void onMessage(String message)
{
System.out.println("Received TEXT message: " + message);
}
@OnClose
public void onClose(CloseReason reason)
{
System.out.println("Socket Closed: " + reason);
closed.countDown();
}
@OnError
public void onError(Throwable cause)
{
cause.printStackTrace(System.err);
}
}
@Test
public void test() throws Exception
{
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(8080);
server.addConnector(connector);
ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
contextHandler.setContextPath("/");
server.setHandler(contextHandler);
try
{
ServerContainer serverContainer = JavaxWebSocketServletContainerInitializer.configureContext(contextHandler);
serverContainer.addEndpoint(EventSocket.class);
server.start();
URI uri = URI.create("ws://localhost:8080/path");
WebSocketContainer clientContainer = ContainerProvider.getWebSocketContainer();
EventSocket clientEndpoint = new EventSocket();
try(Session session = clientContainer.connectToServer(clientEndpoint, uri))
{
session.getBasicRemote().sendText("hello world");
}
clientEndpoint.closed.await(10, TimeUnit.SECONDS);
server.stop();
}
catch (Throwable t)
{
t.printStackTrace();
}
}
}