mirror of https://github.com/grpc/grpc-java.git
xds: allow injecting bootstrapOverride in xdsNameResolverProvider (#8358)
This commit is contained in:
parent
96a5c25056
commit
1eb1d157a7
|
|
@ -52,7 +52,7 @@ final class SharedXdsClientPoolProvider implements XdsClientPoolFactory {
|
||||||
private final AtomicReference<Map<String, ?>> bootstrapOverride = new AtomicReference<>();
|
private final AtomicReference<Map<String, ?>> bootstrapOverride = new AtomicReference<>();
|
||||||
private volatile ObjectPool<XdsClient> xdsClientPool;
|
private volatile ObjectPool<XdsClient> xdsClientPool;
|
||||||
|
|
||||||
private SharedXdsClientPoolProvider() {
|
SharedXdsClientPoolProvider() {
|
||||||
this(new BootstrapperImpl());
|
this(new BootstrapperImpl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,22 +124,25 @@ final class XdsNameResolver extends NameResolver {
|
||||||
private ResolveState resolveState;
|
private ResolveState resolveState;
|
||||||
|
|
||||||
XdsNameResolver(String name, ServiceConfigParser serviceConfigParser,
|
XdsNameResolver(String name, ServiceConfigParser serviceConfigParser,
|
||||||
SynchronizationContext syncContext, ScheduledExecutorService scheduler) {
|
SynchronizationContext syncContext, ScheduledExecutorService scheduler,
|
||||||
|
@Nullable Map<String, ?> bootstrapOverride) {
|
||||||
this(name, serviceConfigParser, syncContext, scheduler,
|
this(name, serviceConfigParser, syncContext, scheduler,
|
||||||
SharedXdsClientPoolProvider.getDefaultProvider(), ThreadSafeRandomImpl.instance,
|
SharedXdsClientPoolProvider.getDefaultProvider(), ThreadSafeRandomImpl.instance,
|
||||||
FilterRegistry.getDefaultRegistry());
|
FilterRegistry.getDefaultRegistry(), bootstrapOverride);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
XdsNameResolver(String name, ServiceConfigParser serviceConfigParser,
|
XdsNameResolver(String name, ServiceConfigParser serviceConfigParser,
|
||||||
SynchronizationContext syncContext, ScheduledExecutorService scheduler,
|
SynchronizationContext syncContext, ScheduledExecutorService scheduler,
|
||||||
XdsClientPoolFactory xdsClientPoolFactory, ThreadSafeRandom random,
|
XdsClientPoolFactory xdsClientPoolFactory, ThreadSafeRandom random,
|
||||||
FilterRegistry filterRegistry) {
|
FilterRegistry filterRegistry, @Nullable Map<String, ?> bootstrapOverride) {
|
||||||
authority = GrpcUtil.checkAuthority(checkNotNull(name, "name"));
|
authority = GrpcUtil.checkAuthority(checkNotNull(name, "name"));
|
||||||
this.serviceConfigParser = checkNotNull(serviceConfigParser, "serviceConfigParser");
|
this.serviceConfigParser = checkNotNull(serviceConfigParser, "serviceConfigParser");
|
||||||
this.syncContext = checkNotNull(syncContext, "syncContext");
|
this.syncContext = checkNotNull(syncContext, "syncContext");
|
||||||
this.scheduler = checkNotNull(scheduler, "scheduler");
|
this.scheduler = checkNotNull(scheduler, "scheduler");
|
||||||
this.xdsClientPoolFactory = checkNotNull(xdsClientPoolFactory, "xdsClientPoolFactory");
|
this.xdsClientPoolFactory = bootstrapOverride == null ? checkNotNull(xdsClientPoolFactory,
|
||||||
|
"xdsClientPoolFactory") : new SharedXdsClientPoolProvider();
|
||||||
|
this.xdsClientPoolFactory.setBootstrapOverride(bootstrapOverride);
|
||||||
this.random = checkNotNull(random, "random");
|
this.random = checkNotNull(random, "random");
|
||||||
this.filterRegistry = checkNotNull(filterRegistry, "filterRegistry");
|
this.filterRegistry = checkNotNull(filterRegistry, "filterRegistry");
|
||||||
logId = InternalLogId.allocate("xds-resolver", name);
|
logId = InternalLogId.allocate("xds-resolver", name);
|
||||||
|
|
|
||||||
|
|
@ -42,10 +42,31 @@ import javax.annotation.Nullable;
|
||||||
public final class XdsNameResolverProvider extends NameResolverProvider {
|
public final class XdsNameResolverProvider extends NameResolverProvider {
|
||||||
|
|
||||||
private static final String SCHEME = "xds";
|
private static final String SCHEME = "xds";
|
||||||
|
private final String scheme;
|
||||||
|
private final Map<String, ?> bootstrapOverride;
|
||||||
|
|
||||||
|
public XdsNameResolverProvider() {
|
||||||
|
this(SCHEME, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private XdsNameResolverProvider(String scheme,
|
||||||
|
@Nullable Map<String, ?> bootstrapOverride) {
|
||||||
|
this.scheme = checkNotNull(scheme, "scheme");
|
||||||
|
this.bootstrapOverride = bootstrapOverride;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenient method to allow creating a {@link XdsNameResolverProvider} with custom scheme
|
||||||
|
* and bootstrap.
|
||||||
|
*/
|
||||||
|
public static XdsNameResolverProvider createForTest(String scheme,
|
||||||
|
@Nullable Map<String, ?> bootstrapOverride) {
|
||||||
|
return new XdsNameResolverProvider(scheme, bootstrapOverride);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XdsNameResolver newNameResolver(URI targetUri, Args args) {
|
public XdsNameResolver newNameResolver(URI targetUri, Args args) {
|
||||||
if (SCHEME.equals(targetUri.getScheme())) {
|
if (scheme.equals(targetUri.getScheme())) {
|
||||||
String targetPath = checkNotNull(targetUri.getPath(), "targetPath");
|
String targetPath = checkNotNull(targetUri.getPath(), "targetPath");
|
||||||
Preconditions.checkArgument(
|
Preconditions.checkArgument(
|
||||||
targetPath.startsWith("/"),
|
targetPath.startsWith("/"),
|
||||||
|
|
@ -54,14 +75,15 @@ public final class XdsNameResolverProvider extends NameResolverProvider {
|
||||||
targetUri);
|
targetUri);
|
||||||
String name = targetPath.substring(1);
|
String name = targetPath.substring(1);
|
||||||
return new XdsNameResolver(name, args.getServiceConfigParser(),
|
return new XdsNameResolver(name, args.getServiceConfigParser(),
|
||||||
args.getSynchronizationContext(), args.getScheduledExecutorService());
|
args.getSynchronizationContext(), args.getScheduledExecutorService(),
|
||||||
|
bootstrapOverride);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDefaultScheme() {
|
public String getDefaultScheme() {
|
||||||
return SCHEME;
|
return scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -20,15 +20,20 @@ import static com.google.common.truth.Truth.assertThat;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import io.grpc.ChannelLogger;
|
import io.grpc.ChannelLogger;
|
||||||
import io.grpc.InternalServiceProviders;
|
import io.grpc.InternalServiceProviders;
|
||||||
import io.grpc.NameResolver;
|
import io.grpc.NameResolver;
|
||||||
import io.grpc.NameResolver.ServiceConfigParser;
|
import io.grpc.NameResolver.ServiceConfigParser;
|
||||||
import io.grpc.NameResolverProvider;
|
import io.grpc.NameResolverProvider;
|
||||||
|
import io.grpc.NameResolverRegistry;
|
||||||
import io.grpc.SynchronizationContext;
|
import io.grpc.SynchronizationContext;
|
||||||
import io.grpc.internal.FakeClock;
|
import io.grpc.internal.FakeClock;
|
||||||
import io.grpc.internal.GrpcUtil;
|
import io.grpc.internal.GrpcUtil;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.JUnit4;
|
import org.junit.runners.JUnit4;
|
||||||
|
|
@ -114,4 +119,54 @@ public class XdsNameResolverProviderTest {
|
||||||
// Expected
|
// Expected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void newProvider_multipleScheme() {
|
||||||
|
NameResolverRegistry registry = NameResolverRegistry.getDefaultRegistry();
|
||||||
|
XdsNameResolverProvider provider0 = XdsNameResolverProvider.createForTest("no-scheme", null);
|
||||||
|
registry.register(provider0);
|
||||||
|
XdsNameResolverProvider provider1 = XdsNameResolverProvider.createForTest("new-xds-scheme",
|
||||||
|
new HashMap<String, String>());
|
||||||
|
registry.register(provider1);
|
||||||
|
assertThat(registry.asFactory()
|
||||||
|
.newNameResolver(URI.create("xds:///localhost"), args)).isNotNull();
|
||||||
|
assertThat(registry.asFactory()
|
||||||
|
.newNameResolver(URI.create("new-xds-scheme:///localhost"), args)).isNotNull();
|
||||||
|
assertThat(registry.asFactory()
|
||||||
|
.newNameResolver(URI.create("no-scheme:///localhost"), args)).isNotNull();
|
||||||
|
registry.deregister(provider1);
|
||||||
|
assertThat(registry.asFactory()
|
||||||
|
.newNameResolver(URI.create("new-xds-scheme:///localhost"), args)).isNull();
|
||||||
|
registry.deregister(provider0);
|
||||||
|
assertThat(registry.asFactory()
|
||||||
|
.newNameResolver(URI.create("xds:///localhost"), args)).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void newProvider_overrideBootstrap() {
|
||||||
|
Map<String, ?> b = ImmutableMap.of(
|
||||||
|
"node", ImmutableMap.of(
|
||||||
|
"id", "ENVOY_NODE_ID",
|
||||||
|
"cluster", "ENVOY_CLUSTER"),
|
||||||
|
"xds_servers", Collections.singletonList(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"server_uri", "trafficdirector.googleapis.com:443",
|
||||||
|
"channel_creds", Collections.singletonList(
|
||||||
|
ImmutableMap.of("type", "insecure")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
NameResolverRegistry registry = new NameResolverRegistry();
|
||||||
|
XdsNameResolverProvider provider = XdsNameResolverProvider.createForTest("no-scheme", b);
|
||||||
|
registry.register(provider);
|
||||||
|
NameResolver resolver = registry.asFactory()
|
||||||
|
.newNameResolver(URI.create("no-scheme:///localhost"), args);
|
||||||
|
resolver.start(mock(NameResolver.Listener2.class));
|
||||||
|
assertThat(resolver).isInstanceOf(XdsNameResolver.class);
|
||||||
|
assertThat(((XdsNameResolver)resolver).getXdsClient().getBootstrapInfo().getNode().getId())
|
||||||
|
.isEqualTo("ENVOY_NODE_ID");
|
||||||
|
resolver.shutdown();
|
||||||
|
registry.deregister(provider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ public class XdsNameResolverTest {
|
||||||
new FaultFilter(mockRandom, new AtomicLong()),
|
new FaultFilter(mockRandom, new AtomicLong()),
|
||||||
RouterFilter.INSTANCE);
|
RouterFilter.INSTANCE);
|
||||||
resolver = new XdsNameResolver(AUTHORITY, serviceConfigParser, syncContext, scheduler,
|
resolver = new XdsNameResolver(AUTHORITY, serviceConfigParser, syncContext, scheduler,
|
||||||
xdsClientPoolFactory, mockRandom, filterRegistry);
|
xdsClientPoolFactory, mockRandom, filterRegistry, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|
@ -172,7 +172,6 @@ public class XdsNameResolverTest {
|
||||||
XdsClientPoolFactory xdsClientPoolFactory = new XdsClientPoolFactory() {
|
XdsClientPoolFactory xdsClientPoolFactory = new XdsClientPoolFactory() {
|
||||||
@Override
|
@Override
|
||||||
public void setBootstrapOverride(Map<String, ?> bootstrap) {
|
public void setBootstrapOverride(Map<String, ?> bootstrap) {
|
||||||
throw new UnsupportedOperationException("Should not be called");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -187,7 +186,7 @@ public class XdsNameResolverTest {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
resolver = new XdsNameResolver(AUTHORITY, serviceConfigParser, syncContext, scheduler,
|
resolver = new XdsNameResolver(AUTHORITY, serviceConfigParser, syncContext, scheduler,
|
||||||
xdsClientPoolFactory, mockRandom, FilterRegistry.getDefaultRegistry());
|
xdsClientPoolFactory, mockRandom, FilterRegistry.getDefaultRegistry(), null);
|
||||||
resolver.start(mockListener);
|
resolver.start(mockListener);
|
||||||
verify(mockListener).onError(errorCaptor.capture());
|
verify(mockListener).onError(errorCaptor.capture());
|
||||||
Status error = errorCaptor.getValue();
|
Status error = errorCaptor.getValue();
|
||||||
|
|
@ -437,7 +436,7 @@ public class XdsNameResolverTest {
|
||||||
ServiceConfigParser realParser = new ScParser(
|
ServiceConfigParser realParser = new ScParser(
|
||||||
true, 5, 5, new AutoConfiguredLoadBalancerFactory("pick-first"));
|
true, 5, 5, new AutoConfiguredLoadBalancerFactory("pick-first"));
|
||||||
resolver = new XdsNameResolver(AUTHORITY, realParser, syncContext, scheduler,
|
resolver = new XdsNameResolver(AUTHORITY, realParser, syncContext, scheduler,
|
||||||
xdsClientPoolFactory, mockRandom, FilterRegistry.getDefaultRegistry());
|
xdsClientPoolFactory, mockRandom, FilterRegistry.getDefaultRegistry(), null);
|
||||||
resolver.start(mockListener);
|
resolver.start(mockListener);
|
||||||
FakeXdsClient xdsClient = (FakeXdsClient) resolver.getXdsClient();
|
FakeXdsClient xdsClient = (FakeXdsClient) resolver.getXdsClient();
|
||||||
RetryPolicy retryPolicy = RetryPolicy.create(
|
RetryPolicy retryPolicy = RetryPolicy.create(
|
||||||
|
|
@ -640,7 +639,7 @@ public class XdsNameResolverTest {
|
||||||
resolver.shutdown();
|
resolver.shutdown();
|
||||||
reset(mockListener);
|
reset(mockListener);
|
||||||
resolver = new XdsNameResolver(AUTHORITY, serviceConfigParser, syncContext, scheduler,
|
resolver = new XdsNameResolver(AUTHORITY, serviceConfigParser, syncContext, scheduler,
|
||||||
xdsClientPoolFactory, mockRandom, FilterRegistry.getDefaultRegistry());
|
xdsClientPoolFactory, mockRandom, FilterRegistry.getDefaultRegistry(), null);
|
||||||
resolver.start(mockListener);
|
resolver.start(mockListener);
|
||||||
xdsClient = (FakeXdsClient) resolver.getXdsClient();
|
xdsClient = (FakeXdsClient) resolver.getXdsClient();
|
||||||
xdsClient.deliverLdsUpdate(
|
xdsClient.deliverLdsUpdate(
|
||||||
|
|
@ -1701,10 +1700,8 @@ public class XdsNameResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class FakeXdsClientPoolFactory implements XdsClientPoolFactory {
|
private final class FakeXdsClientPoolFactory implements XdsClientPoolFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBootstrapOverride(Map<String, ?> bootstrap) {
|
public void setBootstrapOverride(Map<String, ?> bootstrap) {
|
||||||
throw new UnsupportedOperationException("Should not be called");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue