Issue #207 - Support javax.websocket version 1.1

+ More testcase improvements
This commit is contained in:
Joakim Erdfelt 2016-08-25 11:03:42 -07:00
parent 1bb25adbdc
commit 36f657165f
20 changed files with 101 additions and 27 deletions

View File

@ -22,6 +22,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
@ -199,6 +200,18 @@ public class PathMappings<E> implements Iterable<MappedResource<E>>, Dumpable
return pathSpecString.charAt(0) == '^' ? new RegexPathSpec(pathSpecString):new ServletPathSpec(pathSpecString);
}
public E get(PathSpec spec)
{
Optional<E> optionalResource = _mappings.stream()
.filter(mappedResource -> mappedResource.getPathSpec().equals(spec))
.map(mappedResource -> mappedResource.getResource())
.findFirst();
if(!optionalResource.isPresent())
return null;
return optionalResource.get();
}
public boolean put(String pathSpecString, E resource)
{
return put(asPathSpec(pathSpecString),resource);

View File

@ -207,6 +207,27 @@ public class AnnotatedServerEndpointConfig implements ServerEndpointConfig
return userProperties;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AnnotatedServerEndpointConfig that = (AnnotatedServerEndpointConfig) o;
if (endpointClass != null ? !endpointClass.equals(that.endpointClass) : that.endpointClass != null)
return false;
return path != null ? path.equals(that.path) : that.path == null;
}
@Override
public int hashCode()
{
int result = endpointClass != null ? endpointClass.hashCode() : 0;
result = 31 * result + (path != null ? path.hashCode() : 0);
return result;
}
@Override
public String toString()
{

View File

@ -173,9 +173,27 @@ public class JsrCreator implements WebSocketCreator
}
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
JsrCreator that = (JsrCreator) o;
return baseConfig != null ? baseConfig.equals(that.baseConfig) : that.baseConfig == null;
}
@Override
public int hashCode()
{
int result = (baseConfig != null ? baseConfig.hashCode() : 0);
return result;
}
@Override
public String toString()
{
return String.format("%s[config=%s]",this.getClass().getName(),baseConfig);
return String.format("JsrCreator[%s%s]", (baseConfig instanceof AnnotatedServerEndpointConfig ? "@" : ""), baseConfig.getEndpointClass().getName());
}
}

View File

