Remove GrpcClientFactoryCustomizer
Existing APIs for customizing channel creation can be used instead.
This commit is contained in:
@@ -1,15 +1,11 @@
|
||||
package org.springframework.grpc.sample;
|
||||
|
||||
import io.grpc.Status.Code;
|
||||
import io.grpc.StatusRuntimeException;
|
||||
import io.grpc.reflection.v1.ServerReflectionGrpc;
|
||||
import io.grpc.reflection.v1.ServerReflectionRequest;
|
||||
import io.grpc.reflection.v1.ServerReflectionResponse;
|
||||
import io.grpc.stub.StreamObserver;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
@@ -23,8 +19,7 @@ import org.springframework.experimental.boot.server.exec.CommonsExecWebServerFac
|
||||
import org.springframework.experimental.boot.server.exec.MavenClasspathEntry;
|
||||
import org.springframework.experimental.boot.test.context.EnableDynamicProperty;
|
||||
import org.springframework.experimental.boot.test.context.OAuth2ClientProviderIssuerUri;
|
||||
import org.springframework.grpc.client.ChannelBuilderOptions;
|
||||
import org.springframework.grpc.client.GrpcClientFactoryCustomizer;
|
||||
import org.springframework.grpc.client.GrpcChannelBuilderCustomizer;
|
||||
import org.springframework.grpc.client.ImportGrpcClients;
|
||||
import org.springframework.grpc.client.interceptor.security.BearerTokenAuthenticationInterceptor;
|
||||
import org.springframework.grpc.sample.proto.HelloReply;
|
||||
@@ -36,8 +31,12 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import io.grpc.Status.Code;
|
||||
import io.grpc.StatusRuntimeException;
|
||||
import io.grpc.reflection.v1.ServerReflectionGrpc;
|
||||
import io.grpc.reflection.v1.ServerReflectionRequest;
|
||||
import io.grpc.reflection.v1.ServerReflectionResponse;
|
||||
import io.grpc.stub.StreamObserver;
|
||||
|
||||
@SpringBootTest(properties = { "spring.grpc.server.port=0",
|
||||
"spring.grpc.client.default-channel.address=static://0.0.0.0:${local.grpc.port}" })
|
||||
@@ -129,9 +128,9 @@ public class GrpcServerApplicationTests {
|
||||
}
|
||||
|
||||
@Bean
|
||||
GrpcClientFactoryCustomizer stubs(ObjectProvider<ClientRegistrationRepository> context) {
|
||||
return registry -> registry.channel("secure", ChannelBuilderOptions.defaults()
|
||||
.withInterceptors(List.of(new BearerTokenAuthenticationInterceptor(() -> token(context)))));
|
||||
GrpcChannelBuilderCustomizer<?> stubs(ObjectProvider<ClientRegistrationRepository> context) {
|
||||
return GrpcChannelBuilderCustomizer.matching("secure",
|
||||
builder -> builder.intercept(new BearerTokenAuthenticationInterceptor(() -> token(context))));
|
||||
}
|
||||
|
||||
private String token(ObjectProvider<ClientRegistrationRepository> context) {
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.springframework.grpc.sample;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@@ -15,8 +14,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
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.ChannelBuilderOptions;
|
||||
import org.springframework.grpc.client.GrpcClientFactoryCustomizer;
|
||||
import org.springframework.grpc.client.GrpcChannelBuilderCustomizer;
|
||||
import org.springframework.grpc.client.ImportGrpcClients;
|
||||
import org.springframework.grpc.client.interceptor.security.BasicAuthenticationInterceptor;
|
||||
import org.springframework.grpc.sample.proto.HelloReply;
|
||||
@@ -113,9 +111,9 @@ public class GrpcServerApplicationTests {
|
||||
static class ExtraConfiguration {
|
||||
|
||||
@Bean
|
||||
GrpcClientFactoryCustomizer basicStubs() {
|
||||
return registry -> registry.channel("secure", ChannelBuilderOptions.defaults()
|
||||
.withInterceptors(List.of(new BasicAuthenticationInterceptor("user", "user"))));
|
||||
GrpcChannelBuilderCustomizer<?> basicStubsCustomizer() {
|
||||
return GrpcChannelBuilderCustomizer.matching("secure",
|
||||
builder -> builder.intercept(new BasicAuthenticationInterceptor("user", "user")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.grpc.client;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import io.grpc.ManagedChannelBuilder;
|
||||
|
||||
/**
|
||||
@@ -54,4 +56,13 @@ public interface GrpcChannelBuilderCustomizer<T extends ManagedChannelBuilder<T>
|
||||
};
|
||||
}
|
||||
|
||||
static <T extends ManagedChannelBuilder<T>> GrpcChannelBuilderCustomizer<T> matching(String pattern,
|
||||
Consumer<ManagedChannelBuilder<T>> consumer) {
|
||||
return (authority, channel) -> {
|
||||
if (pattern.matches(authority)) {
|
||||
consumer.accept(channel);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,14 +18,12 @@ package org.springframework.grpc.client;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
@@ -42,14 +40,11 @@ import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.stub.AbstractStub;
|
||||
|
||||
/**
|
||||
* A factory of gRPC clients that can be used to create client stubs as beans in an
|
||||
* application context. The best way to interact with the factory is to declare a bean of
|
||||
* type {@link GrpcClientFactoryCustomizer} in the application context. The customizer
|
||||
* will be called with the factory before it is used to create the beans.
|
||||
* application context.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -63,8 +58,6 @@ public class GrpcClientFactory {
|
||||
|
||||
private final ApplicationContext context;
|
||||
|
||||
private Map<String, Supplier<ManagedChannel>> options = new HashMap<>();
|
||||
|
||||
static {
|
||||
DEFAULT_FACTORIES.add((Class<? extends StubFactory<?>>) BlockingStubFactory.class);
|
||||
DEFAULT_FACTORIES.add((Class<? extends StubFactory<?>>) BlockingV2StubFactory.class);
|
||||
@@ -80,25 +73,10 @@ public class GrpcClientFactory {
|
||||
public <T> T getClient(String target, Class<T> type, Class<?> factory) {
|
||||
@SuppressWarnings("unchecked")
|
||||
StubFactory<T> stubs = (StubFactory<T>) findFactory(factory, type);
|
||||
Supplier<ManagedChannel> channel = this.options.get(target);
|
||||
if (channel == null) {
|
||||
channel = () -> channels().createChannel(target, ChannelBuilderOptions.defaults());
|
||||
}
|
||||
Supplier<ManagedChannel> finalChannel = channel;
|
||||
T client = (T) stubs.create(() -> finalChannel.get(), type);
|
||||
T client = (T) stubs.create(() -> channels().createChannel(target, ChannelBuilderOptions.defaults()), type);
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a channel factory for the given target. The channel will be created using
|
||||
* the given options. If no options are provided, the default options will be used.
|
||||
* @param target the name (or base url) of the target
|
||||
* @param options the options to use to create the channel
|
||||
*/
|
||||
public void channel(String target, ChannelBuilderOptions options) {
|
||||
this.options.put(target, () -> channels().createChannel(target, options));
|
||||
}
|
||||
|
||||
private StubFactory<?> findFactory(Class<?> factoryType, Class<?> type) {
|
||||
if (this.factories.isEmpty()) {
|
||||
List<StubFactory<?>> factories = new ArrayList<>();
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* Callback interface that can be implemented by beans wishing to customize the
|
||||
* {@link GrpcClientFactory} before it is used. The registry is used by the application
|
||||
* context very early in its lifecycle, so customizers should not refer directly to other
|
||||
* beans. It is better to use a lazy lookup via the {@link ApplicationContext} or an
|
||||
* {@link ObjectProvider}
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public interface GrpcClientFactoryCustomizer {
|
||||
|
||||
void customize(GrpcClientFactory registry);
|
||||
|
||||
}
|
||||
@@ -15,14 +15,9 @@
|
||||
*/
|
||||
package org.springframework.grpc.client;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
|
||||
/**
|
||||
* Post processor for {@link GrpcClientFactory} that applies the customizers and provides
|
||||
@@ -44,12 +39,6 @@ public class GrpcClientFactoryPostProcessor implements ApplicationContextAware {
|
||||
}
|
||||
this.initialized = true;
|
||||
this.registry = new GrpcClientFactory(context);
|
||||
if (context.getBeanNamesForType(GrpcClientFactoryCustomizer.class).length > 0) {
|
||||
List<GrpcClientFactoryCustomizer> values = new ArrayList<>(
|
||||
context.getBeansOfType(GrpcClientFactoryCustomizer.class).values());
|
||||
AnnotationAwareOrderComparator.sort(values);
|
||||
values.forEach(customizer -> customizer.customize(this.registry));
|
||||
}
|
||||
}
|
||||
|
||||
<T> T getClient(String target, Class<T> type, Class<?> factory) {
|
||||
@@ -59,12 +48,7 @@ public class GrpcClientFactoryPostProcessor implements ApplicationContextAware {
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
if (applicationContext instanceof GenericApplicationContext generic) {
|
||||
this.context = generic;
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("ApplicationContext must be a GenericApplicationContext");
|
||||
}
|
||||
this.context = applicationContext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,9 +25,7 @@ import java.lang.annotation.Target;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Annotation to create gRPC client beans. If you want more control over the creation of
|
||||
* the clients, or you don't want to use the annotation, you can use a bean of type
|
||||
* {@link GrpcClientFactoryCustomizer} instead.
|
||||
* Annotation to create gRPC client beans.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user