Skip to content

Commit b3ee513

Browse files
committed
Fix code configuration (client-side)
- only use default de/compressor registry when user provides no custom de/compressor - update tests accordingly Signed-off-by: onobc <chris.bono@gmail.com>
1 parent 850990b commit b3ee513

File tree

3 files changed

+100
-20
lines changed

3 files changed

+100
-20
lines changed

module/spring-boot-grpc-client/src/main/java/org/springframework/boot/grpc/client/autoconfigure/GrpcCodecConfiguration.java

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.grpc.CompressorRegistry;
2222
import io.grpc.Decompressor;
2323
import io.grpc.DecompressorRegistry;
24+
import io.grpc.ManagedChannelBuilder;
2425

2526
import org.springframework.beans.factory.ObjectProvider;
2627
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -37,19 +38,46 @@
3738
@ConditionalOnClass(Codec.class)
3839
class GrpcCodecConfiguration {
3940

41+
/**
42+
* The compressor registry that is set on the
43+
* {@link ManagedChannelBuilder#compressorRegistry(CompressorRegistry) channel
44+
* builder}.
45+
* @param compressors the compressors to use on the registry
46+
* @return a new {@link CompressorRegistry#newEmptyInstance() registry} with the
47+
* specified compressors or the {@link CompressorRegistry#getDefaultInstance() default
48+
* registry} if no custom compressors are available in the application context.
49+
*/
4050
@Bean
4151
@ConditionalOnMissingBean
4252
CompressorRegistry compressorRegistry(ObjectProvider<Compressor> compressors) {
43-
CompressorRegistry registry = CompressorRegistry.getDefaultInstance();
53+
if (compressors.stream().count() == 0) {
54+
return CompressorRegistry.getDefaultInstance();
55+
}
56+
CompressorRegistry registry = CompressorRegistry.newEmptyInstance();
4457
compressors.orderedStream().forEachOrdered(registry::register);
4558
return registry;
4659
}
4760

61+
/**
62+
* The decompressor registry that is set on the
63+
* {@link ManagedChannelBuilder#decompressorRegistry(DecompressorRegistry) channel
64+
* builder}.
65+
* @param decompressors the decompressors to use on the registry
66+
* @return a new {@link DecompressorRegistry#emptyInstance() registry} with the
67+
* specified decompressors or the {@link DecompressorRegistry#getDefaultInstance()
68+
* default registry} if no custom decompressors are available in the application
69+
* context.
70+
*/
4871
@Bean
4972
@ConditionalOnMissingBean
5073
DecompressorRegistry decompressorRegistry(ObjectProvider<Decompressor> decompressors) {
51-
DecompressorRegistry registry = DecompressorRegistry.getDefaultInstance();
52-
decompressors.orderedStream().forEachOrdered((decompressor) -> registry.with(decompressor, false));
74+
if (decompressors.stream().count() == 0) {
75+
return DecompressorRegistry.getDefaultInstance();
76+
}
77+
DecompressorRegistry registry = DecompressorRegistry.emptyInstance();
78+
for (Decompressor decompressor : decompressors.orderedStream().toList()) {
79+
registry = registry.with(decompressor, false);
80+
}
5381
return registry;
5482
}
5583

module/spring-boot-grpc-client/src/test/java/org/springframework/boot/grpc/client/autoconfigure/GrpcClientAutoConfigurationTests.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -164,17 +164,6 @@ void clientPropertiesChannelCustomizerAutoConfiguredWithoutHealthAsExpected() {
164164
});
165165
}
166166

