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 6f46a4c8bbc..ac70ddf9357 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 @@ -24,6 +24,7 @@ import org.springframework.boot.rsocket.server.RSocketServerFactory; import org.springframework.boot.rsocket.server.ServerRSocketFactoryCustomizer; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.web.context.RSocketPortInfoApplicationContextInitializer; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -39,6 +40,7 @@ import static org.mockito.Mockito.mock; * Tests for {@link RSocketServerAutoConfiguration}. * * @author Brian Clozel + * @author Verónica Vásquez */ class RSocketServerAutoConfigurationTests { @@ -80,6 +82,17 @@ class RSocketServerAutoConfigurationTests { .hasSingleBean(ServerRSocketFactoryCustomizer.class)); } + @Test + void shouldSetLocalServerPortWhenRSocketServerPortIsSet() { + reactiveWebContextRunner().withPropertyValues("spring.rsocket.server.port=0") + .withInitializer(new RSocketPortInfoApplicationContextInitializer()).run((context) -> { + assertThat(context).hasSingleBean(RSocketServerFactory.class) + .hasSingleBean(RSocketServerBootstrap.class) + .hasSingleBean(ServerRSocketFactoryCustomizer.class); + assertThat(context.getEnvironment().getProperty("local.rsocket.server.port")).isNotNull(); + }); + } + @Test void shouldUseCustomServerBootstrap() { contextRunner().withUserConfiguration(CustomServerBootstrapConfig.class).run((context) -> assertThat(context) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/RSocketPortInfoApplicationContextInitializer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/RSocketPortInfoApplicationContextInitializer.java new file mode 100644 index 00000000000..f68271df051 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/RSocketPortInfoApplicationContextInitializer.java @@ -0,0 +1,85 @@ +/* + * Copyright 2012-2019 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.web.context; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.rsocket.context.RSocketServerInitializedEvent; +import org.springframework.boot.rsocket.server.RSocketServer; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ApplicationListener; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.Environment; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertySource; + +/** + * {@link ApplicationContextInitializer} that sets {@link Environment} properties for the + * ports that {@link RSocketServer} servers are actually listening on. The property + * {@literal "local.rsocket.server.port"} can be injected directly into tests using + * {@link Value @Value} or obtained via the {@link Environment}. + *
+ * Properties are automatically propagated up to any parent context.
+ *
+ * @author Verónica Vásquez
+ * @author Eddú Meléndez
+ * @since 2.2.0
+ */
+public class RSocketPortInfoApplicationContextInitializer
+ implements ApplicationContextInitializer@Value("${local.rsocket.server.port}").
+ *
+ * @author Verónica Vásquez
+ * @author Eddú Meléndez
+ * @since 2.2.0
+ */
+@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Value("${local.rsocket.server.port}")
+public @interface LocalRSocketServerPort {
+
+}
diff --git a/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories
index cbaf16b4ab1..2641b68becb 100644
--- a/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories
+++ b/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories
@@ -16,7 +16,8 @@ org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
-org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
+org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer,\
+org.springframework.boot.web.context.RSocketPortInfoApplicationContextInitializer
# Application Listeners
org.springframework.context.ApplicationListener=\
diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java
index 87f8f2bc8b9..8f374ad1531 100644
--- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java
+++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java
@@ -240,7 +240,7 @@ class SpringApplicationBuilderTests {
SpringApplicationBuilder application = new SpringApplicationBuilder(ExampleConfig.class)
.web(WebApplicationType.NONE);
this.context = application.run();
- assertThat(application.application().getInitializers()).hasSize(4);
+ assertThat(application.application().getInitializers()).hasSize(5);
}
@Test
@@ -248,7 +248,7 @@ class SpringApplicationBuilderTests {
SpringApplicationBuilder application = new SpringApplicationBuilder(ExampleConfig.class)
.child(ChildConfig.class).web(WebApplicationType.NONE);
this.context = application.run();
- assertThat(application.application().getInitializers()).hasSize(5);
+ assertThat(application.application().getInitializers()).hasSize(6);
}
@Test
@@ -257,7 +257,7 @@ class SpringApplicationBuilderTests {
.web(WebApplicationType.NONE).initializers((ConfigurableApplicationContext applicationContext) -> {
});
this.context = application.run();
- assertThat(application.application().getInitializers()).hasSize(5);
+ assertThat(application.application().getInitializers()).hasSize(6);
}
@Test
diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/LocalRSocketServerPortTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/LocalRSocketServerPortTests.java
new file mode 100644
index 00000000000..bde44bd33cf
--- /dev/null
+++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/LocalRSocketServerPortTests.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2012-2019 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.web.server;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link LocalRSocketServerPort @LocalRSocketServerPort}.
+ *
+ * @author Verónica Vásquez
+ * @author Eddú Meléndez
+ */
+@ExtendWith(SpringExtension.class)
+@TestPropertySource(properties = "local.rsocket.server.port=8181")
+class LocalRSocketServerPortTests {
+
+ @Value("${local.rsocket.server.port}")
+ private String fromValue;
+
+ @LocalRSocketServerPort
+ private String fromAnnotation;
+
+ @Test
+ void testLocalRSocketServerPortAnnotation() {
+ assertThat(this.fromAnnotation).isNotNull().isEqualTo(this.fromValue);
+ }
+
+ @Configuration(proxyBeanMethods = false)
+ static class Config {
+
+ }
+
+}