Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.Order;
import org.springframework.grpc.client.ChannelCredentialsProvider;
import org.springframework.grpc.client.ClientInterceptorsConfigurer;
import org.springframework.grpc.client.CoroutineStubFactory;
Expand All @@ -46,6 +47,26 @@
GrpcChannelFactoryConfigurations.InProcessChannelFactoryConfiguration.class, ClientScanConfiguration.class })
public final class GrpcClientAutoConfiguration {

/**
* Order applied to the {@link ClientPropertiesChannelBuilderCustomizer} used to apply
* {@link GrpcClientProperties} to channel builders.
*/
public static final int CLIENT_PROPS_CHANNEL_BUILDER_CUSTOMIZER_ORDER = 0;

/**
* Order applied to the {@link GrpcChannelBuilderCustomizer
* compressionClientCustomizer} used to set the compressor registry on the channel
* builder.
*/
public static final int COMPRESSION_CHANNEL_BUILDER_CUSTOMIZER_ORDER = 1;

/**
* Order applied to the {@link GrpcChannelBuilderCustomizer
* decompressionClientCustomizer} used to set the decompressor registry on the channel
* builder.
*/
public static final int DECOMPRESSION_CHANNEL_BUILDER_CUSTOMIZER_ORDER = 2;

@Bean
@ConditionalOnMissingBean
ClientInterceptorsConfigurer clientInterceptorsConfigurer(ApplicationContext applicationContext) {
Expand All @@ -59,20 +80,23 @@ NamedChannelCredentialsProvider channelCredentialsProvider(SslBundles bundles, G
}

@Bean
@Order(CLIENT_PROPS_CHANNEL_BUILDER_CUSTOMIZER_ORDER)
<T extends ManagedChannelBuilder<T>> GrpcChannelBuilderCustomizer<T> clientPropertiesChannelCustomizer(
GrpcClientProperties properties) {
return new ClientPropertiesChannelBuilderCustomizer<>(properties);
}

@ConditionalOnBean(CompressorRegistry.class)
@Bean
@Order(COMPRESSION_CHANNEL_BUILDER_CUSTOMIZER_ORDER)
<T extends ManagedChannelBuilder<T>> GrpcChannelBuilderCustomizer<T> compressionClientCustomizer(
CompressorRegistry registry) {
return (name, builder) -> builder.compressorRegistry(registry);
}

@ConditionalOnBean(DecompressorRegistry.class)
@Bean
@Order(DECOMPRESSION_CHANNEL_BUILDER_CUSTOMIZER_ORDER)
<T extends ManagedChannelBuilder<T>> GrpcChannelBuilderCustomizer<T> decompressionClientCustomizer(
DecompressorRegistry registry) {
return (name, builder) -> builder.decompressorRegistry(registry);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.springframework.grpc.client.InProcessGrpcChannelFactory;
import org.springframework.grpc.client.NettyGrpcChannelFactory;
import org.springframework.grpc.client.ShadedNettyGrpcChannelFactory;
import org.springframework.test.util.ReflectionTestUtils;

import io.grpc.Codec;
import io.grpc.CompressorRegistry;
Expand Down Expand Up @@ -230,6 +231,21 @@ void channelBuilderCustomizersAutoConfiguredAsExpected() {
ChannelBuilderCustomizersConfig.CUSTOMIZER_FOO));
}

@Test
void userDefinedCustomizerCanRunBeforeAndAfterClientPropsCustomizer() {
this.contextRunner().withUserConfiguration(UserClientPropsCustomizerConfig.class).run((context) -> {
// NOTE: AssertJ "extract list + satisfies" balks about generic types
// so we have to do this the old fashion way.
var clientPropsCustomizer = context.getBean(ClientPropertiesChannelBuilderCustomizer.class);
var channelBuilderCustomizers = context.getBean(ChannelBuilderCustomizers.class);
List<GrpcChannelBuilderCustomizer<?>> customizers = (List<GrpcChannelBuilderCustomizer<?>>) ReflectionTestUtils
.getField(channelBuilderCustomizers, "customizers");
assertThat(customizers).isNotNull();
assertThat(customizers).containsSequence(UserClientPropsCustomizerConfig.CUSTOMIZER_PRE_CLIENT_PROPS,
clientPropsCustomizer, UserClientPropsCustomizerConfig.CUSTOMIZER_POST_CLIENT_PROPS);
});
}

@Test
void clientScanConfigurationAutoConfiguredAsExpected() {
this.contextRunner().run((context) -> assertThat(context).hasSingleBean(ClientScanConfiguration.class));
Expand Down Expand Up @@ -447,4 +463,25 @@ GrpcChannelBuilderCustomizer<?> customizerBar() {

}

@Configuration(proxyBeanMethods = false)
static class UserClientPropsCustomizerConfig {

static GrpcChannelBuilderCustomizer<?> CUSTOMIZER_PRE_CLIENT_PROPS = mock();

static GrpcChannelBuilderCustomizer<?> CUSTOMIZER_POST_CLIENT_PROPS = mock();

@Bean
@Order(GrpcClientAutoConfiguration.CLIENT_PROPS_CHANNEL_BUILDER_CUSTOMIZER_ORDER - 1)
GrpcChannelBuilderCustomizer<?> customizerFoo() {
return CUSTOMIZER_PRE_CLIENT_PROPS;
}

@Bean
@Order(GrpcClientAutoConfiguration.CLIENT_PROPS_CHANNEL_BUILDER_CUSTOMIZER_ORDER + 1)
GrpcChannelBuilderCustomizer<?> customizerBar() {
return CUSTOMIZER_POST_CLIENT_PROPS;
}

}

}
Loading