From bfa54f94230b02b131456413b201826e094a9b02 Mon Sep 17 00:00:00 2001 From: Chris Bono Date: Sun, 1 Dec 2024 11:09:03 -0600 Subject: [PATCH] Move client properties customizer to upper level This commit moves the client properties customizer from an inner class to its own top-level class to make it easier to test and for readability. Signed-off-by: Chris Bono --- ...entPropertiesChannelBuilderCustomizer.java | 73 +++++++++++++++++++ .../client/GrpcClientAutoConfiguration.java | 41 +---------- .../GrpcClientAutoConfigurationTests.java | 12 +-- 3 files changed, 81 insertions(+), 45 deletions(-) create mode 100644 spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/client/ClientPropertiesChannelBuilderCustomizer.java diff --git a/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/client/ClientPropertiesChannelBuilderCustomizer.java b/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/client/ClientPropertiesChannelBuilderCustomizer.java new file mode 100644 index 0000000..31b0162 --- /dev/null +++ b/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/client/ClientPropertiesChannelBuilderCustomizer.java @@ -0,0 +1,73 @@ +/* + * Copyright 2023-2024 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.grpc.autoconfigure.client; + +import java.time.Duration; +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.NamedChannel; +import org.springframework.grpc.client.GrpcChannelBuilderCustomizer; +import org.springframework.util.unit.DataSize; + +import io.grpc.ManagedChannelBuilder; + +/** + * A {@link GrpcChannelBuilderCustomizer} that maps {@link GrpcClientProperties client + * properties} to a channel builder. + * + * @author David Syer + * @author Chris Bono + */ +class ClientPropertiesChannelBuilderCustomizer implements GrpcChannelBuilderCustomizer { + + private final GrpcClientProperties properties; + + ClientPropertiesChannelBuilderCustomizer(GrpcClientProperties properties) { + this.properties = properties; + } + + @Override + public void customize(String authority, ManagedChannelBuilder builder) { + NamedChannel channel = this.properties.getChannels().get(authority); + if (channel == null) { + return; + } + PropertyMapper mapper = PropertyMapper.get().alwaysApplyingWhenNonNull(); + mapper.from(channel.getUserAgent()).to(builder::userAgent); + mapper.from(channel.getDefaultLoadBalancingPolicy()).to(builder::defaultLoadBalancingPolicy); + mapper.from(channel.getMaxInboundMessageSize()).asInt(DataSize::toBytes).to(builder::maxInboundMessageSize); + mapper.from(channel.getMaxInboundMetadataSize()).asInt(DataSize::toBytes).to(builder::maxInboundMessageSize); + mapper.from(channel.getKeepAliveTime()).to(durationProperty(builder::keepAliveTime)); + mapper.from(channel.getKeepAliveTimeout()).to(durationProperty(builder::keepAliveTimeout)); + mapper.from(channel.getIdleTimeout()).to(durationProperty(builder::idleTimeout)); + mapper.from(channel.isKeepAliveWithoutCalls()).to(builder::keepAliveWithoutCalls); + if (channel.getHealth().isEnabled()) { + String serviceNameToCheck = channel.getHealth().getServiceName() != null + ? channel.getHealth().getServiceName() : ""; + Map healthCheckConfig = Map.of("healthCheckConfig", Map.of("serviceName", serviceNameToCheck)); + builder.defaultServiceConfig(healthCheckConfig); + } + } + + Consumer durationProperty(BiConsumer setter) { + return (duration) -> setter.accept(duration.toNanos(), TimeUnit.NANOSECONDS); + } + +} diff --git a/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/client/GrpcClientAutoConfiguration.java b/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/client/GrpcClientAutoConfiguration.java index 99daae7..4cf9826 100644 --- a/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/client/GrpcClientAutoConfiguration.java +++ b/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/client/GrpcClientAutoConfiguration.java @@ -16,8 +16,6 @@ package org.springframework.grpc.autoconfigure.client; import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -60,43 +58,8 @@ public class GrpcClientAutoConfiguration { } @Bean - public GrpcChannelBuilderCustomizer baseGrpcChannelBuilderCustomizer(GrpcClientProperties channels) { - return (authority, builder) -> { - for (String name : channels.getChannels().keySet()) { - if (authority.equals(name)) { - NamedChannel channel = channels.getChannels().get(name); - if (channel.getUserAgent() != null) { - builder.userAgent(channel.getUserAgent()); - } - if (channel.getDefaultLoadBalancingPolicy() != null) { - builder.defaultLoadBalancingPolicy(channel.getDefaultLoadBalancingPolicy()); - } - if (channel.getHealth().isEnabled()) { - String serviceNameToCheck = channel.getHealth().getServiceName() != null - ? channel.getHealth().getServiceName() : ""; - Map healthCheckConfig = Map.of("healthCheckConfig", - Map.of("serviceName", serviceNameToCheck)); - builder.defaultServiceConfig(healthCheckConfig); - } - if (channel.getMaxInboundMessageSize() != null) { - builder.maxInboundMessageSize((int) channel.getMaxInboundMessageSize().toBytes()); - } - if (channel.getMaxInboundMetadataSize() != null) { - builder.maxInboundMetadataSize((int) channel.getMaxInboundMetadataSize().toBytes()); - } - if (channel.getKeepAliveTime() != null) { - builder.keepAliveTime(channel.getKeepAliveTime().toNanos(), TimeUnit.NANOSECONDS); - } - if (channel.getKeepAliveTimeout() != null) { - builder.keepAliveTimeout(channel.getKeepAliveTimeout().toNanos(), TimeUnit.NANOSECONDS); - } - builder.keepAliveWithoutCalls(channel.isKeepAliveWithoutCalls()); - if (channel.getIdleTimeout() != null) { - builder.idleTimeout(channel.getIdleTimeout().toNanos(), TimeUnit.NANOSECONDS); - } - } - } - }; + public GrpcChannelBuilderCustomizer clientPropertiesChannelCustomizer(GrpcClientProperties properties) { + return new ClientPropertiesChannelBuilderCustomizer(properties); } @ConditionalOnBean(CompressorRegistry.class) diff --git a/spring-grpc-spring-boot-autoconfigure/src/test/java/org/springframework/grpc/autoconfigure/client/GrpcClientAutoConfigurationTests.java b/spring-grpc-spring-boot-autoconfigure/src/test/java/org/springframework/grpc/autoconfigure/client/GrpcClientAutoConfigurationTests.java index 9284cdd..6521d37 100644 --- a/spring-grpc-spring-boot-autoconfigure/src/test/java/org/springframework/grpc/autoconfigure/client/GrpcClientAutoConfigurationTests.java +++ b/spring-grpc-spring-boot-autoconfigure/src/test/java/org/springframework/grpc/autoconfigure/client/GrpcClientAutoConfigurationTests.java @@ -91,14 +91,14 @@ class GrpcClientAutoConfigurationTests { } @Test - void baseChannelCustomizerAutoConfiguredWithHealthAsExpected() { + void clientPropertiesChannelCustomizerAutoConfiguredWithHealthAsExpected() { this.contextRunner() .withPropertyValues("spring.grpc.client.channels.test.health.enabled=true", "spring.grpc.client.channels.test.health.service-name=my-service") .run((context) -> { - assertThat(context).getBean("baseGrpcChannelBuilderCustomizer", GrpcChannelBuilderCustomizer.class) + assertThat(context).getBean("clientPropertiesChannelCustomizer", GrpcChannelBuilderCustomizer.class) .isNotNull(); - var customizer = context.getBean("baseGrpcChannelBuilderCustomizer", + var customizer = context.getBean("clientPropertiesChannelCustomizer", GrpcChannelBuilderCustomizer.class); ManagedChannelBuilder builder = Mockito.mock(); customizer.customize("test", builder); @@ -108,11 +108,11 @@ class GrpcClientAutoConfigurationTests { } @Test - void baseChannelCustomizerAutoConfiguredWithoutHealthAsExpected() { + void clientPropertiesChannelCustomizerAutoConfiguredWithoutHealthAsExpected() { this.contextRunner().run((context) -> { - assertThat(context).getBean("baseGrpcChannelBuilderCustomizer", GrpcChannelBuilderCustomizer.class) + assertThat(context).getBean("clientPropertiesChannelCustomizer", GrpcChannelBuilderCustomizer.class) .isNotNull(); - var customizer = context.getBean("baseGrpcChannelBuilderCustomizer", GrpcChannelBuilderCustomizer.class); + var customizer = context.getBean("clientPropertiesChannelCustomizer", GrpcChannelBuilderCustomizer.class); ManagedChannelBuilder builder = Mockito.mock(); customizer.customize("test", builder); verify(builder, never()).defaultServiceConfig(anyMap());