mirror of https://github.com/grpc/grpc-java.git
Add internal channel builder API to get target
This will be used for gRFC A66's OTel per-RPC metric label: > `grpc.target` : Canonicalized target URI used when creating gRPC > Channel, e.g. "dns:///pubsub.googleapis.com:443", > "xds:///helloworld-gke:8000". Canonicalized target URI is the form > with the scheme included if the user didn't mention the scheme > (`scheme://[authority]/path`). The majority of the changes are to move target computation from ManagedChannelImpl into the builder. A small hack API was added to ManagedChannelBuilder to get the target to create an interceptor.
This commit is contained in:
parent
affa470252
commit
952ac022ee
|
@ -94,6 +94,12 @@ public abstract class ForwardingChannelBuilder2<T extends ManagedChannelBuilder<
|
|||
return thisT();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T interceptWithTarget(InterceptorFactory factory) {
|
||||
delegate().interceptWithTarget(factory);
|
||||
return thisT();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T addTransportFilter(ClientTransportFilter transportFilter) {
|
||||
delegate().addTransportFilter(transportFilter);
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2024 The gRPC 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
|
||||
*
|
||||
* http://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 io.grpc;
|
||||
|
||||
/**
|
||||
* Internal accessors for {@link ManagedChannelBuilder}.
|
||||
*/
|
||||
public final class InternalManagedChannelBuilder {
|
||||
private InternalManagedChannelBuilder() {}
|
||||
|
||||
public static <T extends ManagedChannelBuilder<T>> T interceptWithTarget(
|
||||
ManagedChannelBuilder<T> builder, InternalInterceptorFactory factory) {
|
||||
return builder.interceptWithTarget(factory);
|
||||
}
|
||||
|
||||
public interface InternalInterceptorFactory extends ManagedChannelBuilder.InterceptorFactory {}
|
||||
}
|
|
@ -159,6 +159,21 @@ public abstract class ManagedChannelBuilder<T extends ManagedChannelBuilder<T>>
|
|||
*/
|
||||
public abstract T intercept(ClientInterceptor... interceptors);
|
||||
|
||||
/**
|
||||
* Internal-only: Adds a factory that will construct an interceptor based on the channel's target.
|
||||
* This can be used to work around nameResolverFactory() changing the target string.
|
||||
*/
|
||||
@Internal
|
||||
protected T interceptWithTarget(InterceptorFactory factory) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/** Internal-only. */
|
||||
@Internal
|
||||
protected interface InterceptorFactory {
|
||||
ClientInterceptor newInterceptor(String target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link ClientTransportFilter}. The order of filters being added is the order they will
|
||||
* be executed
|
||||
|
|
|
@ -93,9 +93,7 @@ import io.grpc.internal.ManagedChannelServiceConfig.ServiceConfigConvertedSelect
|
|||
import io.grpc.internal.RetriableStream.ChannelBufferMeter;
|
||||
import io.grpc.internal.RetriableStream.Throttle;
|
||||
import io.grpc.internal.RetryingNameResolver.ResolutionResultListener;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -117,7 +115,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
|
@ -129,12 +126,6 @@ final class ManagedChannelImpl extends ManagedChannel implements
|
|||
@VisibleForTesting
|
||||
static final Logger logger = Logger.getLogger(ManagedChannelImpl.class.getName());
|
||||
|
||||
// Matching this pattern means the target string is a URI target or at least intended to be one.
|
||||
// A URI target must be an absolute hierarchical URI.
|
||||
// From RFC 2396: scheme = alpha *( alpha | digit | "+" | "-" | "." )
|
||||
@VisibleForTesting
|
||||
static final Pattern URI_PATTERN = Pattern.compile("[a-zA-Z][a-zA-Z0-9+.-]*:/.*");
|
||||
|
||||
static final long IDLE_TIMEOUT_MILLIS_DISABLE = -1;
|
||||
|
||||
static final long SUBCHANNEL_SHUTDOWN_DELAY_SECONDS = 5;
|
||||
|
@ -595,6 +586,8 @@ final class ManagedChannelImpl extends ManagedChannel implements
|
|||
ManagedChannelImpl(
|
||||
ManagedChannelImplBuilder builder,
|
||||
ClientTransportFactory clientTransportFactory,
|
||||
URI targetUri,
|
||||
NameResolverProvider nameResolverProvider,
|
||||
BackoffPolicy.Provider backoffPolicyProvider,
|
||||
ObjectPool<? extends Executor> balancerRpcExecutorPool,
|
||||
Supplier<Stopwatch> stopwatchSupplier,
|
||||
|
@ -625,10 +618,8 @@ final class ManagedChannelImpl extends ManagedChannel implements
|
|||
this.retryEnabled = builder.retryEnabled;
|
||||
this.loadBalancerFactory = new AutoConfiguredLoadBalancerFactory(builder.defaultLbPolicy);
|
||||
this.nameResolverRegistry = builder.nameResolverRegistry;
|
||||
ResolvedNameResolver resolvedResolver = getNameResolverProvider(
|
||||
target, nameResolverRegistry, transportFactory.getSupportedSocketAddressTypes());
|
||||
this.targetUri = resolvedResolver.targetUri;
|
||||
this.nameResolverProvider = resolvedResolver.provider;
|
||||
this.targetUri = checkNotNull(targetUri, "targetUri");
|
||||
this.nameResolverProvider = checkNotNull(nameResolverProvider, "nameResolverProvider");
|
||||
ScParser serviceConfigParser =
|
||||
new ScParser(
|
||||
retryEnabled,
|
||||
|
@ -722,69 +713,6 @@ final class ManagedChannelImpl extends ManagedChannel implements
|
|||
MetricInstrumentRegistry.getDefaultRegistry());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class ResolvedNameResolver {
|
||||
public final URI targetUri;
|
||||
public final NameResolverProvider provider;
|
||||
|
||||
public ResolvedNameResolver(URI targetUri, NameResolverProvider provider) {
|
||||
this.targetUri = checkNotNull(targetUri, "targetUri");
|
||||
this.provider = checkNotNull(provider, "provider");
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static ResolvedNameResolver getNameResolverProvider(
|
||||
String target, NameResolverRegistry nameResolverRegistry,
|
||||
Collection<Class<? extends SocketAddress>> channelTransportSocketAddressTypes) {
|
||||
// Finding a NameResolver. Try using the target string as the URI. If that fails, try prepending
|
||||
// "dns:///".
|
||||
NameResolverProvider provider = null;
|
||||
URI targetUri = null;
|
||||
StringBuilder uriSyntaxErrors = new StringBuilder();
|
||||
try {
|
||||
targetUri = new URI(target);
|
||||
} catch (URISyntaxException e) {
|
||||
// Can happen with ip addresses like "[::1]:1234" or 127.0.0.1:1234.
|
||||
uriSyntaxErrors.append(e.getMessage());
|
||||
}
|
||||
if (targetUri != null) {
|
||||
// For "localhost:8080" this would likely cause provider to be null, because "localhost" is
|
||||
// parsed as the scheme. Will hit the next case and try "dns:///localhost:8080".
|
||||
provider = nameResolverRegistry.getProviderForScheme(targetUri.getScheme());
|
||||
}
|
||||
|
||||
if (provider == null && !URI_PATTERN.matcher(target).matches()) {
|
||||
// It doesn't look like a URI target. Maybe it's an authority string. Try with the default
|
||||
// scheme from the registry.
|
||||
try {
|
||||
targetUri = new URI(nameResolverRegistry.getDefaultScheme(), "", "/" + target, null);
|
||||
} catch (URISyntaxException e) {
|
||||
// Should not be possible.
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
provider = nameResolverRegistry.getProviderForScheme(targetUri.getScheme());
|
||||
}
|
||||
|
||||
if (provider == null) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Could not find a NameResolverProvider for %s%s",
|
||||
target, uriSyntaxErrors.length() > 0 ? " (" + uriSyntaxErrors + ")" : ""));
|
||||
}
|
||||
|
||||
if (channelTransportSocketAddressTypes != null) {
|
||||
Collection<Class<? extends SocketAddress>> nameResolverSocketAddressTypes
|
||||
= provider.getProducedSocketAddressTypes();
|
||||
if (!channelTransportSocketAddressTypes.containsAll(nameResolverSocketAddressTypes)) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Address types of NameResolver '%s' for '%s' not supported by transport",
|
||||
targetUri.getScheme(), target));
|
||||
}
|
||||
}
|
||||
|
||||
return new ResolvedNameResolver(targetUri, provider);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static NameResolver getNameResolver(
|
||||
URI targetUri, @Nullable final String overrideAuthority,
|
||||
|
|
|
@ -26,7 +26,10 @@ import com.google.errorprone.annotations.DoNotCall;
|
|||
import io.grpc.Attributes;
|
||||
import io.grpc.BinaryLog;
|
||||
import io.grpc.CallCredentials;
|
||||
import io.grpc.CallOptions;
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.ChannelCredentials;
|
||||
import io.grpc.ClientCall;
|
||||
import io.grpc.ClientInterceptor;
|
||||
import io.grpc.ClientTransportFilter;
|
||||
import io.grpc.CompressorRegistry;
|
||||
|
@ -36,6 +39,7 @@ import io.grpc.InternalChannelz;
|
|||
import io.grpc.InternalConfiguratorRegistry;
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.ManagedChannelBuilder;
|
||||
import io.grpc.MethodDescriptor;
|
||||
import io.grpc.MetricSink;
|
||||
import io.grpc.NameResolver;
|
||||
import io.grpc.NameResolverProvider;
|
||||
|
@ -57,6 +61,7 @@ import java.util.concurrent.Executor;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
|
@ -109,6 +114,12 @@ public final class ManagedChannelImplBuilder
|
|||
private static final long DEFAULT_RETRY_BUFFER_SIZE_IN_BYTES = 1L << 24; // 16M
|
||||
private static final long DEFAULT_PER_RPC_BUFFER_LIMIT_IN_BYTES = 1L << 20; // 1M
|
||||
|
||||
// Matching this pattern means the target string is a URI target or at least intended to be one.
|
||||
// A URI target must be an absolute hierarchical URI.
|
||||
// From RFC 2396: scheme = alpha *( alpha | digit | "+" | "-" | "." )
|
||||
@VisibleForTesting
|
||||
static final Pattern URI_PATTERN = Pattern.compile("[a-zA-Z][a-zA-Z0-9+.-]*:/.*");
|
||||
|
||||
private static final Method GET_CLIENT_INTERCEPTOR_METHOD;
|
||||
|
||||
static {
|
||||
|
@ -384,6 +395,14 @@ public final class ManagedChannelImplBuilder
|
|||
return intercept(Arrays.asList(interceptors));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ManagedChannelImplBuilder interceptWithTarget(InterceptorFactory factory) {
|
||||
// Add a placeholder instance to the interceptor list, and replace it with a real instance
|
||||
// during build().
|
||||
this.interceptors.add(new InterceptorFactoryWrapper(factory));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedChannelImplBuilder addTransportFilter(ClientTransportFilter hook) {
|
||||
transportFilters.add(checkNotNull(hook, "transport filter"));
|
||||
|
@ -675,13 +694,19 @@ public final class ManagedChannelImplBuilder
|
|||
|
||||
@Override
|
||||
public ManagedChannel build() {
|
||||
ClientTransportFactory clientTransportFactory =
|
||||
clientTransportFactoryBuilder.buildClientTransportFactory();
|
||||
ResolvedNameResolver resolvedResolver = getNameResolverProvider(
|
||||
target, nameResolverRegistry, clientTransportFactory.getSupportedSocketAddressTypes());
|
||||
return new ManagedChannelOrphanWrapper(new ManagedChannelImpl(
|
||||
this,
|
||||
clientTransportFactoryBuilder.buildClientTransportFactory(),
|
||||
clientTransportFactory,
|
||||
resolvedResolver.targetUri,
|
||||
resolvedResolver.provider,
|
||||
new ExponentialBackoffPolicy.Provider(),
|
||||
SharedResourcePool.forResource(GrpcUtil.SHARED_CHANNEL_EXECUTOR),
|
||||
GrpcUtil.STOPWATCH_SUPPLIER,
|
||||
getEffectiveInterceptors(),
|
||||
getEffectiveInterceptors(resolvedResolver.targetUri.toString()),
|
||||
TimeProvider.SYSTEM_TIME_PROVIDER));
|
||||
}
|
||||
|
||||
|
@ -689,12 +714,25 @@ public final class ManagedChannelImplBuilder
|
|||
// what should be the desired behavior for retry + stats/tracing.
|
||||
// TODO(zdapeng): FIX IT
|
||||
@VisibleForTesting
|
||||
List<ClientInterceptor> getEffectiveInterceptors() {
|
||||
List<ClientInterceptor> getEffectiveInterceptors(String computedTarget) {
|
||||
List<ClientInterceptor> effectiveInterceptors = new ArrayList<>(this.interceptors);
|
||||
for (int i = 0; i < effectiveInterceptors.size(); i++) {
|
||||
if (!(effectiveInterceptors.get(i) instanceof InterceptorFactoryWrapper)) {
|
||||
continue;
|
||||
}
|
||||
InterceptorFactory factory =
|
||||
((InterceptorFactoryWrapper) effectiveInterceptors.get(i)).factory;
|
||||
ClientInterceptor interceptor = factory.newInterceptor(computedTarget);
|
||||
if (interceptor == null) {
|
||||
throw new NullPointerException("Factory returned null interceptor: " + factory);
|
||||
}
|
||||
effectiveInterceptors.set(i, interceptor);
|
||||
}
|
||||
|
||||
boolean disableImplicitCensus = InternalConfiguratorRegistry.wasSetConfiguratorsCalled();
|
||||
if (disableImplicitCensus) {
|
||||
return this.interceptors;
|
||||
return effectiveInterceptors;
|
||||
}
|
||||
List<ClientInterceptor> effectiveInterceptors = new ArrayList<>(this.interceptors);
|
||||
if (statsEnabled) {
|
||||
ClientInterceptor statsInterceptor = null;
|
||||
|
||||
|
@ -754,6 +792,69 @@ public final class ManagedChannelImplBuilder
|
|||
return channelBuilderDefaultPortProvider.getDefaultPort();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class ResolvedNameResolver {
|
||||
public final URI targetUri;
|
||||
public final NameResolverProvider provider;
|
||||
|
||||
public ResolvedNameResolver(URI targetUri, NameResolverProvider provider) {
|
||||
this.targetUri = checkNotNull(targetUri, "targetUri");
|
||||
this.provider = checkNotNull(provider, "provider");
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static ResolvedNameResolver getNameResolverProvider(
|
||||
String target, NameResolverRegistry nameResolverRegistry,
|
||||
Collection<Class<? extends SocketAddress>> channelTransportSocketAddressTypes) {
|
||||
// Finding a NameResolver. Try using the target string as the URI. If that fails, try prepending
|
||||
// "dns:///".
|
||||
NameResolverProvider provider = null;
|
||||
URI targetUri = null;
|
||||
StringBuilder uriSyntaxErrors = new StringBuilder();
|
||||
try {
|
||||
targetUri = new URI(target);
|
||||
} catch (URISyntaxException e) {
|
||||
// Can happen with ip addresses like "[::1]:1234" or 127.0.0.1:1234.
|
||||
uriSyntaxErrors.append(e.getMessage());
|
||||
}
|
||||
if (targetUri != null) {
|
||||
// For "localhost:8080" this would likely cause provider to be null, because "localhost" is
|
||||
// parsed as the scheme. Will hit the next case and try "dns:///localhost:8080".
|
||||
provider = nameResolverRegistry.getProviderForScheme(targetUri.getScheme());
|
||||
}
|
||||
|
||||
if (provider == null && !URI_PATTERN.matcher(target).matches()) {
|
||||
// It doesn't look like a URI target. Maybe it's an authority string. Try with the default
|
||||
// scheme from the registry.
|
||||
try {
|
||||
targetUri = new URI(nameResolverRegistry.getDefaultScheme(), "", "/" + target, null);
|
||||
} catch (URISyntaxException e) {
|
||||
// Should not be possible.
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
provider = nameResolverRegistry.getProviderForScheme(targetUri.getScheme());
|
||||
}
|
||||
|
||||
if (provider == null) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Could not find a NameResolverProvider for %s%s",
|
||||
target, uriSyntaxErrors.length() > 0 ? " (" + uriSyntaxErrors + ")" : ""));
|
||||
}
|
||||
|
||||
if (channelTransportSocketAddressTypes != null) {
|
||||
Collection<Class<? extends SocketAddress>> nameResolverSocketAddressTypes
|
||||
= provider.getProducedSocketAddressTypes();
|
||||
if (!channelTransportSocketAddressTypes.containsAll(nameResolverSocketAddressTypes)) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Address types of NameResolver '%s' for '%s' not supported by transport",
|
||||
targetUri.getScheme(), target));
|
||||
}
|
||||
}
|
||||
|
||||
return new ResolvedNameResolver(targetUri, provider);
|
||||
}
|
||||
|
||||
private static class DirectAddressNameResolverProvider extends NameResolverProvider {
|
||||
final SocketAddress address;
|
||||
final String authority;
|
||||
|
@ -809,6 +910,20 @@ public final class ManagedChannelImplBuilder
|
|||
}
|
||||
}
|
||||
|
||||
private static final class InterceptorFactoryWrapper implements ClientInterceptor {
|
||||
final InterceptorFactory factory;
|
||||
|
||||
public InterceptorFactoryWrapper(InterceptorFactory factory) {
|
||||
this.factory = checkNotNull(factory, "factory");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
|
||||
MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
|
||||
throw new AssertionError("Should have been replaced with real instance");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the internal offload executor pool for offloading tasks.
|
||||
*/
|
||||
|
|
|
@ -38,6 +38,7 @@ import io.grpc.CompressorRegistry;
|
|||
import io.grpc.DecompressorRegistry;
|
||||
import io.grpc.InternalConfigurator;
|
||||
import io.grpc.InternalConfiguratorRegistry;
|
||||
import io.grpc.InternalManagedChannelBuilder.InternalInterceptorFactory;
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.ManagedChannelBuilder;
|
||||
import io.grpc.MethodDescriptor;
|
||||
|
@ -473,7 +474,7 @@ public class ManagedChannelImplBuilderTest {
|
|||
@Test
|
||||
public void getEffectiveInterceptors_default() {
|
||||
builder.intercept(DUMMY_USER_INTERCEPTOR);
|
||||
List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors();
|
||||
List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors("unused:///");
|
||||
assertEquals(3, effectiveInterceptors.size());
|
||||
assertThat(effectiveInterceptors.get(0).getClass().getName())
|
||||
.isEqualTo("io.grpc.census.CensusTracingModule$TracingClientInterceptor");
|
||||
|
@ -486,7 +487,7 @@ public class ManagedChannelImplBuilderTest {
|
|||
public void getEffectiveInterceptors_disableStats() {
|
||||
builder.intercept(DUMMY_USER_INTERCEPTOR);
|
||||
builder.setStatsEnabled(false);
|
||||
List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors();
|
||||
List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors("unused:///");
|
||||
assertEquals(2, effectiveInterceptors.size());
|
||||
assertThat(effectiveInterceptors.get(0).getClass().getName())
|
||||
.isEqualTo("io.grpc.census.CensusTracingModule$TracingClientInterceptor");
|
||||
|
@ -497,7 +498,7 @@ public class ManagedChannelImplBuilderTest {
|
|||
public void getEffectiveInterceptors_disableTracing() {
|
||||
builder.intercept(DUMMY_USER_INTERCEPTOR);
|
||||
builder.setTracingEnabled(false);
|
||||
List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors();
|
||||
List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors("unused:///");
|
||||
assertEquals(2, effectiveInterceptors.size());
|
||||
assertThat(effectiveInterceptors.get(0).getClass().getName())
|
||||
.isEqualTo("io.grpc.census.CensusStatsModule$StatsClientInterceptor");
|
||||
|
@ -509,7 +510,7 @@ public class ManagedChannelImplBuilderTest {
|
|||
builder.intercept(DUMMY_USER_INTERCEPTOR);
|
||||
builder.setStatsEnabled(false);
|
||||
builder.setTracingEnabled(false);
|
||||
List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors();
|
||||
List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors("unused:///");
|
||||
assertThat(effectiveInterceptors).containsExactly(DUMMY_USER_INTERCEPTOR);
|
||||
}
|
||||
|
||||
|
@ -529,7 +530,8 @@ public class ManagedChannelImplBuilderTest {
|
|||
DUMMY_TARGET,
|
||||
new UnsupportedClientTransportFactoryBuilder(),
|
||||
new FixedPortProvider(DUMMY_PORT));
|
||||
List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors();
|
||||
List<ClientInterceptor> effectiveInterceptors =
|
||||
builder.getEffectiveInterceptors("unused:///");
|
||||
assertThat(effectiveInterceptors).hasSize(2);
|
||||
try {
|
||||
InternalConfiguratorRegistry.setConfigurators(Collections.emptyList());
|
||||
|
@ -563,7 +565,8 @@ public class ManagedChannelImplBuilderTest {
|
|||
DUMMY_TARGET,
|
||||
new UnsupportedClientTransportFactoryBuilder(),
|
||||
new FixedPortProvider(DUMMY_PORT));
|
||||
List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors();
|
||||
List<ClientInterceptor> effectiveInterceptors =
|
||||
builder.getEffectiveInterceptors("unused:///");
|
||||
assertThat(effectiveInterceptors)
|
||||
.containsExactly(DUMMY_USER_INTERCEPTOR, DUMMY_USER_INTERCEPTOR1);
|
||||
}
|
||||
|
@ -587,11 +590,35 @@ public class ManagedChannelImplBuilderTest {
|
|||
DUMMY_TARGET,
|
||||
new UnsupportedClientTransportFactoryBuilder(),
|
||||
new FixedPortProvider(DUMMY_PORT));
|
||||
List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors();
|
||||
List<ClientInterceptor> effectiveInterceptors =
|
||||
builder.getEffectiveInterceptors("unused:///");
|
||||
assertThat(effectiveInterceptors).isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEffectiveInterceptors_createsFromInterceptorFactories() throws Exception {
|
||||
String target = "dns:///the-host";
|
||||
builder.setStatsEnabled(false);
|
||||
builder.setTracingEnabled(false);
|
||||
|
||||
builder.intercept(DUMMY_USER_INTERCEPTOR)
|
||||
.interceptWithTarget(new InternalInterceptorFactory() {
|
||||
@Override
|
||||
public ClientInterceptor newInterceptor(String passedTarget) {
|
||||
assertThat(passedTarget).isEqualTo(target);
|
||||
return DUMMY_USER_INTERCEPTOR1;
|
||||
}
|
||||
})
|
||||
.intercept(DUMMY_USER_INTERCEPTOR);
|
||||
|
||||
assertThat(builder.getEffectiveInterceptors(target))
|
||||
.isEqualTo(Arrays.asList(
|
||||
DUMMY_USER_INTERCEPTOR,
|
||||
DUMMY_USER_INTERCEPTOR1,
|
||||
DUMMY_USER_INTERCEPTOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void idleTimeout() {
|
||||
assertEquals(ManagedChannelImplBuilder.IDLE_MODE_DEFAULT_TIMEOUT_MILLIS,
|
||||
|
@ -744,4 +771,15 @@ public class ManagedChannelImplBuilderTest {
|
|||
|
||||
assertThat(builder.metricSinks).contains(mocksink);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uriPattern() {
|
||||
Pattern uriPattern = ManagedChannelImplBuilder.URI_PATTERN;
|
||||
assertTrue(uriPattern.matcher("a:/").matches());
|
||||
assertTrue(uriPattern.matcher("Z019+-.:/!@ #~ ").matches());
|
||||
assertFalse(uriPattern.matcher("a/:").matches()); // "/:" not matched
|
||||
assertFalse(uriPattern.matcher("0a:/").matches()); // '0' not matched
|
||||
assertFalse(uriPattern.matcher("a,:/").matches()); // ',' not matched
|
||||
assertFalse(uriPattern.matcher(" a:/").matches()); // space not matched
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ import org.junit.Test;
|
|||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for ManagedChannelImpl#getNameResolverProvider(). */
|
||||
/** Unit tests for ManagedChannelImplBuilder#getNameResolverProvider(). */
|
||||
@RunWith(JUnit4.class)
|
||||
public class ManagedChannelImplGetNameResolverTest {
|
||||
@Test
|
||||
|
@ -95,7 +95,7 @@ public class ManagedChannelImplGetNameResolverTest {
|
|||
public void validTargetNoProvider() {
|
||||
NameResolverRegistry nameResolverRegistry = new NameResolverRegistry();
|
||||
try {
|
||||
ManagedChannelImpl.getNameResolverProvider(
|
||||
ManagedChannelImplBuilder.getNameResolverProvider(
|
||||
"foo.googleapis.com:8080", nameResolverRegistry,
|
||||
Collections.singleton(InetSocketAddress.class));
|
||||
fail("Should fail");
|
||||
|
@ -108,7 +108,7 @@ public class ManagedChannelImplGetNameResolverTest {
|
|||
public void validTargetProviderAddrTypesNotSupported() {
|
||||
NameResolverRegistry nameResolverRegistry = getTestRegistry("testscheme");
|
||||
try {
|
||||
ManagedChannelImpl.getNameResolverProvider(
|
||||
ManagedChannelImplBuilder.getNameResolverProvider(
|
||||
"testscheme:///foo.googleapis.com:8080", nameResolverRegistry,
|
||||
Collections.singleton(InProcessSocketAddress.class));
|
||||
fail("Should fail");
|
||||
|
@ -121,8 +121,9 @@ public class ManagedChannelImplGetNameResolverTest {
|
|||
|
||||
private void testValidTarget(String target, String expectedUriString, URI expectedUri) {
|
||||
NameResolverRegistry nameResolverRegistry = getTestRegistry(expectedUri.getScheme());
|
||||
ManagedChannelImpl.ResolvedNameResolver resolved = ManagedChannelImpl.getNameResolverProvider(
|
||||
target, nameResolverRegistry, Collections.singleton(InetSocketAddress.class));
|
||||
ManagedChannelImplBuilder.ResolvedNameResolver resolved =
|
||||
ManagedChannelImplBuilder.getNameResolverProvider(
|
||||
target, nameResolverRegistry, Collections.singleton(InetSocketAddress.class));
|
||||
assertThat(resolved.provider).isInstanceOf(FakeNameResolverProvider.class);
|
||||
assertThat(resolved.targetUri).isEqualTo(expectedUri);
|
||||
assertThat(resolved.targetUri.toString()).isEqualTo(expectedUriString);
|
||||
|
@ -132,8 +133,9 @@ public class ManagedChannelImplGetNameResolverTest {
|
|||
NameResolverRegistry nameResolverRegistry = getTestRegistry("dns");
|
||||
|
||||
try {
|
||||
ManagedChannelImpl.ResolvedNameResolver resolved = ManagedChannelImpl.getNameResolverProvider(
|
||||
target, nameResolverRegistry, Collections.singleton(InetSocketAddress.class));
|
||||
ManagedChannelImplBuilder.ResolvedNameResolver resolved =
|
||||
ManagedChannelImplBuilder.getNameResolverProvider(
|
||||
target, nameResolverRegistry, Collections.singleton(InetSocketAddress.class));
|
||||
FakeNameResolverProvider nameResolverProvider = (FakeNameResolverProvider) resolved.provider;
|
||||
fail("Should have failed, but got resolver provider " + nameResolverProvider);
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
|
|
@ -61,6 +61,7 @@ import io.grpc.MethodDescriptor;
|
|||
import io.grpc.MethodDescriptor.MethodType;
|
||||
import io.grpc.NameResolver;
|
||||
import io.grpc.NameResolver.ResolutionResult;
|
||||
import io.grpc.NameResolverProvider;
|
||||
import io.grpc.Status;
|
||||
import io.grpc.StringMarshaller;
|
||||
import io.grpc.internal.FakeClock.ScheduledTask;
|
||||
|
@ -169,7 +170,9 @@ public class ManagedChannelImplIdlenessTest {
|
|||
when(mockTransportFactory.getSupportedSocketAddressTypes())
|
||||
.thenReturn(Collections.singleton(InetSocketAddress.class));
|
||||
|
||||
ManagedChannelImplBuilder builder = new ManagedChannelImplBuilder("mockscheme:///target",
|
||||
String target = "mockscheme:///target";
|
||||
URI targetUri = URI.create(target);
|
||||
ManagedChannelImplBuilder builder = new ManagedChannelImplBuilder(target,
|
||||
new UnsupportedClientTransportFactoryBuilder(), null);
|
||||
|
||||
builder
|
||||
|
@ -178,8 +181,11 @@ public class ManagedChannelImplIdlenessTest {
|
|||
.idleTimeout(IDLE_TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||
.userAgent(USER_AGENT);
|
||||
builder.executorPool = executorPool;
|
||||
NameResolverProvider nameResolverProvider =
|
||||
builder.nameResolverRegistry.getProviderForScheme(targetUri.getScheme());
|
||||
channel = new ManagedChannelImpl(
|
||||
builder, mockTransportFactory, new FakeBackoffPolicyProvider(),
|
||||
builder, mockTransportFactory, targetUri, nameResolverProvider,
|
||||
new FakeBackoffPolicyProvider(),
|
||||
oobExecutorPool, timer.getStopwatchSupplier(),
|
||||
Collections.<ClientInterceptor>emptyList(),
|
||||
TimeProvider.SYSTEM_TIME_PROVIDER);
|
||||
|
|
|
@ -310,8 +310,11 @@ public class ManagedChannelImplTest {
|
|||
|
||||
when(mockTransportFactory.getSupportedSocketAddressTypes()).thenReturn(Collections.singleton(
|
||||
InetSocketAddress.class));
|
||||
NameResolverProvider nameResolverProvider =
|
||||
channelBuilder.nameResolverRegistry.getProviderForScheme(expectedUri.getScheme());
|
||||
channel = new ManagedChannelImpl(
|
||||
channelBuilder, mockTransportFactory, new FakeBackoffPolicyProvider(),
|
||||
channelBuilder, mockTransportFactory, expectedUri, nameResolverProvider,
|
||||
new FakeBackoffPolicyProvider(),
|
||||
balancerRpcExecutorPool, timer.getStopwatchSupplier(), Arrays.asList(interceptors),
|
||||
timer.getTimeProvider());
|
||||
|
||||
|
@ -499,7 +502,8 @@ public class ManagedChannelImplTest {
|
|||
when(mockTransportFactory.getSupportedSocketAddressTypes()).thenReturn(Collections.singleton(
|
||||
InetSocketAddress.class));
|
||||
channel = new ManagedChannelImpl(
|
||||
channelBuilder, mockTransportFactory, new FakeBackoffPolicyProvider(),
|
||||
channelBuilder, mockTransportFactory, expectedUri, nameResolverFactory,
|
||||
new FakeBackoffPolicyProvider(),
|
||||
balancerRpcExecutorPool, timer.getStopwatchSupplier(),
|
||||
Collections.<ClientInterceptor>emptyList(), timer.getTimeProvider());
|
||||
Map<String, Object> rawServiceConfig =
|
||||
|
@ -563,7 +567,8 @@ public class ManagedChannelImplTest {
|
|||
when(mockTransportFactory.getSupportedSocketAddressTypes()).thenReturn(Collections.singleton(
|
||||
InetSocketAddress.class));
|
||||
channel = new ManagedChannelImpl(
|
||||
channelBuilder, mockTransportFactory, new FakeBackoffPolicyProvider(),
|
||||
channelBuilder, mockTransportFactory, expectedUri, nameResolverFactory,
|
||||
new FakeBackoffPolicyProvider(),
|
||||
balancerRpcExecutorPool, timer.getStopwatchSupplier(),
|
||||
Collections.<ClientInterceptor>emptyList(), timer.getTimeProvider());
|
||||
nameResolverFactory.nextConfigOrError.set(
|
||||
|
@ -2181,16 +2186,6 @@ public class ManagedChannelImplTest {
|
|||
assertEquals(expectedRefreshCount, resolver.refreshCalled);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uriPattern() {
|
||||
assertTrue(ManagedChannelImpl.URI_PATTERN.matcher("a:/").matches());
|
||||
assertTrue(ManagedChannelImpl.URI_PATTERN.matcher("Z019+-.:/!@ #~ ").matches());
|
||||
assertFalse(ManagedChannelImpl.URI_PATTERN.matcher("a/:").matches()); // "/:" not matched
|
||||
assertFalse(ManagedChannelImpl.URI_PATTERN.matcher("0a:/").matches()); // '0' not matched
|
||||
assertFalse(ManagedChannelImpl.URI_PATTERN.matcher("a,:/").matches()); // ',' not matched
|
||||
assertFalse(ManagedChannelImpl.URI_PATTERN.matcher(" a:/").matches()); // space not matched
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that information such as the Call's context, MethodDescriptor, authority, executor are
|
||||
* propagated to newStream() and applyRequestMetadata().
|
||||
|
@ -4429,7 +4424,7 @@ public class ManagedChannelImplTest {
|
|||
}
|
||||
}
|
||||
|
||||
private static final class FakeNameResolverFactory extends NameResolver.Factory {
|
||||
private static final class FakeNameResolverFactory extends NameResolverProvider {
|
||||
final List<URI> expectedUris;
|
||||
final List<EquivalentAddressGroup> servers;
|
||||
final boolean resolvedAtStart;
|
||||
|
@ -4466,6 +4461,16 @@ public class ManagedChannelImplTest {
|
|||
return "fake";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return 9;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void allResolved() {
|
||||
for (FakeNameResolverFactory.FakeNameResolver resolver : resolvers) {
|
||||
resolver.resolved();
|
||||
|
|
|
@ -45,6 +45,7 @@ import io.grpc.LoadBalancerProvider;
|
|||
import io.grpc.LoadBalancerRegistry;
|
||||
import io.grpc.NameResolver;
|
||||
import io.grpc.NameResolver.ConfigOrError;
|
||||
import io.grpc.NameResolverProvider;
|
||||
import io.grpc.Status;
|
||||
import io.grpc.internal.ManagedChannelImplBuilder.FixedPortProvider;
|
||||
import io.grpc.internal.ManagedChannelImplBuilder.UnsupportedClientTransportFactoryBuilder;
|
||||
|
@ -161,10 +162,14 @@ public class ServiceConfigErrorHandlingTest {
|
|||
|
||||
when(mockTransportFactory.getSupportedSocketAddressTypes()).thenReturn(Collections.singleton(
|
||||
InetSocketAddress.class));
|
||||
NameResolverProvider nameResolverProvider =
|
||||
channelBuilder.nameResolverRegistry.getProviderForScheme(expectedUri.getScheme());
|
||||
channel =
|
||||
new ManagedChannelImpl(
|
||||
channelBuilder,
|
||||
mockTransportFactory,
|
||||
expectedUri,
|
||||
nameResolverProvider,
|
||||
new FakeBackoffPolicyProvider(),
|
||||
balancerRpcExecutorPool,
|
||||
timer.getStopwatchSupplier(),
|
||||
|
|
Loading…
Reference in New Issue