From a63ab468a32b2f2d9d6350fd6abe5fe7daf91401 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Tue, 28 Apr 2020 11:07:04 +0200 Subject: [PATCH] Upgrade to RSocket 1.0.0-RC7 This commit upgrades to RSocket 1.0.0-RC7. This new RC brings API changes we have to adapt to. As of this commit, we're introducing a new `RSocketServerCustomizer` which replaces the now deprecated `ServerRSocketFactoryProcessor`. Closes gh-21046 --- .../RSocketServerAutoConfiguration.java | 25 ++++++----- .../RSocketWebSocketNettyRouteProvider.java | 22 +++++---- .../RSocketSecurityAutoConfiguration.java | 9 ++-- .../RSocketServerAutoConfigurationTests.java | 10 ++--- ...ocketWebSocketNettyRouteProviderTests.java | 2 +- ...RSocketSecurityAutoConfigurationTests.java | 25 +++++------ .../spring-boot-dependencies/pom.xml | 2 +- .../netty/NettyRSocketServerFactory.java | 45 ++++++++++++++++--- .../server/RSocketServerCustomizer.java | 37 +++++++++++++++ .../server/ServerRSocketFactoryProcessor.java | 2 + .../netty/NettyRSocketServerFactoryTests.java | 20 +++++++++ 11 files changed, 150 insertions(+), 49 deletions(-) create mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/RSocketServerCustomizer.java 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 8856f145213..866d7ed1473 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -18,7 +18,7 @@ package org.springframework.boot.autoconfigure.rsocket; import java.util.stream.Collectors; -import io.rsocket.RSocketFactory; +import io.rsocket.core.RSocketServer; import io.rsocket.frame.decoder.PayloadDecoder; import io.rsocket.transport.netty.server.TcpServerTransport; import reactor.netty.http.server.HttpServer; @@ -36,6 +36,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.rsocket.context.RSocketServerBootstrap; import org.springframework.boot.rsocket.netty.NettyRSocketServerFactory; +import org.springframework.boot.rsocket.server.RSocketServerCustomizer; import org.springframework.boot.rsocket.server.RSocketServerFactory; import org.springframework.boot.rsocket.server.ServerRSocketFactoryProcessor; import org.springframework.context.annotation.Bean; @@ -57,7 +58,7 @@ import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHa * @since 2.2.0 */ @Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ RSocketFactory.class, RSocketStrategies.class, HttpServer.class, TcpServerTransport.class }) +@ConditionalOnClass({ RSocketServer.class, RSocketStrategies.class, HttpServer.class, TcpServerTransport.class }) @ConditionalOnBean(RSocketMessageHandler.class) @AutoConfigureAfter(RSocketStrategiesAutoConfiguration.class) @EnableConfigurationProperties(RSocketProperties.class) @@ -69,10 +70,12 @@ public class RSocketServerAutoConfiguration { @Bean @ConditionalOnMissingBean + @SuppressWarnings("deprecation") RSocketWebSocketNettyRouteProvider rSocketWebsocketRouteProvider(RSocketProperties properties, - RSocketMessageHandler messageHandler, ObjectProvider processors) { + RSocketMessageHandler messageHandler, ObjectProvider processors, + ObjectProvider customizers) { return new RSocketWebSocketNettyRouteProvider(properties.getServer().getMappingPath(), - messageHandler.responder(), processors.orderedStream()); + messageHandler.responder(), processors.orderedStream(), customizers.orderedStream()); } } @@ -89,14 +92,17 @@ public class RSocketServerAutoConfiguration { @Bean @ConditionalOnMissingBean + @SuppressWarnings("deprecation") RSocketServerFactory rSocketServerFactory(RSocketProperties properties, ReactorResourceFactory resourceFactory, - ObjectProvider processors) { + ObjectProvider processors, + ObjectProvider customizers) { NettyRSocketServerFactory factory = new NettyRSocketServerFactory(); factory.setResourceFactory(resourceFactory); factory.setTransport(properties.getServer().getTransport()); PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); map.from(properties.getServer().getAddress()).to(factory::setAddress); map.from(properties.getServer().getPort()).to(factory::setPort); + factory.setRSocketServerCustomizers(customizers.orderedStream().collect(Collectors.toList())); factory.setSocketFactoryProcessors(processors.orderedStream().collect(Collectors.toList())); return factory; } @@ -109,13 +115,12 @@ public class RSocketServerAutoConfiguration { } @Bean - ServerRSocketFactoryProcessor frameDecoderServerFactoryCustomizer(RSocketMessageHandler rSocketMessageHandler) { - return (serverRSocketFactory) -> { + RSocketServerCustomizer frameDecoderRSocketServerCustomizer(RSocketMessageHandler rSocketMessageHandler) { + return (server) -> { if (rSocketMessageHandler.getRSocketStrategies() .dataBufferFactory() instanceof NettyDataBufferFactory) { - return serverRSocketFactory.frameDecoder(PayloadDecoder.ZERO_COPY); + server.payloadDecoder(PayloadDecoder.ZERO_COPY); } - return serverRSocketFactory; }; } 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 a15a82cc099..5cab0498404 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -22,10 +22,12 @@ import java.util.stream.Stream; import io.rsocket.RSocketFactory; import io.rsocket.SocketAcceptor; +import io.rsocket.core.RSocketServer; import io.rsocket.transport.ServerTransport; import io.rsocket.transport.netty.server.WebsocketRouteTransport; import reactor.netty.http.server.HttpServerRoutes; +import org.springframework.boot.rsocket.server.RSocketServerCustomizer; import org.springframework.boot.rsocket.server.ServerRSocketFactoryProcessor; import org.springframework.boot.web.embedded.netty.NettyRouteProvider; @@ -34,6 +36,7 @@ import org.springframework.boot.web.embedded.netty.NettyRouteProvider; * * @author Brian Clozel */ +@SuppressWarnings("deprecation") class RSocketWebSocketNettyRouteProvider implements NettyRouteProvider { private final String mappingPath; @@ -42,21 +45,24 @@ class RSocketWebSocketNettyRouteProvider implements NettyRouteProvider { private final List processors; + private final List customizers; + RSocketWebSocketNettyRouteProvider(String mappingPath, SocketAcceptor socketAcceptor, - Stream processors) { + Stream processors, Stream customizers) { this.mappingPath = mappingPath; this.socketAcceptor = socketAcceptor; this.processors = processors.collect(Collectors.toList()); + this.customizers = customizers.collect(Collectors.toList()); } @Override public HttpServerRoutes apply(HttpServerRoutes httpServerRoutes) { - RSocketFactory.ServerRSocketFactory server = RSocketFactory.receive(); - for (ServerRSocketFactoryProcessor processor : this.processors) { - server = processor.process(server); - } - ServerTransport.ConnectionAcceptor acceptor = server.acceptor(this.socketAcceptor).toConnectionAcceptor(); - return httpServerRoutes.ws(this.mappingPath, WebsocketRouteTransport.newHandler(acceptor)); + RSocketServer server = RSocketServer.create(this.socketAcceptor); + RSocketFactory.ServerRSocketFactory factory = new RSocketFactory.ServerRSocketFactory(server); + this.processors.forEach((processor) -> processor.process(factory)); + this.customizers.forEach((customizer) -> customizer.customize(server)); + ServerTransport.ConnectionAcceptor connectionAcceptor = server.asConnectionAcceptor(); + return httpServerRoutes.ws(this.mappingPath, WebsocketRouteTransport.newHandler(connectionAcceptor)); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java index f95790be6bf..69235ed362c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -18,7 +18,7 @@ package org.springframework.boot.autoconfigure.security.rsocket; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.rsocket.server.ServerRSocketFactoryProcessor; +import org.springframework.boot.rsocket.server.RSocketServerCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.rsocket.EnableRSocketSecurity; @@ -29,6 +29,7 @@ import org.springframework.security.rsocket.core.SecuritySocketAcceptorIntercept * server. * * @author Madhura Bhave + * @author Brian Clozel * @since 2.2.0 */ @Configuration(proxyBeanMethods = false) @@ -37,8 +38,8 @@ import org.springframework.security.rsocket.core.SecuritySocketAcceptorIntercept public class RSocketSecurityAutoConfiguration { @Bean - ServerRSocketFactoryProcessor springSecurityRSocketSecurity(SecuritySocketAcceptorInterceptor interceptor) { - return (factory) -> factory.addSocketAcceptorPlugin(interceptor); + RSocketServerCustomizer springSecurityRSocketSecurity(SecuritySocketAcceptorInterceptor interceptor) { + return (server) -> server.interceptors((registry) -> registry.forSocketAcceptor(interceptor)); } } 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 f03c09c9fa9..2134011e8a1 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -21,8 +21,8 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer; import org.springframework.boot.rsocket.context.RSocketServerBootstrap; +import org.springframework.boot.rsocket.server.RSocketServerCustomizer; import org.springframework.boot.rsocket.server.RSocketServerFactory; -import org.springframework.boot.rsocket.server.ServerRSocketFactoryProcessor; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.web.server.WebServerFactoryCustomizer; @@ -78,8 +78,7 @@ class RSocketServerAutoConfigurationTests { void shouldCreateDefaultBeansForRSocketServerWhenPortIsSet() { reactiveWebContextRunner().withPropertyValues("spring.rsocket.server.port=0") .run((context) -> assertThat(context).hasSingleBean(RSocketServerFactory.class) - .hasSingleBean(RSocketServerBootstrap.class) - .hasSingleBean(ServerRSocketFactoryProcessor.class)); + .hasSingleBean(RSocketServerBootstrap.class).hasSingleBean(RSocketServerCustomizer.class)); } @Test @@ -87,8 +86,7 @@ class RSocketServerAutoConfigurationTests { reactiveWebContextRunner().withPropertyValues("spring.rsocket.server.port=0") .withInitializer(new RSocketPortInfoApplicationContextInitializer()).run((context) -> { assertThat(context).hasSingleBean(RSocketServerFactory.class) - .hasSingleBean(RSocketServerBootstrap.class) - .hasSingleBean(ServerRSocketFactoryProcessor.class); + .hasSingleBean(RSocketServerBootstrap.class).hasSingleBean(RSocketServerCustomizer.class); assertThat(context.getEnvironment().getProperty("local.rsocket.server.port")).isNotNull(); }); } 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 b6ea6c9bb6b..7d85b90c362 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java index 584782e04e6..64f7a20dfd5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -16,28 +16,26 @@ package org.springframework.boot.autoconfigure.security.rsocket; -import io.rsocket.RSocketFactory; +import io.rsocket.core.RSocketServer; import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration; import org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration; import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; -import org.springframework.boot.rsocket.server.ServerRSocketFactoryProcessor; +import org.springframework.boot.rsocket.server.RSocketServerCustomizer; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.security.config.annotation.rsocket.RSocketSecurity; import org.springframework.security.rsocket.core.SecuritySocketAcceptorInterceptor; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; /** * Tests for {@link RSocketSecurityAutoConfiguration}. * * @author Madhura Bhave + * @author Brian Clozel */ class RSocketSecurityAutoConfigurationTests { @@ -58,14 +56,15 @@ class RSocketSecurityAutoConfigurationTests { @Test void autoConfigurationAddsCustomizerForServerRSocketFactory() { - RSocketFactory.ServerRSocketFactory factory = mock(RSocketFactory.ServerRSocketFactory.class); - ArgumentCaptor captor = ArgumentCaptor - .forClass(SecuritySocketAcceptorInterceptor.class); + RSocketServer server = RSocketServer.create(); this.contextRunner.run((context) -> { - ServerRSocketFactoryProcessor customizer = context.getBean(ServerRSocketFactoryProcessor.class); - customizer.process(factory); - verify(factory).addSocketAcceptorPlugin(captor.capture()); - assertThat(captor.getValue()).isInstanceOf(SecuritySocketAcceptorInterceptor.class); + RSocketServerCustomizer customizer = context.getBean(RSocketServerCustomizer.class); + customizer.customize(server); + server.interceptors((registry) -> registry.forSocketAcceptor((interceptors) -> { + assertThat(interceptors).isNotEmpty(); + assertThat(interceptors) + .anyMatch((interceptor) -> interceptor instanceof SecuritySocketAcceptorInterceptor); + })); }); } diff --git a/spring-boot-project/spring-boot-dependencies/pom.xml b/spring-boot-project/spring-boot-dependencies/pom.xml index cb472c5dba6..8511e0c1b62 100644 --- a/spring-boot-project/spring-boot-dependencies/pom.xml +++ b/spring-boot-project/spring-boot-dependencies/pom.xml @@ -175,7 +175,7 @@ Dysprosium-SR7 3.3.0 1.0.3 - 1.0.0-RC6 + 1.0.0-RC7 1.3.8 1.2.1 2.2.19 diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java index 9a2bbae9c8d..c3580c1d37c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -37,6 +37,7 @@ import reactor.netty.tcp.TcpServer; import org.springframework.boot.rsocket.server.ConfigurableRSocketServerFactory; import org.springframework.boot.rsocket.server.RSocketServer; +import org.springframework.boot.rsocket.server.RSocketServerCustomizer; import org.springframework.boot.rsocket.server.RSocketServerFactory; import org.springframework.boot.rsocket.server.ServerRSocketFactoryProcessor; import org.springframework.http.client.reactive.ReactorResourceFactory; @@ -63,6 +64,8 @@ public class NettyRSocketServerFactory implements RSocketServerFactory, Configur private List socketFactoryProcessors = new ArrayList<>(); + private List rSocketServerCustomizers = new ArrayList<>(); + @Override public void setPort(int port) { this.port = port; @@ -91,7 +94,10 @@ public class NettyRSocketServerFactory implements RSocketServerFactory, Configur * {@link ServerRSocketFactory} while building the server. Calling this method will * replace any existing processors. * @param socketFactoryProcessors processors to apply before the server starts + * @deprecated in favor of {@link #setRSocketServerCustomizers(Collection)} as of + * 2.2.7 */ + @Deprecated public void setSocketFactoryProcessors( Collection socketFactoryProcessors) { Assert.notNull(socketFactoryProcessors, "SocketFactoryProcessors must not be null"); @@ -102,12 +108,38 @@ public class NettyRSocketServerFactory implements RSocketServerFactory, Configur * Add {@link ServerRSocketFactoryProcessor}s that should be called to process the * {@link ServerRSocketFactory} while building the server. * @param socketFactoryProcessors processors to apply before the server starts + * @deprecated in favor of + * {@link #addRSocketServerCustomizers(RSocketServerCustomizer...)} as of 2.2.7 */ + @Deprecated public void addSocketFactoryProcessors(ServerRSocketFactoryProcessor... socketFactoryProcessors) { Assert.notNull(socketFactoryProcessors, "SocketFactoryProcessors must not be null"); this.socketFactoryProcessors.addAll(Arrays.asList(socketFactoryProcessors)); } + /** + * Set {@link RSocketServerCustomizer}s that should be called to configure the + * {@link io.rsocket.core.RSocketServer} while building the server. Calling this + * method will replace any existing customizers. + * @param rSocketServerCustomizers customizers to apply before the server starts + * @since 2.2.7 + */ + public void setRSocketServerCustomizers(Collection rSocketServerCustomizers) { + Assert.notNull(rSocketServerCustomizers, "RSocketServerCustomizers must not be null"); + this.rSocketServerCustomizers = new ArrayList<>(rSocketServerCustomizers); + } + + /** + * Add {@link RSocketServerCustomizer}s that should be called to configure the + * {@link io.rsocket.core.RSocketServer}. + * @param rSocketServerCustomizers customizers to apply before the server starts + * @since 2.2.7 + */ + public void addRSocketServerCustomizers(RSocketServerCustomizer... rSocketServerCustomizers) { + Assert.notNull(rSocketServerCustomizers, "RSocketServerCustomizers must not be null"); + this.rSocketServerCustomizers.addAll(Arrays.asList(rSocketServerCustomizers)); + } + /** * Set the maximum amount of time that should be waited when starting or stopping the * server. @@ -118,13 +150,14 @@ public class NettyRSocketServerFactory implements RSocketServerFactory, Configur } @Override + @SuppressWarnings("deprecation") public NettyRSocketServer create(SocketAcceptor socketAcceptor) { ServerTransport transport = createTransport(); - RSocketFactory.ServerRSocketFactory factory = RSocketFactory.receive(); - for (ServerRSocketFactoryProcessor processor : this.socketFactoryProcessors) { - factory = processor.process(factory); - } - Mono starter = factory.acceptor(socketAcceptor).transport(transport).start(); + io.rsocket.core.RSocketServer server = io.rsocket.core.RSocketServer.create(socketAcceptor); + RSocketFactory.ServerRSocketFactory factory = new ServerRSocketFactory(server); + this.rSocketServerCustomizers.forEach((customizer) -> customizer.customize(server)); + this.socketFactoryProcessors.forEach((processor) -> processor.process(factory)); + Mono starter = server.bind(transport); return new NettyRSocketServer(starter, this.lifecycleTimeout); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/RSocketServerCustomizer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/RSocketServerCustomizer.java new file mode 100644 index 00000000000..200c579332b --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/RSocketServerCustomizer.java @@ -0,0 +1,37 @@ +/* + * Copyright 2012-2020 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 + * + * https://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.springframework.boot.rsocket.server; + +import io.rsocket.core.RSocketServer; + +/** + * Callback interface that can be used to customize a {@link RSocketServer}. + * + * @author Brian Clozel + * @see RSocketServer + * @since 2.3.0 + */ +@FunctionalInterface +public interface RSocketServerCustomizer { + + /** + * Callback to customize a {@link RSocketServer} instance. + * @param rSocketServer the RSocket server to customize + */ + void customize(RSocketServer rSocketServer); + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/ServerRSocketFactoryProcessor.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/ServerRSocketFactoryProcessor.java index 46242cc771a..9b67aa0d060 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/ServerRSocketFactoryProcessor.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/ServerRSocketFactoryProcessor.java @@ -25,8 +25,10 @@ import io.rsocket.RSocketFactory.ServerRSocketFactory; * @author Brian Clozel * @see RSocketServerFactory * @since 2.2.0 + * @deprecated in favor of {@link RSocketServerCustomizer} as of 2.2.7 */ @FunctionalInterface +@Deprecated public interface ServerRSocketFactoryProcessor { /** diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java index a8055999f46..f23b8a5ef98 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java @@ -36,6 +36,7 @@ import org.mockito.InOrder; import reactor.core.publisher.Mono; import org.springframework.boot.rsocket.server.RSocketServer; +import org.springframework.boot.rsocket.server.RSocketServerCustomizer; import org.springframework.boot.rsocket.server.ServerRSocketFactoryProcessor; import org.springframework.core.codec.CharSequenceEncoder; import org.springframework.core.codec.StringDecoder; @@ -48,6 +49,7 @@ import org.springframework.util.SocketUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.will; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; @@ -129,6 +131,7 @@ class NettyRSocketServerFactoryTests { } @Test + @SuppressWarnings("deprecation") void serverProcessors() { NettyRSocketServerFactory factory = getFactory(); ServerRSocketFactoryProcessor[] processors = new ServerRSocketFactoryProcessor[2]; @@ -145,6 +148,23 @@ class NettyRSocketServerFactoryTests { } } + @Test + void serverCustomizers() { + NettyRSocketServerFactory factory = getFactory(); + RSocketServerCustomizer[] customizers = new RSocketServerCustomizer[2]; + for (int i = 0; i < customizers.length; i++) { + customizers[i] = mock(RSocketServerCustomizer.class); + will((invocation) -> invocation.getArgument(0)).given(customizers[i]) + .customize(any(io.rsocket.core.RSocketServer.class)); + } + factory.setRSocketServerCustomizers(Arrays.asList(customizers)); + this.server = factory.create(new EchoRequestResponseAcceptor()); + InOrder ordered = inOrder((Object[]) customizers); + for (RSocketServerCustomizer customizer : customizers) { + ordered.verify(customizer).customize(any(io.rsocket.core.RSocketServer.class)); + } + } + private RSocketRequester createRSocketTcpClient() { Assertions.assertThat(this.server).isNotNull(); InetSocketAddress address = this.server.address();