@ -35,7 +35,6 @@ import javax.websocket.server.ServerEndpointConfig;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.DecoratedObjectFactory;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -91,6 +90,7 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
* @return the created websocket server container
* @throws ServletException if unable to create the websocket server container
*/
@SuppressWarnings("Duplicates")
public static ServerContainer configureContext(ServletContextHandler context) throws ServletException
{
// Create Filter
@ -116,6 +116,7 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
* @return the created websocket server container
* @throws ServletException if unable to create the websocket server container
*/
@SuppressWarnings("Duplicates")
public static ServerContainer configureContext(ServletContext context, ServletContextHandler jettyContext) throws ServletException
{
// Create Filter
@ -209,14 +210,14 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
context.addListener(new ContextDestroyListener()); //make sure context is cleaned up when the context stops
// Establish the DecoratedObjectFactory thread local
// for various ServiceLoader initiated components to use.
DecoratedObjectFactory instantiator = (DecoratedObjectFactory)context.getAttribute(DecoratedObjectFactory.ATTR);
if (instantiator == null)
{
LOG.info("Using WebSocket local DecoratedObjectFactory - none found in ServletContext");
instantiator = new DecoratedObjectFactory();
}
// // Establish the DecoratedObjectFactory thread local
// // for various ServiceLoader initiated components to use.
// DecoratedObjectFactory instantiation = (DecoratedObjectFactory)context.getAttribute(DecoratedObjectFactory.ATTR);
// if (instantiation == null)
// {
// LOG.info("Using WebSocket local DecoratedObjectFactory - none found in ServletContext");
// instantiation = new DecoratedObjectFactory();
// }
if (LOG.isDebugEnabled())
{

View File

@ -1 +1 @@
org.eclipse.jetty.websocket.common.reflect.NameArgIdentifier
org.eclipse.jetty.websocket.jsr356.server.PathParamArgIdentifier

View File

@ -295,7 +295,7 @@ public class EchoTest
System.err.println(testcase);
}
@Test(timeout=2000)
@Test(timeout=10000)
public void testEcho() throws Exception
{
int messageCount = testcase.getMessageCount();
@ -306,7 +306,7 @@ public class EchoTest
{
// Connect
client.connectToServer(socket,toUri);
socket.waitForConnected(2,TimeUnit.SECONDS);
socket.waitForConnected(10,TimeUnit.SECONDS);
// Send Messages
for (Object msg : testcase.messages)

View File

@ -25,7 +25,7 @@ import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.websocket.jsr356.server.TrackingSocket;
@ServerEndpoint(value="/basic")
@ServerEndpoint(value="/echo/close/reason/session")
public class BasicCloseReasonSessionSocket extends TrackingSocket
{
@OnClose

View File

@ -24,7 +24,7 @@ import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.websocket.jsr356.server.TrackingSocket;
@ServerEndpoint(value="/basic")
@ServerEndpoint(value="/echo/close/reason")
public class BasicCloseReasonSocket extends TrackingSocket
{
@OnClose

View File

@ -25,7 +25,7 @@ import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.websocket.jsr356.server.TrackingSocket;
@ServerEndpoint(value="/basic")
@ServerEndpoint(value="/echo/close/session/reason")
public class BasicCloseSessionReasonSocket extends TrackingSocket
{
@OnClose

View File

@ -23,7 +23,7 @@ import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.websocket.jsr356.server.TrackingSocket;
@ServerEndpoint(value = "/basic")
@ServerEndpoint(value = "/echo/close")
public class BasicCloseSocket extends TrackingSocket
{
@OnClose

View File

@ -24,7 +24,7 @@ import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.websocket.jsr356.server.TrackingSocket;
@ServerEndpoint(value="/basic")
@ServerEndpoint(value="/echo/error/session")
public class BasicErrorSessionSocket extends TrackingSocket
{
@OnError

View File

@ -24,7 +24,7 @@ import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.websocket.jsr356.server.TrackingSocket;
@ServerEndpoint(value="/basic")
@ServerEndpoint(value="/echo/error/session/throwable")
public class BasicErrorSessionThrowableSocket extends TrackingSocket
{
@OnError

View File

@ -23,7 +23,7 @@ import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.websocket.jsr356.server.TrackingSocket;
@ServerEndpoint(value="/basic")
@ServerEndpoint(value="/echo/error")
public class BasicErrorSocket extends TrackingSocket
{
@OnError

View File

@ -24,7 +24,7 @@ import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.websocket.jsr356.server.TrackingSocket;
@ServerEndpoint(value="/basic")
@ServerEndpoint(value="/echo/error/throwable/session")
public class BasicErrorThrowableSessionSocket extends TrackingSocket
{
@OnError

View File

@ -23,7 +23,7 @@ import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.websocket.jsr356.server.TrackingSocket;
@ServerEndpoint(value="/basic")
@ServerEndpoint(value="/echo/error/throwable")
public class BasicErrorThrowableSocket extends TrackingSocket
{
@OnError

View File

@ -24,7 +24,7 @@ import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.websocket.jsr356.server.TrackingSocket;
@ServerEndpoint(value="/basic")
@ServerEndpoint(value="/echo/open/session")
public class BasicOpenSessionSocket extends TrackingSocket
{
@OnOpen

View File

@ -23,7 +23,7 @@ import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.websocket.jsr356.server.TrackingSocket;
@ServerEndpoint(value="/basic")
@ServerEndpoint(value="/echo/open")
public class BasicOpenSocket extends TrackingSocket
{
@OnOpen

View File

@ -24,7 +24,7 @@ import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.websocket.jsr356.server.TrackingSocket;
@ServerEndpoint(value="/basic")
@ServerEndpoint(value="/echo/pong")
public class BasicPongMessageSocket extends TrackingSocket
{
@OnMessage

View File

@ -664,8 +664,10 @@ public class CommonEndpointFunctions<T extends Session> extends AbstractLifeCycl
{
assertIsStarted();
// Always set session in endpoint functions
this.session = session;
// Call (optional) on open method
if (onOpenFunction != null)
onOpenFunction.apply(this.session);
}

View File

@ -48,6 +48,7 @@ import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
@ -142,6 +143,24 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
@Override
public void addMapping(PathSpec spec, WebSocketCreator creator)
{
WebSocketCreator existingCreator = pathmap.get(spec);
if (existingCreator != null)
{
if(existingCreator.equals(creator))
{
// Entry already exists, don't add it again.
return;
}
StringBuilder err = new StringBuilder();
err.append("Duplicate path mapping for \"");
err.append(spec.getDeclaration());
err.append("\" both ");
err.append(existingCreator);
err.append(" and ");
err.append(creator);
throw new InvalidWebSocketException(err.toString());
}
pathmap.put(spec,creator);
}