diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java b/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java index 70b4da00e95..9005d622861 100644 --- a/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java @@ -238,6 +238,7 @@ public class ConfigurationAssert } + @SuppressWarnings("Duplicates") public static void assertOrdered(String msg, List expectedList, List actualList) { try diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java index 89b29622151..f1edb439bd0 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java @@ -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; @@ -56,11 +57,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.scopes.DelegatedContainerScope; +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. @@ -100,6 +104,21 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont ShutdownThread.register(this); } + public EndpointFunctions newJsrEndpointFunction(Object endpoint, + AvailableEncoders availableEncoders, + AvailableDecoders availableDecoders, + Map 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"); diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSession.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSession.java index 2dcb52a6cfd..0f83fb8d3cc 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSession.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSession.java @@ -95,9 +95,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, diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/decoders/AvailableDecoders.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/decoders/AvailableDecoders.java index 0507eeba774..6e0fb5d50cc 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/decoders/AvailableDecoders.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/decoders/AvailableDecoders.java @@ -85,6 +85,7 @@ public class AvailableDecoders implements Predicate> 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> 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); diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/encoders/AvailableEncoders.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/encoders/AvailableEncoders.java index 51e5ed073bb..83692304426 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/encoders/AvailableEncoders.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/encoders/AvailableEncoders.java @@ -83,6 +83,7 @@ public class AvailableEncoders implements Predicate> 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> 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); diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/AbstractJsrEventDriver.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/AbstractJsrEventDriver.java deleted file mode 100644 index 78747d0d236..00000000000 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/AbstractJsrEventDriver.java +++ /dev/null @@ -1,106 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2017 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 pathParameters); - - public void dispatch(Runnable runnable) - { - executor.execute(runnable); - }*/ -} diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrAnnotatedEventDriver.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrAnnotatedEventDriver.java deleted file mode 100644 index 88aa311d699..00000000000 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrAnnotatedEventDriver.java +++ /dev/null @@ -1,389 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2017 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; - - EndpointMetadata metadata = endpointInstance.getMetadata(); - - if (metadata.maxTextMessageSize() >= 1) - policy.setMaxTextMessageSize((int) metadata.maxTextMessageSize()); - if (metadata.maxBinaryMessageSize() >= 1) - policy.setMaxBinaryMessageSize((int) metadata.maxBinaryMessageSize()); - } - - @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 pathParameters) - { - events.setPathParameters(pathParameters); - } - - @Override - public String toString() - { - return String.format("%s[websocket=%s]",this.getClass().getSimpleName(),websocket); - }*/ -} diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrEndpointEventDriver.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrEndpointEventDriver.java deleted file mode 100644 index 1b7cf782208..00000000000 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrEndpointEventDriver.java +++ /dev/null @@ -1,270 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2017 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 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 handler = (Whole)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 handler = (Whole)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 pathParameters) - { - this.pathParameters = pathParameters; - } - - @Override - public String toString() - { - return String.format("%s[%s]",JsrEndpointEventDriver.class.getSimpleName(),endpoint.getClass().getName()); - }*/ -} diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrEndpointImpl.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrEndpointImpl.java deleted file mode 100644 index 3617c0dc331..00000000000 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrEndpointImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2017 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); - }*/ -} diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrEventDriverFactory.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrEventDriverFactory.java deleted file mode 100644 index 2694185e47a..00000000000 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrEventDriverFactory.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2017 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(); - }*/ -} diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/function/JsrEndpointFunctions.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/function/JsrEndpointFunctions.java index ac6a9541b0c..ea1ead77d62 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/function/JsrEndpointFunctions.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/function/JsrEndpointFunctions.java @@ -149,8 +149,8 @@ public class JsrEndpointFunctions extends CommonEndpointFunctions } } - private final AvailableEncoders encoders; - private final AvailableDecoders decoders; + protected final AvailableEncoders encoders; + protected final AvailableDecoders decoders; private final EndpointConfig endpointConfig; private List staticArgs; @@ -424,6 +424,7 @@ public class JsrEndpointFunctions extends CommonEndpointFunctions * * @param endpoint the endpoint object */ + @SuppressWarnings("Duplicates") protected void discoverAnnotatedEndpointFunctions(Object endpoint) { Class endpointClass = endpoint.getClass(); diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/OnCloseTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/OnCloseTest.java index 4d142b9084e..87a085b51c7 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/OnCloseTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/OnCloseTest.java @@ -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 data() throws Exception { List 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 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 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 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 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 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(); + } } } diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/samples/close/CloseEndpointConfigSocket.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/samples/close/CloseEndpointConfigSocket.java index e59e2e946b3..65c3d483120 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/samples/close/CloseEndpointConfigSocket.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/samples/close/CloseEndpointConfigSocket.java @@ -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()); } } diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrCreator.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrCreator.java index 9098e07f002..3c1ce65cd9b 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrCreator.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrCreator.java @@ -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) { diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrServerEndpointFunctions.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrServerEndpointFunctions.java new file mode 100644 index 00000000000..e0d8811af44 --- /dev/null +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrServerEndpointFunctions.java @@ -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 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); + } + +} diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java index 84c6744f291..5437e59bdfa 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java @@ -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; @@ -38,8 +39,11 @@ import org.eclipse.jetty.util.annotation.ManagedObject; 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; @@ -157,6 +161,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 pathParameters, + EndpointConfig config) + { + return new JsrServerEndpointFunctions(endpoint, + getPolicy(), + getExecutor(), + availableEncoders, + availableDecoders, + pathParameters, + config); + } + @Override protected void doStart() throws Exception { diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoCase.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoCase.java index 2e4a24f5832..6fb14a18af1 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoCase.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoCase.java @@ -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; diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java index 92e70be75a7..197e60596c1 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java @@ -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 data() throws Exception { return TESTCASES; @@ -339,7 +340,7 @@ public class EchoTest EventQueue 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 expectedList, EventQueue 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; + } + } } diff --git a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java index b9bc8fd024b..765ed186741 100644 --- a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java +++ b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java @@ -282,8 +282,8 @@ 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()); } /**