416763 - WebSocket / Jsr Session.getPathParameters() is empty

+ Adding support for `extends Endpoint` based endpoints as well
This commit is contained in:
Joakim Erdfelt 2013-09-06 14:35:22 -07:00
parent fe4a778334
commit ed0f49f819
10 changed files with 263 additions and 22 deletions

View File

@ -89,7 +89,7 @@ public class JsrEvents<T extends Annotation, C extends EndpointConfig>
/**
* The Request Parameters (from resolved javax.websocket.server.PathParam entries)
*/
private Map<String, String> requestParameters;
private Map<String, String> pathParameters;
public JsrEvents(AnnotatedEndpointMetadata<T, C> metadata)
{
@ -231,7 +231,7 @@ public class JsrEvents<T extends Annotation, C extends EndpointConfig>
public void init(JsrSession session)
{
session.setPathParameters(requestParameters);
session.setPathParameters(pathParameters);
if (onOpen != null)
{
@ -285,8 +285,8 @@ public class JsrEvents<T extends Annotation, C extends EndpointConfig>
return onText.isPartialMessageSupported();
}
public void setRequestParameters(Map<String, String> requestParameters)
public void setPathParameters(Map<String, String> pathParameters)
{
this.requestParameters = requestParameters;
this.pathParameters = pathParameters;
}
}

View File

@ -18,6 +18,8 @@
package org.eclipse.jetty.websocket.jsr356.endpoints;
import java.util.Map;
import javax.websocket.CloseReason;
import javax.websocket.CloseReason.CloseCode;
import javax.websocket.CloseReason.CloseCodes;
@ -62,9 +64,7 @@ public abstract class AbstractJsrEventDriver extends AbstractEventDriver impleme
return metadata;
}
protected void init(JsrSession jsrsession)
{
}
public abstract void init(JsrSession jsrsession);
@Override
public final void onClose(CloseInfo close)
@ -110,4 +110,6 @@ public abstract class AbstractJsrEventDriver extends AbstractEventDriver impleme
throw new RuntimeException("Why are you reconfiguring the endpoint?");
// this.config = endpointconfig;
}
public abstract void setPathParameters(Map<String, String> pathParameters);
}

View File

@ -58,7 +58,7 @@ public class JsrAnnotatedEventDriver extends AbstractJsrEventDriver implements E
}
@Override
protected void init(JsrSession jsrsession)
public void init(JsrSession jsrsession)
{
this.events.init(jsrsession);
}
@ -349,9 +349,10 @@ public class JsrAnnotatedEventDriver extends AbstractJsrEventDriver implements E
}
}
public void setRequestParameters(Map<String, String> requestParameters)
@Override
public void setPathParameters(Map<String, String> pathParameters)
{
events.setRequestParameters(requestParameters);
events.setPathParameters(pathParameters);
}
@Override

View File

