From 219bafaba14e48f3752ec5cb69d925b615e4b5ff Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 11 Sep 2019 21:06:11 +0200 Subject: [PATCH] Apply RSocket server customizers to netty web server This commit applies `ServerRSocketFactoryCustomizer` beans to RSocket setups when the RSocket server is being plugged into an existing Reactor Netty web server. Fixes gh-18208 --- .../RSocketServerAutoConfiguration.java | 9 ++++++--- .../RSocketWebSocketNettyRouteProvider.java | 17 +++++++++++++++-- .../RSocketServerAutoConfigurationTests.java | 19 +++++++++++++++++++ ...ocketWebSocketNettyRouteProviderTests.java | 12 ++++++++++++ 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketServerAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketServerAutoConfiguration.java index 34bf6b6581f..1bfdcfde1e4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketServerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketServerAutoConfiguration.java @@ -68,10 +68,13 @@ public class RSocketServerAutoConfiguration { static class WebFluxServerAutoConfiguration { @Bean + @ConditionalOnMissingBean RSocketWebSocketNettyRouteProvider rSocketWebsocketRouteProvider(RSocketProperties properties, - RSocketMessageHandler messageHandler) { - return new RSocketWebSocketNettyRouteProvider(properties.getServer().getMappingPath(), - messageHandler.responder()); + RSocketMessageHandler messageHandler, ObjectProvider customizers) { + RSocketWebSocketNettyRouteProvider routeProvider = new RSocketWebSocketNettyRouteProvider( + properties.getServer().getMappingPath(), messageHandler.responder()); + routeProvider.setCustomizers(customizers.orderedStream().collect(Collectors.toList())); + return routeProvider; } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketWebSocketNettyRouteProvider.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketWebSocketNettyRouteProvider.java index 1eeeb9d2eae..3f7ada8b85c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketWebSocketNettyRouteProvider.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketWebSocketNettyRouteProvider.java @@ -16,12 +16,16 @@ package org.springframework.boot.autoconfigure.rsocket; +import java.util.Collections; +import java.util.List; + import io.rsocket.RSocketFactory; import io.rsocket.SocketAcceptor; import io.rsocket.transport.ServerTransport; import io.rsocket.transport.netty.server.WebsocketRouteTransport; import reactor.netty.http.server.HttpServerRoutes; +import org.springframework.boot.rsocket.server.ServerRSocketFactoryCustomizer; import org.springframework.boot.web.embedded.netty.NettyRouteProvider; /** @@ -35,15 +39,24 @@ class RSocketWebSocketNettyRouteProvider implements NettyRouteProvider { private final SocketAcceptor socketAcceptor; + private List customizers = Collections.emptyList(); + RSocketWebSocketNettyRouteProvider(String mappingPath, SocketAcceptor socketAcceptor) { this.mappingPath = mappingPath; this.socketAcceptor = socketAcceptor; } + void setCustomizers(List customizers) { + this.customizers = customizers; + } + @Override public HttpServerRoutes apply(HttpServerRoutes httpServerRoutes) { - ServerTransport.ConnectionAcceptor acceptor = RSocketFactory.receive().acceptor(this.socketAcceptor) - .toConnectionAcceptor(); + RSocketFactory.ServerRSocketFactory server = RSocketFactory.receive(); + for (ServerRSocketFactoryCustomizer customizer : this.customizers) { + server = customizer.apply(server); + } + ServerTransport.ConnectionAcceptor acceptor = server.acceptor(this.socketAcceptor).toConnectionAcceptor(); return httpServerRoutes.ws(this.mappingPath, WebsocketRouteTransport.newHandler(acceptor)); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketServerAutoConfigurationTests.java index 509e6b5ea02..6f46a4c8bbc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketServerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketServerAutoConfigurationTests.java @@ -86,6 +86,15 @@ class RSocketServerAutoConfigurationTests { .getBeanNames(RSocketServerBootstrap.class).containsExactly("customServerBootstrap")); } + @Test + void shouldUseCustomNettyRouteProvider() { + reactiveWebContextRunner().withUserConfiguration(CustomNettyRouteProviderConfig.class) + .withPropertyValues("spring.rsocket.server.transport=websocket", + "spring.rsocket.server.mapping-path=/rsocket") + .run((context) -> assertThat(context).getBeanNames(RSocketWebSocketNettyRouteProvider.class) + .containsExactly("customNettyRouteProvider")); + } + private ApplicationContextRunner contextRunner() { return new ApplicationContextRunner().withUserConfiguration(BaseConfiguration.class) .withConfiguration(AutoConfigurations.of(RSocketServerAutoConfiguration.class)); @@ -119,4 +128,14 @@ class RSocketServerAutoConfigurationTests { } + @Configuration(proxyBeanMethods = false) + static class CustomNettyRouteProviderConfig { + + @Bean + RSocketWebSocketNettyRouteProvider customNettyRouteProvider() { + return mock(RSocketWebSocketNettyRouteProvider.class); + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketWebSocketNettyRouteProviderTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketWebSocketNettyRouteProviderTests.java index d392e4d82e1..5cbf3a3bd61 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketWebSocketNettyRouteProviderTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketWebSocketNettyRouteProviderTests.java @@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration; +import org.springframework.boot.rsocket.server.ServerRSocketFactoryCustomizer; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; @@ -76,6 +77,7 @@ class RSocketWebSocketNettyRouteProviderTests { WebTestClient client = createWebTestClient(serverContext.getWebServer()); client.get().uri("/protocol").exchange().expectStatus().isOk().expectBody().jsonPath("name", "http"); + assertThat(WebConfiguration.customizerCallCount).isEqualTo(1); }); } @@ -93,6 +95,8 @@ class RSocketWebSocketNettyRouteProviderTests { @Configuration(proxyBeanMethods = false) static class WebConfiguration { + static int customizerCallCount = 0; + @Bean WebController webController() { return new WebController(); @@ -105,6 +109,14 @@ class RSocketWebSocketNettyRouteProviderTests { return serverFactory; } + @Bean + ServerRSocketFactoryCustomizer myRSocketFactoryCustomizer() { + return (server) -> { + customizerCallCount++; + return server; + }; + } + } @Controller