167-
@Test
168-
void whenNoCompressorRegistryAutoConfigurationIsSkipped() {
169-
// Codec class guards the imported GrpcCodecConfiguration which provides the
170-
// registry
171-
this.contextRunner()
172-
.withClassLoader(new FilteredClassLoader(Codec.class))
173-
.run((context) -> assertThat(context)
174-
.getBean("compressionClientCustomizer", GrpcChannelBuilderCustomizer.class)
175-
.isNull());
176-
}
177-
178167
@Test
179168
void compressionCustomizerAutoConfiguredAsExpected() {
180169
this.contextRunner().run((context) -> {
@@ -188,13 +177,13 @@ void compressionCustomizerAutoConfiguredAsExpected() {
188177
}
189178

190179
@Test
191-
void whenNoDecompressorRegistryAutoConfigurationIsSkipped() {
180+
void whenNoCompressorRegistryThenCompressionCustomizerIsNotConfigured() {
192181
// Codec class guards the imported GrpcCodecConfiguration which provides the
193182
// registry
194183
this.contextRunner()
195184
.withClassLoader(new FilteredClassLoader(Codec.class))
196185
.run((context) -> assertThat(context)
197-
.getBean("decompressionClientCustomizer", GrpcChannelBuilderCustomizer.class)
186+
.getBean("compressionClientCustomizer", GrpcChannelBuilderCustomizer.class)
198187
.isNull());
199188
}
200189

@@ -211,6 +200,17 @@ void decompressionCustomizerAutoConfiguredAsExpected() {
211200
});
212201
}
213202

203+
@Test
204+
void whenNoDecompressorRegistryAutoConfigurationIsSkipped() {
205+
// Codec class guards the imported GrpcCodecConfiguration which provides the
206+
// registry
207+
this.contextRunner()
208+
.withClassLoader(new FilteredClassLoader(Codec.class))
209+
.run((context) -> assertThat(context)
210+
.getBean("decompressionClientCustomizer", GrpcChannelBuilderCustomizer.class)
211+
.isNull());
212+
}
213+
214214
@Test
215215
void whenHasUserDefinedChannelBuilderCustomizersDoesNotAutoConfigureBean() {
216216
ChannelBuilderCustomizers customCustomizers = mock();

module/spring-boot-grpc-client/src/test/java/org/springframework/boot/grpc/client/autoconfigure/GrpcCodecConfigurationTests.java

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,20 @@
1616

1717
package org.springframework.boot.grpc.client.autoconfigure;
1818

19+
import io.grpc.Codec;
20+
import io.grpc.Compressor;
1921
import io.grpc.CompressorRegistry;
22+
import io.grpc.Decompressor;
2023
import io.grpc.DecompressorRegistry;
2124
import org.junit.jupiter.api.Test;
2225

2326
import org.springframework.boot.autoconfigure.AutoConfigurations;
27+
import org.springframework.boot.test.context.FilteredClassLoader;
2428
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
2529

2630
import static org.assertj.core.api.Assertions.assertThat;
31+
import static org.mockito.BDDMockito.given;
32+
import static org.mockito.Mockito.mock;
2733

2834
/**
2935
* Tests for {@link GrpcCodecConfiguration}.
@@ -36,13 +42,59 @@ class GrpcCodecConfigurationTests {
3642
.withConfiguration(AutoConfigurations.of(GrpcCodecConfiguration.class));
3743

3844
@Test
39-
void testCompressorRegistryBean() {
40-
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(CompressorRegistry.class));
45+
void whenCodecNotOnClasspathThenAutoconfigurationSkipped() {
46+
this.contextRunner.withClassLoader(new FilteredClassLoader(Codec.class))
47+
.run((context) -> assertThat(context).doesNotHaveBean(GrpcCodecConfiguration.class));
4148
}
4249

4350
@Test
44-
void testDecompressorRegistryBean() {
45-
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(DecompressorRegistry.class));
51+
void whenHasCustomCompressorRegistryDoesNotAutoConfigureBean() {
52+
CompressorRegistry customRegistry = mock();
53+
this.contextRunner.withBean("customCompressorRegistry", CompressorRegistry.class, () -> customRegistry)
54+
.run((context) -> assertThat(context).getBean(CompressorRegistry.class).isSameAs(customRegistry));
55+
}
56+
57+
@Test
58+
void compressorRegistryAutoConfiguredAsExpected() {
59+
this.contextRunner.run((context) -> assertThat(context).getBean(CompressorRegistry.class)
60+
.isSameAs(CompressorRegistry.getDefaultInstance()));
61+
}
62+
63+
@Test
64+
void whenCustomCompressorsThenCompressorRegistryIsNewInstance() {
65+
Compressor compressor = mock();
66+
given(compressor.getMessageEncoding()).willReturn("foo");
67+
this.contextRunner.withBean(Compressor.class, () -> compressor).run((context) -> {
68+
assertThat(context).hasSingleBean(CompressorRegistry.class);
69+
CompressorRegistry registry = context.getBean(CompressorRegistry.class);
70+
assertThat(registry).isNotSameAs(CompressorRegistry.getDefaultInstance());
71+
assertThat(registry.lookupCompressor("foo")).isSameAs(compressor);
72+
});
73+
}
74+
75+
@Test
76+
void whenHasCustomDecompressorRegistryDoesNotAutoConfigureBean() {
77+
DecompressorRegistry customRegistry = mock();
78+
this.contextRunner.withBean("customDecompressorRegistry", DecompressorRegistry.class, () -> customRegistry)
79+
.run((context) -> assertThat(context).getBean(DecompressorRegistry.class).isSameAs(customRegistry));
80+
}
81+
82+
@Test
83+
void decompressorRegistryAutoConfiguredAsExpected() {
84+
this.contextRunner.run((context) -> assertThat(context).getBean(DecompressorRegistry.class)
85+
.isSameAs(DecompressorRegistry.getDefaultInstance()));
86+
}
87+
88+
@Test
89+
void whenCustomDecompressorsThenDecompressorRegistryIsNewInstance() {
90+
Decompressor decompressor = mock();
91+
given(decompressor.getMessageEncoding()).willReturn("foo");
92+
this.contextRunner.withBean(Decompressor.class, () -> decompressor).run((context) -> {
93+
assertThat(context).hasSingleBean(DecompressorRegistry.class);
94+
DecompressorRegistry registry = context.getBean(DecompressorRegistry.class);
95+
assertThat(registry).isNotSameAs(DecompressorRegistry.getDefaultInstance());
96+
assertThat(registry.lookupDecompressor("foo")).isSameAs(decompressor);
97+
});
4698
}
4799

48100
}

0 commit comments

Comments
 (0)