@ -22,6 +22,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.ByteBuffer;
import java.util.Map;
import javax.websocket.CloseReason;
import javax.websocket.Endpoint;
@ -35,6 +36,7 @@ import org.eclipse.jetty.websocket.api.extensions.Frame;
import org.eclipse.jetty.websocket.common.events.EventDriver;
import org.eclipse.jetty.websocket.common.message.MessageInputStream;
import org.eclipse.jetty.websocket.common.message.MessageReader;
import org.eclipse.jetty.websocket.jsr356.JsrSession;
import org.eclipse.jetty.websocket.jsr356.MessageHandlerWrapper;
import org.eclipse.jetty.websocket.jsr356.MessageType;
import org.eclipse.jetty.websocket.jsr356.messages.BinaryPartialMessage;
@ -50,6 +52,7 @@ public class JsrEndpointEventDriver extends AbstractJsrEventDriver implements Ev
private static final Logger LOG = Log.getLogger(JsrEndpointEventDriver.class);
private final Endpoint endpoint;
private Map<String, String> pathParameters;
public JsrEndpointEventDriver(WebSocketPolicy policy, EndpointInstance endpointInstance)
{
@ -57,6 +60,12 @@ public class JsrEndpointEventDriver extends AbstractJsrEventDriver implements Ev
this.endpoint = (Endpoint)endpointInstance.getEndpoint();
}
@Override
public void init(JsrSession jsrsession)
{
jsrsession.setPathParameters(pathParameters);
}
@Override
public void onBinaryFrame(ByteBuffer buffer, boolean fin) throws IOException
{
@ -204,6 +213,12 @@ public class JsrEndpointEventDriver extends AbstractJsrEventDriver implements Ev
/* Ignored, handled by TextWholeMessage */
}
@Override
public void setPathParameters(Map<String, String> pathParameters)
{
this.pathParameters = pathParameters;
}
@Override
public String toString()
{

View File

@ -50,7 +50,7 @@ public class JsrServerEndpointImpl implements EventDriverImpl
if (config instanceof PathParamServerEndpointConfig)
{
PathParamServerEndpointConfig ppconfig = (PathParamServerEndpointConfig)config;
driver.setRequestParameters(ppconfig.getPathParamMap());
driver.setPathParameters(ppconfig.getPathParamMap());
}
return driver;

View File

@ -0,0 +1,71 @@
//
// ========================================================================
// Copyright (c) 1995-2013 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.jsr356.server;
import javax.websocket.server.ServerEndpointConfig;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.common.events.EventDriver;
import org.eclipse.jetty.websocket.common.events.EventDriverImpl;
import org.eclipse.jetty.websocket.jsr356.endpoints.EndpointInstance;
import org.eclipse.jetty.websocket.jsr356.endpoints.JsrEndpointEventDriver;
public class JsrServerExtendsEndpointImpl implements EventDriverImpl
{
@Override
public EventDriver create(Object websocket, WebSocketPolicy policy)
{
if (!(websocket instanceof EndpointInstance))
{
throw new IllegalStateException(String.format("Websocket %s must be an %s",websocket.getClass().getName(),EndpointInstance.class.getName()));
}
EndpointInstance ei = (EndpointInstance)websocket;
JsrEndpointEventDriver driver = new JsrEndpointEventDriver(policy, ei);
ServerEndpointConfig config = (ServerEndpointConfig)ei.getConfig();
if (config instanceof PathParamServerEndpointConfig)
{
PathParamServerEndpointConfig ppconfig = (PathParamServerEndpointConfig)config;
driver.setPathParameters(ppconfig.getPathParamMap());
}
return driver;
}
@Override
public String describeRule()
{
return "class extends " + javax.websocket.Endpoint.class.getName();
}
@Override
public boolean supports(Object websocket)
{
if (!(websocket instanceof EndpointInstance))
{
return false;
}
EndpointInstance ei = (EndpointInstance)websocket;
Object endpoint = ei.getEndpoint();
return (endpoint instanceof javax.websocket.Endpoint);
}
}

View File

@ -30,7 +30,6 @@ import org.eclipse.jetty.websocket.jsr356.ClientContainer;
import org.eclipse.jetty.websocket.jsr356.JsrSessionFactory;
import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner;
import org.eclipse.jetty.websocket.jsr356.endpoints.EndpointInstance;
import org.eclipse.jetty.websocket.jsr356.endpoints.JsrEndpointImpl;
import org.eclipse.jetty.websocket.jsr356.metadata.EndpointMetadata;
import org.eclipse.jetty.websocket.jsr356.server.pathmap.WebSocketPathSpec;
import org.eclipse.jetty.websocket.server.MappedWebSocketCreator;
@ -50,7 +49,7 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
this.webSocketServerFactory = factory;
EventDriverFactory eventDriverFactory = this.webSocketServerFactory.getEventDriverFactory();
eventDriverFactory.addImplementation(new JsrServerEndpointImpl());
eventDriverFactory.addImplementation(new JsrEndpointImpl());
eventDriverFactory.addImplementation(new JsrServerExtendsEndpointImpl());
this.webSocketServerFactory.addSessionFactory(new JsrSessionFactory(this));
}

View File

@ -36,6 +36,12 @@ public class SessionAltConfig implements ServerApplicationConfig
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/info/{a}/{b}/").build());
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/info/{a}/{b}/{c}/").build());
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/info/{a}/{b}/{c}/{d}/").build());
endpointClass = SessionInfoEndpoint.class;
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/einfo/").build());
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/einfo/{a}/").build());
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/einfo/{a}/{b}/").build());
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/einfo/{a}/{b}/{c}/").build());
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/einfo/{a}/{b}/{c}/{d}/").build());
return configs;
}

View File

