From 669859213915a0d6189ce72df942f95a3b204226 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Tue, 28 Jan 2020 18:15:27 +1100 Subject: [PATCH] Add tests for Javax ServerContainer default configuration. Signed-off-by: Lachlan Roberts --- .../jetty/websocket/core/FrameHandler.java | 2 +- .../javax/common/JavaxWebSocketContainer.java | 4 +- .../JavaxWebSocketFrameHandlerMetadata.java | 12 +- .../websocket/javax/tests/EventSocket.java | 14 +- .../javax/tests/JettySpecificConfigTest.java | 2 +- .../websocket/javax/tests/PathParamTest.java | 2 +- .../javax/tests/ServerConfigTest.java | 137 ++++++++++++++++++ .../tests/autobahn/JavaxAutobahnClient.java | 2 +- .../javax/tests/server/ServerDecoderTest.java | 2 +- .../tests/server/SessionTrackingTest.java | 24 +-- 10 files changed, 171 insertions(+), 30 deletions(-) create mode 100644 jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/ServerConfigTest.java diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/FrameHandler.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/FrameHandler.java index f62aef00b47..92715c36a7e 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/FrameHandler.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/FrameHandler.java @@ -545,7 +545,7 @@ public interface FrameHandler extends IncomingFrames if (idleTimeout != null) configurable.setIdleTimeout(idleTimeout); if (writeTimeout != null) - configurable.setWriteTimeout(idleTimeout); + configurable.setWriteTimeout(writeTimeout); if (autoFragment != null) configurable.setAutoFragment(autoFragment); if (maxFrameSize != null) diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketContainer.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketContainer.java index 4cc1af9a4e3..60d38dd1f87 100644 --- a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketContainer.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketContainer.java @@ -41,9 +41,9 @@ public abstract class JavaxWebSocketContainer extends ContainerLifeCycle impleme { private static final Logger LOG = Log.getLogger(JavaxWebSocketContainer.class); private final SessionTracker sessionTracker = new SessionTracker(); + protected final FrameHandler.ConfigurationCustomizer defaultCustomizer = new FrameHandler.ConfigurationCustomizer(); + protected final WebSocketComponents components; private List sessionListeners = new ArrayList<>(); - protected FrameHandler.ConfigurationCustomizer defaultCustomizer = new FrameHandler.ConfigurationCustomizer(); - protected WebSocketComponents components; public JavaxWebSocketContainer(WebSocketComponents components) { diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerMetadata.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerMetadata.java index fb4bbb27a8a..e417a7f5b09 100644 --- a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerMetadata.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerMetadata.java @@ -29,14 +29,6 @@ import org.eclipse.jetty.websocket.javax.common.encoders.AvailableEncoders; public class JavaxWebSocketFrameHandlerMetadata { - /** - * Constant for "unset" @OnMessage annotation values. - *

- * (-2 means unset/undeclared, -1 means whatever that value means, such as: no idletimeout, or no maximum message size limit) - *

- */ - public static final int UNSET = -2; - private static final String[] NO_VARIABLES = new String[0]; // EndpointConfig entries @@ -228,6 +220,8 @@ public class JavaxWebSocketFrameHandlerMetadata public static class MessageMetadata { + private static final int UNSET = -1; + public MethodHandle handle; public Class sinkClass; public AvailableDecoders.RegisteredDecoder registeredDecoder; @@ -249,7 +243,7 @@ public class JavaxWebSocketFrameHandlerMetadata public boolean isMaxMessageSizeSet() { - return (maxMessageSize != UNSET) && (maxMessageSize != 0); + return maxMessageSize != UNSET; } } } diff --git a/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/EventSocket.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/EventSocket.java index 154175233b1..4c6b54151d5 100644 --- a/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/EventSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/EventSocket.java @@ -19,6 +19,7 @@ package org.eclipse.jetty.websocket.javax.tests; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; import javax.websocket.ClientEndpoint; @@ -44,7 +45,8 @@ public class EventSocket public Session session; public EndpointConfig endpointConfig; - public BlockingQueue messageQueue = new BlockingArrayQueue<>(); + public BlockingQueue textMessages = new BlockingArrayQueue<>(); + public BlockingQueue binaryMessages = new BlockingArrayQueue<>(); public volatile Throwable error = null; public volatile CloseReason closeReason = null; @@ -66,7 +68,15 @@ public class EventSocket { if (LOG.isDebugEnabled()) LOG.debug("{} onMessage(): {}", toString(), message); - messageQueue.offer(message); + textMessages.offer(message); + } + + @OnMessage + public void onMessage(ByteBuffer message) throws IOException + { + if (LOG.isDebugEnabled()) + LOG.debug("{} onMessage(): {}", toString(), message); + binaryMessages.offer(message); } @OnClose diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/JettySpecificConfigTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/JettySpecificConfigTest.java index 73163499768..4c48c350898 100644 --- a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/JettySpecificConfigTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/JettySpecificConfigTest.java @@ -140,7 +140,7 @@ public class JettySpecificConfigTest // Send and receive an echo. session.getBasicRemote().sendText("echo"); - String resp = clientEndpoint.messageQueue.poll(1, TimeUnit.SECONDS); + String resp = clientEndpoint.textMessages.poll(1, TimeUnit.SECONDS); assertThat("Response echo", resp, is("echo")); // Close the Session. diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/PathParamTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/PathParamTest.java index 7e3038e2c2d..2b3e28eeff8 100644 --- a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/PathParamTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/PathParamTest.java @@ -96,7 +96,7 @@ public class PathParamTest Session session = container.connectToServer(clientEndpoint, serverUri); session.getBasicRemote().sendText("echo"); - String resp = clientEndpoint.messageQueue.poll(1, TimeUnit.SECONDS); + String resp = clientEndpoint.textMessages.poll(1, TimeUnit.SECONDS); assertThat("Response echo", resp, is("echo-myParam")); session.close(); clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS); diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/ServerConfigTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/ServerConfigTest.java new file mode 100644 index 00000000000..4b1e59b25ef --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/ServerConfigTest.java @@ -0,0 +1,137 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.websocket.javax.tests; + +import java.io.IOException; +import java.net.URI; +import java.nio.ByteBuffer; +import java.util.concurrent.TimeUnit; +import javax.websocket.CloseReason; +import javax.websocket.CloseReason.CloseCodes; +import javax.websocket.ContainerProvider; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.WebSocketContainer; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ServerConfigTest +{ + private Server server; + private WebSocketContainer client; + private ServerConnector connector; + + private static final long idleTimeout = 500; + private static final int maxTextMessageSize = 50; + private static final int maxBinaryMessageSize = 60; + private static final long asyncSendTimeout = 200; + + @BeforeEach + public void start() throws Exception + { + server = new Server(); + connector = new ServerConnector(server); + server.addConnector(connector); + + ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); + contextHandler.setContextPath("/"); + server.setHandler(contextHandler); + + JavaxWebSocketServletContainerInitializer.configure(contextHandler, (context, container) -> + { + container.setDefaultMaxSessionIdleTimeout(idleTimeout); + container.setDefaultMaxTextMessageBufferSize(maxTextMessageSize); + container.setDefaultMaxBinaryMessageBufferSize(maxBinaryMessageSize); + container.setAsyncSendTimeout(asyncSendTimeout); + container.addEndpoint(ConfigTestSocket.class); + container.addEndpoint(AnnotatedOnMessageSocket.class); + }); + + server.start(); + client = ContainerProvider.getWebSocketContainer(); + } + + @AfterEach + public void stop() throws Exception + { + server.stop(); + } + + @ServerEndpoint("/containerDefaults") + public static class ConfigTestSocket + { + @OnOpen + public void onOpen(Session session) + { + assertThat(session.getMaxIdleTimeout(), is(idleTimeout)); + assertThat(session.getMaxTextMessageBufferSize(), is(maxTextMessageSize)); + assertThat(session.getMaxBinaryMessageBufferSize(), is(maxBinaryMessageSize)); + assertThat(session.getAsyncRemote().getSendTimeout(), is(asyncSendTimeout)); + } + } + + @ServerEndpoint("/annotatedOnMessage") + public static class AnnotatedOnMessageSocket + { + @OnOpen + public void onOpen(Session session) + { + assertThat(session.getMaxTextMessageBufferSize(), is(111)); + assertThat(session.getMaxBinaryMessageBufferSize(), is(-1)); + } + + @OnMessage(maxMessageSize = 111) + public void onMessage(String message) throws IOException + { + } + + @OnMessage(maxMessageSize = -1) + public void onMessage(ByteBuffer message) throws IOException + { + } + } + + @ParameterizedTest + @ValueSource(strings = {"/containerDefaults", "/annotatedOnMessage"}) + public void testEndpointSettings(String path) throws Exception + { + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + path); + EventSocket clientEndpoint = new EventSocket(); + client.connectToServer(clientEndpoint, uri); + + clientEndpoint.openLatch.await(5, TimeUnit.SECONDS); + clientEndpoint.session.close(new CloseReason(CloseCodes.NORMAL_CLOSURE, "normal close")); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.closeReason.getCloseCode(), is(CloseCodes.NORMAL_CLOSURE)); + assertThat(clientEndpoint.closeReason.getReasonPhrase(), is("normal close")); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/autobahn/JavaxAutobahnClient.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/autobahn/JavaxAutobahnClient.java index 22d8c980fdd..278eb591863 100644 --- a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/autobahn/JavaxAutobahnClient.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/autobahn/JavaxAutobahnClient.java @@ -160,7 +160,7 @@ public class JavaxAutobahnClient try { clientContainer.connectToServer(onCaseCount, wsUri); - String msg = onCaseCount.messageQueue.poll(10, TimeUnit.SECONDS); + String msg = onCaseCount.textMessages.poll(10, TimeUnit.SECONDS); onCaseCount.session.close(new CloseReason(CloseReason.CloseCodes.GOING_AWAY, null)); assertTrue(onCaseCount.closeLatch.await(2, TimeUnit.SECONDS)); assertNotNull(msg); diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ServerDecoderTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ServerDecoderTest.java index e4618309da9..f64f11814fc 100644 --- a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ServerDecoderTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ServerDecoderTest.java @@ -142,7 +142,7 @@ public class ServerDecoderTest EventSocket serverSocket = annotatedServerSocket.get(5, TimeUnit.SECONDS); assertTrue(serverSocket.openLatch.await(5, TimeUnit.SECONDS)); - String msg = serverSocket.messageQueue.poll(5, TimeUnit.SECONDS); + String msg = serverSocket.textMessages.poll(5, TimeUnit.SECONDS); assertThat(msg, is("hello world=")); clientSocket.session.close(); diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTrackingTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTrackingTest.java index ad811ab992c..c31f6ef65bd 100644 --- a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTrackingTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTrackingTest.java @@ -109,29 +109,29 @@ public class SessionTrackingTest Session serverSession1 = serverSessions.poll(5, TimeUnit.SECONDS); assertNotNull(serverSession1); sendTextFrameToAll("openSessions|in-1", session1); - assertThat(clientSocket1.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@in-1).size=1")); + assertThat(clientSocket1.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@in-1).size=1")); try (Session session2 = client.connectToServer(clientSocket2, server.getWsUri().resolve("/session-info/2"))) { Session serverSession2 = serverSessions.poll(5, TimeUnit.SECONDS); assertNotNull(serverSession2); sendTextFrameToAll("openSessions|in-2", session1, session2); - assertThat(clientSocket1.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@in-2).size=2")); - assertThat(clientSocket2.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@in-2).size=2")); + assertThat(clientSocket1.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@in-2).size=2")); + assertThat(clientSocket2.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@in-2).size=2")); try (Session session3 = client.connectToServer(clientSocket3, server.getWsUri().resolve("/session-info/3"))) { Session serverSession3 = serverSessions.poll(5, TimeUnit.SECONDS); assertNotNull(serverSession3); sendTextFrameToAll("openSessions|in-3", session1, session2, session3); - assertThat(clientSocket1.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@in-3).size=3")); - assertThat(clientSocket2.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@in-3).size=3")); - assertThat(clientSocket3.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@in-3).size=3")); + assertThat(clientSocket1.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@in-3).size=3")); + assertThat(clientSocket2.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@in-3).size=3")); + assertThat(clientSocket3.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@in-3).size=3")); sendTextFrameToAll("openSessions|lvl-3", session1, session2, session3); - assertThat(clientSocket1.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-3).size=3")); - assertThat(clientSocket2.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-3).size=3")); - assertThat(clientSocket3.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-3).size=3")); + assertThat(clientSocket1.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-3).size=3")); + assertThat(clientSocket2.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-3).size=3")); + assertThat(clientSocket3.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-3).size=3")); // assert session is closed, and we have received the notification from the SessionListener session3.close(); @@ -140,8 +140,8 @@ public class SessionTrackingTest } sendTextFrameToAll("openSessions|lvl-2", session1, session2); - assertThat(clientSocket1.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-2).size=2")); - assertThat(clientSocket2.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-2).size=2")); + assertThat(clientSocket1.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-2).size=2")); + assertThat(clientSocket2.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-2).size=2")); // assert session is closed, and we have received the notification from the SessionListener session2.close(); @@ -150,7 +150,7 @@ public class SessionTrackingTest } sendTextFrameToAll("openSessions|lvl-1", session1); - assertThat(clientSocket1.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-1).size=1")); + assertThat(clientSocket1.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-1).size=1")); // assert session is closed, and we have received the notification from the SessionListener session1.close();