diff --git a/module/spring-boot-grpc-test/src/main/java/org/springframework/boot/grpc/test/autoconfigure/GrpcPortInfoApplicationContextInitializer.java b/module/spring-boot-grpc-test/src/main/java/org/springframework/boot/grpc/test/autoconfigure/GrpcServerPortInfoAutoConfiguration.java
similarity index 66%
rename from module/spring-boot-grpc-test/src/main/java/org/springframework/boot/grpc/test/autoconfigure/GrpcPortInfoApplicationContextInitializer.java
rename to module/spring-boot-grpc-test/src/main/java/org/springframework/boot/grpc/test/autoconfigure/GrpcServerPortInfoAutoConfiguration.java
index 76f1e0a3067..80f0109b182 100644
--- a/module/spring-boot-grpc-test/src/main/java/org/springframework/boot/grpc/test/autoconfigure/GrpcPortInfoApplicationContextInitializer.java
+++ b/module/spring-boot-grpc-test/src/main/java/org/springframework/boot/grpc/test/autoconfigure/GrpcServerPortInfoAutoConfiguration.java
@@ -21,11 +21,14 @@ import java.util.Map;
import io.grpc.Server;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.env.ConfigTreePropertySource.Value;
import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Bean;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
@@ -36,34 +39,41 @@ import org.springframework.grpc.server.InProcessGrpcServerFactory;
import org.springframework.grpc.server.lifecycle.GrpcServerStartedEvent;
/**
- * {@link ApplicationContextInitializer} that sets {@link Environment} properties for the
- * ports that {@link Server gRPC servers} are actually listening on. The property
- * {@literal "local.grpc.server.port"} can be injected directly into tests using
- * {@link Value @Value} or obtained through the {@link Environment}.
+ * {@link EnableAutoConfiguration Auto-configuration} for an {@link ApplicationListener}
+ * that sets {@link Environment} properties for the port that a {@link Server gRPC server}
+ * is actually listening on. The property {@value PROPERTY_NAME} can be injected directly
+ * into tests using {@link Value @Value} or obtained through the {@link Environment}.
*
* Properties are automatically propagated up to any parent context.
*
* @author Dave Syer
* @author Chris Bono
* @author Phillip Webb
+ * @author Stephane Nicoll
+ * @since 4.1.1
*/
-class GrpcPortInfoApplicationContextInitializer
- implements ApplicationContextInitializer {
+@AutoConfiguration(beforeName = "org.springframework.boot.grpc.server.autoconfigure.GrpcServerAutoConfiguration")
+@ConditionalOnClass(GrpcServerStartedEvent.class)
+public final class GrpcServerPortInfoAutoConfiguration {
- @Override
- public void initialize(ConfigurableApplicationContext applicationContext) {
- applicationContext.addApplicationListener(new Listener(applicationContext));
+ /**
+ * Property that contains the port that a {@link Server gRPC server} is actually
+ * listening on.
+ */
+ public static final String PROPERTY_NAME = "local.grpc.server.port";
+
+ @Bean
+ GrpcPortInfoApplicationListener grpcPortInfoApplicationListener(ConfigurableApplicationContext applicationContext) {
+ return new GrpcPortInfoApplicationListener(applicationContext);
}
- private static class Listener implements ApplicationListener {
-
- private static final String PROPERTY_NAME = "local.grpc.server.port";
+ static class GrpcPortInfoApplicationListener implements ApplicationListener {
private static final String PROPERTY_SOURCE_NAME = "server.ports";
private final ConfigurableApplicationContext applicationContext;
- Listener(ConfigurableApplicationContext applicationContext) {
+ GrpcPortInfoApplicationListener(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
diff --git a/module/spring-boot-grpc-test/src/main/resources/META-INF/spring.factories b/module/spring-boot-grpc-test/src/main/resources/META-INF/spring.factories
deleted file mode 100644
index a9432eff747..00000000000
--- a/module/spring-boot-grpc-test/src/main/resources/META-INF/spring.factories
+++ /dev/null
@@ -1,3 +0,0 @@
-# Application Context Initializers
-org.springframework.context.ApplicationContextInitializer=\
-org.springframework.boot.grpc.test.autoconfigure.GrpcPortInfoApplicationContextInitializer
diff --git a/module/spring-boot-grpc-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/module/spring-boot-grpc-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 00000000000..6ff75cfc88f
--- /dev/null
+++ b/module/spring-boot-grpc-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1 @@
+org.springframework.boot.grpc.test.autoconfigure.GrpcServerPortInfoAutoConfiguration
diff --git a/module/spring-boot-grpc-test/src/test/java/org/springframework/boot/grpc/test/autoconfigure/GrpcPortInfoApplicationContextInitializerTests.java b/module/spring-boot-grpc-test/src/test/java/org/springframework/boot/grpc/test/autoconfigure/GrpcServerPortInfoAutoConfigurationTests.java
similarity index 65%
rename from module/spring-boot-grpc-test/src/test/java/org/springframework/boot/grpc/test/autoconfigure/GrpcPortInfoApplicationContextInitializerTests.java
rename to module/spring-boot-grpc-test/src/test/java/org/springframework/boot/grpc/test/autoconfigure/GrpcServerPortInfoAutoConfigurationTests.java
index 7e37a43647c..73815d94837 100644
--- a/module/spring-boot-grpc-test/src/test/java/org/springframework/boot/grpc/test/autoconfigure/GrpcPortInfoApplicationContextInitializerTests.java
+++ b/module/spring-boot-grpc-test/src/test/java/org/springframework/boot/grpc/test/autoconfigure/GrpcServerPortInfoAutoConfigurationTests.java
@@ -20,10 +20,10 @@ import io.grpc.Server;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.grpc.test.autoconfigure.GrpcServerPortInfoAutoConfiguration.GrpcPortInfoApplicationListener;
+import org.springframework.boot.test.context.FilteredClassLoader;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.grpc.server.GrpcServerFactory;
import org.springframework.grpc.server.InProcessGrpcServerFactory;
import org.springframework.grpc.server.NettyGrpcServerFactory;
@@ -35,22 +35,36 @@ import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
- * Tests for {@link GrpcPortInfoApplicationContextInitializer}.
+ * Tests for {@link GrpcServerPortInfoAutoConfiguration}.
*
* @author Phillip Webb
*/
-class GrpcPortInfoApplicationContextInitializerTests {
+class GrpcServerPortInfoAutoConfigurationTests {
+
+ private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(GrpcServerPortInfoAutoConfiguration.class));
private static final String PORT_PROPERTY = "local.grpc.server.port";
@Test
- void whenServerHasAddressInitializerSetsPortProperty() {
+ void createsGrpcPortInfoApplicationListenerBean() {
+ this.contextRunner.run((context) -> assertThat(context).hasSingleBean(GrpcPortInfoApplicationListener.class));
+ }
+
+ @Test
+ void whenNoGrpcServerStartedEventClassDoesNotCreateBean() {
+ this.contextRunner.withClassLoader(new FilteredClassLoader(GrpcServerStartedEvent.class))
+ .run((context) -> assertThat(context).doesNotHaveBean(GrpcPortInfoApplicationListener.class));
+ }
+
+ @Test
+ void whenServerHasAddressListenerSetsPortProperty() {
NettyGrpcServerFactory factory = mock();
testListener(factory, 65535, "65535");
}
@Test
- void whenServerHasNoAddressInitializerSetsNoPortProperty() {
+ void whenServerHasNoAddressListenerSetsNoPortProperty() {
NettyGrpcServerFactory factory = mock();
testListener(factory, -1, null);
}
@@ -68,25 +82,14 @@ class GrpcPortInfoApplicationContextInitializerTests {
}
private void testListener(GrpcServerFactory factory, int port, @Nullable String expected) {
- try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(Config.class)) {
- context.getBean(GrpcPortInfoApplicationContextInitializer.class).initialize(context);
+ this.contextRunner.run((context) -> {
GrpcServerLifecycle lifecycle = mock();
Server server = mock();
given(lifecycle.getFactory()).willReturn(factory);
GrpcServerStartedEvent event = new GrpcServerStartedEvent(lifecycle, server, "localhost", port);
context.publishEvent(event);
assertThat(context.getEnvironment().getProperty(PORT_PROPERTY)).isEqualTo(expected);
- }
- }
-
- @Configuration(proxyBeanMethods = false)
- static class Config {
-
- @Bean
- GrpcPortInfoApplicationContextInitializer grpcPortInfoApplicationContextInitializer() {
- return new GrpcPortInfoApplicationContextInitializer();
- }
-
+ });
}
}
diff --git a/smoke-test/spring-boot-smoke-test-grpc-server-netty-shaded/build.gradle b/smoke-test/spring-boot-smoke-test-grpc-server-netty-shaded/build.gradle
index 76fbfdca0df..3997c3e266a 100644
--- a/smoke-test/spring-boot-smoke-test-grpc-server-netty-shaded/build.gradle
+++ b/smoke-test/spring-boot-smoke-test-grpc-server-netty-shaded/build.gradle
@@ -28,7 +28,7 @@ dependencies {
}
implementation("io.grpc:grpc-netty-shaded")
- dockerTestImplementation(project(":starter:spring-boot-starter-test"))
+ dockerTestImplementation(project(":starter:spring-boot-starter-grpc-server-test"))
dockerTestImplementation("org.testcontainers:testcontainers-junit-jupiter")
}
diff --git a/smoke-test/spring-boot-smoke-test-grpc-server-netty-shaded/src/dockerTest/java/smoketest/grpcservernettyshaded/SampleGrpcServerNettyShadedApplicationTests.java b/smoke-test/spring-boot-smoke-test-grpc-server-netty-shaded/src/dockerTest/java/smoketest/grpcservernettyshaded/SampleGrpcServerNettyShadedApplicationTests.java
index 63af451767b..8aa6a766755 100644
--- a/smoke-test/spring-boot-smoke-test-grpc-server-netty-shaded/src/dockerTest/java/smoketest/grpcservernettyshaded/SampleGrpcServerNettyShadedApplicationTests.java
+++ b/smoke-test/spring-boot-smoke-test-grpc-server-netty-shaded/src/dockerTest/java/smoketest/grpcservernettyshaded/SampleGrpcServerNettyShadedApplicationTests.java
@@ -21,13 +21,9 @@ import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.startupcheck.IndefiniteWaitOneShotStartupCheckStrategy;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
-import smoketest.grpcservernettyshaded.SampleGrpcServerNettyShadedApplicationTests.GrpcServerStartedEventListener;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.context.ApplicationListener;
-import org.springframework.context.annotation.Import;
-import org.springframework.grpc.server.lifecycle.GrpcServerStartedEvent;
import static org.assertj.core.api.Assertions.assertThat;
@@ -38,18 +34,16 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@SpringBootTest(properties = "spring.grpc.server.port=0")
@Testcontainers(disabledWithoutDocker = true)
-@Import(GrpcServerStartedEventListener.class)
class SampleGrpcServerNettyShadedApplicationTests {
- @Autowired
- private GrpcServerStartedEventListener startedEventListener;
+ @Value("${local.grpc.server.port}")
+ private int port;
@Test
@SuppressWarnings("resource")
void test() {
- int port = this.startedEventListener.getPort();
- String address = "host.testcontainers.internal:" + port;
- org.testcontainers.Testcontainers.exposeHostPorts(port);
+ String address = "host.testcontainers.internal:" + this.port;
+ org.testcontainers.Testcontainers.exposeHostPorts(this.port);
try (GenericContainer> container = new GenericContainer<>(
DockerImageName.parse("fullstorydev/grpcurl:v1.9.3"))
.withCommand("-d", "{\"name\": \"spring\"}", "--plaintext", address, "HelloWorld/SayHello")
@@ -60,19 +54,4 @@ class SampleGrpcServerNettyShadedApplicationTests {
}
- static class GrpcServerStartedEventListener implements ApplicationListener {
-
- private int port;
-
- @Override
- public void onApplicationEvent(GrpcServerStartedEvent event) {
- this.port = event.getPort();
- }
-
- int getPort() {
- return this.port;
- }
-
- }
-
}
diff --git a/smoke-test/spring-boot-smoke-test-grpc-server/build.gradle b/smoke-test/spring-boot-smoke-test-grpc-server/build.gradle
index 28ab9ef252b..b14151d0f48 100644
--- a/smoke-test/spring-boot-smoke-test-grpc-server/build.gradle
+++ b/smoke-test/spring-boot-smoke-test-grpc-server/build.gradle
@@ -25,7 +25,7 @@ description = "Spring Boot gRPC server smoke test"
dependencies {
implementation(project(":starter:spring-boot-starter-grpc-server"))
- dockerTestImplementation(project(":starter:spring-boot-starter-test"))
+ dockerTestImplementation(project(":starter:spring-boot-starter-grpc-server-test"))
dockerTestImplementation("org.testcontainers:testcontainers-junit-jupiter")
}
diff --git a/smoke-test/spring-boot-smoke-test-grpc-server/src/dockerTest/java/smoketest/grpcserver/SampleGrpcServerApplicationTests.java b/smoke-test/spring-boot-smoke-test-grpc-server/src/dockerTest/java/smoketest/grpcserver/SampleGrpcServerApplicationTests.java
index ca79ef5cf5d..c36a5fa1aa8 100644
--- a/smoke-test/spring-boot-smoke-test-grpc-server/src/dockerTest/java/smoketest/grpcserver/SampleGrpcServerApplicationTests.java
+++ b/smoke-test/spring-boot-smoke-test-grpc-server/src/dockerTest/java/smoketest/grpcserver/SampleGrpcServerApplicationTests.java
@@ -21,35 +21,30 @@ import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.startupcheck.IndefiniteWaitOneShotStartupCheckStrategy;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
-import smoketest.grpcserver.SampleGrpcServerApplicationTests.GrpcServerStartedEventListener;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.context.ApplicationListener;
-import org.springframework.context.annotation.Import;
-import org.springframework.grpc.server.lifecycle.GrpcServerStartedEvent;
import static org.assertj.core.api.Assertions.assertThat;
/**
- * Integration tests for the default Spring gRPC netty server.
+ * Integration tests for the default Spring gRPC Netty server.
*
* @author Phillip Webb
+ * @author Stephane Nicoll
*/
@SpringBootTest(properties = "spring.grpc.server.port=0")
@Testcontainers(disabledWithoutDocker = true)
-@Import(GrpcServerStartedEventListener.class)
class SampleGrpcServerApplicationTests {
- @Autowired
- private GrpcServerStartedEventListener startedEventListener;
+ @Value("${local.grpc.server.port}")
+ private int port;
@Test
@SuppressWarnings("resource")
void test() {
- int port = this.startedEventListener.getPort();
- String address = "host.testcontainers.internal:" + port;
- org.testcontainers.Testcontainers.exposeHostPorts(port);
+ String address = "host.testcontainers.internal:" + this.port;
+ org.testcontainers.Testcontainers.exposeHostPorts(this.port);
try (GenericContainer> container = new GenericContainer<>(
DockerImageName.parse("fullstorydev/grpcurl:v1.9.3"))
.withNetworkAliases("")
@@ -61,19 +56,4 @@ class SampleGrpcServerApplicationTests {
}
- static class GrpcServerStartedEventListener implements ApplicationListener {
-
- private int port;
-
- @Override
- public void onApplicationEvent(GrpcServerStartedEvent event) {
- this.port = event.getPort();
- }
-
- int getPort() {
- return this.port;
- }
-
- }
-
}