initParams = new HashMap<>();
- private final String jsonpPath = "/?jsonp=";
-
- public JSONPTransportCallbackParamValidationTest() {
- initParams.put("long-polling.jsonp.callbackParameterMaxLength", "10");
- }
-
- @Test
- public void testValidCallbackParamLength() throws Exception {
- startServer(serverTransport, initParams);
- cometdURL = cometdURL + jsonpPath + "short";
- testSubscribe(200);
- }
-
- @Test
- public void testInvalidCallbackParamLength() throws Exception {
- startServer(serverTransport, initParams);
- cometdURL = cometdURL + jsonpPath + "waytoolongforthistest";
- testSubscribe(400);
- }
-
- @Test
- public void testValidCallbackParamCharacters() throws Exception {
- startServer(serverTransport, initParams);
- cometdURL = cometdURL + jsonpPath + "s-h_o.R1";
- testSubscribe(200);
- }
-
- @Test
- public void testInvalidCallbackParamCharacters() throws Exception {
- startServer(serverTransport, initParams);
- cometdURL = cometdURL + jsonpPath + "sh%20rt";
- testSubscribe(400);
- cometdURL = cometdURL + jsonpPath + "sh%0d%0art";
- testSubscribe(400);
- cometdURL = cometdURL + jsonpPath + "NOTICE:";
- testSubscribe(400);
- }
-
- @Override
- protected Request newBayeuxRequest(String requestBody) throws UnsupportedEncodingException {
- String messagePath = "&message=";
- Request request = httpClient.newRequest(cometdURL + messagePath + URLEncoder.encode(requestBody, StandardCharsets.UTF_8));
- request.timeout(5, TimeUnit.SECONDS);
- request.method(HttpMethod.GET);
- return request;
- }
-
- private void testSubscribe(int errorCode) throws UnsupportedEncodingException, InterruptedException, TimeoutException, ExecutionException {
- Request handshake = newBayeuxRequest("[{" +
- "\"channel\": \"/meta/handshake\"," +
- "\"version\": \"1.0\"," +
- "\"minimumVersion\": \"1.0\"," +
- "\"supportedConnectionTypes\": [\"callback-polling\"]" +
- "}]");
- ContentResponse response = handshake.send();
- Assertions.assertEquals(errorCode, response.getStatus());
- }
-}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-common/src/test/resources/jetty-logging.properties b/cometd-java/cometd-java-server/cometd-java-server-common/src/test/resources/jetty-logging.properties
new file mode 100644
index 0000000000..6a0fcfb868
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-common/src/test/resources/jetty-logging.properties
@@ -0,0 +1,3 @@
+## Levels: ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF.
+#org.cometd.LEVEL=DEBUG
+#org.eclipse.jetty.LEVEL=DEBUG
diff --git a/cometd-java/cometd-java-server/cometd-java-server-common/src/test/resources/log4j2-test.properties b/cometd-java/cometd-java-server/cometd-java-server-common/src/test/resources/log4j2-test.properties
deleted file mode 100644
index 276f0d2e8b..0000000000
--- a/cometd-java/cometd-java-server/cometd-java-server-common/src/test/resources/log4j2-test.properties
+++ /dev/null
@@ -1,16 +0,0 @@
-# LOG4J2 levels: fatal, error, warn, info, debug, trace
-#
-appender.console.type=Console
-appender.console.name=console
-appender.console.target=SYSTEM_ERR
-appender.console.layout.type=PatternLayout
-appender.console.layout.pattern=%d %t [%5p][%c{2}] %m%n
-
-rootLogger.level=debug
-rootLogger.appenderRef.console.ref=console
-
-logger.jetty.name=org.eclipse.jetty
-logger.jetty.level=info
-
-logger.cometd.name=org.cometd
-logger.cometd.level=info
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/pom.xml b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/pom.xml
new file mode 100644
index 0000000000..896593d4ce
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/pom.xml
@@ -0,0 +1,85 @@
+
+
+
+ org.cometd.java
+ cometd-java-server-http
+ 8.0.0-SNAPSHOT
+
+
+ 4.0.0
+ cometd-java-server-http-jakarta
+ CometD :: Java :: Server :: HTTP :: Jakarta EE10
+
+
+
+
+ maven-surefire-plugin
+
+
+ @{argLine}
+
+ --add-modules org.eclipse.jetty.jmx
+
+ --add-modules org.eclipse.jetty.util.ajax
+
+ --add-exports org.cometd.server.servlet/org.cometd.server.servlet.ext=org.cometd.server
+ --add-exports org.cometd.server.servlet/org.cometd.server.servlet.ext=ALL-UNNAMED
+
+
+
+
+
+
+
+
+ jakarta.servlet
+ jakarta.servlet-api
+
+
+ org.cometd.java
+ cometd-java-api-server
+ ${project.version}
+
+
+ org.cometd.java
+ cometd-java-common
+ ${project.version}
+
+
+ org.cometd.java
+ cometd-java-server-common
+ ${project.version}
+
+
+ org.eclipse.jetty
+ jetty-jmx
+ ${jetty-version}
+ true
+
+
+ org.eclipse.jetty
+ jetty-util-ajax
+ ${jetty-version}
+ true
+
+
+
+ org.eclipse.jetty
+ jetty-client
+ ${jetty-version}
+ test
+
+
+ org.eclipse.jetty
+ jetty-server
+ ${jetty-version}
+ test
+
+
+ org.eclipse.jetty.ee10
+ jetty-ee10-servlet
+ ${jetty-version}
+ test
+
+
+
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/module-info.java b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/module-info.java
new file mode 100644
index 0000000000..bce7c17f3f
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/module-info.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2008-2022 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module org.cometd.server.http.jakarta {
+ exports org.cometd.server.http.jakarta;
+
+ requires transitive jakarta.servlet;
+ requires transitive org.cometd.api.server;
+ requires org.cometd.server;
+ requires org.slf4j;
+
+ // Only required when using JMX.
+ requires static org.eclipse.jetty.jmx;
+ // Only required when using Jetty's JSON.
+ requires static org.eclipse.jetty.util.ajax;
+}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-common/src/main/java/org/cometd/server/CometDServlet.java b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/org/cometd/server/http/jakarta/CometDServlet.java
similarity index 53%
rename from cometd-java/cometd-java-server/cometd-java-server-common/src/main/java/org/cometd/server/CometDServlet.java
rename to cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/org/cometd/server/http/jakarta/CometDServlet.java
index 76b68bc4f6..82c4af5c2e 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-common/src/main/java/org/cometd/server/CometDServlet.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/org/cometd/server/http/jakarta/CometDServlet.java
@@ -13,23 +13,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.cometd.server;
+package org.cometd.server.http.jakarta;
import java.io.IOException;
import java.util.Collections;
+import jakarta.servlet.AsyncContext;
+import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
+
+import org.cometd.bayeux.Promise;
+import org.cometd.bayeux.server.BayeuxContext;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.bayeux.server.ServerSession;
+import org.cometd.server.BayeuxServerImpl;
+import org.cometd.server.CometDRequest;
+import org.cometd.server.CometDResponse;
+import org.cometd.server.HttpException;
+import org.cometd.server.ServerSessionImpl;
import org.cometd.server.http.AbstractHttpTransport;
+import org.eclipse.jetty.util.component.LifeCycle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * The CometD Servlet maps HTTP requests to the {@link org.cometd.server.http.AbstractHttpTransport}
+ *
The CometD Servlet maps HTTP requests to the {@link AbstractHttpTransport}
* of a {@link BayeuxServer} instance.
* The {@link BayeuxServer} instance is searched in the servlet context under the {@link BayeuxServer#ATTRIBUTE}
* attribute; if it is found then it is used without further configuration, otherwise a new {@link BayeuxServer}
@@ -38,41 +49,42 @@
public class CometDServlet extends HttpServlet {
private static final Logger LOGGER = LoggerFactory.getLogger(CometDServlet.class);
- private BayeuxServerImpl _bayeux;
+ private BayeuxServer bayeuxServer;
@Override
public void init() throws ServletException {
try {
+ bayeuxServer = (BayeuxServer)getServletContext().getAttribute(BayeuxServer.ATTRIBUTE);
+
boolean export = false;
- _bayeux = (BayeuxServerImpl)getServletContext().getAttribute(BayeuxServer.ATTRIBUTE);
- if (_bayeux == null) {
+ if (bayeuxServer == null) {
export = true;
- _bayeux = newBayeuxServer();
+ bayeuxServer = newBayeuxServer();
- // Transfer all servlet init parameters to the BayeuxServer implementation
+ // Transfer all servlet init parameters to the BayeuxServer implementation.
for (String initParamName : Collections.list(getInitParameterNames())) {
- _bayeux.setOption(initParamName, getInitParameter(initParamName));
+ bayeuxServer.setOption(initParamName, getInitParameter(initParamName));
}
-
- // Add the ServletContext to the options
- _bayeux.setOption(ServletContext.class.getName(), getServletContext());
}
- _bayeux.start();
+ // Add the ServletContext to the options.
+ bayeuxServer.setOption(ServletContext.class.getName(), getServletContext());
+
+ LifeCycle.start(bayeuxServer);
if (export) {
- getServletContext().setAttribute(BayeuxServer.ATTRIBUTE, _bayeux);
+ getServletContext().setAttribute(BayeuxServer.ATTRIBUTE, bayeuxServer);
}
} catch (Exception x) {
throw new ServletException(x);
}
}
- public BayeuxServerImpl getBayeux() {
- return _bayeux;
+ public BayeuxServer getBayeuxServer() {
+ return bayeuxServer;
}
- protected BayeuxServerImpl newBayeuxServer() {
+ protected BayeuxServer newBayeuxServer() {
return new BayeuxServerImpl();
}
@@ -83,11 +95,41 @@ protected void service(HttpServletRequest request, HttpServletResponse response)
return;
}
- AbstractHttpTransport transport = _bayeux.findHttpTransport(request);
+ // API calls could be async, so we must be async in the request processing too.
+ AsyncContext asyncContext = request.startAsync();
+ // Explicitly disable the timeout, to prevent
+ // that the timeout fires in case of slow reads.
+ asyncContext.setTimeout(0);
+
+ CometDRequest cometDRequest = new JakartaCometDRequest(request);
+ CometDResponse cometDResponse = new JakartaCometDResponse(response);
+ BayeuxContext bayeuxContext = new JakartaBayeuxContext(request);
+
+ Promise promise = new Promise<>() {
+ @Override
+ public void succeed(Void result) {
+ asyncContext.complete();
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Handling successful");
+ }
+ }
+
+ @Override
+ public void fail(Throwable failure) {
+ int code = failure instanceof HttpException http ? http.getCode() : HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
+ sendError(request, response, code, failure);
+ asyncContext.complete();
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Handling failed", failure);
+ }
+ }
+ };
+
+ AbstractHttpTransport transport = AbstractHttpTransport.find(bayeuxServer, cometDRequest);
if (transport == null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unknown Bayeux Transport");
} else {
- transport.handle(request, response);
+ transport.handle(bayeuxContext, cometDRequest, cometDResponse, promise);
}
}
@@ -102,20 +144,31 @@ protected void serviceOptions(HttpServletRequest request, HttpServletResponse re
// Just return 200 OK, there is nothing more to add to such requests.
}
+ protected void sendError(HttpServletRequest request, HttpServletResponse response, int code, Throwable failure) {
+ try {
+ request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, failure);
+ response.setStatus(code);
+ } catch (Throwable x) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("", x);
+ }
+ }
+ }
+
@Override
public void destroy() {
- for (ServerSession session : _bayeux.getSessions()) {
+ for (ServerSession session : bayeuxServer.getSessions()) {
((ServerSessionImpl)session).destroyScheduler();
}
try {
- _bayeux.stop();
+ LifeCycle.start(bayeuxServer);
} catch (Exception x) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("", x);
}
} finally {
- _bayeux = null;
+ bayeuxServer = null;
getServletContext().removeAttribute(BayeuxServer.ATTRIBUTE);
}
}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/org/cometd/server/http/jakarta/JakartaBayeuxContext.java b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/org/cometd/server/http/jakarta/JakartaBayeuxContext.java
new file mode 100644
index 0000000000..802da73db0
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/org/cometd/server/http/jakarta/JakartaBayeuxContext.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2008-2022 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.cometd.server.http.jakarta;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.http.Cookie;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpSession;
+
+import org.cometd.bayeux.server.BayeuxContext;
+
+class JakartaBayeuxContext implements BayeuxContext {
+ private final HttpServletRequest request;
+
+ JakartaBayeuxContext(HttpServletRequest request) {
+ this.request = request;
+ }
+
+ @Override
+ public Principal getUserPrincipal() {
+ return request.getUserPrincipal();
+ }
+
+ @Override
+ public boolean isUserInRole(String role) {
+ return request.isUserInRole(role);
+ }
+
+ @Override
+ public SocketAddress getRemoteAddress() {
+ return new InetSocketAddress(request.getRemoteHost(), request.getRemotePort());
+ }
+
+ @Override
+ public SocketAddress getLocalAddress() {
+ return new InetSocketAddress(request.getLocalName(), request.getLocalPort());
+ }
+
+ @Override
+ public String getHeader(String name) {
+ return request.getHeader(name);
+ }
+
+ @Override
+ public List getHeaderValues(String name) {
+ return Collections.list(request.getHeaders(name));
+ }
+
+ @Override
+ public String getParameter(String name) {
+ return request.getParameter(name);
+ }
+
+ @Override
+ public List getParameterValues(String name) {
+ return List.of(request.getParameterValues(name));
+ }
+
+ @Override
+ public String getCookie(String name) {
+ Cookie[] cookies = request.getCookies();
+ if (cookies != null) {
+ for (Cookie c : cookies) {
+ if (name.equals(c.getName())) {
+ return c.getValue();
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Object getContextAttribute(String name) {
+ return getServletContext().getAttribute(name);
+ }
+
+ @Override
+ public Object getRequestAttribute(String name) {
+ return request.getAttribute(name);
+ }
+
+ @Override
+ public Object getSessionAttribute(String name) {
+ HttpSession session = request.getSession(false);
+ return session != null ? session.getAttribute(name) : null;
+ }
+
+ private ServletContext getServletContext() {
+ return request.getServletContext();
+ }
+
+ @Override
+ public String getContextPath() {
+ return request.getContextPath();
+ }
+
+ @Override
+ public String getURL() {
+ StringBuffer url = request.getRequestURL();
+ String query = request.getQueryString();
+ if (query != null) {
+ url.append("?").append(query);
+ }
+ return url.toString();
+ }
+
+ @Override
+ public List getLocales() {
+ return Collections.list(request.getLocales());
+ }
+
+ @Override
+ public String getProtocol() {
+ return request.getProtocol();
+ }
+
+ @Override
+ public boolean isSecure() {
+ return request.isSecure();
+ }
+}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/org/cometd/server/http/jakarta/JakartaCometDRequest.java b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/org/cometd/server/http/jakarta/JakartaCometDRequest.java
new file mode 100644
index 0000000000..67ff27e9bf
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/org/cometd/server/http/jakarta/JakartaCometDRequest.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2008-2022 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.cometd.server.http.jakarta;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+import jakarta.servlet.ReadListener;
+import jakarta.servlet.ServletInputStream;
+import jakarta.servlet.http.Cookie;
+import jakarta.servlet.http.HttpServletRequest;
+
+import org.cometd.server.CometDRequest;
+import org.eclipse.jetty.util.IO;
+
+class JakartaCometDRequest implements CometDRequest {
+ private final HttpServletRequest request;
+ private JakartaCometDInput input;
+
+ JakartaCometDRequest(HttpServletRequest request) {
+ this.request = request;
+ }
+
+ @Override
+ public String getCharacterEncoding() {
+ return request.getCharacterEncoding();
+ }
+
+ @Override
+ public List getCookies() {
+ Cookie[] cookies = request.getCookies();
+ if (cookies == null) {
+ return null;
+ }
+ List result = new ArrayList<>();
+ for (Cookie cookie : cookies) {
+ result.add(new CometDCookie(cookie.getName(), cookie.getValue()));
+ }
+ return result;
+ }
+
+ @Override
+ public String[] getParameterValues(String name) {
+ return request.getParameterValues(name);
+ }
+
+ @Override
+ public String getMethod() {
+ return request.getMethod();
+ }
+
+ @Override
+ public Input getInput() {
+ if (input == null) {
+ try {
+ input = new JakartaCometDInput(request);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return input;
+ }
+
+ @Override
+ public String getProtocol() {
+ return request.getProtocol();
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+ return request.getAttribute(name);
+ }
+
+ @Override
+ public void setAttribute(String name, Object value) {
+ request.setAttribute(name, value);
+ }
+
+ private static class JakartaCometDInput implements Input, ReadListener {
+ private static final Runnable READ_READY = () -> {};
+
+ private final ServletInputStream inputStream;
+ private final AtomicReference state = new AtomicReference<>();
+ private volatile Throwable failure;
+
+ private JakartaCometDInput(HttpServletRequest request) throws IOException {
+ this.inputStream = request.getInputStream();
+ if ("POST".equals(request.getMethod())) {
+ this.inputStream.setReadListener(this);
+ }
+ }
+
+ @Override
+ public void demand(Runnable demandCallback) {
+ // This method races with onDataAvailable() and onAllDataRead().
+ Runnable readReady = state.getAndUpdate(existing -> existing == null ? demandCallback : null);
+ if (readReady != null) {
+ // Lost the race with onDataAvailable(), but there
+ // is data available, so run the demandCallback.
+ demandCallback.run();
+ }
+ }
+
+ @Override
+ public Input.Chunk read() throws IOException {
+ if (failure != null) {
+ throw IO.rethrow(failure);
+ } else if (inputStream.isFinished()) {
+ return Input.Chunk.EOF;
+ } else if (inputStream.isReady()) {
+ // TODO: the chunks can be pooled.
+ Input.Chunk chunk = new Chunk();
+ ByteBuffer byteBuffer = chunk.byteBuffer();
+ int read = inputStream.read(byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.remaining());
+ if (read < 0) {
+ chunk.release();
+ return Input.Chunk.EOF;
+ } else if (read == 0) {
+ chunk.release();
+ return null;
+ } else {
+ byteBuffer.limit(read);
+ return chunk;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void onDataAvailable() {
+ // This method races with demand(Runnable).
+ Runnable readCallback = state.getAndUpdate(existing -> existing == null ? READ_READY : null);
+ if (readCallback != null) {
+ readCallback.run();
+ }
+ }
+
+ @Override
+ public void onAllDataRead() {
+ onDataAvailable();
+ }
+
+ @Override
+ public void onError(Throwable failure) {
+ this.failure = failure;
+ onDataAvailable();
+ }
+
+ private static class Chunk implements Input.Chunk {
+ private final ByteBuffer byteBuffer = ByteBuffer.allocate(512);
+
+ @Override
+ public ByteBuffer byteBuffer() {
+ return byteBuffer;
+ }
+
+ @Override
+ public boolean isLast() {
+ return false;
+ }
+
+ @Override
+ public void release() {
+ }
+
+ @Override
+ public String toString() {
+ return "%s@%x[last=%b,%s]".formatted(getClass().getSimpleName(), hashCode(), isLast(), byteBuffer());
+ }
+ }
+ }
+}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/org/cometd/server/http/jakarta/JakartaCometDResponse.java b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/org/cometd/server/http/jakarta/JakartaCometDResponse.java
new file mode 100644
index 0000000000..6c036c9e90
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jakarta/src/main/java/org/cometd/server/http/jakarta/JakartaCometDResponse.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2008-2022 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.cometd.server.http.jakarta;
+
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicReference;
+import jakarta.servlet.ServletOutputStream;
+import jakarta.servlet.WriteListener;
+import jakarta.servlet.http.HttpServletResponse;
+
+import org.cometd.bayeux.Promise;
+import org.cometd.server.CometDResponse;
+
+class JakartaCometDResponse implements CometDResponse {
+ private final HttpServletResponse response;
+ private JakartaCometDOutput output;
+
+ JakartaCometDResponse(HttpServletResponse response) {
+ this.response = response;
+ }
+
+ @Override
+ public void addHeader(String name, String value) {
+ response.addHeader(name, value);
+ }
+
+ @Override
+ public Output getOutput() {
+ if (output == null) {
+ try {
+ output = new JakartaCometDOutput(response);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return output;
+ }
+
+ @Override
+ public void setContentType(String contentType) {
+ response.setContentType(contentType);
+ }
+
+ private static class JakartaCometDOutput implements Output, WriteListener {
+ public static final Promise WRITE_READY = new Promise<>() {};
+
+ private final AtomicReference> state = new AtomicReference<>();
+ private final ServletOutputStream outputStream;
+
+ private JakartaCometDOutput(HttpServletResponse response) throws IOException {
+ this.outputStream = response.getOutputStream();
+ this.outputStream.setWriteListener(this);
+ }
+
+ @Override
+ public void onWritePossible() {
+ // This method races with write().
+ Promise pendingPromise = state.getAndUpdate(existing -> existing == null ? WRITE_READY : null);
+ if (pendingPromise != null) {
+ pendingPromise.succeed(null);
+ }
+ }
+
+ @Override
+ public void onError(Throwable failure) {
+ // This method races with write().
+ Promise pendingPromise = state.getAndUpdate(existing -> existing == null ? WRITE_READY : null);
+ if (pendingPromise != null) {
+ pendingPromise.fail(failure);
+ }
+ }
+
+ @Override
+ public void write(boolean last, byte[] bytes, Promise promise) {
+ try {
+ outputStream.write(bytes);
+ if (outputStream.isReady()) {
+ promise.succeed(null);
+ } else {
+ // In a race with onWritePossible().
+ Promise writeReady = state.getAndUpdate(existing -> existing == null ? promise : null);
+ if (writeReady != null) {
+ // Lost the race with onWritePossible(), but it
+ // is possible to write, so succeed the promise.
+ promise.succeed(null);
+ }
+ }
+ } catch (Throwable x) {
+ promise.fail(x);
+ }
+ }
+ }
+}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/pom.xml b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/pom.xml
new file mode 100644
index 0000000000..8e4fcd1696
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/pom.xml
@@ -0,0 +1,67 @@
+
+
+
+ org.cometd.java
+ cometd-java-server-http
+ 8.0.0-SNAPSHOT
+
+
+ 4.0.0
+ cometd-java-server-http-jetty
+ CometD :: Java :: Server :: HTTP :: Jetty
+
+
+
+
+ maven-surefire-plugin
+
+
+ @{argLine}
+
+ --add-modules org.eclipse.jetty.jmx
+
+ --add-modules org.eclipse.jetty.util.ajax
+
+ --add-exports org.cometd.server.servlet/org.cometd.server.http.ext=org.cometd.server
+ --add-exports org.cometd.server.servlet/org.cometd.server.http.ext=ALL-UNNAMED
+
+
+
+
+
+
+
+
+ org.eclipse.jetty
+ jetty-server
+ ${jetty-version}
+
+
+ org.cometd.java
+ cometd-java-api-server
+ ${project.version}
+
+
+ org.cometd.java
+ cometd-java-common
+ ${project.version}
+
+
+ org.cometd.java
+ cometd-java-server-common
+ ${project.version}
+
+
+ org.eclipse.jetty
+ jetty-jmx
+ ${jetty-version}
+ true
+
+
+ org.eclipse.jetty
+ jetty-util-ajax
+ ${jetty-version}
+ true
+
+
+
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/module-info.java b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/module-info.java
new file mode 100644
index 0000000000..2687c5ead8
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/module-info.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2008-2022 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module org.cometd.server.http.jetty {
+ exports org.cometd.server.http.jetty;
+
+ requires transitive org.eclipse.jetty.server;
+ requires transitive org.cometd.api.server;
+ requires org.cometd.server;
+ requires org.slf4j;
+
+ // Only required when using JMX.
+ requires static org.eclipse.jetty.jmx;
+ // Only required when using Jetty's JSON.
+ requires static org.eclipse.jetty.util.ajax;
+}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/org/cometd/server/http/jetty/CometDHandler.java b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/org/cometd/server/http/jetty/CometDHandler.java
new file mode 100644
index 0000000000..446a1ba902
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/org/cometd/server/http/jetty/CometDHandler.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2008-2022 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.cometd.server.http.jetty;
+
+import java.util.Map;
+import java.util.Objects;
+
+import org.cometd.bayeux.Promise;
+import org.cometd.bayeux.server.BayeuxServer;
+import org.cometd.bayeux.server.ServerSession;
+import org.cometd.server.BayeuxServerImpl;
+import org.cometd.server.HttpException;
+import org.cometd.server.ServerSessionImpl;
+import org.cometd.server.http.AbstractHttpTransport;
+import org.cometd.server.http.JSONHttpTransport;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.server.Context;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.util.Callback;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * {@code CometDHandler} maps HTTP requests to the HTTP server transports
+ * of a {@link BayeuxServer} instance.
+ * The {@link BayeuxServer} instance is created and configured using the
+ * given {@link #setOptions(Map) options}.
+ */
+
+// TODO: can this handler be the direct child of Server?
+// In this way we will save the ContextHandler wrapping & machinery.
+
+public class CometDHandler extends Handler.Abstract {
+ private static final Logger LOGGER = LoggerFactory.getLogger(CometDHandler.class);
+
+ private Map options = Map.of();
+ private BayeuxServer bayeuxServer;
+
+ public CometDHandler() {
+ this(InvocationType.BLOCKING);
+ }
+
+ public CometDHandler(InvocationType invocationType) {
+ super(invocationType);
+ }
+
+ public Map getOptions() {
+ return options;
+ }
+
+ public void setOptions(Map options) {
+ this.options = Objects.requireNonNull(options);
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+ Context context = ContextHandler.getCurrentContext(getServer());
+ bayeuxServer = (BayeuxServer)context.getAttribute(BayeuxServer.ATTRIBUTE);
+
+ boolean export = false;
+ if (bayeuxServer == null) {
+ export = true;
+ bayeuxServer = newBayeuxServer();
+
+ String transports = JSONHttpTransport.class.getName() + ",org.cometd.server.websocket.jetty.JettyWebSocketTransport";
+ bayeuxServer.setOption(BayeuxServerImpl.TRANSPORTS_OPTION, transports);
+ for (Map.Entry entry : getOptions().entrySet()) {
+ this.bayeuxServer.setOption(entry.getKey(), entry.getValue());
+ }
+ }
+
+ bayeuxServer.setOption(Context.class.getName(), context);
+
+ addBean(bayeuxServer);
+
+ if (export) {
+ context.setAttribute(BayeuxServer.ATTRIBUTE, bayeuxServer);
+ }
+
+ super.doStart();
+ }
+
+ @Override
+ protected void doStop() throws Exception {
+ for (ServerSession session : bayeuxServer.getSessions()) {
+ ((ServerSessionImpl)session).destroyScheduler();
+ }
+ super.doStop();
+ removeBean(bayeuxServer);
+ }
+
+ public BayeuxServer getBayeuxServer() {
+ return bayeuxServer;
+ }
+
+ protected BayeuxServer newBayeuxServer() {
+ return new BayeuxServerImpl();
+ }
+
+ @Override
+ public boolean handle(Request request, Response response, Callback callback) {
+ if ("OPTIONS".equals(request.getMethod())) {
+ serviceOptions(request, response, callback);
+ return true;
+ }
+
+ JettyCometDRequest cometDRequest = new JettyCometDRequest(request);
+ JettyCometDResponse cometDResponse = new JettyCometDResponse(response);
+ JettyBayeuxContext bayeuxContext = new JettyBayeuxContext(cometDRequest, request);
+
+ Promise promise = new Promise<>() {
+ @Override
+ public void succeed(Void result) {
+ callback.succeeded();
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Handling successful");
+ }
+ }
+
+ @Override
+ public void fail(Throwable failure) {
+ int code = failure instanceof HttpException http ? http.getCode() : HttpStatus.INTERNAL_SERVER_ERROR_500;
+ sendError(request, response, callback, code, failure);
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Handling failed", failure);
+ }
+ }
+ };
+
+ AbstractHttpTransport transport = AbstractHttpTransport.find(bayeuxServer, cometDRequest);
+ if (transport == null) {
+ Response.writeError(request, response, callback, HttpStatus.BAD_REQUEST_400, "Unknown Bayeux Transport");
+ } else {
+ transport.handle(bayeuxContext, cometDRequest, cometDResponse, promise);
+ }
+ return true;
+ }
+
+ protected void serviceOptions(Request request, Response response, Callback callback) {
+ // OPTIONS requests are made by browsers that are CORS compliant
+ // (see http://www.w3.org/TR/cors/) during a "preflight request".
+ // Preflight requests happen for each different new URL, then
+ // results are cached by the browser.
+ // For the Bayeux protocol, preflight requests happen for URLs
+ // such as "/cometd/handshake", "/cometd/connect", etc., since
+ // the Bayeux clients append the Bayeux message type to the base
+ // Bayeux server URL.
+ // Just return 200 OK, there is nothing more to add to such requests.
+ callback.succeeded();
+ }
+
+ protected void sendError(Request request, Response response, Callback callback, int code, Throwable failure) {
+ Response.writeError(request, response, callback, code);
+ }
+}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/org/cometd/server/http/jetty/JettyBayeuxContext.java b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/org/cometd/server/http/jetty/JettyBayeuxContext.java
new file mode 100644
index 0000000000..0f8bf3c66f
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/org/cometd/server/http/jetty/JettyBayeuxContext.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2008-2022 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.cometd.server.http.jetty;
+
+import java.net.SocketAddress;
+import java.security.Principal;
+import java.util.List;
+import java.util.Locale;
+
+import org.cometd.bayeux.server.BayeuxContext;
+import org.cometd.server.CometDRequest;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Session;
+
+class JettyBayeuxContext implements BayeuxContext {
+ private final JettyCometDRequest cometDRequest;
+ private final Request request;
+
+ JettyBayeuxContext(JettyCometDRequest cometDRequest, Request request) {
+ this.cometDRequest = cometDRequest;
+ this.request = request;
+ }
+
+ @Override
+ public Principal getUserPrincipal() {
+ return null;
+ }
+
+ @Override
+ public boolean isUserInRole(String role) {
+ return false;
+ }
+
+ @Override
+ public SocketAddress getRemoteAddress() {
+ return request.getConnectionMetaData().getRemoteSocketAddress();
+ }
+
+ @Override
+ public SocketAddress getLocalAddress() {
+ return request.getConnectionMetaData().getLocalSocketAddress();
+ }
+
+ @Override
+ public String getHeader(String name) {
+ return request.getHeaders().get(name);
+ }
+
+ @Override
+ public List getHeaderValues(String name) {
+ return request.getHeaders().getValuesList(name);
+ }
+
+ @Override
+ public String getParameter(String name) {
+ return Request.extractQueryParameters(request).getValue(name);
+ }
+
+ @Override
+ public List getParameterValues(String name) {
+ return Request.extractQueryParameters(request).getValues(name);
+ }
+
+ @Override
+ public String getCookie(String name) {
+ return cometDRequest.getCookies().stream()
+ .filter(cometDCookie -> cometDCookie.name().equals(name))
+ .map(CometDRequest.CometDCookie::value)
+ .findFirst()
+ .orElse(null);
+ }
+
+ @Override
+ public Object getContextAttribute(String name) {
+ return request.getContext().getAttribute(name);
+ }
+
+ @Override
+ public Object getRequestAttribute(String name) {
+ return request.getAttribute(name);
+ }
+
+ @Override
+ public Object getSessionAttribute(String name) {
+ Session session = request.getSession(false);
+ return session == null ? null : session.getAttribute(name);
+ }
+
+ @Override
+ public String getContextPath() {
+ return request.getContext().getContextPath();
+ }
+
+ @Override
+ public String getURL() {
+ return request.getHttpURI().asString();
+ }
+
+ @Override
+ public List getLocales() {
+ return Request.getLocales(request);
+ }
+
+ @Override
+ public String getProtocol() {
+ return request.getConnectionMetaData().getProtocol();
+ }
+
+ @Override
+ public boolean isSecure() {
+ return request.getConnectionMetaData().isSecure();
+ }
+}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/org/cometd/server/http/jetty/JettyCometDRequest.java b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/org/cometd/server/http/jetty/JettyCometDRequest.java
new file mode 100644
index 0000000000..6f8fc655e7
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/org/cometd/server/http/jetty/JettyCometDRequest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2008-2022 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.cometd.server.http.jetty;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.cometd.server.CometDRequest;
+import org.eclipse.jetty.http.CookieCache;
+import org.eclipse.jetty.http.HttpCookie;
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.io.Content;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.IO;
+
+class JettyCometDRequest implements CometDRequest {
+ private final Request request;
+ private final CookieCache cookieCache = new CookieCache();
+ private Input cometDInput;
+
+ public JettyCometDRequest(Request request) {
+ this.request = request;
+ }
+
+ @Override
+ public String getCharacterEncoding() {
+ String[] split = request.getHeaders().get(HttpHeader.CONTENT_TYPE).split(";");
+ if (split.length == 2)
+ return split[1].split("=")[1];
+ return "iso-8859-1";
+ }
+
+ @Override
+ public List getCookies() {
+ List cookies = cookieCache.getCookies(request.getHeaders());
+ return cookies.stream()
+ .map(httpCookie -> new CometDCookie(httpCookie.getName(), httpCookie.getValue()))
+ .toList();
+ }
+
+ @Override
+ public String[] getParameterValues(String name) {
+ throw new UnsupportedOperationException("REMOVE API?");
+ }
+
+ @Override
+ public String getMethod() {
+ return request.getMethod();
+ }
+
+ @Override
+ public String getProtocol() {
+ return request.getConnectionMetaData().getProtocol();
+ }
+
+ @Override
+ public Input getInput() {
+ if (cometDInput == null) {
+ cometDInput = new JettyCometDInput(this);
+ }
+ return cometDInput;
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+ return request.getAttribute(name);
+ }
+
+ @Override
+ public void setAttribute(String name, Object value) {
+ request.setAttribute(name, value);
+ }
+
+ private static class JettyCometDInput implements Input {
+ private final JettyCometDRequest request;
+
+ private JettyCometDInput(JettyCometDRequest request) {
+ this.request = request;
+ }
+
+ @Override
+ public void demand(Runnable r) {
+ request.request.demand(r);
+ }
+
+ @Override
+ public Input.Chunk read() throws IOException {
+ Content.Chunk chunk = request.request.read();
+ if (chunk == null) {
+ return null;
+ }
+ if (Content.Chunk.isFailure(chunk)) {
+ throw IO.rethrow(chunk.getFailure());
+ }
+ return new Chunk(chunk);
+ }
+
+ private static class Chunk implements Input.Chunk {
+ private final Content.Chunk chunk;
+
+ private Chunk(Content.Chunk chunk) {
+ this.chunk = chunk;
+ }
+
+ @Override
+ public ByteBuffer byteBuffer() {
+ return chunk.getByteBuffer();
+ }
+
+ @Override
+ public boolean isLast() {
+ return chunk.isLast();
+ }
+
+ @Override
+ public void release() {
+ chunk.release();
+ }
+
+ @Override
+ public String toString() {
+ return "%s@%x[%s]".formatted(getClass().getSimpleName(), hashCode(), chunk);
+ }
+ }
+ }
+}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/org/cometd/server/http/jetty/JettyCometDResponse.java b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/org/cometd/server/http/jetty/JettyCometDResponse.java
new file mode 100644
index 0000000000..39429bab0c
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-jetty/src/main/java/org/cometd/server/http/jetty/JettyCometDResponse.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2008-2022 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.cometd.server.http.jetty;
+
+import java.nio.ByteBuffer;
+
+import org.cometd.bayeux.Promise;
+import org.cometd.server.CometDResponse;
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.io.Content;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
+
+class JettyCometDResponse implements CometDResponse {
+ private final Response response;
+ private Output cometDOutput;
+
+ JettyCometDResponse(Response response) {
+ this.response = response;
+ }
+
+ @Override
+ public void addHeader(String name, String value) {
+ response.getHeaders().add(name, value);
+ }
+
+ @Override
+ public Output getOutput() {
+ if (cometDOutput == null) {
+ cometDOutput = new JettyCometDOutput(Response.asBufferedSink(response.getRequest(), response));
+ }
+ return cometDOutput;
+ }
+
+ @Override
+ public void setContentType(String contentType) {
+ response.getHeaders().put(HttpHeader.CONTENT_TYPE, contentType);
+ }
+
+ private static class JettyCometDOutput implements Output {
+ private final Content.Sink sink;
+
+ private JettyCometDOutput(Content.Sink sink) {
+ this.sink = sink;
+ }
+
+ @Override
+ public void write(boolean last, byte[] bytes, Promise promise) {
+ sink.write(last, ByteBuffer.wrap(bytes), new Callback() {
+ @Override
+ public void succeeded() {
+ promise.succeed(null);
+ }
+
+ @Override
+ public void failed(Throwable x) {
+ promise.fail(x);
+ }
+ });
+ }
+ }
+}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/pom.xml b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/pom.xml
new file mode 100644
index 0000000000..2557632fb3
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/pom.xml
@@ -0,0 +1,47 @@
+
+
+
+ org.cometd.java
+ cometd-java-server-http
+ 8.0.0-SNAPSHOT
+
+
+ 4.0.0
+ cometd-java-server-http-tests
+ CometD :: Java :: Server :: HTTP :: Tests
+
+
+
+ org.cometd.java
+ cometd-java-server-http-jakarta
+ ${project.version}
+ test
+
+
+ org.cometd.java
+ cometd-java-server-http-jetty
+ ${project.version}
+ test
+
+
+ org.eclipse.jetty
+ jetty-client
+ ${jetty-version}
+ test
+
+
+ org.eclipse.jetty.ee10
+ jetty-ee10-servlet
+ ${jetty-version}
+ test
+
+
+ org.eclipse.jetty
+ jetty-util-ajax
+ ${jetty-version}
+ test
+
+
+
diff --git a/cometd-java/cometd-java-server/cometd-java-server-common/src/test/java/org/cometd/server/AbstractBayeuxClientServerTest.java b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/src/test/java/org/cometd/server/http/AbstractBayeuxClientServerTest.java
similarity index 98%
rename from cometd-java/cometd-java-server/cometd-java-server-common/src/test/java/org/cometd/server/AbstractBayeuxClientServerTest.java
rename to cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/src/test/java/org/cometd/server/http/AbstractBayeuxClientServerTest.java
index d169c94f71..86b2956c93 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-common/src/test/java/org/cometd/server/AbstractBayeuxClientServerTest.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/src/test/java/org/cometd/server/http/AbstractBayeuxClientServerTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.cometd.server;
+package org.cometd.server.http;
import java.io.UnsupportedEncodingException;
import java.net.URI;
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/src/test/java/org/cometd/server/http/AbstractBayeuxServerTest.java b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/src/test/java/org/cometd/server/http/AbstractBayeuxServerTest.java
new file mode 100644
index 0000000000..f4e48bb15a
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/src/test/java/org/cometd/server/http/AbstractBayeuxServerTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2008-2022 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.cometd.server.http;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.cometd.bayeux.server.BayeuxServer;
+import org.cometd.server.BayeuxServerImpl;
+import org.cometd.server.http.jakarta.CometDServlet;
+import org.cometd.server.http.jetty.CometDHandler;
+import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
+import org.eclipse.jetty.ee10.servlet.ServletHolder;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public abstract class AbstractBayeuxServerTest {
+ public static Transport[] transports() {
+ return Transport.values();
+ }
+
+ @RegisterExtension
+ public final BeforeTestExecutionCallback printMethodName = context ->
+ System.err.printf("Running %s.%s() %s%n", context.getRequiredTestClass().getSimpleName(), context.getRequiredTestMethod().getName(), context.getDisplayName());
+ protected Server server;
+ protected ServerConnector connector;
+ protected int port;
+ protected ContextHandler context;
+ protected String cometdURL;
+ protected BayeuxServerImpl bayeux;
+ protected long timeout = 2000;
+
+ public void startServer(Transport transport, Map options) throws Exception {
+ server = new Server();
+ connector = new ServerConnector(server);
+ server.addConnector(connector);
+
+ String contextPath = "/";
+ String cometdPath = "/cometd";
+ Supplier getBayeuxServer = switch (transport) {
+ case JAKARTA -> {
+ ServletContextHandler servletContext = new ServletContextHandler(contextPath);
+ context = servletContext;
+ server.setHandler(context);
+ CometDServlet cometdServlet = new CometDServlet();
+ ServletHolder cometdServletHolder = new ServletHolder(cometdServlet);
+ if (options == null) {
+ options = new HashMap<>();
+ }
+ options.put("timeout", String.valueOf(timeout));
+ options.put("transports", JSONHttpTransport.class.getName());
+ for (Map.Entry entry : options.entrySet()) {
+ cometdServletHolder.setInitParameter(entry.getKey(), entry.getValue());
+ }
+ servletContext.addServlet(cometdServletHolder, cometdPath + "/*");
+ yield cometdServlet::getBayeuxServer;
+ }
+ case JETTY -> {
+ context = new ContextHandler(contextPath);
+ server.setHandler(context);
+ CometDHandler cometdHandler = new CometDHandler();
+ context.setHandler(cometdHandler);
+ if (options == null) {
+ options = new HashMap<>();
+ }
+ options.put("timeout", String.valueOf(timeout));
+ options.put("transports", JSONHttpTransport.class.getName());
+ cometdHandler.setOptions(options);
+ yield cometdHandler::getBayeuxServer;
+ }
+ };
+
+ server.start();
+ port = connector.getLocalPort();
+
+ cometdURL = "http://localhost:" + port + cometdPath;
+
+ bayeux = (BayeuxServerImpl)getBayeuxServer.get();
+ }
+
+ @AfterEach
+ public void stopServer() throws Exception {
+ if (server != null) {
+ server.stop();
+ }
+ }
+
+ public enum Transport {
+ JAKARTA, JETTY
+ }
+}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-common/src/test/java/org/cometd/server/BadJSONTest.java b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/src/test/java/org/cometd/server/http/BadJSONTest.java
similarity index 51%
rename from cometd-java/cometd-java-server/cometd-java-server-common/src/test/java/org/cometd/server/BadJSONTest.java
rename to cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/src/test/java/org/cometd/server/http/BadJSONTest.java
index d12677f01e..06bfb4be3a 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-common/src/test/java/org/cometd/server/BadJSONTest.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/src/test/java/org/cometd/server/http/BadJSONTest.java
@@ -13,92 +13,80 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.cometd.server;
-
-import java.io.IOException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+package org.cometd.server.http;
import org.cometd.bayeux.Message;
import org.cometd.common.JSONContext;
import org.cometd.common.JettyJSONContextClient;
-import org.cometd.server.http.JSONTransport;
import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.client.Request;
import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class BadJSONTest extends AbstractBayeuxClientServerTest {
- @Test
- public void testBadJSON() throws Exception {
- startServer(JSONTransport.class.getName(), null);
-
- JSONTransport transport = new JSONTransport(bayeux) {
- @Override
- protected void handleJSONParseException(HttpServletRequest request, HttpServletResponse response, String json, Throwable exception) throws IOException {
- // Suppress logging during tests
- if (!response.isCommitted()) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- }
- }
- };
- transport.init();
- bayeux.setTransports(transport);
-
- Request handshake = newBayeuxRequest("[{" +
- "\"channel\": \"/meta/handshake\"," +
- "\"version\": \"1.0\"," +
- "\"minimumVersion\": \"1.0\"," +
- "\"supportedConnectionTypes\": [\"long-polling\"]" +
- "}]");
+ @ParameterizedTest
+ @MethodSource("transports")
+ public void testBadJSON(Transport transport) throws Exception {
+ startServer(transport, null);
+
+ Request handshake = newBayeuxRequest("""
+ [{
+ "channel": "/meta/handshake",
+ "version": "1.0",
+ "minimumVersion": "1.0",
+ "supportedConnectionTypes": ["long-polling"]
+ }]
+ """);
ContentResponse response = handshake.send();
Assertions.assertEquals(200, response.getStatus());
String clientId = extractClientId(response);
- Request connect = newBayeuxRequest("[{" +
- "\"channel\": \"/meta/connect\"," +
- "\"clientId\": \"" + clientId + "\"," +
- "\"connectionType\": \"long-polling\"" +
- "}]");
+ Request connect = newBayeuxRequest("""
+ [{
+ "channel": "/meta/connect",
+ "clientId": "%s",
+ "connectionType": "long-polling"
+ }]
+ """.formatted(clientId));
response = connect.send();
Assertions.assertEquals(200, response.getStatus());
- // Forge a bad JSON message
- Request badConnect = newBayeuxRequest("[{" +
- "\"channel\": \"/meta/connect\"," +
- "\"clientId\": \"" + clientId + "\"," +
- "\"connectionType\": \"long-polling\"");
- //"}]"); Bad JSON, missing this line
+ // Forge a bad JSON message, missing the closing brackets.
+ Request badConnect = newBayeuxRequest("""
+ [{
+ "channel": "/meta/connect",
+ "clientId": "%s",
+ "connectionType": "long-polling"
+ """.formatted(clientId));
response = badConnect.send();
Assertions.assertEquals(400, response.getStatus());
}
@ParameterizedTest
@MethodSource("transports")
- public void testValidation(String serverTransport) throws Exception {
- startServer(serverTransport, null);
+ public void testValidation(Transport transport) throws Exception {
+ startServer(transport, null);
Request handshake = newBayeuxRequest("[{" +
- "\"channel\": \"/meta/handshake\"," +
- "\"version\": \"1.0\"," +
- "\"minimumVersion\": \"1.0\"," +
- "\"supportedConnectionTypes\": [\"long-polling\"]" +
- "}]");
+ "\"channel\": \"/meta/handshake\"," +
+ "\"version\": \"1.0\"," +
+ "\"minimumVersion\": \"1.0\"," +
+ "\"supportedConnectionTypes\": [\"long-polling\"]" +
+ "}]");
ContentResponse response = handshake.send();
Assertions.assertEquals(200, response.getStatus());
String clientId = extractClientId(response);
Request connect = newBayeuxRequest("[{" +
- "\"id\": \"\"," +
- "\"channel\": \"/meta/connect\"," +
- "\"clientId\": \"" + clientId + "\"," +
- "\"connectionType\": \"long-polling\"" +
- "}]");
+ "\"id\": \"\"," +
+ "\"channel\": \"/meta/connect\"," +
+ "\"clientId\": \"" + clientId + "\"," +
+ "\"connectionType\": \"long-polling\"" +
+ "}]");
response = connect.send();
Assertions.assertEquals(200, response.getStatus());
JSONContext.Client jsonContext = new JettyJSONContextClient();
@@ -107,10 +95,10 @@ public void testValidation(String serverTransport) throws Exception {
Assertions.assertFalse(reply.isSuccessful());
Request subscribe = newBayeuxRequest("[{" +
- "\"channel\": \"/meta/subscribe\"," +
- "\"clientId\": \"" + clientId + "\"," +
- "\"subscription\": \"/bar";
Request publish = newBayeuxRequest("[{" +
- "\"channel\": \"" + unfiltered + "\"," +
- "\"clientId\": \"" + clientId + "\"," +
- "\"data\": {" +
- " \"message\": \"" + script + "\"" +
- "}" +
- "}]");
+ "\"channel\": \"" + unfiltered + "\"," +
+ "\"clientId\": \"" + clientId + "\"," +
+ "\"data\": {" +
+ " \"message\": \"" + script + "\"" +
+ "}" +
+ "}]");
response = publish.send();
Assertions.assertEquals(200, response.getStatus());
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/src/test/resources/jetty-logging.properties b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/src/test/resources/jetty-logging.properties
new file mode 100644
index 0000000000..6a0fcfb868
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/cometd-java-server-http-tests/src/test/resources/jetty-logging.properties
@@ -0,0 +1,3 @@
+## Levels: ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF.
+#org.cometd.LEVEL=DEBUG
+#org.eclipse.jetty.LEVEL=DEBUG
diff --git a/cometd-java/cometd-java-server/cometd-java-server-http/pom.xml b/cometd-java/cometd-java-server/cometd-java-server-http/pom.xml
new file mode 100644
index 0000000000..b83becc5c2
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-http/pom.xml
@@ -0,0 +1,19 @@
+
+
+
+ org.cometd.java
+ cometd-java-server
+ 8.0.0-SNAPSHOT
+
+
+ 4.0.0
+ cometd-java-server-http
+ pom
+ CometD :: Java :: Server :: HTTP
+
+
+ cometd-java-server-http-jakarta
+ cometd-java-server-http-jetty
+ cometd-java-server-http-tests
+
+
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-common/pom.xml b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-common/pom.xml
index 102902fbc8..9b8fdc2ac0 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-common/pom.xml
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-common/pom.xml
@@ -11,10 +11,6 @@
CometD :: Java :: Server :: WebSocket :: Common
-
- jakarta.servlet
- jakarta.servlet-api
-
org.cometd.java
cometd-java-api-server
@@ -39,18 +35,5 @@
org.slf4j
slf4j-api
-
-
- org.junit.jupiter
- junit-jupiter
-
-
- org.apache.logging.log4j
- log4j-core
-
-
- org.apache.logging.log4j
- log4j-slf4j2-impl
-
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-common/src/main/java/org/cometd/server/websocket/common/AbstractBayeuxContext.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-common/src/main/java/org/cometd/server/websocket/common/AbstractBayeuxContext.java
index 1d101998fb..105b316c08 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-common/src/main/java/org/cometd/server/websocket/common/AbstractBayeuxContext.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-common/src/main/java/org/cometd/server/websocket/common/AbstractBayeuxContext.java
@@ -16,15 +16,14 @@
package org.cometd.server.websocket.common;
import java.net.HttpCookie;
-import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.security.Principal;
import java.text.ParseException;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
-import jakarta.servlet.ServletContext;
-import jakarta.servlet.http.HttpSession;
+
import org.cometd.bayeux.server.BayeuxContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,26 +31,24 @@
public abstract class AbstractBayeuxContext implements BayeuxContext {
private static final Logger logger = LoggerFactory.getLogger(BayeuxContext.class);
- private final ServletContext context;
private final String url;
+ private final String contextPath;
private final Map> headers;
private final Map> parameters;
private final Principal principal;
- private final HttpSession session;
- private final InetSocketAddress localAddress;
- private final InetSocketAddress remoteAddress;
+ private final SocketAddress localAddress;
+ private final SocketAddress remoteAddress;
private final List locales;
private final String protocol;
private final boolean secure;
- public AbstractBayeuxContext(ServletContext context, String uri, String query, Map> headers, Map> parameters, Principal principal, HttpSession session, InetSocketAddress local, InetSocketAddress remote, List locales, String protocol, boolean secure) {
- this.context = context;
+ public AbstractBayeuxContext(String uri, String contextPath, String query, Map> headers, Map> parameters, Principal principal, SocketAddress local, SocketAddress remote, List locales, String protocol, boolean secure) {
this.url = uri + (query == null ? "" : "?" + query);
+ this.contextPath = contextPath;
this.headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
this.headers.putAll(headers);
this.parameters = parameters;
this.principal = principal;
- this.session = session;
this.localAddress = local;
this.remoteAddress = remote;
this.locales = locales;
@@ -97,36 +94,12 @@ public boolean isUserInRole(String role) {
}
@Override
- public String getHttpSessionId() {
- return session == null ? null : session.getId();
- }
-
- @Override
- public Object getHttpSessionAttribute(String name) {
- return session == null ? null : session.getAttribute(name);
- }
-
- @Override
- public void setHttpSessionAttribute(String name, Object value) {
- if (session != null) {
- session.setAttribute(name, value);
- }
- }
-
- @Override
- public void invalidateHttpSession() {
- if (session != null) {
- session.invalidate();
- }
- }
-
- @Override
- public InetSocketAddress getRemoteAddress() {
+ public SocketAddress getRemoteAddress() {
return remoteAddress;
}
@Override
- public InetSocketAddress getLocalAddress() {
+ public SocketAddress getLocalAddress() {
return localAddress;
}
@@ -156,23 +129,23 @@ public String getCookie(String name) {
}
@Override
- public Object getRequestAttribute(String name) {
+ public Object getContextAttribute(String name) {
return null;
}
@Override
- public Object getContextAttribute(String name) {
- return context.getAttribute(name);
+ public Object getRequestAttribute(String name) {
+ return null;
}
@Override
- public String getContextInitParameter(String name) {
- return context.getInitParameter(name);
+ public Object getSessionAttribute(String name) {
+ return null;
}
@Override
public String getContextPath() {
- return context.getContextPath();
+ return contextPath;
}
@Override
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-common/src/main/java/org/cometd/server/websocket/common/AbstractWebSocketEndPoint.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-common/src/main/java/org/cometd/server/websocket/common/AbstractWebSocketEndPoint.java
index cfbdd64e87..23b1efba36 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-common/src/main/java/org/cometd/server/websocket/common/AbstractWebSocketEndPoint.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-common/src/main/java/org/cometd/server/websocket/common/AbstractWebSocketEndPoint.java
@@ -16,7 +16,7 @@
package org.cometd.server.websocket.common;
import java.io.IOException;
-import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.text.ParseException;
import java.util.ArrayDeque;
@@ -38,7 +38,6 @@
import org.cometd.server.AbstractServerTransport;
import org.cometd.server.ServerMessageImpl;
import org.cometd.server.ServerSessionImpl;
-import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.IteratingCallback;
import org.eclipse.jetty.util.thread.AutoLock;
import org.eclipse.jetty.util.thread.Scheduler;
@@ -58,7 +57,7 @@ protected AbstractWebSocketEndPoint(AbstractWebSocketTransport transport, Bayeux
this._bayeuxContext = context;
}
- protected abstract void send(ServerSession session, String data, Callback callback);
+ protected abstract void send(ServerSession session, String data, Promise promise);
public abstract void close(int code, String reason);
@@ -109,7 +108,7 @@ public void onError(Throwable failure) {
_logger.debug("WebSocket timeout on {}", this, failure);
}
} else {
- InetSocketAddress address = _bayeuxContext == null ? null : _bayeuxContext.getRemoteAddress();
+ SocketAddress address = _bayeuxContext == null ? null : _bayeuxContext.getRemoteAddress();
if (_logger.isDebugEnabled()) {
_logger.debug("WebSocket failure, address {} on {}", address, this, failure);
}
@@ -125,15 +124,15 @@ private void processMessages(ServerMessage.Mutable[] messages, Promise pro
ServerMessage.Mutable m = messages[0];
if (Channel.META_HANDSHAKE.equals(m.getChannel())) {
_session = null;
- session = _transport.getBayeux().newServerSession();
+ session = _transport.getBayeuxServer().newServerSession();
session.setAllowMessageDeliveryDuringHandshake(_transport.isAllowMessageDeliveryDuringHandshake());
} else {
session = _session;
if (session == null) {
if (!_transport.isRequireHandshakePerConnection()) {
- session = _session = (ServerSessionImpl)_transport.getBayeux().getSession(m.getClientId());
+ session = _session = (ServerSessionImpl)_transport.getBayeuxServer().getSession(m.getClientId());
}
- } else if (_transport.getBayeux().getSession(session.getId()) == null) {
+ } else if (_transport.getBayeuxServer().getSession(session.getId()) == null) {
session = _session = null;
}
}
@@ -199,7 +198,7 @@ private void processMessage(ServerMessage.Mutable[] messages, Context context, S
private void processMetaHandshake(Context context, ServerMessage.Mutable message, Promise promise) {
ServerSessionImpl session = context.session;
- _transport.getBayeux().handle(session, message, Promise.from(reply -> {
+ _transport.getBayeuxServer().handle(session, message, Promise.from(reply -> {
_transport.processReply(session, reply, Promise.from(r -> {
if (r != null) {
context.replies.add(r);
@@ -218,7 +217,7 @@ private void processMetaConnect(Context context, ServerMessage.Mutable message,
ServerSessionImpl session = context.session;
// Remember the connected status before handling the message.
boolean wasConnected = session != null && session.isConnected();
- _transport.getBayeux().handle(session, message, Promise.from(reply -> {
+ _transport.getBayeuxServer().handle(session, message, Promise.from(reply -> {
boolean proceed = true;
if (session != null) {
boolean maySuspend = !session.shouldSchedule();
@@ -241,7 +240,7 @@ private void processMetaConnect(Context context, ServerMessage.Mutable message,
private void processMessage(Context context, ServerMessageImpl message, Promise promise) {
ServerSessionImpl session = context.session;
- _transport.getBayeux().handle(session, message, Promise.from(y ->
+ _transport.getBayeuxServer().handle(session, message, Promise.from(y ->
_transport.processReply(session, message.getAssociated(), Promise.from(reply -> {
if (reply != null) {
context.replies.add(reply);
@@ -333,7 +332,7 @@ private class WebSocketScheduler implements AbstractServerTransport.Scheduler, R
public WebSocketScheduler(Context context, ServerMessage.Mutable message, long timeout) {
this.context = context;
this.message = message;
- this.taskRef = new AtomicMarkableReference<>(timeout > 0 ? _transport.getBayeux().schedule(this, timeout) : null, true);
+ this.taskRef = new AtomicMarkableReference<>(timeout > 0 ? _transport.getBayeuxServer().schedule(this, timeout) : null, true);
context.metaConnectCycle = _transport.newMetaConnectCycle();
}
@@ -387,7 +386,7 @@ private void flush(Context context) {
}
private void executeFlush(Context context, Promise promise) {
- _transport.getBayeux().execute(() -> AbstractWebSocketEndPoint.this.flush(context, promise));
+ _transport.getBayeuxServer().execute(() -> AbstractWebSocketEndPoint.this.flush(context, promise));
}
@Override
@@ -454,7 +453,7 @@ public String toString() {
}
}
- private class Flusher extends IteratingCallback {
+ private class Flusher extends IteratingCallback implements Promise {
private final AutoLock _lock = new AutoLock();
private final Queue _entries = new ArrayDeque<>();
private State _state = State.IDLE;
@@ -506,7 +505,7 @@ protected Action process() {
if (_transport.allowMessageDeliveryDuringHandshake(_session) && !queue.isEmpty()) {
reply.put("x-messages", queue.size());
}
- _transport.getBayeux().freeze(reply);
+ _transport.getBayeuxServer().freeze(reply);
_buffer.setLength(0);
_buffer.append("[");
_buffer.append(toJSON(reply));
@@ -560,7 +559,7 @@ protected Action process() {
boolean comma = false;
while (_replyIndex < size) {
ServerMessage.Mutable reply = replies.get(_replyIndex);
- _transport.getBayeux().freeze(reply);
+ _transport.getBayeuxServer().freeze(reply);
if (comma) {
_buffer.append(",");
}
@@ -591,6 +590,16 @@ protected Action process() {
}
}
+ @Override
+ public void succeed(Void result) {
+ succeeded();
+ }
+
+ @Override
+ public void fail(Throwable failure) {
+ failed(failure);
+ }
+
@Override
protected void onCompleteFailure(Throwable x) {
List entries;
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/pom.xml b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/pom.xml
index 6fac72f87f..707641bc0b 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/pom.xml
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/pom.xml
@@ -8,7 +8,7 @@
4.0.0
cometd-java-server-websocket-jakarta
- CometD :: Java :: Server :: WebSocket :: EE10
+ CometD :: Java :: Server :: WebSocket :: Jakarta EE10
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/src/main/java/module-info.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/src/main/java/module-info.java
index fb2ce40345..cb703d6a5d 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/src/main/java/module-info.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/src/main/java/module-info.java
@@ -19,4 +19,5 @@
requires transitive jakarta.websocket;
requires transitive org.cometd.server.websocket.common;
requires org.slf4j;
+ requires jakarta.servlet;
}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/src/main/java/org/cometd/server/websocket/jakarta/WebSocketEndPoint.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/src/main/java/org/cometd/server/websocket/jakarta/WebSocketEndPoint.java
index 449a33d2f8..8938f67d45 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/src/main/java/org/cometd/server/websocket/jakarta/WebSocketEndPoint.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/src/main/java/org/cometd/server/websocket/jakarta/WebSocketEndPoint.java
@@ -29,7 +29,6 @@
import org.cometd.bayeux.server.ServerSession;
import org.cometd.server.websocket.common.AbstractWebSocketEndPoint;
import org.cometd.server.websocket.common.AbstractWebSocketTransport;
-import org.eclipse.jetty.util.Callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -94,7 +93,7 @@ public Delegate(AbstractWebSocketTransport transport, BayeuxContext bayeuxContex
}
@Override
- protected void send(ServerSession session, String data, Callback callback) {
+ protected void send(ServerSession session, String data, Promise promise) {
if (_logger.isDebugEnabled()) {
_logger.debug("Sending {} on {}", data, this);
}
@@ -102,9 +101,9 @@ protected void send(ServerSession session, String data, Callback callback) {
_wsSession.getAsyncRemote().sendText(data, result -> {
Throwable failure = result.getException();
if (failure == null) {
- callback.succeeded();
+ promise.succeed(null);
} else {
- callback.failed(failure);
+ promise.fail(failure);
}
});
}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/src/main/java/org/cometd/server/websocket/jakarta/WebSocketTransport.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/src/main/java/org/cometd/server/websocket/jakarta/WebSocketTransport.java
index 8544ae5846..350b5e7063 100755
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/src/main/java/org/cometd/server/websocket/jakarta/WebSocketTransport.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jakarta/src/main/java/org/cometd/server/websocket/jakarta/WebSocketTransport.java
@@ -15,13 +15,16 @@
*/
package org.cometd.server.websocket.jakarta;
-import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import java.util.function.Function;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpSession;
import jakarta.websocket.DeploymentException;
@@ -51,7 +54,7 @@ public WebSocketTransport(BayeuxServerImpl bayeux) {
public void init() {
super.init();
- ServletContext context = (ServletContext)getOption(ServletContext.class.getName());
+ ServletContext context = (ServletContext)getBayeuxServer().getOption(ServletContext.class.getName());
if (context == null) {
throw new IllegalArgumentException("Missing ServletContext");
}
@@ -105,15 +108,57 @@ protected Object newWebSocketEndPoint(BayeuxContext bayeuxContext) {
return new EndPoint(bayeuxContext);
}
- private static class WebSocketContext extends AbstractBayeuxContext {
- private WebSocketContext(ServletContext context, HandshakeRequest request, Map userProperties) {
- super(context, request.getRequestURI().toString(), request.getQueryString(), request.getHeaders(),
- request.getParameterMap(), request.getUserPrincipal(), (HttpSession)request.getHttpSession(),
+ private static class JakartaWebSocketContext extends AbstractBayeuxContext {
+ private final Map contextAttributes;
+ private final Map requestAttributes;
+ private final Map sessionAttributes;
+
+ private JakartaWebSocketContext(ServletContext context, HandshakeRequest request, Map userProperties) {
+ super(request.getRequestURI().toString(), context.getContextPath(), request.getQueryString(), request.getHeaders(),
+ request.getParameterMap(), request.getUserPrincipal(),
// Hopefully these will become a standard, for now they are Jetty specific.
- (InetSocketAddress)userProperties.get("jakarta.websocket.endpoint.localAddress"),
- (InetSocketAddress)userProperties.get("jakarta.websocket.endpoint.remoteAddress"),
+ (SocketAddress)userProperties.get("jakarta.websocket.endpoint.localAddress"),
+ (SocketAddress)userProperties.get("jakarta.websocket.endpoint.remoteAddress"),
WebSocketTransport.retrieveLocales(userProperties), "HTTP/1.1",
WebSocketTransport.isSecure(request));
+ contextAttributes = Map.copyOf(attributesToMap(context));
+ requestAttributes = Map.of();
+ sessionAttributes = Map.copyOf(attributesToMap((HttpSession)request.getHttpSession()));
+ }
+
+ private static Map attributesToMap(ServletContext context) {
+ return attributesToMap(context.getAttributeNames(), context::getAttribute);
+ }
+
+ private static Map attributesToMap(HttpSession session) {
+ if (session == null) {
+ return Map.of();
+ }
+ return attributesToMap(session.getAttributeNames(), session::getAttribute);
+ }
+
+ private static Map attributesToMap(Enumeration names, Function getter) {
+ Map result = new HashMap<>();
+ while (names.hasMoreElements()) {
+ String name = names.nextElement();
+ result.put(name, getter.apply(name));
+ }
+ return result;
+ }
+
+ @Override
+ public Object getContextAttribute(String name) {
+ return contextAttributes.get(name);
+ }
+
+ @Override
+ public Object getRequestAttribute(String name) {
+ return requestAttributes.get(name);
+ }
+
+ @Override
+ public Object getSessionAttribute(String name) {
+ return sessionAttributes.get(name);
}
}
@@ -141,7 +186,7 @@ private Configurator(ServletContext servletContext) {
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
BayeuxContextHolder context = provideContext();
- context.bayeuxContext = new WebSocketContext(servletContext, request, sec.getUserProperties());
+ context.bayeuxContext = new JakartaWebSocketContext(servletContext, request, sec.getUserProperties());
WebSocketTransport.this.modifyHandshake(request, response);
}
@@ -183,7 +228,7 @@ public List getNegotiatedExtensions(List installed, List T getEndpointInstance(Class endpointClass) throws InstantiationException {
BayeuxContextHolder holder = provideContext();
- if (!getBayeux().getAllowedTransports().contains(getName())) {
+ if (!getBayeuxServer().getAllowedTransports().contains(getName())) {
throw new InstantiationException("Transport not allowed");
}
if (!holder.protocolMatches) {
@@ -223,7 +268,7 @@ private BayeuxContextHolder provideContext() {
private static class BayeuxContextHolder {
private static final ThreadLocal holder = new ThreadLocal<>();
- private WebSocketContext bayeuxContext;
+ private JakartaWebSocketContext bayeuxContext;
private boolean protocolMatches;
public void clear() {
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/pom.xml b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/pom.xml
index 431b476ea6..8701da656f 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/pom.xml
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/pom.xml
@@ -21,10 +21,9 @@
${project.version}
- org.eclipse.jetty.ee10.websocket
- jetty-ee10-websocket-jetty-server
+ org.eclipse.jetty.websocket
+ jetty-websocket-jetty-server
${jetty-version}
- provided
org.slf4j
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/src/main/java/module-info.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/src/main/java/module-info.java
index 91017da461..81bf6aeb55 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/src/main/java/module-info.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/src/main/java/module-info.java
@@ -17,6 +17,6 @@
exports org.cometd.server.websocket.jetty;
requires transitive org.cometd.server.websocket.common;
- requires transitive org.eclipse.jetty.ee10.websocket.jetty.server;
+ requires transitive org.eclipse.jetty.websocket.server;
requires org.slf4j;
}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/src/main/java/org/cometd/server/websocket/jetty/JettyWebSocketEndPoint.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/src/main/java/org/cometd/server/websocket/jetty/JettyWebSocketEndPoint.java
index ba2ef33eaa..e4997dcb0a 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/src/main/java/org/cometd/server/websocket/jetty/JettyWebSocketEndPoint.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/src/main/java/org/cometd/server/websocket/jetty/JettyWebSocketEndPoint.java
@@ -19,7 +19,6 @@
import org.cometd.bayeux.server.BayeuxContext;
import org.cometd.bayeux.server.ServerSession;
import org.cometd.server.websocket.common.AbstractWebSocketEndPoint;
-import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.websocket.api.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -59,21 +58,20 @@ public void onWebSocketError(Throwable failure) {
}
@Override
- protected void send(ServerSession session, String data, Callback callback) {
+ protected void send(ServerSession session, String data, Promise promise) {
if (_logger.isDebugEnabled()) {
_logger.debug("Sending {} on {}", data, this);
}
- // Async version.
_wsSession.sendText(data, new org.eclipse.jetty.websocket.api.Callback() {
@Override
public void succeed() {
- callback.succeeded();
+ promise.succeed(null);
}
@Override
public void fail(Throwable x) {
- callback.failed(x);
+ promise.fail(x);
}
});
}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/src/main/java/org/cometd/server/websocket/jetty/JettyWebSocketTransport.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/src/main/java/org/cometd/server/websocket/jetty/JettyWebSocketTransport.java
index c9f2a411aa..814671f95f 100755
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/src/main/java/org/cometd/server/websocket/jetty/JettyWebSocketTransport.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-jetty/src/main/java/org/cometd/server/websocket/jetty/JettyWebSocketTransport.java
@@ -15,24 +15,26 @@
*/
package org.cometd.server.websocket.jetty;
-import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.ArrayList;
-import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import jakarta.servlet.ServletContext;
-import jakarta.servlet.http.HttpSession;
import org.cometd.bayeux.server.BayeuxContext;
import org.cometd.bayeux.server.ServerMessage;
import org.cometd.server.BayeuxServerImpl;
import org.cometd.server.websocket.common.AbstractBayeuxContext;
import org.cometd.server.websocket.common.AbstractWebSocketTransport;
-import org.eclipse.jetty.ee10.websocket.server.JettyServerUpgradeRequest;
-import org.eclipse.jetty.ee10.websocket.server.JettyServerUpgradeResponse;
-import org.eclipse.jetty.ee10.websocket.server.JettyWebSocketServerContainer;
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.server.Context;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Session;
+import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.websocket.api.ExtensionConfig;
+import org.eclipse.jetty.websocket.server.ServerUpgradeRequest;
+import org.eclipse.jetty.websocket.server.ServerUpgradeResponse;
+import org.eclipse.jetty.websocket.server.ServerWebSocketContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,9 +49,9 @@ public JettyWebSocketTransport(BayeuxServerImpl bayeux) {
public void init() {
super.init();
- ServletContext context = (ServletContext)getOption(ServletContext.class.getName());
+ Context context = (Context)getBayeuxServer().getOption(Context.class.getName());
if (context == null) {
- throw new IllegalArgumentException("Missing ServletContext");
+ throw new IllegalArgumentException("Missing Context");
}
String cometdURLMapping = (String)getOption(COMETD_URL_MAPPING_OPTION);
@@ -57,7 +59,7 @@ public void init() {
throw new IllegalArgumentException("Missing '" + COMETD_URL_MAPPING_OPTION + "' parameter");
}
- JettyWebSocketServerContainer container = JettyWebSocketServerContainer.getContainer(context);
+ ServerWebSocketContainer container = ServerWebSocketContainer.get(context);
if (container == null) {
throw new IllegalArgumentException("Missing JettyWebSocketServerContainer");
}
@@ -74,10 +76,10 @@ public void init() {
container.setIdleTimeout(Duration.ofMillis(idleTimeout));
for (String mapping : normalizeURLMapping(cometdURLMapping)) {
- container.addMapping(mapping, (request, response) -> {
- String origin = request.getHeader("Origin");
+ container.addMapping(mapping, (request, response, callback) -> {
+ String origin = request.getHeaders().get("Origin");
if (origin == null) {
- origin = request.getHeader("Sec-WebSocket-Origin");
+ origin = request.getHeaders().get("Sec-WebSocket-Origin");
}
if (checkOrigin(request, origin)) {
List negotiated = new ArrayList<>();
@@ -92,9 +94,9 @@ public void init() {
modifyUpgrade(request, response);
- List allowedTransports = getBayeux().getAllowedTransports();
+ List allowedTransports = getBayeuxServer().getAllowedTransports();
if (allowedTransports.contains(getName())) {
- WebSocketContext handshake = new WebSocketContext(context, request);
+ JettyWebSocketContext handshake = new JettyWebSocketContext(request);
Object instance = newWebSocketEndPoint(handshake);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Created {}", instance);
@@ -119,35 +121,74 @@ protected Object newWebSocketEndPoint(BayeuxContext bayeuxContext) {
return new EndPoint(bayeuxContext);
}
- protected void modifyUpgrade(JettyServerUpgradeRequest request, JettyServerUpgradeResponse response) {
+ protected void modifyUpgrade(ServerUpgradeRequest request, ServerUpgradeResponse response) {
}
- protected boolean checkOrigin(JettyServerUpgradeRequest request, String origin) {
+ protected boolean checkOrigin(ServerUpgradeRequest request, String origin) {
return true;
}
- private static class WebSocketContext extends AbstractBayeuxContext {
- private final Map attributes;
+ private static class JettyWebSocketContext extends AbstractBayeuxContext {
+ private final Map contextAttributes;
+ private final Map requestAttributes;
+ private final Map sessionAttributes;
+
+ private JettyWebSocketContext(ServerUpgradeRequest request) {
+ super(request.getHttpURI().toString(), request.getContext().getContextPath(), null, headersToMap(request),
+ queryToMap(request), /*TODO*/null,
+ request.getConnectionMetaData().getLocalSocketAddress(), request.getConnectionMetaData().getRemoteSocketAddress(),
+ Request.getLocales(request), "HTTP/1.1", request.isSecure());
+ this.contextAttributes = Map.copyOf(request.getContext().asAttributeMap());
+ this.requestAttributes = Map.copyOf(request.asAttributeMap());
+ Session session = request.getSession(false);
+ this.sessionAttributes = session == null ? Map.of() : Map.copyOf(session.asAttributeMap());
+ }
+
+ private static Map> headersToMap(ServerUpgradeRequest request) {
+ HttpFields headers = request.getHeaders();
+ Map> result = new LinkedHashMap<>();
+ headers.forEach(field -> {
+ String name = field.getName();
+ result.compute(name, (k, v) -> {
+ if (v == null) {
+ v = new ArrayList<>(1);
+ }
+ v.addAll(field.getValueList());
+ return v;
+ });
+ });
+ return result;
+ }
+
+ private static Map> queryToMap(ServerUpgradeRequest request) {
+ Fields fields = Request.extractQueryParameters(request);
+ Map> result = new LinkedHashMap<>();
+ fields.forEach(field -> {
+ String name = field.getName();
+ result.compute(name, (k, v) -> {
+ if (v == null) {
+ v = new ArrayList<>(1);
+ }
+ v.addAll(field.getValues());
+ return v;
+ });
+ });
+ return result;
+ }
- private WebSocketContext(ServletContext context, JettyServerUpgradeRequest request) {
- super(context, request.getRequestURI().toString(), request.getQueryString(), request.getHeaders(),
- request.getParameterMap(), request.getUserPrincipal(), getHttpSession(request),
- (InetSocketAddress)request.getLocalSocketAddress(), (InetSocketAddress)request.getRemoteSocketAddress(),
- Collections.list(request.getLocales()), "HTTP/1.1", request.isSecure());
- this.attributes = request.getServletAttributes();
+ @Override
+ public Object getContextAttribute(String name) {
+ return contextAttributes.get(name);
}
@Override
public Object getRequestAttribute(String name) {
- return attributes.get(name);
+ return requestAttributes.get(name);
}
- private static HttpSession getHttpSession(JettyServerUpgradeRequest request) {
- try {
- return (HttpSession)request.getSession();
- } catch (Throwable x) {
- return null;
- }
+ @Override
+ public Object getSessionAttribute(String name) {
+ return sessionAttributes.get(name);
}
}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/pom.xml b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/pom.xml
index 702b641b36..a1fa513f77 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/pom.xml
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/pom.xml
@@ -15,18 +15,6 @@
-
- org.junit.jupiter
- junit-jupiter
-
-
- org.apache.logging.log4j
- log4j-core
-
-
- org.apache.logging.log4j
- log4j-slf4j2-impl
-
jakarta.servlet
jakarta.servlet-api
@@ -63,7 +51,13 @@
org.cometd.java
- cometd-java-server-common
+ cometd-java-server-http-jakarta
+ ${project.version}
+ test
+
+
+ org.cometd.java
+ cometd-java-server-http-jetty
${project.version}
test
@@ -110,8 +104,8 @@
test
- org.eclipse.jetty.ee10.websocket
- jetty-ee10-websocket-jetty-server
+ org.eclipse.jetty.websocket
+ jetty-websocket-jetty-server
${jetty-version}
test
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BatchedRepliesWebSocketTest.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BatchedRepliesWebSocketTest.java
index e12a55bf06..de505b2fcc 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BatchedRepliesWebSocketTest.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BatchedRepliesWebSocketTest.java
@@ -32,8 +32,8 @@
public class BatchedRepliesWebSocketTest extends ClientServerWebSocketTest {
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testBatchedReplies(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testBatchedReplies(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
AtomicReference> batch = new AtomicReference<>();
@@ -42,7 +42,6 @@ public void testBatchedReplies(String wsType) throws Exception {
case WEBSOCKET_JAKARTA -> new WSTransport(batch, repliesLatch);
case WEBSOCKET_JETTY -> new JettyWSTransport(batch, repliesLatch);
case WEBSOCKET_OKHTTP -> new OkWSTransport(batch, repliesLatch);
- default -> throw new IllegalArgumentException();
};
BayeuxClient client = new BayeuxClient(cometdURL, transport);
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BayeuxClientTest.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BayeuxClientTest.java
index a759d61ce9..0ba6ac185b 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BayeuxClientTest.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BayeuxClientTest.java
@@ -15,22 +15,11 @@
*/
package org.cometd.server.websocket;
-import java.io.IOException;
-import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
-import jakarta.servlet.DispatcherType;
-import jakarta.servlet.Filter;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.FilterConfig;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.ServletRequest;
-import jakarta.servlet.ServletResponse;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.servlet.http.HttpServletResponseWrapper;
import org.cometd.bayeux.Channel;
import org.cometd.bayeux.MarkedReference;
@@ -47,8 +36,8 @@
import org.cometd.client.http.jetty.JettyHttpClientTransport;
import org.cometd.client.transport.ClientTransport;
import org.cometd.common.HashMapMessage;
+import org.cometd.server.BayeuxServerImpl;
import org.cometd.server.DefaultSecurityPolicy;
-import org.eclipse.jetty.ee10.servlet.FilterHolder;
import org.eclipse.jetty.util.BlockingArrayQueue;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
@@ -57,16 +46,16 @@
public class BayeuxClientTest extends ClientServerWebSocketTest {
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testHandshakeDenied(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testHandshakeDenied(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
BayeuxClient client = newBayeuxClient(wsType);
long backOffIncrement = 500;
client.setBackOffStrategy(new BayeuxClient.BackOffStrategy.Linear(backOffIncrement, -1));
- SecurityPolicy oldPolicy = bayeux.getSecurityPolicy();
- bayeux.setSecurityPolicy(new DefaultSecurityPolicy() {
+ SecurityPolicy oldPolicy = bayeuxServer.getSecurityPolicy();
+ bayeuxServer.setSecurityPolicy(new DefaultSecurityPolicy() {
@Override
public boolean canHandshake(BayeuxServer server, ServerSession session, ServerMessage message) {
return false;
@@ -88,20 +77,20 @@ public boolean canHandshake(BayeuxServer server, ServerSession session, ServerMe
Assertions.assertTrue(client.waitFor(5000, State.DISCONNECTED));
} finally {
- bayeux.setSecurityPolicy(oldPolicy);
+ bayeuxServer.setSecurityPolicy(oldPolicy);
disconnectBayeuxClient(client);
}
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testPublish(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testPublish(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
BlockingArrayQueue results = new BlockingArrayQueue<>();
String channelName = "/chat/msg";
- MarkedReference channel = bayeux.createChannelIfAbsent(channelName);
+ MarkedReference channel = bayeuxServer.createChannelIfAbsent(channelName);
channel.getReference().addListener(new ServerChannel.MessageListener() {
@Override
public boolean onMessage(ServerSession from, ServerChannel channel, Mutable message) {
@@ -128,14 +117,14 @@ public boolean onMessage(ServerSession from, ServerChannel channel, Mutable mess
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testWaitFor(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testWaitFor(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
BlockingArrayQueue results = new BlockingArrayQueue<>();
String channelName = "/chat/msg";
- MarkedReference channel = bayeux.createChannelIfAbsent(channelName);
+ MarkedReference channel = bayeuxServer.createChannelIfAbsent(channelName);
channel.getReference().addListener(new ServerChannel.MessageListener() {
@Override
public boolean onMessage(ServerSession from, ServerChannel channel, Mutable message) {
@@ -169,8 +158,8 @@ public boolean onMessage(ServerSession from, ServerChannel channel, Mutable mess
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testAuthentication(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testAuthentication(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
AtomicReference sessionId = new AtomicReference<>();
@@ -208,8 +197,8 @@ public void removed(ServerSession session, ServerMessage message, boolean timeou
}
A authenticator = new A();
- SecurityPolicy oldPolicy = bayeux.getSecurityPolicy();
- bayeux.setSecurityPolicy(authenticator);
+ SecurityPolicy oldPolicy = bayeuxServer.getSecurityPolicy();
+ bayeuxServer.setSecurityPolicy(authenticator);
try {
BayeuxClient client = newBayeuxClient(wsType);
@@ -227,13 +216,13 @@ public void removed(ServerSession session, ServerMessage message, boolean timeou
Assertions.assertNull(sessionId.get());
} finally {
- bayeux.setSecurityPolicy(oldPolicy);
+ bayeuxServer.setSecurityPolicy(oldPolicy);
}
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testClient(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testClient(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
BayeuxClient client = newBayeuxClient(wsType);
@@ -292,12 +281,12 @@ public void testClient(String wsType) throws Exception {
@Disabled("TODO: verify why it does not work; I suspect the setAllowedTransport() does not play since the WSUpgradeFilter kicks in first")
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testHandshakeOverWebSocketReportsHTTPFailure(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testHandshakeOverWebSocketReportsHTTPFailure(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
// No transports on server, to make the client fail
- bayeux.setAllowedTransports();
+ ((BayeuxServerImpl)bayeuxServer).setAllowedTransports();
BayeuxClient client = newBayeuxClient(wsType);
CountDownLatch latch = new CountDownLatch(1);
@@ -328,36 +317,37 @@ public void testHandshakeOverWebSocketReportsHTTPFailure(String wsType) throws E
// response so they cannot be removed/intercepted before they are sent to the client.
@Disabled
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testWebSocketResponseHeadersRemoved(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testWebSocketResponseHeadersRemoved(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
- context.addFilter(new FilterHolder(new Filter() {
- @Override
- public void init(FilterConfig filterConfig) {
- }
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- try {
- // Wrap the response to remove the header
- chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse)response) {
- @Override
- public void addHeader(String name, String value) {
- if (!"Sec-WebSocket-Accept".equals(name)) {
- super.addHeader(name, value);
- }
- }
- });
- } finally {
- ((HttpServletResponse)response).setHeader("Sec-WebSocket-Accept", null);
- }
- }
-
- @Override
- public void destroy() {
- }
- }), cometdServletPath, EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC));
+ // TODO
+// context.addFilter(new FilterHolder(new Filter() {
+// @Override
+// public void init(FilterConfig filterConfig) {
+// }
+//
+// @Override
+// public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+// try {
+// // Wrap the response to remove the header
+// chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse)response) {
+// @Override
+// public void addHeader(String name, String value) {
+// if (!"Sec-WebSocket-Accept".equals(name)) {
+// super.addHeader(name, value);
+// }
+// }
+// });
+// } finally {
+// ((HttpServletResponse)response).setHeader("Sec-WebSocket-Accept", null);
+// }
+// }
+//
+// @Override
+// public void destroy() {
+// }
+// }), cometdServletPath, EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC));
ClientTransport webSocketTransport = newWebSocketTransport(wsType, null);
ClientTransport longPollingTransport = newLongPollingTransport(null);
@@ -378,8 +368,8 @@ public void destroy() {
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testCustomTransportURL(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testCustomTransportURL(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
ClientTransport transport = newWebSocketTransport(wsType, cometdURL, null);
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BayeuxClientWebSocketTest.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BayeuxClientWebSocketTest.java
index 51a2dd9e06..b995ddc8a7 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BayeuxClientWebSocketTest.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BayeuxClientWebSocketTest.java
@@ -48,13 +48,14 @@
import org.cometd.server.AbstractServerTransport;
import org.cometd.server.BayeuxServerImpl;
import org.cometd.server.ext.AcknowledgedMessagesExtension;
-import org.cometd.server.http.JSONTransport;
+import org.cometd.server.http.JSONHttpTransport;
import org.cometd.server.websocket.jakarta.WebSocketTransport;
+import org.eclipse.jetty.util.BlockingArrayQueue;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;
-import org.eclipse.jetty.util.BlockingArrayQueue;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@@ -62,8 +63,8 @@
public class BayeuxClientWebSocketTest extends ClientServerWebSocketTest {
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testClientRetriesWebSocketTransportIfCannotConnect(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testClientRetriesWebSocketTransportIfCannotConnect(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
CountDownLatch connectLatch = new CountDownLatch(2);
@@ -102,8 +103,8 @@ protected void sendConnect() {
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testAbortThenRestart(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testAbortThenRestart(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
BayeuxClient client = newBayeuxClient(wsType);
@@ -133,8 +134,8 @@ public void testAbortThenRestart(String wsType) throws Exception {
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testRestart(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testRestart(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
ClientTransport webSocketTransport = newWebSocketTransport(wsType, null);
@@ -177,9 +178,10 @@ public void testRestart(String wsType) throws Exception {
disconnectBayeuxClient(client);
}
+ @Disabled("WEBSOCKET_JETTY transport does not clear previous mappings upon restart")
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testRestartAfterConnectWithFatalException(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testRestartAfterConnectWithFatalException(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
// ConnectException is a recoverable exception that does not disable the transport.
@@ -231,7 +233,6 @@ public void onFailure(Throwable failure, List extends Message> messages) {
}, messages);
}
};
- default -> throw new IllegalArgumentException();
};
BayeuxClient client = new BayeuxClient(cometdURL, webSocketTransport);
@@ -273,13 +274,13 @@ public void onFailure(Throwable failure, List extends Message> messages) {
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testHandshakeExpiration(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testHandshakeExpiration(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
long maxNetworkDelay = 2000;
- bayeux.getChannel(Channel.META_HANDSHAKE).addListener(new ServerChannel.MessageListener() {
+ bayeuxServer.getChannel(Channel.META_HANDSHAKE).addListener(new ServerChannel.MessageListener() {
@Override
public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessage.Mutable message) {
try {
@@ -317,8 +318,8 @@ public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessag
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testMetaConnectNotRespondedOnServerSidePublish(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testMetaConnectNotRespondedOnServerSidePublish(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
BayeuxClient client = newBayeuxClient(wsType);
@@ -338,10 +339,10 @@ public void testMetaConnectNotRespondedOnServerSidePublish(String wsType) throws
Thread.sleep(1000);
// Test publish triggered by an external event
- LocalSession emitter = bayeux.newLocalSession("test_emitter");
+ LocalSession emitter = bayeuxServer.newLocalSession("test_emitter");
emitter.handshake();
String data = "test_data";
- bayeux.getChannel(channelName).publish(emitter, data, Promise.noop());
+ bayeuxServer.getChannel(channelName).publish(emitter, data, Promise.noop());
Assertions.assertTrue(publishLatch.get().await(5, TimeUnit.SECONDS));
// Make sure long poll is not responded
@@ -352,11 +353,11 @@ public void testMetaConnectNotRespondedOnServerSidePublish(String wsType) throws
publishLatch.set(new CountDownLatch(1));
connectLatch.set(new CountDownLatch(1));
String serviceChannelName = "/service/test";
- ServerChannel serviceChannel = bayeux.createChannelIfAbsent(serviceChannelName, new Persistent()).getReference();
+ ServerChannel serviceChannel = bayeuxServer.createChannelIfAbsent(serviceChannelName, new Persistent()).getReference();
serviceChannel.addListener(new ServerChannel.MessageListener() {
@Override
public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessage.Mutable message) {
- bayeux.getChannel(channelName).publish(emitter, data, Promise.noop());
+ bayeuxServer.getChannel(channelName).publish(emitter, data, Promise.noop());
return true;
}
});
@@ -370,8 +371,8 @@ public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessag
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testMetaConnectDeliveryOnlyTransport(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testMetaConnectDeliveryOnlyTransport(Transport wsType) throws Exception {
Map options = new HashMap<>();
options.put(AbstractServerTransport.META_CONNECT_DELIVERY_OPTION, "true");
prepareAndStart(wsType, options);
@@ -393,10 +394,10 @@ public void testMetaConnectDeliveryOnlyTransport(String wsType) throws Exception
Thread.sleep(1000);
// Test publish triggered by an external event
- LocalSession emitter = bayeux.newLocalSession("test_emitter");
+ LocalSession emitter = bayeuxServer.newLocalSession("test_emitter");
emitter.handshake();
String data = "test_data";
- bayeux.getChannel(channelName).publish(emitter, data, Promise.noop());
+ bayeuxServer.getChannel(channelName).publish(emitter, data, Promise.noop());
Assertions.assertTrue(publishLatch.get().await(5, TimeUnit.SECONDS));
// Make sure long poll is responded
@@ -408,11 +409,11 @@ public void testMetaConnectDeliveryOnlyTransport(String wsType) throws Exception
publishLatch.set(new CountDownLatch(1));
connectLatch.set(new CountDownLatch(1));
String serviceChannelName = "/service/test";
- ServerChannel serviceChannel = bayeux.createChannelIfAbsent(serviceChannelName, new Persistent()).getReference();
+ ServerChannel serviceChannel = bayeuxServer.createChannelIfAbsent(serviceChannelName, new Persistent()).getReference();
serviceChannel.addListener(new ServerChannel.MessageListener() {
@Override
public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessage.Mutable message) {
- bayeux.getChannel(channelName).publish(emitter, data, Promise.noop());
+ bayeuxServer.getChannel(channelName).publish(emitter, data, Promise.noop());
return true;
}
});
@@ -426,11 +427,11 @@ public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessag
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testMetaConnectDeliveryOnlySession(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testMetaConnectDeliveryOnlySession(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
- bayeux.addExtension(new BayeuxServer.Extension() {
+ bayeuxServer.addExtension(new BayeuxServer.Extension() {
@Override
public boolean sendMeta(ServerSession to, ServerMessage.Mutable message) {
if (Channel.META_HANDSHAKE.equals(message.getChannel())) {
@@ -459,10 +460,10 @@ public boolean sendMeta(ServerSession to, ServerMessage.Mutable message) {
Thread.sleep(1000);
// Test publish triggered by an external event
- LocalSession emitter = bayeux.newLocalSession("test_emitter");
+ LocalSession emitter = bayeuxServer.newLocalSession("test_emitter");
emitter.handshake();
String data = "test_data";
- bayeux.getChannel(channelName).publish(emitter, data, Promise.noop());
+ bayeuxServer.getChannel(channelName).publish(emitter, data, Promise.noop());
Assertions.assertTrue(publishLatch.get().await(5, TimeUnit.SECONDS));
// Make sure long poll is responded
@@ -473,11 +474,11 @@ public boolean sendMeta(ServerSession to, ServerMessage.Mutable message) {
publishLatch.set(new CountDownLatch(1));
connectLatch.set(new CountDownLatch(1));
String serviceChannelName = "/service/test";
- ServerChannel serviceChannel = bayeux.createChannelIfAbsent(serviceChannelName, new Persistent()).getReference();
+ ServerChannel serviceChannel = bayeuxServer.createChannelIfAbsent(serviceChannelName, new Persistent()).getReference();
serviceChannel.addListener(new ServerChannel.MessageListener() {
@Override
public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessage.Mutable message) {
- bayeux.getChannel(channelName).publish(emitter, data, Promise.noop());
+ bayeuxServer.getChannel(channelName).publish(emitter, data, Promise.noop());
return true;
}
});
@@ -491,8 +492,8 @@ public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessag
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testMetaConnectExpires(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testMetaConnectExpires(Transport wsType) throws Exception {
long timeout = 2000;
Map options = new HashMap<>();
options.put(AbstractServerTransport.TIMEOUT_OPTION, String.valueOf(timeout));
@@ -515,13 +516,13 @@ public void testMetaConnectExpires(String wsType) throws Exception {
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testWebSocketWithAckExtension(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testWebSocketWithAckExtension(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
BayeuxClient client = newBayeuxClient(wsType);
- bayeux.addExtension(new AcknowledgedMessagesExtension());
+ bayeuxServer.addExtension(new AcknowledgedMessagesExtension());
client.addExtension(new AckExtension());
String channelName = "/chat/demo";
@@ -542,7 +543,7 @@ public void testWebSocketWithAckExtension(String wsType) throws Exception {
Assertions.assertTrue(subscribed.await(5, TimeUnit.SECONDS));
Assertions.assertEquals(0, messages.size());
- ServerChannel chatChannel = bayeux.getChannel(channelName);
+ ServerChannel chatChannel = bayeuxServer.getChannel(channelName);
Assertions.assertNotNull(chatChannel);
int count = 5;
@@ -598,22 +599,22 @@ public void testWebSocketWithAckExtension(String wsType) throws Exception {
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testMetaConnectDelayedOnServerRespondedBeforeRetry(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testMetaConnectDelayedOnServerRespondedBeforeRetry(Transport wsType) throws Exception {
long maxNetworkDelay = 2000;
long backoffIncrement = 2000;
testMetaConnectDelayedOnServer(wsType, maxNetworkDelay, backoffIncrement, maxNetworkDelay + backoffIncrement / 2);
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testMetaConnectDelayedOnServerRespondedAfterRetry(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testMetaConnectDelayedOnServerRespondedAfterRetry(Transport wsType) throws Exception {
long maxNetworkDelay = 2000;
long backoffIncrement = 1000;
testMetaConnectDelayedOnServer(wsType, maxNetworkDelay, backoffIncrement, maxNetworkDelay + backoffIncrement * 2);
}
- private void testMetaConnectDelayedOnServer(String wsType, long maxNetworkDelay, long backoffIncrement, long delay) throws Exception {
+ private void testMetaConnectDelayedOnServer(Transport wsType, long maxNetworkDelay, long backoffIncrement, long delay) throws Exception {
stopAndDispose();
Map initParams = new HashMap<>();
@@ -621,9 +622,9 @@ private void testMetaConnectDelayedOnServer(String wsType, long maxNetworkDelay,
initParams.put("timeout", String.valueOf(timeout));
switch (wsType) {
case WEBSOCKET_JAKARTA, WEBSOCKET_OKHTTP ->
- initParams.put("transports", CloseLatchWebSocketTransport.class.getName() + "," + JSONTransport.class.getName());
+ initParams.put("transports", CloseLatchWebSocketTransport.class.getName() + "," + JSONHttpTransport.class.getName());
case WEBSOCKET_JETTY ->
- initParams.put("transports", CloseLatchJettyWebSocketTransport.class.getName() + "," + JSONTransport.class.getName());
+ initParams.put("transports", CloseLatchJettyWebSocketTransport.class.getName() + "," + JSONHttpTransport.class.getName());
default -> throw new IllegalArgumentException();
}
prepareAndStart(wsType, initParams);
@@ -634,7 +635,7 @@ private void testMetaConnectDelayedOnServer(String wsType, long maxNetworkDelay,
BayeuxClient client = new BayeuxClient(cometdURL, webSocketTransport);
client.setOption(BayeuxClient.BACKOFF_INCREMENT_OPTION, backoffIncrement);
- bayeux.getChannel(Channel.META_CONNECT).addListener(new ServerChannel.MessageListener() {
+ bayeuxServer.getChannel(Channel.META_CONNECT).addListener(new ServerChannel.MessageListener() {
private final AtomicInteger connects = new AtomicInteger();
@Override
@@ -683,8 +684,8 @@ public void onMessage(ClientSessionChannel channel, Message message) {
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testClientSendsAndReceivesBigMessage(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testClientSendsAndReceivesBigMessage(Transport wsType) throws Exception {
int maxMessageSize = 128 * 1024;
Map serverOptions = new HashMap<>();
serverOptions.put("ws.maxMessageSize", String.valueOf(maxMessageSize));
@@ -712,14 +713,14 @@ public void testClientSendsAndReceivesBigMessage(String wsType) throws Exception
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testClientDisconnectingClosesTheConnection(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testClientDisconnectingClosesTheConnection(Transport wsType) throws Exception {
Map initParams = new HashMap<>();
switch (wsType) {
case WEBSOCKET_JAKARTA, WEBSOCKET_OKHTTP ->
- initParams.put("transports", CloseLatchWebSocketTransport.class.getName() + "," + JSONTransport.class.getName());
+ initParams.put("transports", CloseLatchWebSocketTransport.class.getName() + "," + JSONHttpTransport.class.getName());
case WEBSOCKET_JETTY ->
- initParams.put("transports", CloseLatchJettyWebSocketTransport.class.getName() + "," + JSONTransport.class.getName());
+ initParams.put("transports", CloseLatchJettyWebSocketTransport.class.getName() + "," + JSONHttpTransport.class.getName());
default -> throw new IllegalArgumentException();
}
prepareAndStart(wsType, initParams);
@@ -733,11 +734,11 @@ public void testClientDisconnectingClosesTheConnection(String wsType) throws Exc
switch (wsType) {
case WEBSOCKET_JAKARTA, WEBSOCKET_OKHTTP -> {
- CloseLatchWebSocketTransport jakartaTransport = (CloseLatchWebSocketTransport)bayeux.getTransport("websocket");
+ CloseLatchWebSocketTransport jakartaTransport = (CloseLatchWebSocketTransport)bayeuxServer.getTransport("websocket");
Assertions.assertTrue(jakartaTransport.latch.await(5, TimeUnit.SECONDS));
}
case WEBSOCKET_JETTY -> {
- CloseLatchJettyWebSocketTransport jettyTransport = (CloseLatchJettyWebSocketTransport)bayeux.getTransport("websocket");
+ CloseLatchJettyWebSocketTransport jettyTransport = (CloseLatchJettyWebSocketTransport)bayeuxServer.getTransport("websocket");
Assertions.assertTrue(jettyTransport.latch.await(5, TimeUnit.SECONDS));
}
default -> throw new IllegalArgumentException();
@@ -745,14 +746,14 @@ public void testClientDisconnectingClosesTheConnection(String wsType) throws Exc
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testClientDisconnectingSynchronouslyClosesTheConnection(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testClientDisconnectingSynchronouslyClosesTheConnection(Transport wsType) throws Exception {
Map initParams = new HashMap<>();
switch (wsType) {
case WEBSOCKET_JAKARTA, WEBSOCKET_OKHTTP ->
- initParams.put("transports", CloseLatchWebSocketTransport.class.getName() + "," + JSONTransport.class.getName());
+ initParams.put("transports", CloseLatchWebSocketTransport.class.getName() + "," + JSONHttpTransport.class.getName());
case WEBSOCKET_JETTY ->
- initParams.put("transports", CloseLatchJettyWebSocketTransport.class.getName() + "," + JSONTransport.class.getName());
+ initParams.put("transports", CloseLatchJettyWebSocketTransport.class.getName() + "," + JSONHttpTransport.class.getName());
default -> throw new IllegalArgumentException();
}
prepareAndStart(wsType, initParams);
@@ -766,11 +767,11 @@ public void testClientDisconnectingSynchronouslyClosesTheConnection(String wsTyp
switch (wsType) {
case WEBSOCKET_JAKARTA, WEBSOCKET_OKHTTP -> {
- CloseLatchWebSocketTransport jakartaTransport = (CloseLatchWebSocketTransport)bayeux.getTransport("websocket");
+ CloseLatchWebSocketTransport jakartaTransport = (CloseLatchWebSocketTransport)bayeuxServer.getTransport("websocket");
Assertions.assertTrue(jakartaTransport.latch.await(5, TimeUnit.SECONDS));
}
case WEBSOCKET_JETTY -> {
- CloseLatchJettyWebSocketTransport jettyTransport = (CloseLatchJettyWebSocketTransport)bayeux.getTransport("websocket");
+ CloseLatchJettyWebSocketTransport jettyTransport = (CloseLatchJettyWebSocketTransport)bayeuxServer.getTransport("websocket");
Assertions.assertTrue(jettyTransport.latch.await(5, TimeUnit.SECONDS));
}
default -> throw new IllegalArgumentException();
@@ -804,8 +805,8 @@ protected void onClose(int code, String reason) {
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testWhenClientAbortsServerSessionIsSwept(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testWhenClientAbortsServerSessionIsSwept(Transport wsType) throws Exception {
Map options = new HashMap<>();
long timeout = 2000;
long maxInterval = 1000;
@@ -821,7 +822,7 @@ public void testWhenClientAbortsServerSessionIsSwept(String wsType) throws Excep
Thread.sleep(1000);
CountDownLatch latch = new CountDownLatch(1);
- ServerSession session = bayeux.getSession(client.getId());
+ ServerSession session = bayeuxServer.getSession(client.getId());
session.addListener((ServerSession.RemovedListener)(s, m, t) -> latch.countDown());
client.abort();
@@ -830,14 +831,14 @@ public void testWhenClientAbortsServerSessionIsSwept(String wsType) throws Excep
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testDisconnectWithPendingMetaConnectWithoutResponseIsFailedOnClient(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testDisconnectWithPendingMetaConnectWithoutResponseIsFailedOnClient(Transport wsType) throws Exception {
long timeout = 2000L;
Map serverOptions = new HashMap<>();
serverOptions.put("timeout", String.valueOf(timeout));
prepareAndStart(wsType, serverOptions);
- bayeux.addExtension(new BayeuxServer.Extension() {
+ bayeuxServer.addExtension(new BayeuxServer.Extension() {
@Override
public boolean sendMeta(ServerSession to, ServerMessage.Mutable message) {
if (Channel.META_CONNECT.equals(message.getChannel())) {
@@ -880,8 +881,8 @@ public boolean sendMeta(ServerSession to, ServerMessage.Mutable message) {
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testDeliverDuringHandshakeProcessing(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testDeliverDuringHandshakeProcessing(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
String channelName = "/service/test";
@@ -895,7 +896,7 @@ public void testDeliverDuringHandshakeProcessing(String wsType) throws Exception
});
// SessionListener is the first listener notified after the ServerSession is created.
- bayeux.addListener(new BayeuxServer.SessionListener() {
+ bayeuxServer.addListener(new BayeuxServer.SessionListener() {
@Override
public void sessionAdded(ServerSession session, ServerMessage message) {
session.deliver(null, channelName, "data", Promise.noop());
@@ -911,11 +912,11 @@ public void sessionAdded(ServerSession session, ServerMessage message) {
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testDeliverDuringHandshakeProcessingWithAckExtension(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testDeliverDuringHandshakeProcessingWithAckExtension(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
- bayeux.addExtension(new AcknowledgedMessagesExtension());
+ bayeuxServer.addExtension(new AcknowledgedMessagesExtension());
String channelName = "/service/test";
BayeuxClient client = newBayeuxClient(wsType);
@@ -929,7 +930,7 @@ public void testDeliverDuringHandshakeProcessingWithAckExtension(String wsType)
});
// SessionListener is the first listener notified after the ServerSession is created.
- bayeux.addListener(new BayeuxServer.SessionListener() {
+ bayeuxServer.addListener(new BayeuxServer.SessionListener() {
@Override
public void sessionAdded(ServerSession session, ServerMessage message) {
session.deliver(null, channelName, "data", Promise.noop());
@@ -945,14 +946,14 @@ public void sessionAdded(ServerSession session, ServerMessage message) {
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testExtensionIsInvokedAfterNetworkFailure(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testExtensionIsInvokedAfterNetworkFailure(Transport wsType) throws Exception {
// No way to stop OkHttpClient.
- Assumptions.assumeFalse(wsType.equals(WEBSOCKET_OKHTTP));
+ Assumptions.assumeFalse(wsType == Transport.WEBSOCKET_OKHTTP);
prepareAndStart(wsType, null);
- bayeux.addExtension(new AcknowledgedMessagesExtension());
+ bayeuxServer.addExtension(new AcknowledgedMessagesExtension());
BayeuxClient client = newBayeuxClient(wsType);
String channelName = "/test";
@@ -972,7 +973,7 @@ public boolean rcv(ClientSession session, Message.Mutable message) {
Assertions.assertTrue(client.waitFor(5000, BayeuxClient.State.CONNECTED));
// This message will be delivered via /meta/connect.
- bayeux.createChannelIfAbsent(channelName).getReference().publish(null, "data1", Promise.noop());
+ bayeuxServer.createChannelIfAbsent(channelName).getReference().publish(null, "data1", Promise.noop());
Assertions.assertTrue(rcv.get().await(5, TimeUnit.SECONDS));
// Wait for the /meta/connect to be established again.
Thread.sleep(1000);
@@ -982,7 +983,7 @@ public boolean rcv(ClientSession session, Message.Mutable message) {
Assertions.assertTrue(client.waitFor(5000, BayeuxClient.State.UNCONNECTED));
// Send a message while disconnected.
- bayeux.createChannelIfAbsent(channelName).getReference().publish(null, "data2", Promise.noop());
+ bayeuxServer.createChannelIfAbsent(channelName).getReference().publish(null, "data2", Promise.noop());
rcv.set(new CountDownLatch(1));
httpClient.start();
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BayeuxContextTest.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BayeuxContextTest.java
index c5aaf23f94..bab8f153cf 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BayeuxContextTest.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/BayeuxContextTest.java
@@ -43,22 +43,29 @@
import org.cometd.server.websocket.jakarta.WebSocketTransport;
import org.cometd.server.websocket.jetty.JettyWebSocketTransport;
import org.eclipse.jetty.client.ContentResponse;
+import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
-import org.eclipse.jetty.ee10.websocket.server.JettyServerUpgradeRequest;
-import org.eclipse.jetty.ee10.websocket.server.JettyServerUpgradeResponse;
import org.eclipse.jetty.http.HttpCookie;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.server.Session;
+import org.eclipse.jetty.session.SessionHandler;
+import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.websocket.server.ServerUpgradeRequest;
+import org.eclipse.jetty.websocket.server.ServerUpgradeResponse;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class BayeuxContextTest extends ClientServerWebSocketTest {
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testRequestHeaderIsCaseInsensitive(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testRequestHeaderIsCaseInsensitive(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
CountDownLatch latch = new CountDownLatch(1);
- bayeux.getChannel(Channel.META_HANDSHAKE).addListener(new ServerChannel.MessageListener() {
+ bayeuxServer.getChannel(Channel.META_HANDSHAKE).addListener(new ServerChannel.MessageListener() {
@Override
public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessage.Mutable message) {
BayeuxContext context = message.getBayeuxContext();
@@ -78,14 +85,14 @@ public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessag
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testCookiesSentToServer(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testCookiesSentToServer(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
String cookieName = "name";
String cookieValue = "value";
CountDownLatch latch = new CountDownLatch(1);
- bayeux.getChannel(Channel.META_HANDSHAKE).addListener(new ServerChannel.MessageListener() {
+ bayeuxServer.getChannel(Channel.META_HANDSHAKE).addListener(new ServerChannel.MessageListener() {
@Override
public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessage.Mutable message) {
BayeuxContext context = message.getBayeuxContext();
@@ -105,12 +112,11 @@ public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessag
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testCookiesSentToClient(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testCookiesSentToClient(Transport wsType) throws Exception {
String wsTransportClass = switch (wsType) {
case WEBSOCKET_JAKARTA, WEBSOCKET_OKHTTP -> CookieWebSocketTransport.class.getName();
case WEBSOCKET_JETTY -> CookieJettyWebSocketTransport.class.getName();
- default -> throw new IllegalArgumentException();
};
prepareServer(wsType, 0, "/cometd", null, wsTransportClass);
startServer();
@@ -129,8 +135,8 @@ public void testCookiesSentToClient(String wsType) throws Exception {
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testMultipleCookiesSentToServer(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testMultipleCookiesSentToServer(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
List cookieNames = List.of("a", "BAYEUX_BROWSER", "b");
@@ -141,7 +147,7 @@ public void testMultipleCookiesSentToServer(String wsType) throws Exception {
}
CountDownLatch latch = new CountDownLatch(1);
- bayeux.getChannel(Channel.META_HANDSHAKE).addListener(new ServerChannel.MessageListener() {
+ bayeuxServer.getChannel(Channel.META_HANDSHAKE).addListener(new ServerChannel.MessageListener() {
@Override
public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessage.Mutable message) {
BayeuxContext context = message.getBayeuxContext();
@@ -156,14 +162,14 @@ public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessag
try (Socket socket = new Socket("localhost", connector.getLocalPort())) {
OutputStream output = socket.getOutputStream();
String upgrade = "" +
- "GET " + cometdServletPath + " HTTP/1.1\r\n" +
- "Host: localhost:" + connector.getLocalPort() + "\r\n" +
- "Connection: Upgrade\r\n" +
- "Upgrade: websocket\r\n" +
- "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" +
- "Sec-WebSocket-Version: 13\r\n" +
- "Cookie: " + cookies + "\r\n" +
- "\r\n";
+ "GET " + cometdPath + " HTTP/1.1\r\n" +
+ "Host: localhost:" + connector.getLocalPort() + "\r\n" +
+ "Connection: Upgrade\r\n" +
+ "Upgrade: websocket\r\n" +
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" +
+ "Sec-WebSocket-Version: 13\r\n" +
+ "Cookie: " + cookies + "\r\n" +
+ "\r\n";
output.write(upgrade.getBytes(StandardCharsets.UTF_8));
output.flush();
@@ -171,12 +177,12 @@ public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessag
Thread.sleep(1000);
String handshake = "" +
- "{" +
- "\"id\":\"1\"," +
- "\"channel\":\"/meta/handshake\"," +
- "\"version\":\"1.0\"," +
- "\"supportedConnectionTypes\":[\"websocket\"]" +
- "}";
+ "{" +
+ "\"id\":\"1\"," +
+ "\"channel\":\"/meta/handshake\"," +
+ "\"version\":\"1.0\"," +
+ "\"supportedConnectionTypes\":[\"websocket\"]" +
+ "}";
byte[] handshakeBytes = handshake.getBytes(StandardCharsets.UTF_8);
Assertions.assertTrue(handshakeBytes.length <= 125); // Max payload length
@@ -191,22 +197,44 @@ public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessag
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testSessionAttribute(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testSessionAttribute(Transport wsType) throws Exception {
String wsTransportClass = switch (wsType) {
case WEBSOCKET_JAKARTA, WEBSOCKET_OKHTTP -> SessionWebSocketTransport.class.getName();
case WEBSOCKET_JETTY -> SessionJettyWebSocketTransport.class.getName();
- default -> throw new IllegalArgumentException();
};
prepareServer(wsType, 0, "/cometd", null, wsTransportClass);
- context.addServlet(new ServletHolder(new HttpServlet() {
- @Override
- protected void service(HttpServletRequest request, HttpServletResponse resp) {
- HttpSession session = request.getSession(true);
- session.setAttribute(SessionConstants.ATTRIBUTE_NAME, SessionConstants.ATTRIBUTE_VALUE);
+ switch (wsType) {
+ case WEBSOCKET_JAKARTA, WEBSOCKET_OKHTTP -> {
+ context.insertHandler(new org.eclipse.jetty.ee10.servlet.SessionHandler());
+ ((ServletContextHandler)context).addServlet(new ServletHolder(new HttpServlet() {
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) {
+ HttpSession session = request.getSession(true);
+ session.setAttribute(SessionConstants.ATTRIBUTE_NAME, SessionConstants.ATTRIBUTE_VALUE);
+ }
+ }), "/session");
}
- }), "/session");
+ case WEBSOCKET_JETTY -> {
+ SessionHandler sessionHandler = new SessionHandler();
+ context.insertHandler(sessionHandler);
+ sessionHandler.insertHandler(new Handler.Wrapper() {
+ @Override
+ public boolean handle(Request request, Response response, Callback callback) throws Exception {
+ if ("/session".equals(Request.getPathInContext(request))) {
+ Session session = request.getSession(true);
+ session.setAttribute(SessionConstants.ATTRIBUTE_NAME, SessionConstants.ATTRIBUTE_VALUE);
+ callback.succeeded();
+ return true;
+ }
+ return super.handle(request, response, callback);
+ }
+ });
+ }
+ default -> throw new IllegalArgumentException();
+ }
+
startServer();
prepareClient(wsType);
startClient();
@@ -230,11 +258,10 @@ protected void service(HttpServletRequest request, HttpServletResponse resp) {
Assertions.assertNotNull(sessionCookie);
CountDownLatch latch = new CountDownLatch(1);
- bayeux.addListener(new BayeuxServer.SessionListener() {
+ bayeuxServer.addListener(new BayeuxServer.SessionListener() {
@Override
public void sessionAdded(ServerSession session, ServerMessage message) {
- Assertions.assertNotNull(message.getBayeuxContext().getHttpSessionId());
- Assertions.assertEquals(SessionConstants.ATTRIBUTE_VALUE, message.getBayeuxContext().getHttpSessionAttribute(SessionConstants.ATTRIBUTE_NAME));
+ Assertions.assertEquals(SessionConstants.ATTRIBUTE_VALUE, message.getBayeuxContext().getSessionAttribute(SessionConstants.ATTRIBUTE_NAME));
latch.countDown();
}
});
@@ -250,15 +277,15 @@ public void sessionAdded(ServerSession session, ServerMessage message) {
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testContextAttribute(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testContextAttribute(Transport wsType) throws Exception {
prepareAndStart(wsType, null);
CountDownLatch latch = new CountDownLatch(1);
- bayeux.addListener(new BayeuxServer.SessionListener() {
+ bayeuxServer.addListener(new BayeuxServer.SessionListener() {
@Override
public void sessionAdded(ServerSession session, ServerMessage message) {
- Assertions.assertSame(bayeux, message.getBayeuxContext().getContextAttribute(BayeuxServer.ATTRIBUTE));
+ Assertions.assertSame(bayeuxServer, message.getBayeuxContext().getContextAttribute(BayeuxServer.ATTRIBUTE));
latch.countDown();
}
});
@@ -273,12 +300,11 @@ public void sessionAdded(ServerSession session, ServerMessage message) {
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testConcurrentClientsHaveDifferentBayeuxContexts(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testConcurrentClientsHaveDifferentBayeuxContexts(Transport wsType) throws Exception {
String wsTransportClass = switch (wsType) {
case WEBSOCKET_JAKARTA, WEBSOCKET_OKHTTP -> ConcurrentBayeuxContextWebSocketTransport.class.getName();
case WEBSOCKET_JETTY -> ConcurrentBayeuxContextJettyWebSocketTransport.class.getName();
- default -> throw new IllegalArgumentException();
};
prepareServer(wsType, 0, "/cometd", null, wsTransportClass);
startServer();
@@ -293,11 +319,11 @@ public void testConcurrentClientsHaveDifferentBayeuxContexts(String wsType) thro
// Wait for the first client to arrive at the concurrency point.
switch (wsType) {
case WEBSOCKET_JAKARTA, WEBSOCKET_OKHTTP -> {
- CountDownLatch enterLatch = ((ConcurrentBayeuxContextWebSocketTransport)bayeux.getTransport("websocket")).enterLatch;
+ CountDownLatch enterLatch = ((ConcurrentBayeuxContextWebSocketTransport)bayeuxServer.getTransport("websocket")).enterLatch;
Assertions.assertTrue(enterLatch.await(5, TimeUnit.SECONDS));
}
case WEBSOCKET_JETTY -> {
- CountDownLatch enterLatch = ((ConcurrentBayeuxContextJettyWebSocketTransport)bayeux.getTransport("websocket")).enterLatch;
+ CountDownLatch enterLatch = ((ConcurrentBayeuxContextJettyWebSocketTransport)bayeuxServer.getTransport("websocket")).enterLatch;
Assertions.assertTrue(enterLatch.await(5, TimeUnit.SECONDS));
}
default -> throw new IllegalArgumentException();
@@ -311,9 +337,9 @@ public void testConcurrentClientsHaveDifferentBayeuxContexts(String wsType) thro
// Release the first client.
switch (wsType) {
case WEBSOCKET_JAKARTA, WEBSOCKET_OKHTTP ->
- ((ConcurrentBayeuxContextWebSocketTransport)bayeux.getTransport("websocket")).proceedLatch.countDown();
+ ((ConcurrentBayeuxContextWebSocketTransport)bayeuxServer.getTransport("websocket")).proceedLatch.countDown();
case WEBSOCKET_JETTY ->
- ((ConcurrentBayeuxContextJettyWebSocketTransport)bayeux.getTransport("websocket")).proceedLatch.countDown();
+ ((ConcurrentBayeuxContextJettyWebSocketTransport)bayeuxServer.getTransport("websocket")).proceedLatch.countDown();
default -> throw new IllegalArgumentException();
}
Assertions.assertTrue(client1.waitFor(1000, BayeuxClient.State.CONNECTED));
@@ -321,7 +347,7 @@ public void testConcurrentClientsHaveDifferentBayeuxContexts(String wsType) thro
String channelName = "/service/test";
Map contexts = new ConcurrentHashMap<>();
CountDownLatch contextLatch = new CountDownLatch(2);
- bayeux.createChannelIfAbsent(channelName).getReference().addListener(new ServerChannel.MessageListener() {
+ bayeuxServer.createChannelIfAbsent(channelName).getReference().addListener(new ServerChannel.MessageListener() {
@Override
public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessage.Mutable message) {
contexts.put(from.getId(), message.getBayeuxContext());
@@ -363,8 +389,8 @@ public CookieJettyWebSocketTransport(BayeuxServerImpl bayeux) {
}
@Override
- protected void modifyUpgrade(JettyServerUpgradeRequest request, JettyServerUpgradeResponse response) {
- response.setHeader("Set-Cookie", COOKIE_NAME + "=" + COOKIE_VALUE);
+ protected void modifyUpgrade(ServerUpgradeRequest request, ServerUpgradeResponse response) {
+ response.getHeaders().put("Set-Cookie", COOKIE_NAME + "=" + COOKIE_VALUE);
}
}
@@ -392,8 +418,8 @@ public SessionJettyWebSocketTransport(BayeuxServerImpl bayeux) {
}
@Override
- protected void modifyUpgrade(JettyServerUpgradeRequest request, JettyServerUpgradeResponse response) {
- HttpSession session = (HttpSession)request.getSession();
+ protected void modifyUpgrade(ServerUpgradeRequest request, ServerUpgradeResponse response) {
+ Session session = request.getSession(false);
Assertions.assertNotNull(session);
Assertions.assertEquals(ATTRIBUTE_VALUE, session.getAttribute(ATTRIBUTE_NAME));
}
@@ -425,7 +451,7 @@ public ConcurrentBayeuxContextJettyWebSocketTransport(BayeuxServerImpl bayeux) {
}
@Override
- protected void modifyUpgrade(JettyServerUpgradeRequest request, JettyServerUpgradeResponse response) {
+ protected void modifyUpgrade(ServerUpgradeRequest request, ServerUpgradeResponse response) {
onUpgrade(handshakes, enterLatch, proceedLatch);
super.modifyUpgrade(request, response);
}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/ClientServerWebSocketTest.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/ClientServerWebSocketTest.java
index c332f37ef9..271892def3 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/ClientServerWebSocketTest.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/ClientServerWebSocketTest.java
@@ -15,7 +15,7 @@
*/
package org.cometd.server.websocket;
-import java.util.List;
+import java.util.HashMap;
import java.util.Map;
import jakarta.websocket.ContainerProvider;
import jakarta.websocket.WebSocketContainer;
@@ -26,21 +26,25 @@
import org.cometd.client.http.jetty.JettyHttpClientTransport;
import org.cometd.client.transport.ClientTransport;
import org.cometd.client.websocket.okhttp.OkHttpWebSocketTransport;
+import org.cometd.server.AbstractServerTransport;
import org.cometd.server.BayeuxServerImpl;
-import org.cometd.server.CometDServlet;
-import org.cometd.server.http.JSONTransport;
+import org.cometd.server.http.JSONHttpTransport;
+import org.cometd.server.http.jakarta.CometDServlet;
+import org.cometd.server.http.jetty.CometDHandler;
+import org.cometd.server.websocket.common.AbstractWebSocketTransport;
import org.cometd.server.websocket.jakarta.WebSocketTransport;
import org.cometd.server.websocket.jetty.JettyWebSocketTransport;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
-import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
-import org.eclipse.jetty.ee10.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.eclipse.jetty.websocket.client.WebSocketClient;
+import org.eclipse.jetty.websocket.server.WebSocketUpgradeHandler;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -48,58 +52,53 @@
import org.slf4j.LoggerFactory;
public abstract class ClientServerWebSocketTest {
- protected static final String WEBSOCKET_JAKARTA = "JAKARTA";
- protected static final String WEBSOCKET_JETTY = "JETTY";
- protected static final String WEBSOCKET_OKHTTP = "OKHTTP";
-
- public static List wsTypes() {
- return List.of(WEBSOCKET_JAKARTA, WEBSOCKET_JETTY, WEBSOCKET_OKHTTP);
+ public static Transport[] transports() {
+ return Transport.values();
}
@RegisterExtension
- final BeforeTestExecutionCallback printMethodName = context ->
+ public final BeforeTestExecutionCallback printMethodName = context ->
System.err.printf("Running %s.%s() %s%n", context.getRequiredTestClass().getSimpleName(), context.getRequiredTestMethod().getName(), context.getDisplayName());
protected final Logger logger = LoggerFactory.getLogger(getClass());
protected ServerConnector connector;
protected Server server;
- protected ServletContextHandler context;
- protected String cometdServletPath;
+ protected ContextHandler context;
+ protected String cometdPath;
protected HttpClient httpClient;
protected WebSocketContainer wsClientContainer;
protected WebSocketClient wsClient;
protected OkHttpClient okHttpClient;
protected String cometdURL;
- protected BayeuxServerImpl bayeux;
+ protected BayeuxServer bayeuxServer;
- protected void prepareAndStart(String wsType, Map initParams) throws Exception {
- prepareAndStart(wsType, "/cometd", initParams);
+ protected void prepareAndStart(Transport wsType, Map options) throws Exception {
+ prepareAndStart(wsType, "/cometd", options);
}
- protected void prepareAndStart(String wsType, String servletPath, Map initParams) throws Exception {
- prepareServer(wsType, 0, servletPath, initParams);
+ protected void prepareAndStart(Transport wsType, String cometdPath, Map options) throws Exception {
+ prepareServer(wsType, 0, cometdPath, options);
prepareClient(wsType);
startServer();
startClient();
}
- protected void prepareServer(String wsType, int port) {
+ protected void prepareServer(Transport wsType, int port) {
prepareServer(wsType, port, "/cometd", null);
}
- protected void prepareServer(String wsType, Map initParams) {
- prepareServer(wsType, 0, "/cometd", initParams);
+ protected void prepareServer(Transport wsType, Map options) {
+ prepareServer(wsType, 0, "/cometd", options);
}
- protected void prepareServer(String wsType, int port, String servletPath, Map initParams) {
+ protected void prepareServer(Transport wsType, int port, String cometdPath, Map options) {
String wsTransportClass = switch (wsType) {
case WEBSOCKET_JAKARTA, WEBSOCKET_OKHTTP -> WebSocketTransport.class.getName();
case WEBSOCKET_JETTY -> JettyWebSocketTransport.class.getName();
- default -> throw new IllegalArgumentException();
};
- prepareServer(wsType, port, servletPath, initParams, wsTransportClass);
+ prepareServer(wsType, port, cometdPath, options, wsTransportClass);
}
- protected void prepareServer(String wsType, int port, String servletPath, Map initParams, String wsTransportClass) {
+ protected void prepareServer(Transport wsType, int port, String cometdPath, Map options, String wsTransportClass) {
QueuedThreadPool serverThreads = new QueuedThreadPool();
serverThreads.setName("server");
server = new Server(serverThreads);
@@ -108,40 +107,52 @@ protected void prepareServer(String wsType, int port, String servletPath, Map
- JakartaWebSocketServletContainerInitializer.configure(context, null);
- case WEBSOCKET_JETTY -> JettyWebSocketServletContainerInitializer.configure(context, null);
- default -> throw new IllegalArgumentException("Unsupported transport " + wsType);
+ if (cometdPath.endsWith("/*")) {
+ cometdPath = cometdPath.substring(0, cometdPath.length() - 2);
}
+ this.cometdPath = cometdPath;
+ String cometdURLMapping = cometdPath + "/*";
- // CometD servlet
- cometdServletPath = servletPath;
- if (cometdServletPath.endsWith("/*")) {
- cometdServletPath = cometdServletPath.substring(0, cometdServletPath.length() - 2);
- }
- String cometdURLMapping = cometdServletPath;
- if (!cometdURLMapping.endsWith("/*")) {
- cometdURLMapping = cometdURLMapping + "/*";
- }
- ServletHolder cometdServletHolder = new ServletHolder(CometDServlet.class);
- String transports = wsTransportClass + "," + JSONTransport.class.getName();
- cometdServletHolder.setInitParameter("transports", transports);
- cometdServletHolder.setInitParameter("timeout", "10000");
- cometdServletHolder.setInitParameter("ws.cometdURLMapping", cometdURLMapping);
- cometdServletHolder.setInitOrder(1);
- if (initParams != null) {
- for (Map.Entry entry : initParams.entrySet()) {
- cometdServletHolder.setInitParameter(entry.getKey(), entry.getValue());
+ switch (wsType) {
+ case WEBSOCKET_JAKARTA, WEBSOCKET_OKHTTP -> {
+ ServletContextHandler servletContext = new ServletContextHandler("/");
+ server.setHandler(servletContext);
+ context = servletContext;
+ JakartaWebSocketServletContainerInitializer.configure(servletContext, null);
+ CometDServlet cometdServlet = new CometDServlet();
+ ServletHolder cometdServletHolder = new ServletHolder(cometdServlet);
+ String transports = wsTransportClass + "," + JSONHttpTransport.class.getName();
+ cometdServletHolder.setInitParameter(BayeuxServerImpl.TRANSPORTS_OPTION, transports);
+ cometdServletHolder.setInitParameter(AbstractServerTransport.TIMEOUT_OPTION, "10000");
+ cometdServletHolder.setInitParameter(AbstractWebSocketTransport.COMETD_URL_MAPPING_OPTION, cometdURLMapping);
+ if (options != null) {
+ for (Map.Entry entry : options.entrySet()) {
+ cometdServletHolder.setInitParameter(entry.getKey(), entry.getValue());
+ }
+ }
+ cometdServletHolder.setInitOrder(1);
+ servletContext.addServlet(cometdServletHolder, cometdURLMapping);
+ }
+ case WEBSOCKET_JETTY -> {
+ context = new ContextHandler("/");
+ server.setHandler(context);
+ WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
+ context.setHandler(wsHandler);
+ CometDHandler cometdHandler = new CometDHandler();
+ if (options == null) {
+ options = new HashMap<>();
+ }
+ String transports = wsTransportClass + "," + JSONHttpTransport.class.getName();
+ options.putIfAbsent(BayeuxServerImpl.TRANSPORTS_OPTION, transports);
+ options.putIfAbsent(AbstractServerTransport.TIMEOUT_OPTION, "10000");
+ options.putIfAbsent(AbstractWebSocketTransport.COMETD_URL_MAPPING_OPTION, cometdURLMapping);
+ cometdHandler.setOptions(options);
+ wsHandler.setHandler(cometdHandler);
}
}
- context.addServlet(cometdServletHolder, cometdURLMapping);
}
- protected void prepareClient(String wsType) {
+ protected void prepareClient(Transport wsType) {
QueuedThreadPool clientThreads = new QueuedThreadPool();
clientThreads.setName("client");
httpClient = new HttpClient(new HttpClientTransportOverHTTP(1));
@@ -163,32 +174,35 @@ protected void prepareClient(String wsType) {
protected void startServer() throws Exception {
server.start();
int port = connector.getLocalPort();
- cometdURL = "http://localhost:" + port + cometdServletPath;
- bayeux = (BayeuxServerImpl)context.getServletContext().getAttribute(BayeuxServer.ATTRIBUTE);
+ cometdURL = "http://localhost:" + port + cometdPath;
+ bayeuxServer = (BayeuxServer)context.getContext().getAttribute(BayeuxServer.ATTRIBUTE);
}
protected void startClient() throws Exception {
httpClient.start();
}
- protected BayeuxClient newBayeuxClient(String wsType) {
- return new BayeuxClient(cometdURL, newWebSocketTransport(wsType, null));
+ protected BayeuxClient newBayeuxClient(Transport wsType) {
+ return newBayeuxClient(wsType, cometdURL);
+ }
+
+ protected BayeuxClient newBayeuxClient(Transport wsType, String url) {
+ return new BayeuxClient(url, newWebSocketTransport(wsType, null));
}
protected ClientTransport newLongPollingTransport(Map options) {
return new JettyHttpClientTransport(options, httpClient);
}
- protected ClientTransport newWebSocketTransport(String wsType, Map options) {
+ protected ClientTransport newWebSocketTransport(Transport wsType, Map options) {
return newWebSocketTransport(wsType, null, options);
}
- protected ClientTransport newWebSocketTransport(String wsType, String url, Map options) {
+ protected ClientTransport newWebSocketTransport(Transport wsType, String url, Map options) {
return switch (wsType) {
case WEBSOCKET_JAKARTA -> newWebSocketTransport(url, options, wsClientContainer);
case WEBSOCKET_JETTY -> newJettyWebSocketTransport(url, options, wsClient);
case WEBSOCKET_OKHTTP -> newOkHttpWebSocketTransport(url, options, okHttpClient);
- default -> throw new IllegalArgumentException();
};
}
@@ -225,4 +239,8 @@ protected void stopClient() throws Exception {
httpClient.stop();
}
}
+
+ public enum Transport {
+ WEBSOCKET_JAKARTA, WEBSOCKET_JETTY, WEBSOCKET_OKHTTP
+ }
}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/ConcurrentAbortPublishTest.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/ConcurrentAbortPublishTest.java
index 701746dad6..09275029c1 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/ConcurrentAbortPublishTest.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/ConcurrentAbortPublishTest.java
@@ -54,8 +54,8 @@ protected ClientTransport newOkHttpWebSocketTransport(String url, Map serverOptions = new HashMap<>();
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/MultipleURLMappingsTest.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/MultipleURLMappingsTest.java
deleted file mode 100644
index d3f32d7e58..0000000000
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/MultipleURLMappingsTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2008-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.cometd.server.websocket;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import jakarta.websocket.ContainerProvider;
-import jakarta.websocket.WebSocketContainer;
-
-import org.cometd.client.BayeuxClient;
-import org.cometd.client.transport.ClientTransport;
-import org.cometd.server.CometDServlet;
-import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
-import org.eclipse.jetty.ee10.servlet.ServletHolder;
-import org.eclipse.jetty.websocket.client.WebSocketClient;
-import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
-import org.eclipse.jetty.ee10.websocket.server.config.JettyWebSocketServletContainerInitializer;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.MethodSource;
-
-public class MultipleURLMappingsTest {
- private static final String JAKARTA_WS_TRANSPORT = "org.cometd.server.websocket.jakarta.WebSocketTransport";
- private static final String JETTY_WS_TRANSPORT = "org.cometd.server.websocket.jetty.JettyWebSocketTransport";
-
- public static List wsTransports() {
- return List.of(JAKARTA_WS_TRANSPORT, JETTY_WS_TRANSPORT);
- }
-
- private Server server;
- private ServerConnector connector;
- private WebSocketContainer wsClientContainer;
- private WebSocketClient wsClient;
- private String servletPath1 = "/cometd1";
- private String servletPath2 = "/cometd2";
-
- private void start(String wsTransportClass) throws Exception {
- server = new Server();
-
- connector = new ServerConnector(server);
- server.addConnector(connector);
-
- ServletContextHandler context = new ServletContextHandler("/", true, false);
- server.setHandler(context);
-
- switch (wsTransportClass) {
- case JAKARTA_WS_TRANSPORT -> JakartaWebSocketServletContainerInitializer.configure(context, null);
- case JETTY_WS_TRANSPORT -> JettyWebSocketServletContainerInitializer.configure(context, null);
- default -> throw new IllegalArgumentException("Unsupported transport " + wsTransportClass);
- }
-
- ServletHolder cometdServletHolder = new ServletHolder(CometDServlet.class);
- cometdServletHolder.setInitParameter("transports", wsTransportClass);
- cometdServletHolder.setInitParameter("timeout", "10000");
- cometdServletHolder.setInitParameter("ws.cometdURLMapping", servletPath1 + "," + servletPath2);
- cometdServletHolder.setInitOrder(1);
- context.addServlet(cometdServletHolder, servletPath1 + "/*");
- context.addServlet(cometdServletHolder, servletPath2 + "/*");
-
- switch (wsTransportClass) {
- case JAKARTA_WS_TRANSPORT -> {
- wsClientContainer = ContainerProvider.getWebSocketContainer();
- server.addBean(wsClientContainer);
- }
- case JETTY_WS_TRANSPORT -> {
- wsClient = new WebSocketClient();
- server.addBean(wsClient);
- }
- default -> throw new AssertionError();
- }
-
- server.start();
- }
-
- private BayeuxClient newBayeuxClient(String wsTransportClass, String servletPath) {
- return new BayeuxClient("http://localhost:" + connector.getLocalPort() + servletPath, newWebSocketTransport(wsTransportClass));
- }
-
- private ClientTransport newWebSocketTransport(String wsTransportClass) {
- return switch (wsTransportClass) {
- case JAKARTA_WS_TRANSPORT ->
- new org.cometd.client.websocket.jakarta.WebSocketTransport(null, null, wsClientContainer);
- case JETTY_WS_TRANSPORT ->
- new org.cometd.client.websocket.jetty.JettyWebSocketTransport(null, null, wsClient);
- default -> throw new AssertionError();
- };
- }
-
- @AfterEach
- public void dispose() throws Exception {
- server.stop();
- }
-
- @ParameterizedTest
- @MethodSource("wsTransports")
- public void testMultipleURLMappings(String wsTransportClass) throws Exception {
- start(wsTransportClass);
-
- BayeuxClient client1 = newBayeuxClient(wsTransportClass, servletPath1);
- client1.handshake();
- Assertions.assertTrue(client1.waitFor(5000, BayeuxClient.State.CONNECTED));
-
- BayeuxClient client2 = newBayeuxClient(wsTransportClass, servletPath2);
- client2.handshake();
- Assertions.assertTrue(client2.waitFor(5000, BayeuxClient.State.CONNECTED));
-
- String channelName = "/foobarbaz";
- CountDownLatch messageLatch = new CountDownLatch(4);
- CountDownLatch subscribeLatch = new CountDownLatch(2);
- client1.getChannel(channelName).subscribe((channel, message) -> messageLatch.countDown(), message -> subscribeLatch.countDown());
- client2.getChannel(channelName).subscribe((channel, message) -> messageLatch.countDown(), message -> subscribeLatch.countDown());
- Assertions.assertTrue(subscribeLatch.await(5, TimeUnit.SECONDS));
-
- client1.getChannel(channelName).publish("1");
- client2.getChannel(channelName).publish("2");
-
- Assertions.assertTrue(messageLatch.await(5, TimeUnit.SECONDS));
-
- client1.disconnect(1000);
- client2.disconnect(1000);
- }
-}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/SlowConnectionTest.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/SlowConnectionTest.java
index a6467bb0fd..3fbe867ba2 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/SlowConnectionTest.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/SlowConnectionTest.java
@@ -25,6 +25,7 @@
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+
import org.cometd.bayeux.Channel;
import org.cometd.bayeux.Message;
import org.cometd.bayeux.Promise;
@@ -37,23 +38,25 @@
import org.cometd.server.websocket.common.AbstractWebSocketTransport;
import org.eclipse.jetty.util.Utf8StringBuilder;
import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class SlowConnectionTest extends ClientServerWebSocketTest {
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testLargeMessageOnSlowConnection(String wsType) throws Exception {
+ @MethodSource("transports")
+ @Tag("flaky")
+ public void testLargeMessageOnSlowConnection(Transport wsType) throws Exception {
testLargeMessageOnSlowConnection(wsType, false);
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testLargeMessageOnSlowConnectionWithAckExtension(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testLargeMessageOnSlowConnectionWithAckExtension(Transport wsType) throws Exception {
testLargeMessageOnSlowConnection(wsType, true);
}
- private void testLargeMessageOnSlowConnection(String wsType, boolean ackExtension) throws Exception {
+ private void testLargeMessageOnSlowConnection(Transport wsType, boolean ackExtension) throws Exception {
Map serverOptions = new HashMap<>();
long timeout = 2000;
serverOptions.put(AbstractServerTransport.TIMEOUT_OPTION, String.valueOf(timeout));
@@ -64,21 +67,20 @@ private void testLargeMessageOnSlowConnection(String wsType, boolean ackExtensio
prepareServer(wsType, serverOptions);
startServer();
- bayeux.setDetailedDump(true);
if (ackExtension) {
- bayeux.addExtension(new AcknowledgedMessagesExtension());
+ bayeuxServer.addExtension(new AcknowledgedMessagesExtension());
}
try (Socket socket = new Socket("localhost", connector.getLocalPort())) {
OutputStream output = socket.getOutputStream();
String upgrade = "" +
- "GET " + cometdServletPath + " HTTP/1.1\r\n" +
- "Host: localhost:" + connector.getLocalPort() + "\r\n" +
- "Connection: Upgrade\r\n" +
- "Upgrade: websocket\r\n" +
- "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" +
- "Sec-WebSocket-Version: 13\r\n" +
- "\r\n";
+ "GET " + cometdPath + " HTTP/1.1\r\n" +
+ "Host: localhost:" + connector.getLocalPort() + "\r\n" +
+ "Connection: Upgrade\r\n" +
+ "Upgrade: websocket\r\n" +
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" +
+ "Sec-WebSocket-Version: 13\r\n" +
+ "\r\n";
output.write(upgrade.getBytes(StandardCharsets.UTF_8));
output.flush();
@@ -150,7 +152,7 @@ private void testLargeMessageOnSlowConnection(String wsType, boolean ackExtensio
}
CountDownLatch removeLatch = new CountDownLatch(1);
- ServerSessionImpl session = (ServerSessionImpl)bayeux.getSession(clientId);
+ ServerSessionImpl session = (ServerSessionImpl)bayeuxServer.getSession(clientId);
session.addListener((ServerSession.RemovedListener)(s, m, t) -> removeLatch.countDown());
String connect2 = "[{" +
@@ -166,7 +168,7 @@ private void testLargeMessageOnSlowConnection(String wsType, boolean ackExtensio
char[] chars = new char[64 * 1024 * 1024];
Arrays.fill(chars, 'x');
String data = new String(chars);
- bayeux.getChannel(channelName).publish(null, data, Promise.noop());
+ bayeuxServer.getChannel(channelName).publish(null, data, Promise.noop());
// After timeout ms, the /meta/connect reply should be added to the
// queue to be written, but the connection is still TCP congested.
@@ -175,6 +177,9 @@ private void testLargeMessageOnSlowConnection(String wsType, boolean ackExtensio
// After maxInterval, the session should be swept.
Assertions.assertTrue(removeLatch.await(timeout + idleTimeout + 2 * maxInterval, TimeUnit.MILLISECONDS));
+
+ // TODO this helps with the flakyness
+ Thread.sleep(100);
}
}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/URLMappingTest.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/URLMappingTest.java
index 99891537e9..1c45a4ba1d 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/URLMappingTest.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/URLMappingTest.java
@@ -15,38 +15,44 @@
*/
package org.cometd.server.websocket;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
import org.cometd.client.BayeuxClient;
import org.cometd.client.transport.ClientTransport;
+import org.cometd.server.websocket.common.AbstractWebSocketTransport;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class URLMappingTest extends ClientServerWebSocketTest {
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testURLMappingNoGlobbing(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testURLMappingNoGlobbing(Transport wsType) throws Exception {
testURLMapping(wsType, "/cometd");
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testRootURLMappingNoGlobbing(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testRootURLMappingNoGlobbing(Transport wsType) throws Exception {
testURLMapping(wsType, "/");
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testURLMappingWithGlobbing(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testURLMappingWithGlobbing(Transport wsType) throws Exception {
testURLMapping(wsType, "/cometd/*");
}
@ParameterizedTest
- @MethodSource("wsTypes")
- public void testRootURLMappingWithGlobbing(String wsType) throws Exception {
+ @MethodSource("transports")
+ public void testRootURLMappingWithGlobbing(Transport wsType) throws Exception {
testURLMapping(wsType, "/*");
}
- private void testURLMapping(String wsType, String urlMapping) throws Exception {
+ private void testURLMapping(Transport wsType, String urlMapping) throws Exception {
prepareAndStart(wsType, urlMapping, null);
BayeuxClient client = newBayeuxClient(wsType);
@@ -61,4 +67,35 @@ private void testURLMapping(String wsType, String urlMapping) throws Exception {
disconnectBayeuxClient(client);
}
+
+ @ParameterizedTest
+ @MethodSource("transports")
+ public void testMultipleURLMappings(Transport wsType) throws Exception {
+ Map options = new HashMap<>();
+ options.put(AbstractWebSocketTransport.COMETD_URL_MAPPING_OPTION, "/cometd/ws1,/cometd/ws2");
+ prepareAndStart(wsType, "/cometd", options);
+
+ BayeuxClient client1 = newBayeuxClient(wsType, "ws://localhost:%d/cometd/ws1".formatted(connector.getLocalPort()));
+ client1.handshake();
+ Assertions.assertTrue(client1.waitFor(5000, BayeuxClient.State.CONNECTED));
+
+ BayeuxClient client2 = newBayeuxClient(wsType, "ws://localhost:%d/cometd/ws2".formatted(connector.getLocalPort()));
+ client2.handshake();
+ Assertions.assertTrue(client2.waitFor(5000, BayeuxClient.State.CONNECTED));
+
+ String channelName = "/foobarbaz";
+ CountDownLatch messageLatch = new CountDownLatch(4);
+ CountDownLatch subscribeLatch = new CountDownLatch(2);
+ client1.getChannel(channelName).subscribe((channel, message) -> messageLatch.countDown(), message -> subscribeLatch.countDown());
+ client2.getChannel(channelName).subscribe((channel, message) -> messageLatch.countDown(), message -> subscribeLatch.countDown());
+ Assertions.assertTrue(subscribeLatch.await(5, TimeUnit.SECONDS));
+
+ client1.getChannel(channelName).publish("1");
+ client2.getChannel(channelName).publish("2");
+
+ Assertions.assertTrue(messageLatch.await(5, TimeUnit.SECONDS));
+
+ client1.disconnect(1000);
+ client2.disconnect(1000);
+ }
}
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/WebSocketTransportTest.java b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/WebSocketTransportTest.java
index aa7fda6d73..2b811bfd2d 100644
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/WebSocketTransportTest.java
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/java/org/cometd/server/websocket/WebSocketTransportTest.java
@@ -35,7 +35,7 @@
import org.cometd.common.JettyJSONContextClient;
import org.cometd.server.AbstractServerTransport;
import org.cometd.server.BayeuxServerImpl;
-import org.cometd.server.CometDServlet;
+import org.cometd.server.http.jakarta.CometDServlet;
import org.cometd.server.websocket.jakarta.WebSocketTransport;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/resources/jetty-logging.properties b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/resources/jetty-logging.properties
new file mode 100644
index 0000000000..6a0fcfb868
--- /dev/null
+++ b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/resources/jetty-logging.properties
@@ -0,0 +1,3 @@
+## Levels: ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF.
+#org.cometd.LEVEL=DEBUG
+#org.eclipse.jetty.LEVEL=DEBUG
diff --git a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/resources/log4j2-test.properties b/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/resources/log4j2-test.properties
deleted file mode 100644
index 276f0d2e8b..0000000000
--- a/cometd-java/cometd-java-server/cometd-java-server-websocket/cometd-java-server-websocket-tests/src/test/resources/log4j2-test.properties
+++ /dev/null
@@ -1,16 +0,0 @@
-# LOG4J2 levels: fatal, error, warn, info, debug, trace
-#
-appender.console.type=Console
-appender.console.name=console
-appender.console.target=SYSTEM_ERR
-appender.console.layout.type=PatternLayout
-appender.console.layout.pattern=%d %t [%5p][%c{2}] %m%n
-
-rootLogger.level=debug
-rootLogger.appenderRef.console.ref=console
-
-logger.jetty.name=org.eclipse.jetty
-logger.jetty.level=info
-
-logger.cometd.name=org.cometd
-logger.cometd.level=info
diff --git a/cometd-java/cometd-java-server/pom.xml b/cometd-java/cometd-java-server/pom.xml
index 062d027f87..3dee470ba1 100644
--- a/cometd-java/cometd-java-server/pom.xml
+++ b/cometd-java/cometd-java-server/pom.xml
@@ -13,6 +13,7 @@
cometd-java-server-common
+ cometd-java-server-http
cometd-java-server-websocket
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/pom.xml b/cometd-java/cometd-java-tests/cometd-java-tests-common/pom.xml
index cfab926aab..2c08bf1dcd 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/pom.xml
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/pom.xml
@@ -11,18 +11,6 @@
CometD :: Java :: Tests :: Common
-
- org.junit.jupiter
- junit-jupiter
-
-
- org.apache.logging.log4j
- log4j-core
-
-
- org.apache.logging.log4j
- log4j-slf4j2-impl
-
org.eclipse.jetty
jetty-jmx
@@ -60,8 +48,8 @@
test
- org.eclipse.jetty.ee10.websocket
- jetty-ee10-websocket-jetty-server
+ org.eclipse.jetty.websocket
+ jetty-websocket-jetty-server
${jetty-version}
test
@@ -79,7 +67,13 @@
org.cometd.java
- cometd-java-server-common
+ cometd-java-server-http-jakarta
+ ${project.version}
+ test
+
+
+ org.cometd.java
+ cometd-java-server-http-jetty
${project.version}
test
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/AbstractClientServerTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/AbstractClientServerTest.java
index 7199ac546e..402a21e5e5 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/AbstractClientServerTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/AbstractClientServerTest.java
@@ -38,18 +38,19 @@
import org.cometd.client.websocket.jetty.JettyWebSocketTransport;
import org.cometd.client.websocket.okhttp.OkHttpWebSocketTransport;
import org.cometd.server.BayeuxServerImpl;
-import org.cometd.server.CometDServlet;
-import org.cometd.server.http.AsyncJSONTransport;
-import org.cometd.server.http.JSONTransport;
+import org.cometd.server.http.JSONHttpTransport;
+import org.cometd.server.http.jakarta.CometDServlet;
+import org.cometd.server.http.jetty.CometDHandler;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
-import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
-import org.eclipse.jetty.ee10.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.component.LifeCycle;
+import org.eclipse.jetty.websocket.client.WebSocketClient;
+import org.eclipse.jetty.websocket.server.WebSocketUpgradeHandler;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -62,15 +63,15 @@ public static Collection transports() {
}
@RegisterExtension
- final BeforeTestExecutionCallback printMethodName = context ->
+ public final BeforeTestExecutionCallback printMethodName = context ->
System.err.printf("Running %s.%s() %s%n", context.getRequiredTestClass().getSimpleName(), context.getRequiredTestMethod().getName(), context.getDisplayName());
protected final Logger logger = LoggerFactory.getLogger(getClass());
protected Server server;
protected ServerConnector connector;
- protected ServletContextHandler context;
- protected String cometdServletPath = "/cometd";
+ protected ContextHandler context;
+ protected String cometdPath = "/cometd";
protected String cometdURL;
- protected BayeuxServer bayeux;
+ protected BayeuxServer bayeuxServer;
private ScheduledExecutorService scheduler;
private HttpClient httpClient;
private WebSocketContainer wsContainer;
@@ -81,80 +82,88 @@ public void start(Transport transport) throws Exception {
start(transport, serverOptions(transport));
}
- public void start(Transport transport, Map initParams) throws Exception {
- startServer(transport, initParams);
+ public void start(Transport transport, Map options) throws Exception {
+ startServer(transport, options);
startClient(transport);
}
- private void startServer(Transport transport, Map initParams) throws Exception {
+ private void startServer(Transport transport, Map options) throws Exception {
server = new Server();
-
connector = new ServerConnector(server, 1, 1);
- connector.setIdleTimeout(30000);
server.addConnector(connector);
- context = new ServletContextHandler("/");
- server.setHandler(context);
-
switch (transport) {
- case JAKARTA_WEBSOCKET, OKHTTP_WEBSOCKET ->
- JakartaWebSocketServletContainerInitializer.configure(context, null);
- case JETTY_WEBSOCKET -> JettyWebSocketServletContainerInitializer.configure(context, null);
- default -> {
+ case JAKARTA_HTTP, OKHTTP_HTTP, JAKARTA_WEBSOCKET, OKHTTP_WEBSOCKET -> {
+ ServletContextHandler servletContext = new ServletContextHandler("/");
+ context = servletContext;
+ server.setHandler(context);
+ ServletHolder cometdServletHolder = new ServletHolder(CometDServlet.class);
+ cometdServletHolder.setInitParameter("timeout", "10000");
+ cometdServletHolder.setInitOrder(1);
+ if (options != null) {
+ for (Map.Entry entry : options.entrySet()) {
+ cometdServletHolder.setInitParameter(entry.getKey(), entry.getValue());
+ }
+ }
+ servletContext.addServlet(cometdServletHolder, cometdPath + "/*");
+ if (transport == Transport.JAKARTA_WEBSOCKET || transport == Transport.OKHTTP_WEBSOCKET) {
+ JakartaWebSocketServletContainerInitializer.configure(servletContext, null);
+ }
}
- }
-
- // CometD servlet
- ServletHolder cometdServletHolder = new ServletHolder(CometDServlet.class);
- cometdServletHolder.setInitParameter("timeout", "10000");
- cometdServletHolder.setInitOrder(1);
- if (initParams != null) {
- for (Map.Entry entry : initParams.entrySet()) {
- cometdServletHolder.setInitParameter(entry.getKey(), entry.getValue());
+ case JETTY_HTTP, JETTY_WEBSOCKET -> {
+ context = new ContextHandler("/");
+ server.setHandler(context);
+ CometDHandler cometdHandler = new CometDHandler();
+ cometdHandler.setOptions(options == null ? Map.of() : options);
+ context.setHandler(cometdHandler);
+ if (transport == Transport.JETTY_WEBSOCKET) {
+ WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
+ context.insertHandler(wsHandler);
+ }
}
+ default -> throw new IllegalStateException();
}
- context.addServlet(cometdServletHolder, cometdServletPath + "/*");
-
server.start();
int port = connector.getLocalPort();
- cometdURL = "http://localhost:" + port + cometdServletPath;
-
- bayeux = (BayeuxServer)context.getServletContext().getAttribute(BayeuxServer.ATTRIBUTE);
+ cometdURL = "http://localhost:" + port + cometdPath;
+ bayeuxServer = (BayeuxServer)context.getContext().getAttribute(BayeuxServer.ATTRIBUTE);
}
protected void startClient(Transport transport) throws Exception {
scheduler = Executors.newSingleThreadScheduledExecutor();
switch (transport) {
- case JETTY_HTTP, ASYNC_HTTP -> {
+ case JETTY_HTTP, JAKARTA_HTTP -> {
httpClient = new HttpClient();
httpClient.start();
}
- case JAKARTA_WEBSOCKET -> wsContainer = ContainerProvider.getWebSocketContainer();
+ case JAKARTA_WEBSOCKET -> {
+ wsContainer = ContainerProvider.getWebSocketContainer();
+ }
case JETTY_WEBSOCKET -> {
httpClient = new HttpClient();
httpClient.start();
wsClient = new WebSocketClient(httpClient);
wsClient.start();
}
- case OKHTTP_HTTP, OKHTTP_WEBSOCKET ->
+ case OKHTTP_HTTP, OKHTTP_WEBSOCKET -> {
// There's no lifecycle of OkHttp client.
- okHttpClient = new OkHttpClient();
- default -> throw new IllegalArgumentException();
+ okHttpClient = new OkHttpClient();
+ }
+ default -> throw new IllegalStateException();
}
}
protected Map serverOptions(Transport transport) {
Map options = new HashMap<>();
options.put(BayeuxServerImpl.TRANSPORTS_OPTION, serverTransport(transport));
- options.put("ws.cometdURLMapping", cometdServletPath + "/*");
+ options.put("ws.cometdURLMapping", cometdPath + "/*");
return options;
}
protected String serverTransport(Transport transport) {
return switch (transport) {
- case JETTY_HTTP -> JSONTransport.class.getName();
- case ASYNC_HTTP, OKHTTP_HTTP -> AsyncJSONTransport.class.getName();
+ case JAKARTA_HTTP, JETTY_HTTP, OKHTTP_HTTP -> JSONHttpTransport.class.getName();
case JAKARTA_WEBSOCKET, OKHTTP_WEBSOCKET ->
org.cometd.server.websocket.jakarta.WebSocketTransport.class.getName();
case JETTY_WEBSOCKET -> org.cometd.server.websocket.jetty.JettyWebSocketTransport.class.getName();
@@ -167,7 +176,7 @@ protected BayeuxClient newBayeuxClient(Transport transport) {
protected ClientTransport newClientTransport(Transport transport, Map options) {
return switch (transport) {
- case JETTY_HTTP, ASYNC_HTTP -> new JettyHttpClientTransport(options, httpClient);
+ case JETTY_HTTP, JAKARTA_HTTP -> new JettyHttpClientTransport(options, httpClient);
case OKHTTP_HTTP -> new OkHttpClientTransport(options, okHttpClient);
case JAKARTA_WEBSOCKET -> new WebSocketTransport(options, scheduler, wsContainer);
case JETTY_WEBSOCKET -> new JettyWebSocketTransport(options, scheduler, wsClient);
@@ -221,6 +230,6 @@ protected boolean ipv6Available() {
}
public enum Transport {
- JETTY_HTTP, ASYNC_HTTP, OKHTTP_HTTP, JAKARTA_WEBSOCKET, JETTY_WEBSOCKET, OKHTTP_WEBSOCKET
+ JAKARTA_HTTP, JETTY_HTTP, OKHTTP_HTTP, JAKARTA_WEBSOCKET, JETTY_WEBSOCKET, OKHTTP_WEBSOCKET
}
}
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/AckExtensionTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/AckExtensionTest.java
index e2c34b1b9d..3d00161dfe 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/AckExtensionTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/AckExtensionTest.java
@@ -20,6 +20,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+
import org.cometd.bayeux.Promise;
import org.cometd.bayeux.client.ClientSessionChannel;
import org.cometd.bayeux.server.ServerMessage;
@@ -55,7 +56,7 @@ public void onBatchReceive(ServerSession session, long batch) {
}
}
});
- bayeux.addExtension(extension);
+ bayeuxServer.addExtension(extension);
String channelName = "/ack_listener";
@@ -72,7 +73,7 @@ public void onBatchReceive(ServerSession session, long batch) {
Assertions.assertTrue(readyLatch.await(5, TimeUnit.SECONDS));
String sessionId = client.getId();
- ServerSession serverSession = bayeux.getSession(sessionId);
+ ServerSession serverSession = bayeuxServer.getSession(sessionId);
Assertions.assertNotNull(serverSession);
// Send a message directly to the client.
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/BayeuxClientTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/BayeuxClientTest.java
index d9991a6f92..bb660b5d1c 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/BayeuxClientTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/BayeuxClientTest.java
@@ -15,6 +15,7 @@
*/
package org.cometd.tests;
+import java.util.EnumSet;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -33,12 +34,18 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
+import static org.cometd.tests.AbstractClientServerTest.Transport.JAKARTA_HTTP;
+import static org.cometd.tests.AbstractClientServerTest.Transport.JETTY_HTTP;
+import static org.cometd.tests.AbstractClientServerTest.Transport.OKHTTP_HTTP;
+
public class BayeuxClientTest extends AbstractClientServerTest {
@Disabled("Restore when Jetty issue #10219 is released")
@ParameterizedTest
@MethodSource("transports")
public void testIPv6Address(Transport transport) throws Exception {
Assumptions.assumeTrue(ipv6Available());
+ Assumptions.assumeFalse(EnumSet.of(JETTY_HTTP, JAKARTA_HTTP, OKHTTP_HTTP).contains(transport),
+ "Cookies+IPv6 support currently is broken, see bug #9665");
start(transport);
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/DuplicateMetaConnectTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/DuplicateMetaConnectTest.java
index 1ac689cb31..d7e15152cc 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/DuplicateMetaConnectTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/DuplicateMetaConnectTest.java
@@ -21,6 +21,7 @@
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+
import org.cometd.bayeux.Channel;
import org.cometd.bayeux.Message;
import org.cometd.bayeux.client.ClientSessionChannel;
@@ -89,7 +90,7 @@ public void testDuplicateMetaConnectWithExistingMetaConnectFailedOnClient(Transp
clientOptions.put(BayeuxClient.BACKOFF_INCREMENT_OPTION, backoff);
BayeuxClient client = new BayeuxClient(cometdURL, newClientTransport(transport, clientOptions));
- bayeux.getChannel(Channel.META_CONNECT).addListener(new ServerChannel.MessageListener() {
+ bayeuxServer.getChannel(Channel.META_CONNECT).addListener(new ServerChannel.MessageListener() {
private final AtomicInteger metaConnects = new AtomicInteger();
@Override
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/HandshakeReconnectTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/HandshakeReconnectTest.java
index 3facf7e610..39ad73ac0d 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/HandshakeReconnectTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/HandshakeReconnectTest.java
@@ -18,6 +18,7 @@
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+
import org.cometd.bayeux.Channel;
import org.cometd.bayeux.client.ClientSessionChannel;
import org.cometd.bayeux.server.BayeuxServer;
@@ -65,7 +66,7 @@ public void testReconnectUsingHandshake(Transport transport) throws Exception {
// Wait for the session to be swept (timeout + maxInterval).
CountDownLatch sessionRemoved = new CountDownLatch(1);
- bayeux.addListener(new BayeuxServer.SessionListener() {
+ bayeuxServer.addListener(new BayeuxServer.SessionListener() {
@Override
public void sessionRemoved(ServerSession session, ServerMessage message, boolean timeout) {
sessionRemoved.countDown();
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/HandshakeWithExpiredSessionTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/HandshakeWithExpiredSessionTest.java
index 71adf1283b..d9c39f7b15 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/HandshakeWithExpiredSessionTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/HandshakeWithExpiredSessionTest.java
@@ -20,6 +20,7 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
+
import org.cometd.bayeux.Channel;
import org.cometd.bayeux.Message;
import org.cometd.bayeux.client.ClientSessionChannel;
@@ -54,7 +55,7 @@ public void testHandshakeWithExpiredSession(Transport transport) throws Exceptio
metaHandshake.addListener(new ClientSessionChannel.MessageListener() {
@Override
public void onMessage(ClientSessionChannel channel, Message message) {
- sessionRef1.set(bayeux.getSession(message.getClientId()));
+ sessionRef1.set(bayeuxServer.getSession(message.getClientId()));
handshakeLatch1.countDown();
metaHandshake.removeListener(this);
}
@@ -81,7 +82,7 @@ public void onMessage(ClientSessionChannel channel, Message message) {
CountDownLatch handshakeLatch2 = new CountDownLatch(1);
AtomicReference sessionRef2 = new AtomicReference<>();
metaHandshake.addListener((ClientSessionChannel.MessageListener)(channel, message) -> {
- sessionRef2.set(bayeux.getSession(message.getClientId()));
+ sessionRef2.set(bayeuxServer.getSession(message.getClientId()));
handshakeLatch2.countDown();
});
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MaxMessageSizeTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MaxMessageSizeTest.java
index e0a25d93d1..b69d8c1829 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MaxMessageSizeTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MaxMessageSizeTest.java
@@ -20,6 +20,7 @@
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+
import org.cometd.bayeux.Promise;
import org.cometd.bayeux.client.ClientSessionChannel;
import org.cometd.bayeux.server.ServerChannel;
@@ -86,7 +87,7 @@ public void testClientMaxMessageSize(Transport transport) throws Exception {
BayeuxClient client = new BayeuxClient(cometdURL, newClientTransport(transport, clientOptions));
client.handshake(message -> {
ClientSessionChannel channel = client.getChannel(channelName);
- channel.subscribe((c, m) -> messageLatch.countDown(), m -> bayeux.getChannel(channelName).publish(null, data, Promise.noop()));
+ channel.subscribe((c, m) -> messageLatch.countDown(), m -> bayeuxServer.getChannel(channelName).publish(null, data, Promise.noop()));
});
Assertions.assertFalse(messageLatch.await(1, TimeUnit.SECONDS));
@@ -111,7 +112,7 @@ public void testClientMaxSendBayeuxMessageSize(Transport transport) throws Excep
String channelName = "/max_msg";
CountDownLatch serverLatch = new CountDownLatch(1);
- bayeux.createChannelIfAbsent(channelName).getReference().addListener(new ServerChannel.MessageListener() {
+ bayeuxServer.createChannelIfAbsent(channelName).getReference().addListener(new ServerChannel.MessageListener() {
@Override
public boolean onMessage(ServerSession sender, ServerChannel channel, ServerMessage.Mutable message) {
serverLatch.countDown();
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MessageDeliveryDuringHandshakeTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MessageDeliveryDuringHandshakeTest.java
index 6fe5706bae..c659d743d3 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MessageDeliveryDuringHandshakeTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MessageDeliveryDuringHandshakeTest.java
@@ -18,6 +18,7 @@
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+
import org.cometd.bayeux.Channel;
import org.cometd.bayeux.Promise;
import org.cometd.bayeux.client.ClientSessionChannel;
@@ -58,7 +59,7 @@ public void testMessagesSentInHandshakeResponseWithAckExtension(Transport transp
Map options = serverOptions(transport);
options.put(AbstractServerTransport.ALLOW_MESSAGE_DELIVERY_DURING_HANDSHAKE, String.valueOf(true));
start(transport, options);
- bayeux.addExtension(new AcknowledgedMessagesExtension());
+ bayeuxServer.addExtension(new AcknowledgedMessagesExtension());
BayeuxClient client = newBayeuxClient(transport);
client.addExtension(new AckExtension());
testMessagesInHandshakeResponse(client, true);
@@ -66,7 +67,7 @@ public void testMessagesSentInHandshakeResponseWithAckExtension(Transport transp
private void testMessagesInHandshakeResponse(BayeuxClient client, boolean allowHandshakeMessages) throws Exception {
String channelName = "/test";
- bayeux.addListener(new BayeuxServer.SessionListener() {
+ bayeuxServer.addListener(new BayeuxServer.SessionListener() {
@Override
public void sessionAdded(ServerSession session, ServerMessage message) {
// Send messages during the handshake processing.
@@ -87,7 +88,7 @@ public void sessionAdded(ServerSession session, ServerMessage message) {
CountDownLatch queueLatch = new CountDownLatch(1);
client.getChannel(Channel.META_HANDSHAKE).addListener((ClientSessionChannel.MessageListener)(channel, message) -> {
- ServerSessionImpl serverSession = (ServerSessionImpl)bayeux.getSession(client.getId());
+ ServerSessionImpl serverSession = (ServerSessionImpl)bayeuxServer.getSession(client.getId());
if (serverSession.getQueue().isEmpty() == allowHandshakeMessages) {
queueLatch.countDown();
}
@@ -111,8 +112,8 @@ public void testMessagesSentInHandshakeResponseWithAckExtensionWithDeQueueListen
Map options = serverOptions(transport);
options.put(AbstractServerTransport.ALLOW_MESSAGE_DELIVERY_DURING_HANDSHAKE, String.valueOf(true));
start(transport, options);
- bayeux.addExtension(new AcknowledgedMessagesExtension());
- bayeux.addListener(new BayeuxServer.SessionListener() {
+ bayeuxServer.addExtension(new AcknowledgedMessagesExtension());
+ bayeuxServer.addListener(new BayeuxServer.SessionListener() {
@Override
public void sessionAdded(ServerSession session, ServerMessage message) {
session.addListener((ServerSession.DeQueueListener)(s, queue) -> {
@@ -126,7 +127,7 @@ public void sessionAdded(ServerSession session, ServerMessage message) {
client.addExtension(new AckExtension());
String channelName = "/test";
- bayeux.addListener(new BayeuxServer.SessionListener() {
+ bayeuxServer.addListener(new BayeuxServer.SessionListener() {
@Override
public void sessionAdded(ServerSession session, ServerMessage message) {
// Send messages during the handshake processing.
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectDeliverOnlyTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectDeliverOnlyTest.java
index 06521eda09..b4b82b8934 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectDeliverOnlyTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectDeliverOnlyTest.java
@@ -18,6 +18,7 @@
import java.time.Duration;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+
import org.cometd.bayeux.Promise;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.bayeux.server.ServerMessage;
@@ -35,7 +36,7 @@ public void testMetaConnectDeliveryOnly(Transport transport) throws Exception {
BayeuxClient client = newBayeuxClient(transport);
- bayeux.addListener(new BayeuxServer.SessionListener() {
+ bayeuxServer.addListener(new BayeuxServer.SessionListener() {
@Override
public void sessionAdded(ServerSession session, ServerMessage message) {
session.setMetaConnectDeliveryOnly(true);
@@ -49,7 +50,7 @@ public void sessionAdded(ServerSession session, ServerMessage message) {
client.getChannel(channelName).subscribe((c, m) -> {
latch.countDown();
if (latch.getCount() == 1) {
- bayeux.getChannel(channelName).publish(null, "data2", Promise.noop());
+ bayeuxServer.getChannel(channelName).publish(null, "data2", Promise.noop());
Assertions.assertFalse(await(latch, Duration.ofSeconds(1)));
}
});
@@ -63,7 +64,7 @@ public void sessionAdded(ServerSession session, ServerMessage message) {
// In the message listener, we perform a second server-side
// publish and the second message should not arrive to the
// client yet because we deliver messages only via /meta/connect.
- bayeux.getChannel(channelName).publish(null, "data1", Promise.noop());
+ bayeuxServer.getChannel(channelName).publish(null, "data1", Promise.noop());
Assertions.assertTrue(latch.await(5, TimeUnit.SECONDS));
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectFailureTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectFailureTest.java
index de7e567b22..0995c03244 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectFailureTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectFailureTest.java
@@ -18,6 +18,7 @@
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+
import org.cometd.bayeux.Channel;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.bayeux.server.ServerMessage;
@@ -51,7 +52,7 @@ public void testMetaConnectSuspendedThenConnectionClosed(Transport transport) th
// Verify that the /meta/connect reply is written.
CountDownLatch metaConnectReplyLatch = new CountDownLatch(1);
- bayeux.addExtension(new BayeuxServer.Extension() {
+ bayeuxServer.addExtension(new BayeuxServer.Extension() {
@Override
public boolean sendMeta(ServerSession session, ServerMessage.Mutable message) {
if (Channel.META_CONNECT.equals(message.getChannel())) {
@@ -63,7 +64,7 @@ public boolean sendMeta(ServerSession session, ServerMessage.Mutable message) {
// Verify that the session is swept.
CountDownLatch sessionRemovedLatch = new CountDownLatch(1);
- ServerSession session = bayeux.getSession(client.getId());
+ ServerSession session = bayeuxServer.getSession(client.getId());
session.addListener((ServerSession.RemovedListener)(s, m, t) -> sessionRemovedLatch.countDown());
// Stop the connector so the /meta/connect response cannot be sent,
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectFailureWithAckExtensionTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectFailureWithAckExtensionTest.java
index b57ae9dd6c..e1f5551ea2 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectFailureWithAckExtensionTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectFailureWithAckExtensionTest.java
@@ -18,6 +18,7 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+
import org.cometd.bayeux.Channel;
import org.cometd.bayeux.Promise;
import org.cometd.bayeux.client.ClientSession;
@@ -34,17 +35,19 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
public class MetaConnectFailureWithAckExtensionTest extends AbstractClientServerTest {
@ParameterizedTest
@MethodSource("transports")
public void testMetaConnectFailureWithAckExtension(Transport transport) throws Exception {
start(transport);
- bayeux.addExtension(new AcknowledgedMessagesExtension());
+ bayeuxServer.addExtension(new AcknowledgedMessagesExtension());
String channelName = "/test";
CountDownLatch serverSubscribeLatch = new CountDownLatch(1);
- bayeux.addListener(new BayeuxServer.SubscriptionListener() {
+ bayeuxServer.addListener(new BayeuxServer.SubscriptionListener() {
@Override
public void subscribed(ServerSession session, ServerChannel channel, ServerMessage message) {
if (channelName.equals(channel.getId())) {
@@ -55,7 +58,7 @@ public void subscribed(ServerSession session, ServerChannel channel, ServerMessa
long delay = 1000;
long maxNetworkDelay = 3 * delay;
- bayeux.getChannel(Channel.META_CONNECT).addListener(new ServerChannel.MessageListener() {
+ bayeuxServer.getChannel(Channel.META_CONNECT).addListener(new ServerChannel.MessageListener() {
private final AtomicInteger connects = new AtomicInteger();
@Override
@@ -67,16 +70,15 @@ public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessag
// Be sure we are subscribed.
try {
- serverSubscribeLatch.await(5, TimeUnit.SECONDS);
- } catch (InterruptedException x) {
- // Ignored
+ assertTrue(serverSubscribeLatch.await(5, TimeUnit.SECONDS));
+ } catch (InterruptedException ignored) {
}
int connect = connects.incrementAndGet();
if (connect == 1) {
// Publish a message on the first connect, which will fail.
// The ack extension will deliver it via /meta/connect.
- bayeux.createChannelIfAbsent(channelName).getReference().publish(null, "data", Promise.noop());
+ bayeuxServer.createChannelIfAbsent(channelName).getReference().publish(null, "data", Promise.noop());
sleep(maxNetworkDelay + delay);
} else if (connect == 2) {
// When the second connect arrives, maxNetworkDelay has elapsed.
@@ -115,8 +117,8 @@ public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessag
}
});
- Assertions.assertTrue(clientSubscribeLatch.await(5, TimeUnit.SECONDS));
- Assertions.assertTrue(messageLatch1.await(2 * maxNetworkDelay, TimeUnit.MILLISECONDS));
+ assertTrue(clientSubscribeLatch.await(5, TimeUnit.SECONDS));
+ assertTrue(messageLatch1.await(2 * maxNetworkDelay, TimeUnit.MILLISECONDS));
Assertions.assertFalse(messageLatch2.await(2 * delay, TimeUnit.MILLISECONDS));
disconnectBayeuxClient(client);
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectOvertakenWithAckExtensionTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectOvertakenWithAckExtensionTest.java
index b506881dbb..10c776eed1 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectOvertakenWithAckExtensionTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/MetaConnectOvertakenWithAckExtensionTest.java
@@ -20,6 +20,7 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
+
import org.cometd.bayeux.Channel;
import org.cometd.bayeux.Promise;
import org.cometd.bayeux.client.ClientSession;
@@ -47,7 +48,7 @@ public void testMetaConnectFailureWithAckExtension(Transport transport) throws E
start(transport, serverOptions);
AtomicReference messageRef = new AtomicReference<>();
AtomicReference> promiseRef = new AtomicReference<>();
- bayeux.addExtension(new BayeuxServer.Extension() {
+ bayeuxServer.addExtension(new BayeuxServer.Extension() {
@Override
public boolean rcvMeta(ServerSession session, ServerMessage.Mutable message) {
if (Channel.META_HANDSHAKE.equals(message.getChannel())) {
@@ -71,7 +72,7 @@ public void outgoing(ServerSession sender, ServerSession session, ServerMessage.
return true;
}
});
- bayeux.addExtension(new AcknowledgedMessagesExtension());
+ bayeuxServer.addExtension(new AcknowledgedMessagesExtension());
String channelName = "/overtaken";
@@ -111,7 +112,7 @@ public void outgoing(ServerSession sender, ServerSession session, ServerMessage.
// Send a message to deliver it with the ack extension.
// The 2nd /meta/connect reply will be delayed by the extension on server.
- ServerChannel serverChannel = bayeux.getChannel(channelName);
+ ServerChannel serverChannel = bayeuxServer.getChannel(channelName);
serverChannel.publish(null, "data1", Promise.noop());
// Setup to hold the 3rd /meta/connect on the client, so the 4th is delayed.
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/NetworkDelayListenerTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/NetworkDelayListenerTest.java
index 36ca58468c..8f81642ded 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/NetworkDelayListenerTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/NetworkDelayListenerTest.java
@@ -66,9 +66,9 @@ public class NetworkDelayListenerTest extends AbstractClientServerTest {
public void testNetworkDelayListener(Transport transport) throws Exception {
try (ServerSocketChannel serverSocket = ServerSocketChannel.open()) {
serverSocket.bind(new InetSocketAddress("localhost", 0));
- cometdServletPath = "/cometd";
+ cometdPath = "/cometd";
int port = serverSocket.socket().getLocalPort();
- cometdURL = "http://localhost:" + port + cometdServletPath;
+ cometdURL = "http://localhost:" + port + cometdPath;
LOGGER.debug("Listening on localhost:{}", port);
startClient(transport);
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/OrphanedSessionTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/OrphanedSessionTest.java
index 8d243b5c23..73d18ba872 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/OrphanedSessionTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/OrphanedSessionTest.java
@@ -19,6 +19,7 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
+
import org.cometd.bayeux.Promise;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.bayeux.server.ServerMessage;
@@ -40,7 +41,7 @@ public void testForOrphanedSessionDeliverDoesNotEnqueue(Transport transport) thr
AtomicReference serverSessionRef = new AtomicReference<>();
CountDownLatch removedLatch = new CountDownLatch(1);
- bayeux.addListener(new BayeuxServer.SessionListener() {
+ bayeuxServer.addListener(new BayeuxServer.SessionListener() {
@Override
public void sessionAdded(ServerSession session, ServerMessage message) {
serverSessionRef.set(session);
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/ProxyTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/ProxyTest.java
index 4fb429c1c4..b518437be4 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/ProxyTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/ProxyTest.java
@@ -34,9 +34,9 @@
import org.cometd.client.transport.ClientTransport;
import org.cometd.server.AbstractServerTransport;
import org.cometd.server.BayeuxServerImpl;
-import org.cometd.server.CometDServlet;
import org.cometd.server.ServerMessageImpl;
-import org.cometd.server.http.AsyncJSONTransport;
+import org.cometd.server.http.JSONHttpTransport;
+import org.cometd.server.http.jakarta.CometDServlet;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
@@ -97,9 +97,8 @@ protected void startProxy(Map initParams) throws Exception {
private ServletContextHandler prepareContext(Server server, Map initParams) {
ServletContextHandler context = new ServletContextHandler("/");
server.setHandler(context);
- // CometD servlet
ServletHolder cometdServletHolder = new ServletHolder(CometDServlet.class);
- cometdServletHolder.setInitParameter(BayeuxServerImpl.TRANSPORTS_OPTION, AsyncJSONTransport.class.getName());
+ cometdServletHolder.setInitParameter(BayeuxServerImpl.TRANSPORTS_OPTION, JSONHttpTransport.class.getName());
cometdServletHolder.setInitParameter(AbstractServerTransport.TIMEOUT_OPTION, "10000");
cometdServletHolder.setInitOrder(1);
if (initParams != null) {
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/ServerSendMessageTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/ServerSendMessageTest.java
index 9b99d56225..366552b595 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/ServerSendMessageTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/ServerSendMessageTest.java
@@ -17,6 +17,7 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+
import org.cometd.bayeux.Promise;
import org.cometd.bayeux.client.ClientSessionChannel;
import org.cometd.bayeux.server.ServerChannel;
@@ -35,7 +36,7 @@ public void testServerCanSendMessageBeforeFirstMetaConnect(Transport transport)
String channelName = "/service/test";
String response = "response";
- bayeux.createChannelIfAbsent(channelName).getReference().addListener(new ServerChannel.MessageListener() {
+ bayeuxServer.createChannelIfAbsent(channelName).getReference().addListener(new ServerChannel.MessageListener() {
@Override
public boolean onMessage(ServerSession from, ServerChannel channel, ServerMessage.Mutable message) {
from.deliver(null, channelName, response, Promise.noop());
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/SweepTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/SweepTest.java
index a7898c591a..109e585871 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/SweepTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/SweepTest.java
@@ -45,7 +45,7 @@ public void testMaxProcessingPostponesSweeping(Transport transport) throws Excep
CountDownLatch suspendLatch = new CountDownLatch(1);
CountDownLatch removeLatch = new CountDownLatch(1);
client.handshake(r -> {
- ServerSession session = bayeux.getSession(r.getClientId());
+ ServerSession session = bayeuxServer.getSession(r.getClientId());
session.addListener(new ServerSession.HeartBeatListener() {
@Override
public void onSuspended(ServerSession session, ServerMessage message, long timeout) {
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/TransportFailureTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/TransportFailureTest.java
index fa1bb48d92..65fabd090c 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/TransportFailureTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/TransportFailureTest.java
@@ -32,7 +32,7 @@
import org.cometd.client.transport.ClientTransport;
import org.cometd.client.websocket.jakarta.WebSocketTransport;
import org.cometd.server.BayeuxServerImpl;
-import org.cometd.server.CometDServlet;
+import org.cometd.server.http.jakarta.CometDServlet;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
@@ -64,7 +64,6 @@ private void startServer() throws Exception {
cometdServletPath = "/cometd";
- // CometD servlet
ServletHolder cometdServletHolder = new ServletHolder(CometDServlet.class);
cometdServletHolder.setInitParameter("timeout", "10000");
cometdServletHolder.setInitParameter("ws.cometdURLMapping", cometdServletPath);
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/WebAppService.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/WebAppService.java
index 4c78d5f0d5..e74dfee1ec 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/WebAppService.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/WebAppService.java
@@ -176,7 +176,7 @@ public void toJSON(Object obj, JSON.Output out) {
}
@Override
- public Object fromJSON(Map map) {
+ public Object fromJSON(Map map) {
Custom custom = new Custom();
custom.data = (String)map.get("data");
return custom;
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/WebAppTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/WebAppTest.java
index d307f1ce0a..28397052dd 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/WebAppTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/java/org/cometd/tests/WebAppTest.java
@@ -42,7 +42,8 @@
import org.cometd.client.BayeuxClient;
import org.cometd.client.http.jetty.JettyHttpClientTransport;
import org.cometd.client.websocket.jakarta.WebSocketTransport;
-import org.cometd.client.websocket.jetty.JettyWebSocketTransport;
+import org.cometd.server.CometDRequest;
+import org.cometd.server.http.jakarta.CometDServlet;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.component.LifeCycle;
@@ -56,11 +57,10 @@
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.RegisterExtension;
-
public class WebAppTest {
private String testName;
@RegisterExtension
- final BeforeTestExecutionCallback printMethodName = context -> {
+ public final BeforeTestExecutionCallback printMethodName = context -> {
testName = context.getRequiredTestMethod().getName();
System.err.printf("Running %s.%s() %s%n", context.getRequiredTestClass().getSimpleName(), testName, context.getDisplayName());
};
@@ -90,9 +90,7 @@ private void start(Path webXML) throws Exception {
copyWebAppDependency(jakarta.inject.Inject.class, webINF);
copyWebAppDependency(jakarta.annotation.PostConstruct.class, webINF);
copyWebAppDependency(org.slf4j.Logger.class, webINF);
- copyWebAppDependency(org.apache.logging.slf4j.Log4jLogger.class, webINF);
- copyWebAppDependency(org.apache.logging.log4j.Level.class, webINF);
- copyWebAppDependency(org.apache.logging.log4j.core.LoggerContext.class, webINF);
+ copyWebAppDependency(org.eclipse.jetty.logging.JettyLogger.class, webINF);
copyWebAppDependency(org.cometd.annotation.Service.class, webINF);
copyWebAppDependency(org.cometd.annotation.server.RemoteCall.class, webINF);
copyWebAppDependency(org.cometd.bayeux.Message.class, webINF);
@@ -102,7 +100,6 @@ private void start(Path webXML) throws Exception {
copyWebAppDependency(org.cometd.server.BayeuxServerImpl.class, webINF);
copyWebAppDependency(org.cometd.server.websocket.common.AbstractWebSocketTransport.class, webINF);
copyWebAppDependency(org.cometd.server.websocket.jakarta.WebSocketTransport.class, webINF);
- copyWebAppDependency(org.cometd.server.websocket.jetty.JettyWebSocketTransport.class, webINF);
copyWebAppDependency(org.cometd.client.BayeuxClient.class, webINF);
copyWebAppDependency(org.cometd.client.http.common.AbstractHttpClientTransport.class, webINF);
copyWebAppDependency(org.cometd.client.http.jetty.JettyHttpClientTransport.class, webINF);
@@ -117,10 +114,17 @@ private void start(Path webXML) throws Exception {
copyWebAppDependency(org.eclipse.jetty.ee10.servlets.CrossOriginFilter.class, webINF);
copyWebAppDependency(org.eclipse.jetty.util.Callback.class, webINF);
copyWebAppDependency(org.eclipse.jetty.util.ajax.JSON.class, webINF);
+ copyWebAppDependency(org.eclipse.jetty.websocket.api.Configurable.class, webINF);
copyWebAppDependency(org.eclipse.jetty.websocket.common.WebSocketSession.class, webINF);
copyWebAppDependency(org.eclipse.jetty.websocket.client.WebSocketClient.class, webINF);
copyWebAppDependency(org.eclipse.jetty.websocket.core.client.WebSocketCoreClient.class, webINF);
copyWebAppDependency(org.eclipse.jetty.websocket.core.Configuration.class, webINF);
+ copyWebAppDependency(CometDServlet.class, webINF);
+ copyWebAppDependency(CometDRequest.class, webINF);
+ copyWebAppDependency(org.cometd.bayeux.server.BayeuxContext.class, webINF);
+ copyWebAppDependency(org.cometd.bayeux.Promise.class, webINF);
+ copyWebAppDependency(org.cometd.common.JSONContext.class, webINF);
+ copyWebAppDependency(org.cometd.bayeux.client.ClientSession.class, webINF);
// Web application classes.
Path testClasses = baseDir.resolve("target/test-classes/");
@@ -150,9 +154,7 @@ private void start(Path webXML) throws Exception {
addServerDependency(jakarta.annotation.Resources.class, serverClassPath);
addServerDependency(jakarta.annotation.security.RunAs.class, serverClassPath);
addServerDependency(org.slf4j.Logger.class, serverClassPath);
- addServerDependency(org.apache.logging.slf4j.SLF4JServiceProvider.class, serverClassPath);
- addServerDependency(org.apache.logging.log4j.Logger.class, serverClassPath);
- addServerDependency(org.apache.logging.log4j.core.Appender.class, serverClassPath);
+ addServerDependency(org.eclipse.jetty.logging.JettyLogger.class, serverClassPath);
addServerDependency(org.eclipse.jetty.ee10.annotations.AnnotationConfiguration.class, serverClassPath);
addServerDependency(org.eclipse.jetty.client.HttpClient.class, serverClassPath);
addServerDependency(org.eclipse.jetty.http.HttpStatus.class, serverClassPath);
@@ -164,6 +166,9 @@ private void start(Path webXML) throws Exception {
addServerDependency(org.eclipse.jetty.server.Server.class, serverClassPath);
addServerDependency(org.eclipse.jetty.ee10.servlet.ServletContextHandler.class, serverClassPath);
addServerDependency(org.eclipse.jetty.util.Callback.class, serverClassPath);
+ addServerDependency(org.eclipse.jetty.server.Deployable.class, serverClassPath);
+ addServerDependency(org.eclipse.jetty.session.SessionManager.class, serverClassPath);
+ addServerDependency(org.eclipse.jetty.util.ajax.JSON.class, serverClassPath);
addServerDependency(org.eclipse.jetty.ee10.webapp.WebAppContext.class, serverClassPath);
addServerDependency(org.eclipse.jetty.websocket.api.Session.class, serverClassPath);
addServerDependency(org.eclipse.jetty.websocket.common.WebSocketSession.class, serverClassPath);
@@ -173,7 +178,6 @@ private void start(Path webXML) throws Exception {
addServerDependency(org.eclipse.jetty.ee10.websocket.jakarta.client.JakartaWebSocketClientContainerProvider.class, serverClassPath);
addServerDependency(org.eclipse.jetty.ee10.websocket.jakarta.common.JakartaWebSocketContainer.class, serverClassPath);
addServerDependency(org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketConfiguration.class, serverClassPath);
- addServerDependency(org.eclipse.jetty.ee10.websocket.server.config.JettyWebSocketConfiguration.class, serverClassPath);
addServerDependency(org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter.class, serverClassPath);
addServerDependency(org.eclipse.jetty.xml.XmlConfiguration.class, serverClassPath);
addServerDependency(org.objectweb.asm.ClassVisitor.class, serverClassPath);
@@ -212,15 +216,6 @@ public void dispose() {
IO.close(server);
}
- @Test
- public void testWebAppWithNativeJettyWebSocketTransport() throws Exception {
- start(baseDir.resolve("src/test/resources/jetty-ws-web.xml"));
-
- BayeuxClient client = new BayeuxClient(cometdURI, new JettyWebSocketTransport(null, null, wsClient));
- subscribePublishReceive(client);
- client.disconnect();
- }
-
@Test
public void testWebAppWithWebSocketTransport() throws Exception {
start(baseDir.resolve("src/test/resources/jakarta-ws-web.xml"));
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/http-web.xml b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/http-web.xml
index 926b02676e..1edf417652 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/http-web.xml
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/http-web.xml
@@ -17,10 +17,10 @@
cometd
- org.cometd.server.CometDServlet
+ org.cometd.server.http.jakarta.CometDServlet
transports
- org.cometd.server.http.AsyncJSONTransport
+ org.cometd.server.http.JSONHttpTransport
1
true
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/jakarta-ws-web.xml b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/jakarta-ws-web.xml
index 66a27ae789..f9dbe8b1e1 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/jakarta-ws-web.xml
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/jakarta-ws-web.xml
@@ -28,7 +28,7 @@
cometd
- org.cometd.server.CometDServlet
+ org.cometd.server.http.jakarta.CometDServlet
ws.cometdURLMapping
/cometd/*
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/jetty-logging.properties b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/jetty-logging.properties
new file mode 100644
index 0000000000..6a0fcfb868
--- /dev/null
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/jetty-logging.properties
@@ -0,0 +1,3 @@
+## Levels: ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF.
+#org.cometd.LEVEL=DEBUG
+#org.eclipse.jetty.LEVEL=DEBUG
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/jetty-ws-web.xml b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/jetty-ws-web.xml
deleted file mode 100644
index 1c2cec6224..0000000000
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/jetty-ws-web.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
- cross-origin
- org.eclipse.jetty.ee10.servlets.CrossOriginFilter
- true
-
-
- cross-origin
- /cometd/*
-
-
-
- org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter
- org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter
- true
-
-
-
- org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter
- /cometd/*
-
-
-
- cometd
- org.cometd.server.CometDServlet
-
- transports
-
- org.cometd.server.websocket.jetty.JettyWebSocketTransport,org.cometd.server.http.AsyncJSONTransport
-
-
-
- ws.cometdURLMapping
- /cometd/*
-
- 1
- true
-
-
-
- cometd
- /cometd/*
-
-
-
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/log4j2-test.properties b/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/log4j2-test.properties
deleted file mode 100644
index 276f0d2e8b..0000000000
--- a/cometd-java/cometd-java-tests/cometd-java-tests-common/src/test/resources/log4j2-test.properties
+++ /dev/null
@@ -1,16 +0,0 @@
-# LOG4J2 levels: fatal, error, warn, info, debug, trace
-#
-appender.console.type=Console
-appender.console.name=console
-appender.console.target=SYSTEM_ERR
-appender.console.layout.type=PatternLayout
-appender.console.layout.pattern=%d %t [%5p][%c{2}] %m%n
-
-rootLogger.level=debug
-rootLogger.appenderRef.console.ref=console
-
-logger.jetty.name=org.eclipse.jetty
-logger.jetty.level=info
-
-logger.cometd.name=org.cometd
-logger.cometd.level=info
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-oort/pom.xml b/cometd-java/cometd-java-tests/cometd-java-tests-oort/pom.xml
index 6c1ca6f8de..d43e58b38f 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-oort/pom.xml
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-oort/pom.xml
@@ -12,26 +12,32 @@
- org.junit.jupiter
- junit-jupiter
+ org.cometd.java
+ cometd-java-oort-common
+ ${project.version}
+ test
- org.apache.logging.log4j
- log4j-core
+ org.cometd.java
+ cometd-java-oort-jakarta
+ ${project.version}
+ test
- org.apache.logging.log4j
- log4j-slf4j2-impl
+ org.cometd.java
+ cometd-java-annotation-server
+ ${project.version}
+ test
org.cometd.java
- cometd-java-oort
+ cometd-java-server-http-jakarta
${project.version}
test
org.cometd.java
- cometd-java-annotation-server
+ cometd-java-server-http-jetty
${project.version}
test
@@ -90,8 +96,8 @@
test
- org.eclipse.jetty.ee10.websocket
- jetty-ee10-websocket-jetty-server
+ org.eclipse.jetty.websocket
+ jetty-websocket-jetty-server
${jetty-version}
test
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/AbstractOortObjectTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/AbstractOortObjectTest.java
index c66c7536c8..c53334306b 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/AbstractOortObjectTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/AbstractOortObjectTest.java
@@ -21,6 +21,7 @@
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.bayeux.server.ServerChannel;
import org.cometd.bayeux.server.ServerMessage;
@@ -30,19 +31,19 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
-public abstract class AbstractOortObjectTest extends OortTest {
+public abstract class AbstractOortObjectTest extends AbstractOortTest {
private final List> oortObjects = new ArrayList<>();
protected Oort oort1;
protected Oort oort2;
- protected void prepare(String serverTransport) throws Exception {
- prepare(serverTransport, new HashMap<>());
+ protected void prepare(Transport transport) throws Exception {
+ prepare(transport, new HashMap<>());
}
- protected void prepare(String serverTransport, Map options) throws Exception {
- Server server1 = startServer(serverTransport, 0, options);
+ protected void prepare(Transport transport, Map options) throws Exception {
+ Server server1 = startServer(transport, 0, options);
oort1 = startOort(server1);
- Server server2 = startServer(serverTransport, 0, options);
+ Server server2 = startServer(transport, 0, options);
oort2 = startOort(server2);
CountDownLatch latch = new CountDownLatch(2);
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/AbstractOortTest.java
similarity index 72%
rename from cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortTest.java
rename to cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/AbstractOortTest.java
index a4ce7ebdae..23be8ffcf4 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/AbstractOortTest.java
@@ -27,6 +27,7 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Supplier;
import org.cometd.bayeux.Message;
import org.cometd.bayeux.client.ClientSessionChannel;
@@ -35,42 +36,48 @@
import org.cometd.bayeux.server.ServerSession;
import org.cometd.client.BayeuxClient;
import org.cometd.client.http.jetty.JettyHttpClientTransport;
-import org.cometd.server.CometDServlet;
-import org.cometd.server.http.JSONTransport;
+import org.cometd.oort.jakarta.OortConfigServlet;
+import org.cometd.server.AbstractServerTransport;
+import org.cometd.server.BayeuxServerImpl;
+import org.cometd.server.http.JSONHttpTransport;
+import org.cometd.server.http.jakarta.CometDServlet;
+import org.cometd.server.http.jetty.CometDHandler;
+import org.cometd.server.websocket.common.AbstractWebSocketTransport;
import org.cometd.server.websocket.jakarta.WebSocketTransport;
import org.cometd.server.websocket.jetty.JettyWebSocketTransport;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
-import org.eclipse.jetty.ee10.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.eclipse.jetty.websocket.server.WebSocketUpgradeHandler;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public abstract class OortTest {
- public static List transports() {
- return List.of(WebSocketTransport.class.getName(), JettyWebSocketTransport.class.getName());
+public abstract class AbstractOortTest {
+ public static Transport[] transports() {
+ return Transport.values();
}
@RegisterExtension
- final BeforeTestExecutionCallback printMethodName = context ->
+ public final BeforeTestExecutionCallback printMethodName = context ->
System.err.printf("Running %s.%s() %s%n", context.getRequiredTestClass().getSimpleName(), context.getRequiredTestMethod().getName(), context.getDisplayName());
protected final Logger logger = LoggerFactory.getLogger(getClass());
protected final List servers = new ArrayList<>();
protected final List oorts = new ArrayList<>();
private final List clients = new ArrayList<>();
- protected Server startServer(String serverTransport, int port) throws Exception {
- return startServer(serverTransport, port, new HashMap<>());
+ protected Server startServer(Transport transport, int port) throws Exception {
+ return startServer(transport, port, new HashMap<>());
}
- protected Server startServer(String serverTransport, int port, Map options) throws Exception {
+ protected Server startServer(Transport transport, int port, Map options) throws Exception {
QueuedThreadPool serverThreads = new QueuedThreadPool();
serverThreads.setName("server_" + servers.size());
Server server = new Server(serverThreads);
@@ -78,35 +85,46 @@ protected Server startServer(String serverTransport, int port, Map entry : options.entrySet()) {
- cometdServletHolder.setInitParameter(entry.getKey(), entry.getValue());
- }
- cometdServletHolder.setInitOrder(1);
- context.addServlet(cometdServletHolder, cometdURLMapping);
+ String cometdPath = "/cometd";
+ String cometdURLMapping = cometdPath + "/*";
+ Supplier getBayeuxServer = switch (transport) {
+ case JAKARTA_WEBSOCKET -> {
+ ServletContextHandler context = new ServletContextHandler("/");
+ server.setHandler(context);
+ JakartaWebSocketServletContainerInitializer.configure(context, null);
+ CometDServlet cometdServlet = new CometDServlet();
+ ServletHolder cometdServletHolder = new ServletHolder(cometdServlet);
+ String transports = WebSocketTransport.class.getName() + "," + JSONHttpTransport.class.getName();
+ cometdServletHolder.setInitParameter(BayeuxServerImpl.TRANSPORTS_OPTION, transports);
+ cometdServletHolder.setInitParameter(AbstractServerTransport.TIMEOUT_OPTION, "10000");
+ cometdServletHolder.setInitParameter(AbstractWebSocketTransport.COMETD_URL_MAPPING_OPTION, cometdURLMapping);
+ for (Map.Entry entry : options.entrySet()) {
+ cometdServletHolder.setInitParameter(entry.getKey(), entry.getValue());
+ }
+ cometdServletHolder.setInitOrder(1);
+ context.addServlet(cometdServletHolder, cometdURLMapping);
+ yield cometdServlet::getBayeuxServer;
+ }
+ case JETTY_WEBSOCKET -> {
+ ContextHandler context = new ContextHandler("/");
+ server.setHandler(context);
+ WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
+ context.setHandler(wsHandler);
+ CometDHandler cometdHandler = new CometDHandler();
+ wsHandler.setHandler(cometdHandler);
+ String transports = JettyWebSocketTransport.class.getName() + "," + JSONHttpTransport.class.getName();
+ options.put(BayeuxServerImpl.TRANSPORTS_OPTION, transports);
+ options.putIfAbsent(AbstractServerTransport.TIMEOUT_OPTION, "10000");
+ options.put(AbstractWebSocketTransport.COMETD_URL_MAPPING_OPTION, cometdURLMapping);
+ cometdHandler.setOptions(options);
+ yield cometdHandler::getBayeuxServer;
+ }
+ };
server.start();
- String url = "http://localhost:" + connector.getLocalPort() + cometdServletPath;
+ String url = "http://localhost:" + connector.getLocalPort() + cometdPath;
server.setAttribute(OortConfigServlet.OORT_URL_PARAM, url);
- BayeuxServer bayeux = (BayeuxServer)context.getServletContext().getAttribute(BayeuxServer.ATTRIBUTE);
+ BayeuxServer bayeux = getBayeuxServer.get();
server.setAttribute(BayeuxServer.ATTRIBUTE, bayeux);
servers.add(server);
@@ -303,4 +321,8 @@ private boolean snd(ServerMessage.Mutable message) {
return true;
}
}
+
+ public enum Transport {
+ JAKARTA_WEBSOCKET, JETTY_WEBSOCKET
+ }
}
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/JMXTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/JMXTest.java
index 81acef29ce..cb7ea12f9c 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/JMXTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/JMXTest.java
@@ -24,8 +24,11 @@
import jakarta.servlet.http.HttpServlet;
import org.cometd.bayeux.server.BayeuxServer;
+import org.cometd.oort.jakarta.OortConfigServlet;
+import org.cometd.oort.jakarta.OortStaticConfigServlet;
+import org.cometd.oort.jakarta.SetiServlet;
import org.cometd.server.BayeuxServerImpl;
-import org.cometd.server.CometDServlet;
+import org.cometd.server.http.jakarta.CometDServlet;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
@@ -54,9 +57,8 @@ public void testJMX() throws Exception {
String value = BayeuxServerImpl.ATTRIBUTE + "," + Oort.OORT_ATTRIBUTE + "," + Seti.SETI_ATTRIBUTE;
context.setInitParameter(ServletContextHandler.MANAGED_ATTRIBUTES, value);
- // CometD servlet
- String cometdServletPath = "/cometd";
- String cometdURLMapping = cometdServletPath + "/*";
+ String cometdPath = "/cometd";
+ String cometdURLMapping = cometdPath + "/*";
ServletHolder cometdServletHolder = new ServletHolder(CometDServlet.class);
cometdServletHolder.setInitParameter("timeout", "10000");
cometdServletHolder.setInitParameter("ws.cometdURLMapping", cometdURLMapping);
@@ -64,7 +66,7 @@ public void testJMX() throws Exception {
context.addServlet(cometdServletHolder, cometdURLMapping);
ServletHolder oortServletHolder = new ServletHolder(OortStaticConfigServlet.class);
- oortServletHolder.setInitParameter(OortConfigServlet.OORT_URL_PARAM, "http://localhost" + cometdServletPath);
+ oortServletHolder.setInitParameter(OortConfigServlet.OORT_URL_PARAM, "http://localhost" + cometdPath);
oortServletHolder.setInitOrder(2);
context.addServlet(oortServletHolder, "/oort");
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/JacksonOortObjectTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/JacksonOortObjectTest.java
index 0f8d138c7c..f226f66a18 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/JacksonOortObjectTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/JacksonOortObjectTest.java
@@ -25,12 +25,12 @@
public class JacksonOortObjectTest extends OortObjectTest {
@Override
- protected Server startServer(String serverTransport, int port, Map options) throws Exception {
+ protected Server startServer(Transport transport, int port, Map options) throws Exception {
if (options == null) {
options = new HashMap<>();
}
options.put(AbstractServerTransport.JSON_CONTEXT_OPTION, JacksonJSONContextServer.class.getName());
- return super.startServer(serverTransport, port, options);
+ return super.startServer(transport, port, options);
}
@Override
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortAuthenticationTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortAuthenticationTest.java
index 3671726bdf..6892b88c25 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortAuthenticationTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortAuthenticationTest.java
@@ -32,15 +32,15 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
-public class OortAuthenticationTest extends OortTest {
+public class OortAuthenticationTest extends AbstractOortTest {
@ParameterizedTest
@MethodSource("transports")
- public void testAuthenticationWithSecurityPolicy(String serverTransport) throws Exception {
- Server server1 = startServer(serverTransport, 0);
+ public void testAuthenticationWithSecurityPolicy(Transport transport) throws Exception {
+ Server server1 = startServer(transport, 0);
Oort oort1 = startOort(server1);
oort1.setSecret("test_secret");
oort1.getBayeuxServer().setSecurityPolicy(new TestSecurityPolicy(oort1));
- Server server2 = startServer(serverTransport, 0);
+ Server server2 = startServer(transport, 0);
Oort oort2 = startOort(server2);
oort2.setSecret(oort1.getSecret());
oort2.getBayeuxServer().setSecurityPolicy(new TestSecurityPolicy(oort2));
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortDemo.java b/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortDemo.java
index 4f050983cf..cf6a784863 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortDemo.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortDemo.java
@@ -19,7 +19,9 @@
import java.net.URI;
import java.util.List;
-import org.cometd.server.CometDServlet;
+import org.cometd.oort.jakarta.OortMulticastConfigServlet;
+import org.cometd.oort.jakarta.SetiServlet;
+import org.cometd.server.http.jakarta.CometDServlet;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
import org.eclipse.jetty.jmx.MBeanContainer;
@@ -72,7 +74,6 @@ public OortDemo(int port) throws Exception {
URI.create(base + "/../../cometd-demo/target/cometd-demo-2.4.0-SNAPSHOT/")
)));
- // CometD servlet
ServletHolder cometd_holder = new ServletHolder(CometDServlet.class);
cometd_holder.setInitParameter("timeout", "200000");
cometd_holder.setInitParameter("interval", "100");
diff --git a/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortListTest.java b/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortListTest.java
index 2f4d99c628..be057f0b8e 100644
--- a/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortListTest.java
+++ b/cometd-java/cometd-java-tests/cometd-java-tests-oort/src/test/java/org/cometd/oort/OortListTest.java
@@ -30,8 +30,8 @@
public class OortListTest extends AbstractOortObjectTest {
@ParameterizedTest
@MethodSource("transports")
- public void testElementAdded(String serverTransport) throws Exception {
- prepare(serverTransport);
+ public void testElementAdded(Transport transport) throws Exception {
+ prepare(transport);
String name = "test";
OortObject.Factory> factory = OortObjectFactories.forConcurrentList();
@@ -58,8 +58,8 @@ public void onAdded(OortObject.Info> info, List elements) {
@ParameterizedTest
@MethodSource("transports")
- public void testElementRemoved(String serverTransport) throws Exception {
- prepare(serverTransport);
+ public void testElementRemoved(Transport transport) throws Exception {
+ prepare(transport);
String name = "test";
OortObject.Factory> factory = OortObjectFactories.forConcurrentList();
@@ -100,8 +100,8 @@ public void onRemoved(OortObject.Info> info, List elements) {
@ParameterizedTest
@MethodSource("transports")
- public void testDeltaListener(String serverTransport) throws Exception {
- prepare(serverTransport);
+ public void testDeltaListener(Transport transport) throws Exception {
+ prepare(transport);
String name = "test";
OortObject.Factory