From a406f7dc2f76ae3219dc213608ec4f01ebdcf12b Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 9 Sep 2024 10:52:36 +0100 Subject: [PATCH] Add basic GrpcChannelFactory implementation --- .../sample/GrpcServerApplicationTests.java | 14 +--- .../client/DefaultGrpcChannelFactory.java | 68 +++++++++++++++++++ .../grpc/client/GrpcChannelFactory.java | 6 +- .../client/GrpcClientAutoConfiguration.java | 13 +++- ...ot.autoconfigure.AutoConfiguration.imports | 1 + 5 files changed, 85 insertions(+), 17 deletions(-) create mode 100644 spring-grpc-core/src/main/java/org/springframework/grpc/client/DefaultGrpcChannelFactory.java diff --git a/samples/grpc-server/src/test/java/org/springframework/grpc/sample/GrpcServerApplicationTests.java b/samples/grpc-server/src/test/java/org/springframework/grpc/sample/GrpcServerApplicationTests.java index 7e4fc5e..88048eb 100644 --- a/samples/grpc-server/src/test/java/org/springframework/grpc/sample/GrpcServerApplicationTests.java +++ b/samples/grpc-server/src/test/java/org/springframework/grpc/sample/GrpcServerApplicationTests.java @@ -10,15 +10,12 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; +import org.springframework.grpc.client.GrpcChannelFactory; import org.springframework.grpc.sample.proto.HelloReply; import org.springframework.grpc.sample.proto.HelloRequest; import org.springframework.grpc.sample.proto.SimpleGrpc; import org.springframework.test.annotation.DirtiesContext; -import io.grpc.Channel; -import io.grpc.Grpc; -import io.grpc.InsecureChannelCredentials; - @SpringBootTest public class GrpcServerApplicationTests { @@ -48,13 +45,8 @@ public class GrpcServerApplicationTests { static class ExtraConfiguration { @Bean - SimpleGrpc.SimpleBlockingStub stub(Channel channel) { - return SimpleGrpc.newBlockingStub(channel); - } - - @Bean(destroyMethod = "shutdown") - Channel channel() { - return Grpc.newChannelBuilderForAddress("0.0.0.0", 9090, InsecureChannelCredentials.create()).build(); + SimpleGrpc.SimpleBlockingStub stub(GrpcChannelFactory channels) { + return SimpleGrpc.newBlockingStub(channels.createChannel("0.0.0.0:9090").build()); } } diff --git a/spring-grpc-core/src/main/java/org/springframework/grpc/client/DefaultGrpcChannelFactory.java b/spring-grpc-core/src/main/java/org/springframework/grpc/client/DefaultGrpcChannelFactory.java new file mode 100644 index 0000000..a0cc2a2 --- /dev/null +++ b/spring-grpc-core/src/main/java/org/springframework/grpc/client/DefaultGrpcChannelFactory.java @@ -0,0 +1,68 @@ +/* + * 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.client; + +import java.util.ArrayList; +import java.util.Collection; + +import org.springframework.beans.factory.DisposableBean; + +import io.grpc.ForwardingChannelBuilder2; +import io.grpc.Grpc; +import io.grpc.InsecureChannelCredentials; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; + +public class DefaultGrpcChannelFactory implements GrpcChannelFactory, DisposableBean { + + private Collection channels = new ArrayList<>(); + + @Override + public ManagedChannelBuilder createChannel(String authority) { + ManagedChannelBuilder target = Grpc.newChannelBuilder(authority, InsecureChannelCredentials.create()); + return new DisposableChannelBuilder(target); + } + + @Override + public void destroy() throws Exception { + for (ManagedChannel channel : channels) { + channel.shutdown(); + } + } + + class DisposableChannelBuilder extends ForwardingChannelBuilder2 { + + private final ManagedChannelBuilder delegate; + + public DisposableChannelBuilder(ManagedChannelBuilder delegate) { + this.delegate = delegate; + } + + @Override + protected ManagedChannelBuilder delegate() { + return delegate; + } + + @Override + public ManagedChannel build() { + ManagedChannel channel = super.build(); + channels.add(channel); + return channel; + } + + } + +} diff --git a/spring-grpc-core/src/main/java/org/springframework/grpc/client/GrpcChannelFactory.java b/spring-grpc-core/src/main/java/org/springframework/grpc/client/GrpcChannelFactory.java index 2265880..b0cdc2a 100644 --- a/spring-grpc-core/src/main/java/org/springframework/grpc/client/GrpcChannelFactory.java +++ b/spring-grpc-core/src/main/java/org/springframework/grpc/client/GrpcChannelFactory.java @@ -15,10 +15,10 @@ */ package org.springframework.grpc.client; -import io.grpc.Channel; +import io.grpc.ManagedChannelBuilder; -public interface GrpcChannelFactory extends AutoCloseable { +public interface GrpcChannelFactory { - Channel createChannel(String name); + ManagedChannelBuilder createChannel(String authority); } 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 f804764..d4e3185 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 @@ -15,12 +15,19 @@ */ package org.springframework.grpc.autoconfigure.client; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.grpc.server.GrpcServerFactory; +import org.springframework.grpc.client.DefaultGrpcChannelFactory; +import org.springframework.grpc.client.GrpcChannelFactory; @Configuration(proxyBeanMethods = false) -@ConditionalOnBean(GrpcServerFactory.class) public class GrpcClientAutoConfiguration { + @Bean + @ConditionalOnMissingBean(GrpcChannelFactory.class) + public DefaultGrpcChannelFactory defaultGrpcChannelFactory() { + return new DefaultGrpcChannelFactory(); + } + } diff --git a/spring-grpc-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-grpc-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 6b66269..171088e 100644 --- a/spring-grpc-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-grpc-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,2 +1,3 @@ org.springframework.grpc.autoconfigure.server.GrpcServiceAutoConfiguration org.springframework.grpc.autoconfigure.server.GrpcServerFactoryAutoConfiguration +org.springframework.grpc.autoconfigure.client.GrpcClientAutoConfiguration