JSR-356 fixing EndpointConfig use with extends Endpoint

This commit is contained in:
Joakim Erdfelt 2013-04-26 09:30:02 -07:00
parent 7f1e4f764e
commit 092a91008c
12 changed files with 59 additions and 60 deletions

View File

@ -56,16 +56,22 @@ public class ClientContainer implements ContainerService
private Session connect(Object websocket, ClientEndpointConfig config, URI path) throws IOException
{
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(websocket,config);
ClientUpgradeRequest req = new ClientUpgradeRequest();
if (config != null)
ClientEndpointConfig cec = config;
if (cec == null)
{
for (Extension ext : config.getExtensions())
// Create default config
cec = ClientEndpointConfig.Builder.create().build();
}
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(websocket,cec);
ClientUpgradeRequest req = new ClientUpgradeRequest();
if (cec != null)
{
for (Extension ext : cec.getExtensions())
{
req.addExtensions(new JsrExtensionConfig(ext));
}
if (config.getPreferredSubprotocols().size() > 0)
if (cec.getPreferredSubprotocols().size() > 0)
{
req.setSubProtocols(config.getPreferredSubprotocols());
}
@ -100,8 +106,9 @@ public class ClientContainer implements ContainerService
{
try
{
JsrClientMetadata metadata = new JsrClientMetadata(this,annotatedEndpointClass);
Object websocket = annotatedEndpointClass.newInstance();
return connect(websocket,null,path);
return connect(websocket,metadata.getEndpointConfigCopy(),path);
}
catch (InstantiationException | IllegalAccessException e)
{

View File

@ -122,6 +122,7 @@ public class DecoderMetadataFactory
public List<DecoderMetadata> getMetadata(Class<? extends Decoder> decoder)
{
LOG.debug("getDecoder({})",decoder);
List<DecoderMetadata> ret = cache.get(decoder);
if (ret == null)

View File

@ -74,7 +74,14 @@ public class Decoders
{
for (Class<? extends Decoder> decoder : config.getDecoders())
{
addAllMetadata(decoder);
try
{
addAllMetadata(decoder);
}
catch (IllegalStateException e)
{
throw new DeploymentException("Invalid configuration: " + e.getMessage());
}
}
}
}
@ -133,6 +140,10 @@ public class Decoders
{
// try DEFAULT implementations
Class<? extends Decoder> defaultDecoder = DefaultsDecoderFactory.INSTANCE.getDecoder(type);
if (defaultDecoder == null)
{
throw new IllegalStateException("Unable to find decoder for type: " + type);
}
wrapper = addAllMetadata(defaultDecoder);
}

View File

@ -48,13 +48,8 @@ public class JsrClientEndpointImpl implements EventDriverImpl
{
ConfiguredEndpoint ce = (ConfiguredEndpoint)websocket;
endpoint = ce.getEndpoint();
// Classes annotated with @ClientEndpoint cannot be created with
// an external ClientEndpointConfig, this information MUST come
// from the @ClientEndpoint annotation.
if (ce.getConfig() != null)
{
throw new IllegalStateException("Cannot create @ClientEndpoint websocket with an external EndpointConfig");
}
// Classes annotated with @ClientEndpoint will have their ClientEndpointConfig
// built up from the information present in the annotations, any provided config will be ignored
}
Class<?> endpointClass = endpoint.getClass();

View File

@ -25,6 +25,8 @@ import java.util.Objects;
import javax.websocket.MessageHandler;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.jsr356.DecoderWrapper;
import org.eclipse.jetty.websocket.jsr356.Decoders;
import org.eclipse.jetty.websocket.jsr356.MessageType;
@ -34,6 +36,7 @@ import org.eclipse.jetty.websocket.jsr356.MessageType;
*/
public class MessageHandlerMetadataFactory
{
private static final Logger LOG = Log.getLogger(MessageHandlerMetadataFactory.class);
private final Decoders decoders;
public MessageHandlerMetadataFactory(Decoders decoders)
@ -43,10 +46,12 @@ public class MessageHandlerMetadataFactory
private Class<?> findOnMessageType(Class<? extends MessageHandler> handlerClass, int paramCount)
{
LOG.debug("findOnMessageType({}, {})",handlerClass,paramCount);
for (Method method : handlerClass.getMethods())
{
if ("onMessage".equals(method.getName()))
{
LOG.debug("found {}",method);
// make sure we only look for the onMessage method that is relevant
Class<?> paramTypes[] = method.getParameterTypes();
if (paramTypes == null)
@ -77,16 +82,22 @@ public class MessageHandlerMetadataFactory
boolean partial = false;
if (MessageHandler.Partial.class.isAssignableFrom(handler))
{
LOG.debug("supports Partial: {}",handler);
partial = true;
Class<?> onMessageClass = getOnMessagePartialType(handler);
LOG.debug("Partial message class: {}",onMessageClass);
MessageType onMessageType = identifyMessageType(onMessageClass);
LOG.debug("Partial message type: {}",onMessageType);
ret.add(new MessageHandlerMetadata(handler,onMessageType,onMessageClass,partial));
}
if (MessageHandler.Whole.class.isAssignableFrom(handler))
{
LOG.debug("supports Whole: {}",handler.getName());
partial = false;
Class<?> onMessageClass = getOnMessageType(handler);
LOG.debug("Whole message class: {}",onMessageClass);
MessageType onMessageType = identifyMessageType(onMessageClass);
LOG.debug("Whole message type: {}",onMessageType);
MessageHandlerMetadata metadata = new MessageHandlerMetadata(handler,onMessageType,onMessageClass,partial);
ret.add(metadata);
}

View File

@ -59,7 +59,7 @@ public class DecodersTest
}
catch (DeploymentException e)
{
Assert.assertThat("Error Message",e.getMessage(),containsString("Duplicate"));
Assert.assertThat("Error Message",e.getMessage(),containsString("duplicate"));
}
}

View File

@ -51,8 +51,8 @@ public class EndpointEchoClient extends Endpoint
{
LOG.debug("onOpen({}, {})",session,config);
this.session = session;
Assert.assertThat("Session",session,notNullValue());
Assert.assertThat("EndpointConfig",config,notNullValue());
Assert.assertThat("Session is required",session,notNullValue());
Assert.assertThat("EndpointConfig is required",config,notNullValue());
this.session.addMessageHandler(textCapture);
}

View File

@ -20,6 +20,8 @@ package org.eclipse.jetty.websocket.jsr356;
import static org.hamcrest.Matchers.*;
import java.nio.ByteBuffer;
import javax.websocket.DeploymentException;
import javax.websocket.MessageHandler;
@ -54,6 +56,7 @@ public class MessageHandlersTest
mhs.add(new ByteBufferPartialHandler());
MessageHandlerWrapper wrapper = mhs.getWrapper(MessageType.BINARY);
Assert.assertThat("Binary Handler",wrapper.getHandler(),instanceOf(ByteBufferPartialHandler.class));
Assert.assertEquals("Message Class",wrapper.getMetadata().getMessageClass(),ByteBuffer.class);
}
@Test
@ -64,8 +67,10 @@ public class MessageHandlersTest
mhs.add(new ByteArrayWholeHandler());
MessageHandlerWrapper wrapper = mhs.getWrapper(MessageType.TEXT);
Assert.assertThat("Text Handler",wrapper.getHandler(),instanceOf(StringWholeHandler.class));
Assert.assertEquals("Message Class",wrapper.getMetadata().getMessageClass(),String.class);
wrapper = mhs.getWrapper(MessageType.BINARY);
Assert.assertThat("Binary Handler",wrapper.getHandler(),instanceOf(ByteArrayWholeHandler.class));
Assert.assertEquals("Message Class",wrapper.getMetadata().getMessageClass(),byte[].class);
}
@Test
@ -75,6 +80,7 @@ public class MessageHandlersTest
mhs.add(new StringWholeHandler());
MessageHandlerWrapper wrapper = mhs.getWrapper(MessageType.TEXT);
Assert.assertThat("Text Handler",wrapper.getHandler(),instanceOf(StringWholeHandler.class));
Assert.assertEquals("Message Class",wrapper.getMetadata().getMessageClass(),String.class);
}
@Test
@ -88,7 +94,9 @@ public class MessageHandlersTest
mhs.add(new LongMessageHandler()); // add new TEXT handler
MessageHandlerWrapper wrapper = mhs.getWrapper(MessageType.BINARY);
Assert.assertThat("Binary Handler",wrapper.getHandler(),instanceOf(ByteArrayWholeHandler.class));
Assert.assertEquals("Message Class",wrapper.getMetadata().getMessageClass(),byte[].class);
wrapper = mhs.getWrapper(MessageType.TEXT);
Assert.assertThat("Text Handler",wrapper.getHandler(),instanceOf(LongMessageHandler.class));
Assert.assertEquals("Message Class",wrapper.getMetadata().getMessageClass(),Long.class);
}
}

View File

@ -62,14 +62,14 @@ public class BasicEndpointTest
WebAppContext webapp = wsb.createWebAppContext();
wsb.deployWebapp(webapp);
wsb.dump();
// wsb.dump();
WebSocketClient client = new WebSocketClient();
try
{
client.start();
JettyEchoSocket clientEcho = new JettyEchoSocket();
Future<Session> future = client.connect(clientEcho,uri.resolve("/echo"));
Future<Session> future = client.connect(clientEcho,uri.resolve("echo"));
// wait for connect
future.get(1,TimeUnit.SECONDS);
clientEcho.sendMessage("Hello World");

View File

@ -1,37 +0,0 @@
//
// ========================================================================
// 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 static org.hamcrest.Matchers.*;
import javax.websocket.ContainerProvider;
import javax.websocket.WebSocketContainer;
import org.junit.Assert;
import org.junit.Test;
public class ServerContainerTest
{
@Test
public void testServiceLoader()
{
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
Assert.assertThat(container,instanceOf(ServerContainer.class));
}
}

View File

@ -22,6 +22,7 @@ import static org.hamcrest.Matchers.*;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
@ -39,6 +40,7 @@ import org.eclipse.jetty.toolchain.test.OS;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.FragmentConfiguration;
import org.eclipse.jetty.webapp.MetaInfConfiguration;
@ -101,11 +103,11 @@ public class WSServer
IO.copy(testWebXml,webxml);
}
public WebAppContext createWebAppContext()
public WebAppContext createWebAppContext() throws MalformedURLException, IOException
{
WebAppContext context = new WebAppContext();
context.setContextPath(this.contextPath);
context.setWar(this.contextDir.getAbsolutePath());
context.setBaseResource(Resource.newResource(this.contextDir));
// @formatter:off
context.setConfigurations(new Configuration[] {

View File

@ -20,12 +20,13 @@ package org.eclipse.jetty.websocket.jsr356.server.samples.echo;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.Endpoint;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpointConfig;
import org.eclipse.jetty.websocket.jsr356.server.WebSocketConfiguration;
/**
* Example of adding a server WebSocket (extending {@link Endpoint}) programmatically via config
*/
@ -40,7 +41,7 @@ public class BasicEchoEndpointConfigContextListener implements ServletContextLis
@Override
public void contextInitialized(ServletContextEvent sce)
{
ServerContainer container = (ServerContainer)ContainerProvider.getWebSocketContainer();
ServerContainer container = (ServerContainer)sce.getServletContext().getAttribute(WebSocketConfiguration.JAVAX_WEBSOCKET_SERVER_CONTAINER);
// Build up a configuration with a specific path
String path = "/echo";
ServerEndpointConfig.Builder builder = ServerEndpointConfig.Builder.create(BasicEchoEndpoint.class,path);