Issue #207 - Support javax.websocket version 1.1
+ Removing more EventDriver references + Fixing bad implementation exposed by testcases
This commit is contained in:
parent
1d341398da
commit
1cf61d6df7
|
@ -222,6 +222,7 @@ public class ConfigurationAssert
|
|||
|
||||
}
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
public static void assertOrdered(String msg, List<String> expectedList, List<String> actualList)
|
||||
{
|
||||
try
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.net.URI;
|
|||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
@ -53,10 +54,14 @@ import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
|||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||
import org.eclipse.jetty.websocket.client.io.UpgradeListener;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.function.EndpointFunctions;
|
||||
import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||
import org.eclipse.jetty.websocket.jsr356.client.AnnotatedClientEndpointConfig;
|
||||
import org.eclipse.jetty.websocket.jsr356.client.EmptyClientEndpointConfig;
|
||||
import org.eclipse.jetty.websocket.jsr356.decoders.AvailableDecoders;
|
||||
import org.eclipse.jetty.websocket.jsr356.encoders.AvailableEncoders;
|
||||
import org.eclipse.jetty.websocket.jsr356.function.JsrEndpointFunctions;
|
||||
|
||||
/**
|
||||
* Container for Client use of the javax.websocket API.
|
||||
|
@ -95,6 +100,21 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
|||
ShutdownThread.register(this);
|
||||
}
|
||||
|
||||
public EndpointFunctions newJsrEndpointFunction(Object endpoint,
|
||||
AvailableEncoders availableEncoders,
|
||||
AvailableDecoders availableDecoders,
|
||||
Map<String, String> pathParameters,
|
||||
EndpointConfig config)
|
||||
{
|
||||
return new JsrEndpointFunctions(endpoint,
|
||||
getPolicy(),
|
||||
getExecutor(),
|
||||
availableEncoders,
|
||||
availableDecoders,
|
||||
pathParameters,
|
||||
config);
|
||||
}
|
||||
|
||||
private Session connect(ConfiguredEndpoint instance, URI path) throws IOException
|
||||
{
|
||||
Objects.requireNonNull(instance, "EndpointInstance cannot be null");
|
||||
|
|
|
@ -96,9 +96,9 @@ public class JsrSession extends WebSocketSession implements javax.websocket.Sess
|
|||
@Override
|
||||
public EndpointFunctions newEndpointFunctions(Object endpoint)
|
||||
{
|
||||
return new JsrEndpointFunctions(endpoint,
|
||||
getPolicy(),
|
||||
getExecutor(),
|
||||
// Delegate to container to obtain correct version of JsrEndpointFunctions
|
||||
// Could be a Client version, or a Server version
|
||||
return container.newJsrEndpointFunction(endpoint,
|
||||
availableEncoders,
|
||||
availableDecoders,
|
||||
pathParameters,
|
||||
|
|
|
@ -85,6 +85,7 @@ public class AvailableDecoders implements Predicate<Class<?>>
|
|||
registerPrimitive(CharacterDecoder.class, Decoder.Text.class, Character.class);
|
||||
registerPrimitive(DoubleDecoder.class, Decoder.Text.class, Double.class);
|
||||
registerPrimitive(FloatDecoder.class, Decoder.Text.class, Float.class);
|
||||
registerPrimitive(ShortDecoder.class, Decoder.Text.class, Short.class);
|
||||
registerPrimitive(IntegerDecoder.class, Decoder.Text.class, Integer.class);
|
||||
registerPrimitive(LongDecoder.class, Decoder.Text.class, Long.class);
|
||||
registerPrimitive(StringDecoder.class, Decoder.Text.class, String.class);
|
||||
|
@ -95,6 +96,7 @@ public class AvailableDecoders implements Predicate<Class<?>>
|
|||
registerPrimitive(CharacterDecoder.class, Decoder.Text.class, Character.TYPE);
|
||||
registerPrimitive(DoubleDecoder.class, Decoder.Text.class, Double.TYPE);
|
||||
registerPrimitive(FloatDecoder.class, Decoder.Text.class, Float.TYPE);
|
||||
registerPrimitive(ShortDecoder.class, Decoder.Text.class, Short.TYPE);
|
||||
registerPrimitive(IntegerDecoder.class, Decoder.Text.class, Integer.TYPE);
|
||||
registerPrimitive(LongDecoder.class, Decoder.Text.class, Long.TYPE);
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ public class AvailableEncoders implements Predicate<Class<?>>
|
|||
registerPrimitive(CharacterEncoder.class, Encoder.Text.class, Character.class);
|
||||
registerPrimitive(DoubleEncoder.class, Encoder.Text.class, Double.class);
|
||||
registerPrimitive(FloatEncoder.class, Encoder.Text.class, Float.class);
|
||||
registerPrimitive(ShortEncoder.class, Encoder.Text.class, Short.class);
|
||||
registerPrimitive(IntegerEncoder.class, Encoder.Text.class, Integer.class);
|
||||
registerPrimitive(LongEncoder.class, Encoder.Text.class, Long.class);
|
||||
registerPrimitive(StringEncoder.class, Encoder.Text.class, String.class);
|
||||
|
@ -93,6 +94,7 @@ public class AvailableEncoders implements Predicate<Class<?>>
|
|||
registerPrimitive(CharacterEncoder.class, Encoder.Text.class, Character.TYPE);
|
||||
registerPrimitive(DoubleEncoder.class, Encoder.Text.class, Double.TYPE);
|
||||
registerPrimitive(FloatEncoder.class, Encoder.Text.class, Float.TYPE);
|
||||
registerPrimitive(ShortEncoder.class, Encoder.Text.class, Short.TYPE);
|
||||
registerPrimitive(IntegerEncoder.class, Encoder.Text.class, Integer.TYPE);
|
||||
registerPrimitive(LongEncoder.class, Encoder.Text.class, Long.TYPE);
|
||||
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.endpoints;
|
||||
|
||||
@Deprecated
|
||||
public abstract class AbstractJsrEventDriver /*extends AbstractEventDriver*/
|
||||
{
|
||||
/* protected final EndpointMetadata metadata;
|
||||
protected final Executor executor;
|
||||
protected final EndpointConfig config;
|
||||
protected JsrSession jsrsession;
|
||||
private boolean hasCloseBeenCalled = false;
|
||||
|
||||
public AbstractJsrEventDriver(WebSocketPolicy policy, ConfiguredEndpoint endpointInstance, Executor executor)
|
||||
{
|
||||
super(policy,endpointInstance.getEndpoint());
|
||||
this.config = endpointInstance.getConfig();
|
||||
this.metadata = endpointInstance.getMetadata();
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
public EndpointConfig getConfig()
|
||||
{
|
||||
return config;
|
||||
}
|
||||
|
||||
public Session getJsrSession()
|
||||
{
|
||||
return this.jsrsession;
|
||||
}
|
||||
|
||||
public EndpointMetadata getMetadata()
|
||||
{
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public abstract void init(JsrSession jsrsession);
|
||||
|
||||
@Override
|
||||
public final void onClose(CloseInfo close)
|
||||
{
|
||||
if (hasCloseBeenCalled)
|
||||
{
|
||||
// avoid duplicate close events (possible when using harsh Session.disconnect())
|
||||
return;
|
||||
}
|
||||
hasCloseBeenCalled = true;
|
||||
|
||||
CloseCode closecode = CloseCodes.getCloseCode(close.getStatusCode());
|
||||
CloseReason closereason = new CloseReason(closecode,close.getReason());
|
||||
onClose(closereason);
|
||||
}
|
||||
|
||||
protected abstract void onClose(CloseReason closereason);
|
||||
|
||||
@Override
|
||||
public void onFrame(Frame frame)
|
||||
{
|
||||
*//* Ignored, not supported by JSR-356 *//*
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void openSession(WebSocketSession session)
|
||||
{
|
||||
// Cast should be safe, as it was created by JsrSessionFactory
|
||||
this.jsrsession = (JsrSession)session;
|
||||
|
||||
// Allow jsr session to init
|
||||
this.jsrsession.init(config);
|
||||
|
||||
// Allow event driver to init itself
|
||||
init(jsrsession);
|
||||
|
||||
// Allow end-user socket to adjust configuration
|
||||
super.openSession(session);
|
||||
}
|
||||
|
||||
public void setEndpointconfig(EndpointConfig endpointconfig)
|
||||
{
|
||||
throw new RuntimeException("Why are you reconfiguring the endpoint?");
|
||||
// this.config = endpointconfig;
|
||||
}
|
||||
|
||||
public abstract void setPathParameters(Map<String, String> pathParameters);
|
||||
|
||||
public void dispatch(Runnable runnable)
|
||||
{
|
||||
executor.execute(runnable);
|
||||
}*/
|
||||
}
|
|
@ -1,382 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.endpoints;
|
||||
|
||||
import javax.websocket.MessageHandler.Whole;
|
||||
|
||||
/**
|
||||
* Base implementation for JSR-356 Annotated event drivers.
|
||||
*/
|
||||
@Deprecated
|
||||
public class JsrAnnotatedEventDriver /*extends AbstractJsrEventDriver*/
|
||||
{
|
||||
/* private static final Logger LOG = Log.getLogger(JsrAnnotatedEventDriver.class);
|
||||
private final JsrEvents<?, ?> events;
|
||||
|
||||
public JsrAnnotatedEventDriver(WebSocketPolicy policy, ConfiguredEndpoint endpointInstance, JsrEvents<?, ?> events, Executor executor)
|
||||
{
|
||||
super(policy,endpointInstance,executor);
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(JsrSession jsrsession)
|
||||
{
|
||||
this.events.init(jsrsession);
|
||||
}
|
||||
|
||||
*//**
|
||||
* Entry point for all incoming binary frames.
|
||||
*//*
|
||||
@Override
|
||||
public void onBinaryFrame(ByteBuffer buffer, boolean fin) throws IOException
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("onBinaryFrame({}, {})",BufferUtil.toDetailString(buffer),fin);
|
||||
LOG.debug("events.onBinary={}",events.hasBinary());
|
||||
LOG.debug("events.onBinaryStream={}",events.hasBinaryStream());
|
||||
}
|
||||
boolean handled = false;
|
||||
|
||||
if (events.hasBinary())
|
||||
{
|
||||
handled = true;
|
||||
if (activeMessage == null)
|
||||
{
|
||||
if (events.isBinaryPartialSupported())
|
||||
{
|
||||
// Partial Message Support (does not use messageAppender)
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Partial Binary Message: fin={}",fin);
|
||||
}
|
||||
activeMessage = new BinaryPartialOnMessage(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Whole Message Support
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Whole Binary Message");
|
||||
}
|
||||
activeMessage = new ByteArrayMessageSink(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (events.hasBinaryStream())
|
||||
{
|
||||
handled = true;
|
||||
// Streaming Message Support
|
||||
if (activeMessage == null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Binary Message InputStream");
|
||||
}
|
||||
final MessageInputStream stream = new MessageInputStream();
|
||||
activeMessage = stream;
|
||||
|
||||
// Always dispatch streaming read to another thread.
|
||||
dispatch(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
events.callBinaryStream(jsrsession.getAsyncRemote(),websocket,stream);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
onFatalError(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("handled = {}",handled);
|
||||
}
|
||||
|
||||
// Process any active MessageAppender
|
||||
if (handled && (activeMessage != null))
|
||||
{
|
||||
appendMessage(buffer,fin);
|
||||
}
|
||||
}
|
||||
|
||||
*//**
|
||||
* Entry point for binary frames destined for {@link Whole}
|
||||
*//*
|
||||
@Override
|
||||
public void onBinaryMessage(byte[] data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ByteBuffer buf = ByteBuffer.wrap(data);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("onBinaryMessage({})",BufferUtil.toDetailString(buf));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// FIN is always true here
|
||||
events.callBinary(jsrsession.getAsyncRemote(),websocket,buf,true);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
onFatalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onObject(Object obj)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClose(CloseReason closereason)
|
||||
{
|
||||
events.callClose(websocket,closereason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnect()
|
||||
{
|
||||
events.callOpen(websocket,config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable cause)
|
||||
{
|
||||
try
|
||||
{
|
||||
events.callError(websocket,cause);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
LOG.warn("Unable to call onError with cause", cause);
|
||||
LOG.warn("Call to onError resulted in exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void onFatalError(Throwable t)
|
||||
{
|
||||
onError(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFrame(Frame frame)
|
||||
{
|
||||
*//* Ignored in JSR-356 *//*
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputStream(InputStream stream) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
events.callBinaryStream(jsrsession.getAsyncRemote(),websocket,stream);
|
||||
}
|
||||
catch (DecodeException e)
|
||||
{
|
||||
throw new RuntimeException("Unable decode input stream", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void onPartialBinaryMessage(ByteBuffer buffer, boolean fin)
|
||||
{
|
||||
try
|
||||
{
|
||||
events.callBinary(jsrsession.getAsyncRemote(),websocket,buffer,fin);
|
||||
}
|
||||
catch (DecodeException e)
|
||||
{
|
||||
throw new RuntimeException("Unable decode partial binary message", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void onPartialTextMessage(String message, boolean fin)
|
||||
{
|
||||
try
|
||||
{
|
||||
events.callText(jsrsession.getAsyncRemote(),websocket,message,fin);
|
||||
}
|
||||
catch (DecodeException e)
|
||||
{
|
||||
throw new RuntimeException("Unable decode partial text message", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPing(ByteBuffer buffer)
|
||||
{
|
||||
// Call pong, as there is no "onPing" method in the JSR
|
||||
events.callPong(jsrsession.getAsyncRemote(),websocket,buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPong(ByteBuffer buffer)
|
||||
{
|
||||
events.callPong(jsrsession.getAsyncRemote(),websocket,buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReader(Reader reader) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
events.callTextStream(jsrsession.getAsyncRemote(),websocket,reader);
|
||||
}
|
||||
catch (DecodeException e)
|
||||
{
|
||||
throw new RuntimeException("Unable decode reader", e);
|
||||
}
|
||||
}
|
||||
|
||||
*//**
|
||||
* Entry point for all incoming text frames.
|
||||
*//*
|
||||
@Override
|
||||
public void onTextFrame(ByteBuffer buffer, boolean fin) throws IOException
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("onTextFrame({}, {})",BufferUtil.toDetailString(buffer),fin);
|
||||
LOG.debug("events.hasText={}",events.hasText());
|
||||
LOG.debug("events.hasTextStream={}",events.hasTextStream());
|
||||
}
|
||||
|
||||
boolean handled = false;
|
||||
|
||||
if (events.hasText())
|
||||
{
|
||||
handled = true;
|
||||
if (activeMessage == null)
|
||||
{
|
||||
if (events.isTextPartialSupported())
|
||||
{
|
||||
// Partial Message Support
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Partial Text Message: fin={}",fin);
|
||||
}
|
||||
activeMessage = new TextPartialOnMessage(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Whole Message Support
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Whole Text Message");
|
||||
}
|
||||
activeMessage = new StringMessageSink(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (events.hasTextStream())
|
||||
{
|
||||
handled = true;
|
||||
// Streaming Message Support
|
||||
if (activeMessage == null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Text Message Writer");
|
||||
}
|
||||
|
||||
final MessageReader stream = new MessageReader(new MessageInputStream());
|
||||
activeMessage = stream;
|
||||
|
||||
// Always dispatch streaming read to another thread.
|
||||
dispatch(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
events.callTextStream(jsrsession.getAsyncRemote(),websocket,stream);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
onFatalError(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("handled = {}", handled);
|
||||
}
|
||||
|
||||
// Process any active MessageAppender
|
||||
if (handled && (activeMessage != null))
|
||||
{
|
||||
appendMessage(buffer,fin);
|
||||
}
|
||||
}
|
||||
|
||||
*//**
|
||||
* Entry point for whole text messages
|
||||
*//*
|
||||
@Override
|
||||
public void onTextMessage(String message)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("onText({})",message);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// FIN is always true here
|
||||
events.callText(jsrsession.getAsyncRemote(),websocket,message,true);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
onFatalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPathParameters(Map<String, String> pathParameters)
|
||||
{
|
||||
events.setPathParameters(pathParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s[websocket=%s]",this.getClass().getSimpleName(),websocket);
|
||||
}*/
|
||||
}
|
|
@ -1,270 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.endpoints;
|
||||
|
||||
/**
|
||||
* EventDriver for websocket that extend from {@link javax.websocket.Endpoint}
|
||||
*/
|
||||
@Deprecated
|
||||
public class JsrEndpointEventDriver extends AbstractJsrEventDriver
|
||||
{
|
||||
/*private static final Logger LOG = Log.getLogger(JsrEndpointEventDriver.class);
|
||||
|
||||
private final Endpoint endpoint;
|
||||
private Map<String, String> pathParameters;
|
||||
|
||||
public JsrEndpointEventDriver(WebSocketPolicy policy, Executor executor, ConfiguredEndpoint endpointInstance)
|
||||
{
|
||||
super(policy,executor,endpointInstance);
|
||||
this.endpoint = (Endpoint)endpointInstance.getEndpoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(JsrSession jsrsession)
|
||||
{
|
||||
jsrsession.setPathParameters(pathParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBinaryFrame(ByteBuffer buffer, boolean fin) throws IOException
|
||||
{
|
||||
if (activeMessage == null)
|
||||
{
|
||||
activeMessage = jsrsession.newMessageAppenderFor(MessageType.BINARY);
|
||||
if (activeMessage == null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("No BINARY MessageHandler declared");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
*//*
|
||||
if (wrapper.wantsPartialMessages())
|
||||
{
|
||||
activeMessage = new BinaryPartialMessage(wrapper);
|
||||
}
|
||||
else if (wrapper.wantsStreams())
|
||||
{
|
||||
final MessageInputStream stream = new MessageInputStream();
|
||||
activeMessage = stream;
|
||||
dispatch(new Runnable()
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
MessageHandler.Whole<InputStream> handler = (Whole<InputStream>)wrapper.getHandler();
|
||||
handler.onMessage(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
activeMessage = new BinaryWholeMessage(this,wrapper);
|
||||
}
|
||||
*//*
|
||||
}
|
||||
|
||||
activeMessage.appendFrame(buffer,fin);
|
||||
|
||||
if (fin)
|
||||
{
|
||||
activeMessage.messageComplete();
|
||||
activeMessage = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBinaryMessage(byte[] data)
|
||||
{
|
||||
*//* Ignored, handled by BinaryWholeMessage *//*
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onObject(Object o)
|
||||
{
|
||||
// TODO: deliver to message handler
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClose(CloseReason closereason)
|
||||
{
|
||||
endpoint.onClose(this.jsrsession,closereason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnect()
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("onConnect({}, {})",jsrsession,config);
|
||||
}
|
||||
|
||||
// Let unhandled exceptions flow out
|
||||
endpoint.onOpen(jsrsession,config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable cause)
|
||||
{
|
||||
try
|
||||
{
|
||||
endpoint.onError(jsrsession,cause);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOG.warn("Unable to report to onError due to exception",t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFrame(Frame frame)
|
||||
{
|
||||
*//* Ignored, not supported by JSR-356 *//*
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputStream(InputStream stream)
|
||||
{
|
||||
*//* Ignored, handled by BinaryStreamMessage *//*
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReader(Reader reader)
|
||||
{
|
||||
*//* Ignored, handled by TextStreamMessage *//*
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextFrame(ByteBuffer buffer, boolean fin) throws IOException
|
||||
{
|
||||
if (activeMessage == null)
|
||||
{
|
||||
activeMessage = jsrsession.newMessageAppenderFor(MessageType.TEXT);
|
||||
if (activeMessage == null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("No TEXT MessageHandler declared");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// if (wrapper.wantsPartialMessages())
|
||||
// {
|
||||
// activeMessage = new TextPartialMessage(wrapper);
|
||||
// }
|
||||
// else if (wrapper.wantsStreams())
|
||||
// {
|
||||
// final MessageReader stream = new MessageReader(new MessageInputStream());
|
||||
// activeMessage = stream;
|
||||
//
|
||||
// dispatch(new Runnable()
|
||||
// {
|
||||
// @SuppressWarnings("unchecked")
|
||||
// @Override
|
||||
// public void run()
|
||||
// {
|
||||
// MessageHandler.Whole<Reader> handler = (Whole<Reader>)wrapper.getHandler();
|
||||
// handler.onMessage(stream);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// activeMessage = new TextWholeMessage(this,wrapper);
|
||||
// }
|
||||
}
|
||||
|
||||
activeMessage.appendFrame(buffer,fin);
|
||||
|
||||
if (fin)
|
||||
{
|
||||
activeMessage.messageComplete();
|
||||
activeMessage = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextMessage(String message)
|
||||
{
|
||||
*//* Ignored, handled by TextWholeMessage *//*
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPing(ByteBuffer buffer)
|
||||
{
|
||||
onPongMessage(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPong(ByteBuffer buffer)
|
||||
{
|
||||
onPongMessage(buffer);
|
||||
}
|
||||
|
||||
private void onPongMessage(ByteBuffer buffer)
|
||||
{
|
||||
MessageSink appender = jsrsession.newMessageAppenderFor(MessageType.PONG);
|
||||
if (appender == null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("No PONG MessageHandler declared");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ByteBuffer pongBuf = null;
|
||||
|
||||
if (BufferUtil.isEmpty(buffer))
|
||||
{
|
||||
pongBuf = BufferUtil.EMPTY_BUFFER;
|
||||
}
|
||||
else
|
||||
{
|
||||
pongBuf = ByteBuffer.allocate(buffer.remaining());
|
||||
BufferUtil.put(buffer,pongBuf);
|
||||
BufferUtil.flipToFlush(pongBuf,0);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
appender.appendFrame(pongBuf,true);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOG.debug(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPathParameters(Map<String, String> pathParameters)
|
||||
{
|
||||
this.pathParameters = pathParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s[%s]",JsrEndpointEventDriver.class.getSimpleName(),endpoint.getClass().getName());
|
||||
}*/
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.endpoints;
|
||||
|
||||
@Deprecated
|
||||
public class JsrEndpointImpl /*implements EventDriverImpl*/
|
||||
{
|
||||
/*public EventDriver create(Object websocket, WebSocketPolicy policy)
|
||||
{
|
||||
if (!(websocket instanceof ConfiguredEndpoint))
|
||||
{
|
||||
throw new IllegalStateException(String.format("Websocket %s must be an %s",websocket.getClass().getName(),ConfiguredEndpoint.class.getName()));
|
||||
}
|
||||
|
||||
return new JsrEndpointEventDriver(policy,(ConfiguredEndpoint)websocket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String describeRule()
|
||||
{
|
||||
return "class extends " + javax.websocket.Endpoint.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Object websocket)
|
||||
{
|
||||
if (!(websocket instanceof ConfiguredEndpoint))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ConfiguredEndpoint ei = (ConfiguredEndpoint)websocket;
|
||||
Object endpoint = ei.getEndpoint();
|
||||
|
||||
return (endpoint instanceof javax.websocket.Endpoint);
|
||||
}*/
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.endpoints;
|
||||
|
||||
@Deprecated
|
||||
public class JsrEventDriverFactory /*extends EventDriverFactory*/
|
||||
{
|
||||
/* public JsrEventDriverFactory(WebSocketPolicy policy)
|
||||
{
|
||||
// super(policy);
|
||||
|
||||
*//*clearImplementations();
|
||||
// Classes that extend javax.websocket.Endpoint
|
||||
addImplementation(new JsrEndpointImpl());
|
||||
// Classes annotated with @javax.websocket.ClientEndpoint
|
||||
addImplementation(new JsrClientEndpointImpl());*//*
|
||||
}
|
||||
|
||||
*//**
|
||||
* Unwrap ConfiguredEndpoint for end-user.
|
||||
*//*
|
||||
protected String getClassName(Object websocket)
|
||||
{
|
||||
if (websocket instanceof ConfiguredEndpoint)
|
||||
{
|
||||
ConfiguredEndpoint ce = (ConfiguredEndpoint)websocket;
|
||||
return ce.getEndpoint().getClass().getName();
|
||||
}
|
||||
|
||||
return websocket.getClass().getName();
|
||||
}*/
|
||||
}
|
|
@ -149,8 +149,8 @@ public class JsrEndpointFunctions extends CommonEndpointFunctions<JsrSession>
|
|||
}
|
||||
}
|
||||
|
||||
private final AvailableEncoders encoders;
|
||||
private final AvailableDecoders decoders;
|
||||
protected final AvailableEncoders encoders;
|
||||
protected final AvailableDecoders decoders;
|
||||
private final EndpointConfig endpointConfig;
|
||||
private List<StaticArg> staticArgs;
|
||||
|
||||
|
@ -424,6 +424,7 @@ public class JsrEndpointFunctions extends CommonEndpointFunctions<JsrSession>
|
|||
*
|
||||
* @param endpoint the endpoint object
|
||||
*/
|
||||
@SuppressWarnings("Duplicates")
|
||||
protected void discoverAnnotatedEndpointFunctions(Object endpoint)
|
||||
{
|
||||
Class<?> endpointClass = endpoint.getClass();
|
||||
|
|
|
@ -18,17 +18,33 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.jsr356.endpoints;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.websocket.ClientEndpointConfig;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.EventQueue;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.samples.close.CloseEndpointConfigSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.client.EmptyClientEndpointConfig;
|
||||
import org.eclipse.jetty.websocket.jsr356.decoders.AvailableDecoders;
|
||||
import org.eclipse.jetty.websocket.jsr356.encoders.AvailableEncoders;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.samples.close.CloseReasonSessionSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.samples.close.CloseReasonSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.samples.close.CloseSessionReasonSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.samples.close.CloseSessionSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.samples.close.CloseSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.function.JsrEndpointFunctions;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
@ -44,69 +60,81 @@ public class OnCloseTest
|
|||
Case tcase = new Case();
|
||||
tcase.closeClass = closeClass;
|
||||
data.add(new Case[]
|
||||
{ tcase });
|
||||
{tcase});
|
||||
return tcase;
|
||||
}
|
||||
|
||||
|
||||
Class<?> closeClass;
|
||||
String expectedCloseEvent;
|
||||
|
||||
|
||||
public Case expect(String expectedEvent)
|
||||
{
|
||||
this.expectedCloseEvent = expectedEvent;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return closeClass.getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static ClientContainer container = new ClientContainer();
|
||||
|
||||
@Parameters
|
||||
|
||||
@Parameters(name = "{0}")
|
||||
public static Collection<Case[]> data() throws Exception
|
||||
{
|
||||
List<Case[]> data = new ArrayList<>();
|
||||
|
||||
Case.add(data,CloseSocket.class).expect("onClose()");
|
||||
Case.add(data,CloseReasonSocket.class).expect("onClose(CloseReason)");
|
||||
Case.add(data,CloseSessionSocket.class).expect("onClose(Session)");
|
||||
Case.add(data,CloseReasonSessionSocket.class).expect("onClose(CloseReason,Session)");
|
||||
Case.add(data,CloseSessionReasonSocket.class).expect("onClose(Session,CloseReason)");
|
||||
Case.add(data,CloseEndpointConfigSocket.class).expect("onClose(EndpointConfig)");
|
||||
|
||||
|
||||
Case.add(data, CloseSocket.class).expect("onClose()");
|
||||
Case.add(data, CloseReasonSocket.class).expect("onClose(CloseReason)");
|
||||
Case.add(data, CloseSessionSocket.class).expect("onClose(Session)");
|
||||
Case.add(data, CloseReasonSessionSocket.class).expect("onClose(CloseReason,Session)");
|
||||
Case.add(data, CloseSessionReasonSocket.class).expect("onClose(Session,CloseReason)");
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
private final Case testcase;
|
||||
|
||||
|
||||
public OnCloseTest(Case testcase)
|
||||
{
|
||||
this.testcase = testcase;
|
||||
System.err.printf("Testing @OnClose for %s%n",testcase.closeClass.getName());
|
||||
System.err.printf("Testing @OnClose for %s%n", testcase.closeClass.getName());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testOnCloseCall() throws Exception
|
||||
{
|
||||
/*// Scan annotations
|
||||
AnnotatedClientEndpointMetadata metadata = new AnnotatedClientEndpointMetadata(container,testcase.closeClass);
|
||||
AnnotatedEndpointScanner<ClientEndpoint, ClientEndpointConfig> scanner = new AnnotatedEndpointScanner<>(metadata);
|
||||
scanner.scan();
|
||||
|
||||
// Build up EventDriver
|
||||
WebSocketPolicy policy = WebSocketPolicy.newClientPolicy();
|
||||
ClientEndpointConfig config = metadata.getConfig();
|
||||
TrackingSocket endpoint = (TrackingSocket)testcase.closeClass.newInstance();
|
||||
ConfiguredEndpoint ei = new ConfiguredEndpoint(endpoint,config,metadata);
|
||||
JsrEvents<ClientEndpoint, ClientEndpointConfig> jsrevents = new JsrEvents<>(metadata);
|
||||
|
||||
EventDriver driver = new JsrAnnotatedEventDriver(policy,ei,jsrevents);
|
||||
|
||||
// Execute onClose call
|
||||
driver.onClose(new CloseInfo(StatusCode.NORMAL,"normal"));
|
||||
|
||||
// Test captured event
|
||||
EventQueue<String> events = endpoint.eventQueue;
|
||||
Assert.assertThat("Number of Events Captured",events.size(),is(1));
|
||||
String closeEvent = events.poll();
|
||||
Assert.assertThat("Close Event",closeEvent,is(testcase.expectedCloseEvent)); */
|
||||
TrackingSocket endpoint = (TrackingSocket) testcase.closeClass.newInstance();
|
||||
|
||||
Executor executor = new QueuedThreadPool();
|
||||
ClientEndpointConfig config = new EmptyClientEndpointConfig();
|
||||
AvailableEncoders encoders = new AvailableEncoders(config);
|
||||
AvailableDecoders decoders = new AvailableDecoders(config);
|
||||
Map<String, String> uriParams = new HashMap<>();
|
||||
|
||||
JsrEndpointFunctions jsrFunctions = new JsrEndpointFunctions(endpoint, policy,
|
||||
executor, encoders, decoders, uriParams, config);
|
||||
try
|
||||
{
|
||||
jsrFunctions.start();
|
||||
|
||||
// Execute onClose call
|
||||
jsrFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "normal"));
|
||||
|
||||
// Test captured event
|
||||
EventQueue<String> events = endpoint.eventQueue;
|
||||
assertThat("Number of Events Captured", events.size(), is(1));
|
||||
String closeEvent = events.poll();
|
||||
assertThat("Close Event", closeEvent, is(testcase.expectedCloseEvent));
|
||||
}
|
||||
finally
|
||||
{
|
||||
jsrFunctions.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,10 @@ import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
|||
@ClientEndpoint
|
||||
public class CloseEndpointConfigSocket extends TrackingSocket
|
||||
{
|
||||
// Intentionally Invalid Declaration
|
||||
@OnClose
|
||||
public void onClose(EndpointConfig config)
|
||||
{
|
||||
addEvent("onClose(EndpointConfig)");
|
||||
closeLatch.countDown();
|
||||
throw new RuntimeException("Should not have worked. Invalid declaration: " + this.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||
import org.eclipse.jetty.websocket.jsr356.ConfiguredEndpoint;
|
||||
import org.eclipse.jetty.websocket.jsr356.JsrExtension;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||
|
@ -162,7 +163,7 @@ public class JsrCreator implements WebSocketCreator
|
|||
Object endpoint = config.getConfigurator().getEndpointInstance(endpointClass);
|
||||
// Do not decorate here (let the Connection and Session start first)
|
||||
// This will allow CDI to see Session for injection into Endpoint classes.
|
||||
return endpoint;
|
||||
return new ConfiguredEndpoint(endpoint,config);
|
||||
}
|
||||
catch (InstantiationException e)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.websocket.DecodeException;
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.server.ServerEndpoint;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.jsr356.decoders.AvailableDecoders;
|
||||
import org.eclipse.jetty.websocket.jsr356.encoders.AvailableEncoders;
|
||||
import org.eclipse.jetty.websocket.jsr356.function.JsrEndpointFunctions;
|
||||
|
||||
public class JsrServerEndpointFunctions extends JsrEndpointFunctions
|
||||
{
|
||||
public JsrServerEndpointFunctions(Object endpoint, WebSocketPolicy policy, Executor executor,
|
||||
AvailableEncoders encoders, AvailableDecoders decoders,
|
||||
Map<String, String> uriParams, EndpointConfig endpointConfig)
|
||||
{
|
||||
super(endpoint, policy, executor, encoders, decoders, uriParams, endpointConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic discovery of annotated endpoint functions.
|
||||
*
|
||||
* @param endpoint the endpoint object
|
||||
*/
|
||||
@SuppressWarnings("Duplicates")
|
||||
protected void discoverAnnotatedEndpointFunctions(Object endpoint)
|
||||
{
|
||||
Class<?> endpointClass = endpoint.getClass();
|
||||
|
||||
// Use the JSR/Server annotation
|
||||
ServerEndpoint websocket = endpointClass.getAnnotation(ServerEndpoint.class);
|
||||
|
||||
if (websocket != null)
|
||||
{
|
||||
encoders.registerAll(websocket.encoders());
|
||||
decoders.registerAll(websocket.decoders());
|
||||
|
||||
// From here, the discovery of endpoint method is standard across
|
||||
// both JSR356/Client and JSR356/Server endpoints
|
||||
try
|
||||
{
|
||||
discoverJsrAnnotatedEndpointFunctions(endpoint);
|
||||
return;
|
||||
}
|
||||
catch (DecodeException e)
|
||||
{
|
||||
throw new InvalidWebSocketException("Cannot instantiate WebSocket", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Not a ServerEndpoint, let the ClientEndpoint test proceed
|
||||
super.discoverAnnotatedEndpointFunctions(endpoint);
|
||||
}
|
||||
|
||||
}
|
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.websocket.jsr356.server;
|
|||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
|
@ -34,8 +35,11 @@ import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec;
|
|||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.function.EndpointFunctions;
|
||||
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
||||
import org.eclipse.jetty.websocket.jsr356.JsrSessionFactory;
|
||||
import org.eclipse.jetty.websocket.jsr356.decoders.AvailableDecoders;
|
||||
import org.eclipse.jetty.websocket.jsr356.encoders.AvailableEncoders;
|
||||
import org.eclipse.jetty.websocket.server.MappedWebSocketCreator;
|
||||
import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
|
||||
|
||||
|
@ -152,6 +156,22 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
|
|||
mappedCreator.addMapping(new UriTemplatePathSpec(config.getPath()), creator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EndpointFunctions newJsrEndpointFunction(Object endpoint,
|
||||
AvailableEncoders availableEncoders,
|
||||
AvailableDecoders availableDecoders,
|
||||
Map<String, String> pathParameters,
|
||||
EndpointConfig config)
|
||||
{
|
||||
return new JsrServerEndpointFunctions(endpoint,
|
||||
getPolicy(),
|
||||
getExecutor(),
|
||||
availableEncoders,
|
||||
availableDecoders,
|
||||
pathParameters,
|
||||
config);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
|
|
|
@ -124,7 +124,7 @@ public class EchoCase
|
|||
StringBuilder str = new StringBuilder();
|
||||
str.append("EchoCase['");
|
||||
str.append(path);
|
||||
str.append("',").append(serverPojo.getName());
|
||||
str.append("',").append(serverPojo.getSimpleName());
|
||||
str.append(",messages[").append(messages.size());
|
||||
str.append("]=");
|
||||
boolean delim = false;
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.jsr356.server;
|
||||
|
||||
import static org.eclipse.jetty.toolchain.test.ExtraMatchers.ordered;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.net.URI;
|
||||
|
@ -77,7 +76,9 @@ import org.eclipse.jetty.websocket.jsr356.server.samples.streaming.InputStreamSo
|
|||
import org.eclipse.jetty.websocket.jsr356.server.samples.streaming.ReaderParamSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.streaming.ReaderSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.streaming.StringReturnReaderParamSocket;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -280,7 +281,7 @@ public class EchoTest
|
|||
server.stop();
|
||||
}
|
||||
|
||||
@Parameters
|
||||
@Parameters(name = "{0}")
|
||||
public static Collection<EchoCase[]> data() throws Exception
|
||||
{
|
||||
return TESTCASES;
|
||||
|
@ -339,7 +340,7 @@ public class EchoTest
|
|||
EventQueue<String> received = socket.eventQueue;
|
||||
|
||||
// Validate Responses
|
||||
assertThat("Received Events", received, ordered(testcase.expectedStrings));
|
||||
assertOrdered("Received Events", testcase.expectedStrings, received);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -347,4 +348,21 @@ public class EchoTest
|
|||
socket.close();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
public static void assertOrdered(String msg, List<String> expectedList, EventQueue<String> actualList)
|
||||
{
|
||||
try
|
||||
{
|
||||
Assert.assertEquals(msg, expectedList.size(), actualList.size());
|
||||
if (!expectedList.isEmpty())
|
||||
assertThat(msg, actualList, Matchers.contains(expectedList.toArray()));
|
||||
}
|
||||
catch (AssertionError e)
|
||||
{
|
||||
System.err.println("Expected: " + expectedList);
|
||||
System.err.println("Actual : " + actualList);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -264,7 +264,7 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
|||
}
|
||||
}
|
||||
|
||||
throw new InvalidWebSocketException("Unable to create Session: unrecognized internal EventDriver type: " + websocket.getClass().getName());
|
||||
throw new InvalidWebSocketException("Unable to create Session: unrecognized endpoint type: " + websocket.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue