Implement Eclipse Jetty core HTTP handler adapter
This provides an implementation of an HTTP Handler Adapter that is coded directly to the Eclipse Jetty core API, bypassing any servlet implementation. This includes a Jetty implementation of the spring `WebSocketClient` interface, `JettyWebSocketClient`, using an explicit dependency to the jetty-websocket-api. Closes gh-32097 Co-authored-by: Lachlan Roberts <lachlan@webtide.com> Co-authored-by: Arjen Poutsma <arjen.poutsma@broadcom.com>
This commit is contained in:
@@ -16,7 +16,12 @@
|
||||
|
||||
package org.springframework.web.reactive.result.method.annotation;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Named;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -28,10 +33,16 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.reactive.config.EnableWebFlux;
|
||||
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.AbstractHttpServer;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.JettyCoreHttpServer;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.JettyHttpServer;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.ReactorHttpServer;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.TomcatHttpServer;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.UndertowHttpServer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
|
||||
/**
|
||||
* Integration tests related to the use of context paths.
|
||||
@@ -40,15 +51,25 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
class ContextPathIntegrationTests {
|
||||
|
||||
@Test
|
||||
void multipleWebFluxApps() throws Exception {
|
||||
static Stream<Named<HttpServer>> httpServers() {
|
||||
return Stream.of(
|
||||
named("Jetty", new JettyHttpServer()),
|
||||
named("Jetty Core", new JettyCoreHttpServer()),
|
||||
named("Reactor Netty", new ReactorHttpServer()),
|
||||
named("Tomcat", new TomcatHttpServer()),
|
||||
named("Undertow", new UndertowHttpServer())
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "[{index}] {0}")
|
||||
@MethodSource("httpServers")
|
||||
void multipleWebFluxApps(AbstractHttpServer server) throws Exception {
|
||||
AnnotationConfigApplicationContext context1 = new AnnotationConfigApplicationContext(WebAppConfig.class);
|
||||
AnnotationConfigApplicationContext context2 = new AnnotationConfigApplicationContext(WebAppConfig.class);
|
||||
|
||||
HttpHandler webApp1Handler = WebHttpHandlerBuilder.applicationContext(context1).build();
|
||||
HttpHandler webApp2Handler = WebHttpHandlerBuilder.applicationContext(context2).build();
|
||||
|
||||
ReactorHttpServer server = new ReactorHttpServer();
|
||||
server.registerHttpHandler("/webApp1", webApp1Handler);
|
||||
server.registerHttpHandler("/webApp2", webApp2Handler);
|
||||
server.afterPropertiesSet();
|
||||
|
||||
@@ -53,6 +53,7 @@ import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.AbstractHttpHandlerIntegrationTests;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.JettyCoreHttpServer;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.JettyHttpServer;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.ReactorHttpServer;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.TomcatHttpServer;
|
||||
@@ -127,7 +128,7 @@ class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
|
||||
@ParameterizedSseTest
|
||||
void sseAsEvent(HttpServer httpServer, ClientHttpConnector connector) throws Exception {
|
||||
assumeTrue(httpServer instanceof JettyHttpServer);
|
||||
assumeTrue(httpServer instanceof JettyHttpServer || httpServer instanceof JettyCoreHttpServer);
|
||||
|
||||
startServer(httpServer, connector);
|
||||
|
||||
@@ -302,18 +303,21 @@ class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
|
||||
static Stream<Arguments> arguments() {
|
||||
return Stream.of(
|
||||
args(new JettyHttpServer(), new ReactorClientHttpConnector()),
|
||||
args(new JettyHttpServer(), new JettyClientHttpConnector()),
|
||||
args(new JettyHttpServer(), new HttpComponentsClientHttpConnector()),
|
||||
args(new ReactorHttpServer(), new ReactorClientHttpConnector()),
|
||||
args(new ReactorHttpServer(), new JettyClientHttpConnector()),
|
||||
args(new ReactorHttpServer(), new HttpComponentsClientHttpConnector()),
|
||||
args(new TomcatHttpServer(), new ReactorClientHttpConnector()),
|
||||
args(new TomcatHttpServer(), new JettyClientHttpConnector()),
|
||||
args(new TomcatHttpServer(), new HttpComponentsClientHttpConnector()),
|
||||
args(new UndertowHttpServer(), new ReactorClientHttpConnector()),
|
||||
args(new UndertowHttpServer(), new JettyClientHttpConnector()),
|
||||
args(new UndertowHttpServer(), new HttpComponentsClientHttpConnector())
|
||||
args(new JettyHttpServer(), new ReactorClientHttpConnector()),
|
||||
args(new JettyHttpServer(), new JettyClientHttpConnector()),
|
||||
args(new JettyHttpServer(), new HttpComponentsClientHttpConnector()),
|
||||
args(new JettyCoreHttpServer(), new ReactorClientHttpConnector()),
|
||||
args(new JettyCoreHttpServer(), new JettyClientHttpConnector()),
|
||||
args(new JettyCoreHttpServer(), new HttpComponentsClientHttpConnector()),
|
||||
args(new ReactorHttpServer(), new ReactorClientHttpConnector()),
|
||||
args(new ReactorHttpServer(), new JettyClientHttpConnector()),
|
||||
args(new ReactorHttpServer(), new HttpComponentsClientHttpConnector()),
|
||||
args(new TomcatHttpServer(), new ReactorClientHttpConnector()),
|
||||
args(new TomcatHttpServer(), new JettyClientHttpConnector()),
|
||||
args(new TomcatHttpServer(), new HttpComponentsClientHttpConnector()),
|
||||
args(new UndertowHttpServer(), new ReactorClientHttpConnector()),
|
||||
args(new UndertowHttpServer(), new JettyClientHttpConnector()),
|
||||
args(new UndertowHttpServer(), new HttpComponentsClientHttpConnector())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.server.reactive.HttpHandler;
|
||||
import org.springframework.web.filter.reactive.ServerWebExchangeContextFilter;
|
||||
import org.springframework.web.reactive.DispatcherHandler;
|
||||
import org.springframework.web.reactive.socket.client.JettyWebSocketClient;
|
||||
import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient;
|
||||
import org.springframework.web.reactive.socket.client.TomcatWebSocketClient;
|
||||
import org.springframework.web.reactive.socket.client.UndertowWebSocketClient;
|
||||
@@ -53,6 +54,7 @@ import org.springframework.web.reactive.socket.server.RequestUpgradeStrategy;
|
||||
import org.springframework.web.reactive.socket.server.WebSocketService;
|
||||
import org.springframework.web.reactive.socket.server.support.HandshakeWebSocketService;
|
||||
import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter;
|
||||
import org.springframework.web.reactive.socket.server.upgrade.JettyCoreRequestUpgradeStrategy;
|
||||
import org.springframework.web.reactive.socket.server.upgrade.JettyRequestUpgradeStrategy;
|
||||
import org.springframework.web.reactive.socket.server.upgrade.ReactorNetty2RequestUpgradeStrategy;
|
||||
import org.springframework.web.reactive.socket.server.upgrade.ReactorNettyRequestUpgradeStrategy;
|
||||
@@ -61,6 +63,7 @@ import org.springframework.web.reactive.socket.server.upgrade.UndertowRequestUpg
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.JettyCoreHttpServer;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.JettyHttpServer;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.ReactorHttpServer;
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.TomcatHttpServer;
|
||||
@@ -90,6 +93,7 @@ abstract class AbstractReactiveWebSocketIntegrationTests {
|
||||
|
||||
WebSocketClient[] clients = new WebSocketClient[] {
|
||||
new TomcatWebSocketClient(),
|
||||
new JettyWebSocketClient(),
|
||||
new ReactorNettyWebSocketClient(),
|
||||
new UndertowWebSocketClient(Xnio.getInstance().createWorker(OptionMap.EMPTY))
|
||||
};
|
||||
@@ -97,6 +101,7 @@ abstract class AbstractReactiveWebSocketIntegrationTests {
|
||||
Map<HttpServer, Class<?>> servers = new LinkedHashMap<>();
|
||||
servers.put(new TomcatHttpServer(TMP_DIR.getAbsolutePath(), WsContextListener.class), TomcatConfig.class);
|
||||
servers.put(new JettyHttpServer(), JettyConfig.class);
|
||||
servers.put(new JettyCoreHttpServer(), JettyCoreConfig.class);
|
||||
servers.put(new ReactorHttpServer(), ReactorNettyConfig.class);
|
||||
servers.put(new UndertowHttpServer(), UndertowConfig.class);
|
||||
|
||||
@@ -241,4 +246,12 @@ abstract class AbstractReactiveWebSocketIntegrationTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class JettyCoreConfig extends AbstractHandlerAdapterConfig {
|
||||
|
||||
@Override
|
||||
protected RequestUpgradeStrategy getUpgradeStrategy() {
|
||||
return new JettyCoreRequestUpgradeStrategy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user