@ -0,0 +1,102 @@
//
// ========================================================================
// Copyright (c) 1995-2013 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.jsr356.server;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.Session;
public class SessionInfoEndpoint extends Endpoint implements MessageHandler.Whole<String>
{
private Session session;
@Override
public void onOpen(Session session, EndpointConfig config)
{
this.session = session;
this.session.addMessageHandler(this);
}
@Override
public void onMessage(String message)
{
try
{
if ("pathParams".equalsIgnoreCase(message))
{
StringBuilder ret = new StringBuilder();
ret.append("pathParams");
Map<String, String> pathParams = session.getPathParameters();
if (pathParams == null)
{
ret.append("=<null>");
}
else
{
ret.append('[').append(pathParams.size()).append(']');
List<String> keys = new ArrayList<>();
for (String key : pathParams.keySet())
{
keys.add(key);
}
Collections.sort(keys);
for (String key : keys)
{
String value = pathParams.get(key);
ret.append(": '").append(key).append("'=").append(value);
}
}
session.getBasicRemote().sendText(ret.toString());
return;
}
if ("requestUri".equalsIgnoreCase(message))
{
StringBuilder ret = new StringBuilder();
ret.append("requestUri=");
URI uri = session.getRequestURI();
if (uri == null)
{
ret.append("=<null>");
}
else
{
ret.append(uri.toASCIIString());
}
session.getBasicRemote().sendText(ret.toString());
return;
}
// simple echo
session.getBasicRemote().sendText("echo:'" + message + "'");
}
catch (IOException e)
{
e.printStackTrace(System.err);
}
}
}

View File

@ -80,47 +80,92 @@ public class SessionTest
}
@Test
public void testPathParams_Empty() throws Exception
public void testPathParams_Annotated_Empty() throws Exception
{
assertResponse("info/","pathParams","pathParams[0]");
}
@Test
public void testPathParams_Single() throws Exception
public void testPathParams_Annotated_Single() throws Exception
{
assertResponse("info/apple/","pathParams","pathParams[1]: 'a'=apple");
}
@Test
public void testPathParams_Double() throws Exception
public void testPathParams_Annotated_Double() throws Exception
{
assertResponse("info/apple/pear/","pathParams","pathParams[2]: 'a'=apple: 'b'=pear");
}
@Test
public void testPathParams_Triple() throws Exception
public void testPathParams_Annotated_Triple() throws Exception
{
assertResponse("info/apple/pear/cherry/","pathParams","pathParams[3]: 'a'=apple: 'b'=pear: 'c'=cherry");
}
@Test
public void testRequestUri_Basic() throws Exception
public void testPathParams_Endpoint_Empty() throws Exception
{
assertResponse("einfo/","pathParams","pathParams[0]");
}
@Test
public void testPathParams_Endpoint_Single() throws Exception
{
assertResponse("einfo/apple/","pathParams","pathParams[1]: 'a'=apple");
}
@Test
public void testPathParams_Endpoint_Double() throws Exception
{
assertResponse("einfo/apple/pear/","pathParams","pathParams[2]: 'a'=apple: 'b'=pear");
}
@Test
public void testPathParams_Endpoint_Triple() throws Exception
{
assertResponse("einfo/apple/pear/cherry/","pathParams","pathParams[3]: 'a'=apple: 'b'=pear: 'c'=cherry");
}
@Test
public void testRequestUri_Annotated_Basic() throws Exception
{
URI expectedUri = serverUri.resolve("info/");
assertResponse("info/","requestUri","requestUri=" + expectedUri.toASCIIString());
}
@Test
public void testRequestUri_WithPathParam() throws Exception
public void testRequestUri_Annotated_WithPathParam() throws Exception
{
URI expectedUri = serverUri.resolve("info/apple/banana/");
assertResponse("info/apple/banana/","requestUri","requestUri=" + expectedUri.toASCIIString());
}
@Test
public void testRequestUri_WithPathParam_WithQuery() throws Exception
public void testRequestUri_Annotated_WithPathParam_WithQuery() throws Exception
{
URI expectedUri = serverUri.resolve("info/apple/banana/?fruit=fresh&store=grandmasfarm");
assertResponse("info/apple/banana/?fruit=fresh&store=grandmasfarm","requestUri","requestUri=" + expectedUri.toASCIIString());
}
@Test
public void testRequestUri_Endpoint_Basic() throws Exception
{
URI expectedUri = serverUri.resolve("einfo/");
assertResponse("einfo/","requestUri","requestUri=" + expectedUri.toASCIIString());
}
@Test
public void testRequestUri_Endpoint_WithPathParam() throws Exception
{
URI expectedUri = serverUri.resolve("einfo/apple/banana/");
assertResponse("einfo/apple/banana/","requestUri","requestUri=" + expectedUri.toASCIIString());
}
@Test
public void testRequestUri_Endpoint_WithPathParam_WithQuery() throws Exception
{
URI expectedUri = serverUri.resolve("einfo/apple/banana/?fruit=fresh&store=grandmasfarm");
assertResponse("einfo/apple/banana/?fruit=fresh&store=grandmasfarm","requestUri","requestUri=" + expectedUri.toASCIIString());
}
}