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..cf4fedaeea8 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
@@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.rsocket;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer;
import org.springframework.boot.rsocket.server.RSocketServerBootstrap;
import org.springframework.boot.rsocket.server.RSocketServerFactory;
import org.springframework.boot.rsocket.server.ServerRSocketFactoryCustomizer;
@@ -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/rsocket/context/LocalRSocketServerPort.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/LocalRSocketServerPort.java
new file mode 100644
index 00000000000..7da1f6a32c9
--- /dev/null
+++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/LocalRSocketServerPort.java
@@ -0,0 +1,42 @@
+/*
+ * 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.rsocket.context;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.beans.factory.annotation.Value;
+
+/**
+ * Annotation at the field or method/constructor parameter level that injects the RSocket
+ * port that got allocated at runtime. Provides a convenient alternative for
+ * @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/java/org/springframework/boot/rsocket/context/RSocketPortInfoApplicationContextInitializer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/RSocketPortInfoApplicationContextInitializer.java
new file mode 100644
index 00000000000..09fb5d05f5a
--- /dev/null
+++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/RSocketPortInfoApplicationContextInitializer.java
@@ -0,0 +1,95 @@
+/*
+ * 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.rsocket.context;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Value;
+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