diff --git a/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/client/GrpcChannelFactoryConfigurations.java b/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/client/GrpcChannelFactoryConfigurations.java index 51ed5fe..d0bb51d 100644 --- a/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/client/GrpcChannelFactoryConfigurations.java +++ b/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/client/GrpcChannelFactoryConfigurations.java @@ -76,16 +76,11 @@ public class GrpcChannelFactoryConfigurations { } private static io.grpc.netty.shaded.io.grpc.netty.NegotiationType of(final NegotiationType negotiationType) { - switch (negotiationType) { - case PLAINTEXT: - return io.grpc.netty.shaded.io.grpc.netty.NegotiationType.PLAINTEXT; - case PLAINTEXT_UPGRADE: - return io.grpc.netty.shaded.io.grpc.netty.NegotiationType.PLAINTEXT_UPGRADE; - case TLS: - return io.grpc.netty.shaded.io.grpc.netty.NegotiationType.TLS; - default: - throw new IllegalArgumentException("Unsupported NegotiationType: " + negotiationType); - } + return switch (negotiationType) { + case PLAINTEXT -> io.grpc.netty.shaded.io.grpc.netty.NegotiationType.PLAINTEXT; + case PLAINTEXT_UPGRADE -> io.grpc.netty.shaded.io.grpc.netty.NegotiationType.PLAINTEXT_UPGRADE; + case TLS -> io.grpc.netty.shaded.io.grpc.netty.NegotiationType.TLS; + }; } } @@ -126,16 +121,11 @@ public class GrpcChannelFactoryConfigurations { } private static io.grpc.netty.NegotiationType of(final NegotiationType negotiationType) { - switch (negotiationType) { - case PLAINTEXT: - return io.grpc.netty.NegotiationType.PLAINTEXT; - case PLAINTEXT_UPGRADE: - return io.grpc.netty.NegotiationType.PLAINTEXT_UPGRADE; - case TLS: - return io.grpc.netty.NegotiationType.TLS; - default: - throw new IllegalArgumentException("Unsupported NegotiationType: " + negotiationType); - } + return switch (negotiationType) { + case PLAINTEXT -> io.grpc.netty.NegotiationType.PLAINTEXT; + case PLAINTEXT_UPGRADE -> io.grpc.netty.NegotiationType.PLAINTEXT_UPGRADE; + case TLS -> io.grpc.netty.NegotiationType.TLS; + }; } } @@ -151,8 +141,7 @@ public class GrpcChannelFactoryConfigurations { @Override public String getTarget(String authority) { NamedChannel channel = this.channels.getChannel(authority); - String address = channels.getTarget(channel.getAddress()); - return address; + return channels.getTarget(channel.getAddress()); } } 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 e4b08d5..7341750 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 @@ -17,6 +17,9 @@ package org.springframework.grpc.autoconfigure.client; import java.util.concurrent.TimeUnit; +import io.grpc.CompressorRegistry; +import io.grpc.DecompressorRegistry; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslBundles; @@ -24,12 +27,13 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.grpc.autoconfigure.client.GrpcClientProperties.NamedChannel; +import org.springframework.grpc.autoconfigure.common.codec.GrpcCodecConfiguration; import org.springframework.grpc.client.GrpcChannelConfigurer; @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(GrpcClientProperties.class) @Import({ GrpcChannelFactoryConfigurations.ShadedNettyChannelFactoryConfiguration.class, - GrpcChannelFactoryConfigurations.NettyChannelFactoryConfiguration.class }) + GrpcChannelFactoryConfigurations.NettyChannelFactoryConfiguration.class, GrpcCodecConfiguration.class }) public class GrpcClientAutoConfiguration { @Bean @@ -80,4 +84,16 @@ public class GrpcClientAutoConfiguration { }; } + @ConditionalOnBean(CompressorRegistry.class) + @Bean + GrpcChannelConfigurer compressionClientConfigurer(CompressorRegistry registry) { + return (name, builder) -> builder.compressorRegistry(registry); + } + + @ConditionalOnBean(DecompressorRegistry.class) + @Bean + GrpcChannelConfigurer decompressionClientConfigurer(DecompressorRegistry registry) { + return (name, builder) -> builder.decompressorRegistry(registry); + } + } diff --git a/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/common/codec/GrpcCodecConfiguration.java b/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/common/codec/GrpcCodecConfiguration.java new file mode 100644 index 0000000..68f36d5 --- /dev/null +++ b/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/common/codec/GrpcCodecConfiguration.java @@ -0,0 +1,52 @@ +/* + * Copyright 2024-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.common.codec; + +import io.grpc.Codec; +import io.grpc.Compressor; +import io.grpc.Decompressor; +import io.grpc.DecompressorRegistry; +import io.grpc.CompressorRegistry; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * The configuration that contains all codec related beans for clients/servers. + * + * @author Andrei Lisa + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(Codec.class) +public class GrpcCodecConfiguration { + + @Bean + CompressorRegistry compressorRegistry(ObjectProvider compressors) { + CompressorRegistry registry = CompressorRegistry.getDefaultInstance(); + compressors.orderedStream().forEachOrdered(registry::register); + return registry; + } + + @Bean + DecompressorRegistry decompressorRegistry(ObjectProvider decompressors) { + DecompressorRegistry registry = DecompressorRegistry.getDefaultInstance(); + decompressors.orderedStream().forEachOrdered(decompressor -> registry.with(decompressor, false)); + return registry; + } + +} diff --git a/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/server/GrpcServerAutoConfiguration.java b/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/server/GrpcServerAutoConfiguration.java index f1b9a20..fe82d86 100644 --- a/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/server/GrpcServerAutoConfiguration.java +++ b/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/server/GrpcServerAutoConfiguration.java @@ -17,6 +17,9 @@ package org.springframework.grpc.autoconfigure.server; import io.grpc.BindableService; +import io.grpc.CompressorRegistry; +import io.grpc.DecompressorRegistry; +import io.grpc.netty.NettyServerBuilder; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureOrder; @@ -30,6 +33,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Import; import org.springframework.core.Ordered; +import org.springframework.grpc.autoconfigure.common.codec.GrpcCodecConfiguration; import org.springframework.grpc.server.GrpcServerFactory; import org.springframework.grpc.server.ServerBuilderCustomizer; import org.springframework.grpc.server.lifecycle.GrpcServerLifecycle; @@ -49,7 +53,7 @@ import org.springframework.grpc.server.lifecycle.GrpcServerLifecycle; @ConditionalOnBean(BindableService.class) @EnableConfigurationProperties(GrpcServerProperties.class) @Import({ GrpcServerFactoryConfigurations.ShadedNettyServerFactoryConfiguration.class, - GrpcServerFactoryConfigurations.NettyServerFactoryConfiguration.class }) + GrpcServerFactoryConfigurations.NettyServerFactoryConfiguration.class, GrpcCodecConfiguration.class }) public class GrpcServerAutoConfiguration { private final GrpcServerProperties properties; @@ -71,4 +75,16 @@ public class GrpcServerAutoConfiguration { return new ServerBuilderCustomizers(customizers.orderedStream().toList()); } + @ConditionalOnBean(CompressorRegistry.class) + @Bean + ServerBuilderCustomizer compressionServerConfigurer(CompressorRegistry registry) { + return builder -> builder.compressorRegistry(registry); + } + + @ConditionalOnBean(DecompressorRegistry.class) + @Bean + ServerBuilderCustomizer decompressionServerConfigurer(DecompressorRegistry registry) { + return builder -> builder.decompressorRegistry(registry); + } + } diff --git a/spring-grpc-spring-boot-autoconfigure/src/test/java/org/springframework/grpc/autoconfigure/common/GrpcCodecConfigurationTest.java b/spring-grpc-spring-boot-autoconfigure/src/test/java/org/springframework/grpc/autoconfigure/common/GrpcCodecConfigurationTest.java new file mode 100644 index 0000000..4a587d8 --- /dev/null +++ b/spring-grpc-spring-boot-autoconfigure/src/test/java/org/springframework/grpc/autoconfigure/common/GrpcCodecConfigurationTest.java @@ -0,0 +1,48 @@ +/* + * Copyright 2024-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.common; + +import io.grpc.CompressorRegistry; +import io.grpc.DecompressorRegistry; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.grpc.autoconfigure.common.codec.GrpcCodecConfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link GrpcCodecConfiguration}. + * + * @author Andrei Lisa + */ +public class GrpcCodecConfigurationTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(GrpcCodecConfiguration.class)); + + @Test + void testCompressorRegistryBean() { + contextRunner.run(context -> assertThat(context).hasSingleBean(CompressorRegistry.class)); + } + + @Test + void testDecompressorRegistryBean() { + contextRunner.run(context -> assertThat(context).hasSingleBean(DecompressorRegistry.class)); + } + +}