Add default service config to GrpcClientProperties
Ensure that it doesn't conflict with health service configuration. Also ensure random port is used in all tests. Fixes gh-171 (as far as we can)
This commit is contained in:
@@ -15,7 +15,8 @@ import org.springframework.grpc.sample.proto.SimpleGrpc;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = "spring.grpc.client.default-channel.address=0.0.0.0:${local.grpc.port}")
|
||||
properties = { "spring.grpc.client.default-channel.address=0.0.0.0:${local.grpc.port}",
|
||||
"spring.grpc.server.port=0" })
|
||||
@DirtiesContext
|
||||
public class GrpcServerApplicationTests {
|
||||
|
||||
|
||||
@@ -15,18 +15,21 @@
|
||||
*/
|
||||
package org.springframework.grpc.autoconfigure.client;
|
||||
|
||||
import io.grpc.ManagedChannelBuilder;
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.boot.context.properties.PropertyMapper;
|
||||
import org.springframework.grpc.autoconfigure.client.GrpcClientProperties.ChannelConfig;
|
||||
import org.springframework.grpc.client.GrpcChannelBuilderCustomizer;
|
||||
import org.springframework.grpc.client.interceptor.DefaultDeadlineSetupClientInterceptor;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
import io.grpc.ManagedChannelBuilder;
|
||||
|
||||
/**
|
||||
* A {@link GrpcChannelBuilderCustomizer} that maps {@link GrpcClientProperties client
|
||||
* properties} to a channel builder.
|
||||
@@ -58,11 +61,14 @@ class ClientPropertiesChannelBuilderCustomizer<T extends ManagedChannelBuilder<T
|
||||
mapper.from(channel.getKeepAliveTimeout()).to(durationProperty(builder::keepAliveTimeout));
|
||||
mapper.from(channel.getIdleTimeout()).to(durationProperty(builder::idleTimeout));
|
||||
mapper.from(channel.isKeepAliveWithoutCalls()).to(builder::keepAliveWithoutCalls);
|
||||
Map<String, Object> defaultServiceConfig = new HashMap<String, Object>(channel.getServiceConfig());
|
||||
if (channel.getHealth().isEnabled()) {
|
||||
String serviceNameToCheck = channel.getHealth().getServiceName() != null
|
||||
? channel.getHealth().getServiceName() : "";
|
||||
Map<String, ?> healthCheckConfig = Map.of("healthCheckConfig", Map.of("serviceName", serviceNameToCheck));
|
||||
builder.defaultServiceConfig(healthCheckConfig);
|
||||
defaultServiceConfig.put("healthCheckConfig", Map.of("serviceName", serviceNameToCheck));
|
||||
}
|
||||
if (!defaultServiceConfig.isEmpty()) {
|
||||
builder.defaultServiceConfig(defaultServiceConfig);
|
||||
}
|
||||
if (channel.getDefaultDeadline() != null && channel.getDefaultDeadline().toMillis() > 0L) {
|
||||
builder.intercept(new DefaultDeadlineSetupClientInterceptor(channel.getDefaultDeadline()));
|
||||
|
||||
@@ -150,6 +150,16 @@ public class GrpcClientProperties implements EnvironmentAware, VirtualTargets {
|
||||
return this.health;
|
||||
}
|
||||
|
||||
private final Map<String, ?> serviceConfig = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The service config to use for the channel.
|
||||
* @return the service config
|
||||
*/
|
||||
public Map<String, ?> getServiceConfig() {
|
||||
return this.serviceConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* The negotiation type for the channel.
|
||||
*/
|
||||
|
||||
@@ -169,6 +169,17 @@ class GrpcClientPropertiesTests {
|
||||
assertThat(defaultChannel.getMaxInboundMetadataSize()).isEqualTo(DataSize.ofBytes(256));
|
||||
}
|
||||
|
||||
@Test
|
||||
void withServiceConfig() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
// we have to at least bind one property or bind() fails
|
||||
map.put("spring.grpc.client.%s.service-config.something.key".formatted("default-channel"), "value");
|
||||
GrpcClientProperties properties = bindProperties(map);
|
||||
var channel = properties.getDefaultChannel();
|
||||
assertThat(channel.getServiceConfig()).hasSize(1);
|
||||
assertThat(channel.getServiceConfig().get("something")).isInstanceOf(Map.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
@@ -138,6 +138,7 @@ class GrpcServerAutoConfigurationTests {
|
||||
GrpcServiceDiscoverer customGrpcServiceDiscoverer = mock(GrpcServiceDiscoverer.class);
|
||||
this.contextRunnerWithLifecyle()
|
||||
.withBean("customGrpcServiceDiscoverer", GrpcServiceDiscoverer.class, () -> customGrpcServiceDiscoverer)
|
||||
.withPropertyValues("spring.grpc.server.port=0")
|
||||
.run((context) -> assertThat(context).getBean(GrpcServiceDiscoverer.class)
|
||||
.isSameAs(customGrpcServiceDiscoverer));
|
||||
}
|
||||
@@ -145,6 +146,7 @@ class GrpcServerAutoConfigurationTests {
|
||||
@Test
|
||||
void grpcServiceDiscovererAutoConfiguredAsExpected() {
|
||||
this.contextRunnerWithLifecyle()
|
||||
.withPropertyValues("spring.grpc.server.port=0")
|
||||
.run((context) -> assertThat(context).getBean(GrpcServiceDiscoverer.class)
|
||||
.extracting(GrpcServiceDiscoverer::findServices,
|
||||
InstanceOfAssertFactories.list(ServerServiceDefinition.class))
|
||||
@@ -163,6 +165,7 @@ class GrpcServerAutoConfigurationTests {
|
||||
@Test
|
||||
void grpcServiceConfigurerAutoConfiguredAsExpected() {
|
||||
this.contextRunnerWithLifecyle()
|
||||
.withPropertyValues("spring.grpc.server.port=0")
|
||||
.run((context) -> assertThat(context).getBean(GrpcServiceConfigurer.class)
|
||||
.isInstanceOf(DefaultGrpcServiceConfigurer.class));
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ class GrpcServletAutoConfigurationTests {
|
||||
void whenGrpcServletNotOnClasspathAutoConfigurationIsSkipped() {
|
||||
this.contextRunner()
|
||||
.withClassLoader(new FilteredClassLoader(GrpcServlet.class))
|
||||
.withPropertyValues("spring.grpc.server.port=0")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(GrpcServletConfiguration.class)
|
||||
.doesNotHaveBean(ServletRegistrationBean.class));
|
||||
}
|
||||
|
||||
@@ -117,6 +117,7 @@ class GrpcServerHealthAutoConfigurationTests {
|
||||
.withBean("grpcServicesDiscoverer", GrpcServiceDiscoverer.class, Mockito::mock)
|
||||
.withBean("sslBundles", SslBundles.class, Mockito::mock)
|
||||
.withBean(BindableService.class, () -> service)
|
||||
.withPropertyValues("spring.grpc.server.port=0")
|
||||
.run((context) -> assertThatBeanDefinitionsContainInOrder(context, GrpcServerHealthAutoConfiguration.class,
|
||||
GrpcServerFactoryAutoConfiguration.class));
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ class OAuth2ResourceServerAutoConfigurationTests {
|
||||
.withBean(BindableService.class, () -> service)
|
||||
.withBean("noopServerLifecycle", GrpcServerLifecycle.class, Mockito::mock)
|
||||
.withPropertyValues("spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:9000",
|
||||
"spring.grpc.server.servlet.enabled=false")
|
||||
"spring.grpc.server.servlet.enabled=false", "spring.grpc.server.port=0")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(AuthenticationProcessInterceptor.class);
|
||||
});
|
||||
|
||||
@@ -62,7 +62,8 @@ class InProcessTestAutoConfigurationTests {
|
||||
@Test
|
||||
void whenTestInProcessEnabledPropIsSetToTrueDoesAutoConfigureBeans() {
|
||||
this.contextRunner()
|
||||
.withPropertyValues("spring.grpc.test.inprocess.enabled=true", "spring.grpc.server.inprocess.name=foo")
|
||||
.withPropertyValues("spring.grpc.test.inprocess.enabled=true", "spring.grpc.server.inprocess.name=foo",
|
||||
"spring.grpc.server.port=0")
|
||||
.run((context) -> {
|
||||
assertThat(context).getBeans(GrpcServerFactory.class)
|
||||
.containsOnlyKeys("testInProcessGrpcServerFactory", "nettyGrpcServerFactory");
|
||||
@@ -73,18 +74,21 @@ class InProcessTestAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
void whenTestInProcessEnabledPropIsNotSetDoesNotAutoConfigureBeans() {
|
||||
this.contextRunner().withPropertyValues("spring.grpc.server.inprocess.name=foo").run((context) -> {
|
||||
assertThat(context).getBeans(GrpcServerFactory.class)
|
||||
.containsOnlyKeys("inProcessGrpcServerFactory", "nettyGrpcServerFactory");
|
||||
assertThat(context).getBeans(GrpcChannelFactory.class)
|
||||
.containsOnlyKeys("inProcessGrpcChannelFactory", "nettyGrpcChannelFactory");
|
||||
});
|
||||
this.contextRunner()
|
||||
.withPropertyValues("spring.grpc.server.inprocess.name=foo", "spring.grpc.server.port=0")
|
||||
.run((context) -> {
|
||||
assertThat(context).getBeans(GrpcServerFactory.class)
|
||||
.containsOnlyKeys("inProcessGrpcServerFactory", "nettyGrpcServerFactory");
|
||||
assertThat(context).getBeans(GrpcChannelFactory.class)
|
||||
.containsOnlyKeys("inProcessGrpcChannelFactory", "nettyGrpcChannelFactory");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenTestInProcessEnabledPropIsSetToFalseDoesNotAutoConfigureBeans() {
|
||||
this.contextRunner()
|
||||
.withPropertyValues("spring.grpc.test.inprocess.enabled=false", "spring.grpc.server.inprocess.name=foo")
|
||||
.withPropertyValues("spring.grpc.test.inprocess.enabled=false", "spring.grpc.server.inprocess.name=foo",
|
||||
"spring.grpc.server.port=0")
|
||||
.run((context) -> {
|
||||
assertThat(context).getBeans(GrpcServerFactory.class)
|
||||
.containsOnlyKeys("inProcessGrpcServerFactory", "nettyGrpcServerFactory");
|
||||
|
||||
Reference in New Issue
Block a user