From 97ba123fbf80771bb942018ad35a6be144670497 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 3 Apr 2025 09:01:46 +0100 Subject: [PATCH] Add composite pattern to GrpcChannelBuilderCustomizer --- .../grpc/client/ChannelBuilderOptions.java | 3 ++- .../grpc/client/GrpcChannelBuilderCustomizer.java | 7 +++++++ .../grpc/client/ChannelBuilderOptionsTests.java | 15 ++++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/spring-grpc-core/src/main/java/org/springframework/grpc/client/ChannelBuilderOptions.java b/spring-grpc-core/src/main/java/org/springframework/grpc/client/ChannelBuilderOptions.java index a17e5e0..575cec6 100644 --- a/spring-grpc-core/src/main/java/org/springframework/grpc/client/ChannelBuilderOptions.java +++ b/spring-grpc-core/src/main/java/org/springframework/grpc/client/ChannelBuilderOptions.java @@ -142,10 +142,11 @@ public final class ChannelBuilderOptions { * @return a new immutable options instance populated with the specified * {@code customizer} and the settings of this current options instance. */ + @SuppressWarnings("unchecked") public > ChannelBuilderOptions withCustomizer( GrpcChannelBuilderCustomizer customizer) { return new ChannelBuilderOptions(this.interceptors, this.mergeWithGlobalInterceptors, this.shutdownGracePeriod, - customizer); + this.customizer.then(customizer)); } } diff --git a/spring-grpc-core/src/main/java/org/springframework/grpc/client/GrpcChannelBuilderCustomizer.java b/spring-grpc-core/src/main/java/org/springframework/grpc/client/GrpcChannelBuilderCustomizer.java index e3046e2..c23901d 100644 --- a/spring-grpc-core/src/main/java/org/springframework/grpc/client/GrpcChannelBuilderCustomizer.java +++ b/spring-grpc-core/src/main/java/org/springframework/grpc/client/GrpcChannelBuilderCustomizer.java @@ -37,6 +37,13 @@ public interface GrpcChannelBuilderCustomizer */ void customize(String authority, T builder); + default GrpcChannelBuilderCustomizer then(GrpcChannelBuilderCustomizer other) { + return (authority, builder) -> { + customize(authority, builder); + other.customize(authority, builder); + }; + } + /** * Used to indicate no customizations should be made to the builder. * @param type of channel builder diff --git a/spring-grpc-core/src/test/java/org/springframework/grpc/client/ChannelBuilderOptionsTests.java b/spring-grpc-core/src/test/java/org/springframework/grpc/client/ChannelBuilderOptionsTests.java index fb8c379..7ede26c 100644 --- a/spring-grpc-core/src/test/java/org/springframework/grpc/client/ChannelBuilderOptionsTests.java +++ b/spring-grpc-core/src/test/java/org/springframework/grpc/client/ChannelBuilderOptionsTests.java @@ -17,6 +17,7 @@ package org.springframework.grpc.client; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import java.time.Duration; @@ -26,6 +27,7 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import io.grpc.ClientInterceptor; +import io.grpc.ManagedChannelBuilder; import io.grpc.netty.NettyChannelBuilder; /** @@ -56,7 +58,18 @@ class ChannelBuilderOptionsTests { assertThat(options.interceptors()).containsExactly(interceptor1, interceptor2); assertThat(options.mergeWithGlobalInterceptors()).isTrue(); assertThat(options.shutdownGracePeriod()).isEqualTo(Duration.ofMinutes(1)); - assertThat(options.customizer()).isSameAs(customizer); + assertThat(options.customizer()).isNotEqualTo(GrpcChannelBuilderCustomizer.defaults()); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Test + void customizerApplied() { + ManagedChannelBuilder builder = mock(); + GrpcChannelBuilderCustomizer customizer = mock(); + var options = ChannelBuilderOptions.defaults().withCustomizer(customizer); + var applied = options.customizer(); + applied.customize("localhost", builder); + verify(customizer).customize("localhost", builder); } @Test