Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xds: allow injecting bootstrapOverride in xdsNameResolverProvider #8358

Merged
merged 5 commits into from Aug 11, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -52,7 +52,7 @@ final class SharedXdsClientPoolProvider implements XdsClientPoolFactory {
private final AtomicReference<Map<String, ?>> bootstrapOverride = new AtomicReference<>();
private volatile ObjectPool<XdsClient> xdsClientPool;

private SharedXdsClientPoolProvider() {
SharedXdsClientPoolProvider() {
this(new BootstrapperImpl());
}

Expand Down
3 changes: 2 additions & 1 deletion xds/src/main/java/io/grpc/xds/XdsNameResolver.java
Expand Up @@ -140,7 +140,8 @@ final class XdsNameResolver extends NameResolver {
this.serviceConfigParser = checkNotNull(serviceConfigParser, "serviceConfigParser");
this.syncContext = checkNotNull(syncContext, "syncContext");
this.scheduler = checkNotNull(scheduler, "scheduler");
this.xdsClientPoolFactory = checkNotNull(xdsClientPoolFactory, "xdsClientPoolFactory");
this.xdsClientPoolFactory = bootstrapOverride == null ? checkNotNull(xdsClientPoolFactory,
"xdsClientPoolFactory") : new SharedXdsClientPoolProvider();
this.xdsClientPoolFactory.setBootstrapOverride(bootstrapOverride);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mutates the default factory, which would impact other xds clients. Create a new instance if bootstrapOverride is set.

this.random = checkNotNull(random, "random");
this.filterRegistry = checkNotNull(filterRegistry, "filterRegistry");
Expand Down
23 changes: 13 additions & 10 deletions xds/src/main/java/io/grpc/xds/XdsNameResolverProvider.java
Expand Up @@ -41,19 +41,22 @@
@Internal
public final class XdsNameResolverProvider extends NameResolverProvider {

private String scheme = "xds";
private Map<String, ?> bootstrapOverride;
private static final String SCHEME = "xds";
private final String scheme;
private final Map<String, ?> bootstrapOverride;

public XdsNameResolverProvider() {
this(SCHEME, null);
}

/**
* A convenient method to create a {@link XdsNameResolverProvider} with custom scheme and
* bootstrap.
* A convenient constructor to allow creating a {@link XdsNameResolverProvider} with custom scheme
* and bootstrap.
*/
public static XdsNameResolverProvider createForTest(String scheme,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had intended for the constructor to be private, and for us to still have the "for test" factory method to discourage it for other uses.

@Nullable Map<String, ?> bootstrapOverride) {
XdsNameResolverProvider provider = new XdsNameResolverProvider();
provider.scheme = checkNotNull(scheme, "scheme");
provider.bootstrapOverride = bootstrapOverride;
return provider;
public XdsNameResolverProvider(String scheme,
@Nullable Map<String, ?> bootstrapOverride) {
this.scheme = checkNotNull(scheme, "scheme");
this.bootstrapOverride = bootstrapOverride;
}

@Override
Expand Down
17 changes: 11 additions & 6 deletions xds/src/test/java/io/grpc/xds/XdsNameResolverProviderTest.java
Expand Up @@ -121,13 +121,15 @@ public void invalidName_hostnameContainsUnderscore() {
}

@Test
public void newProvider_createForTest() {
NameResolverRegistry registry = new NameResolverRegistry();
XdsNameResolverProvider provider0 = XdsNameResolverProvider.createForTest("no-scheme", null);
public void newProvider_multipleScheme() {
NameResolverRegistry registry = NameResolverRegistry.getDefaultRegistry();
XdsNameResolverProvider provider0 = new XdsNameResolverProvider("no-scheme", null);
registry.register(provider0);
XdsNameResolverProvider provider1 = XdsNameResolverProvider.createForTest("new-xds-scheme",
XdsNameResolverProvider provider1 = new XdsNameResolverProvider("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()
Expand All @@ -136,10 +138,12 @@ public void newProvider_createForTest() {
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_createForTest_overrideBootstrap() {
public void newProvider_overrideBootstrap() {
Map<String, ?> b = ImmutableMap.of(
"node", ImmutableMap.of(
"id", "ENVOY_NODE_ID",
Expand All @@ -154,14 +158,15 @@ public void newProvider_createForTest_overrideBootstrap() {
)
);
NameResolverRegistry registry = new NameResolverRegistry();
XdsNameResolverProvider provider = XdsNameResolverProvider.createForTest("no-scheme", b);
XdsNameResolverProvider provider = new XdsNameResolverProvider("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);
}
}
4 changes: 1 addition & 3 deletions xds/src/test/java/io/grpc/xds/XdsNameResolverTest.java
Expand Up @@ -83,7 +83,6 @@
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
Expand Down Expand Up @@ -186,9 +185,8 @@ public ObjectPool<XdsClient> getOrCreate() throws XdsInitializationException {
throw new XdsInitializationException("Fail to read bootstrap file");
}
};
Map<String, String> b = new HashMap<>();
resolver = new XdsNameResolver(AUTHORITY, serviceConfigParser, syncContext, scheduler,
xdsClientPoolFactory, mockRandom, FilterRegistry.getDefaultRegistry(), b);
xdsClientPoolFactory, mockRandom, FilterRegistry.getDefaultRegistry(), null);
resolver.start(mockListener);
verify(mockListener).onError(errorCaptor.capture());
Status error = errorCaptor.getValue();
Expand Down