xds: append a random number to C2P generated node id (#8239)

Adding a random number to the xDS stream node id helps debugging for distinguishing between different clients.
This commit is contained in:
Chengyuan Zhang 2021-06-07 11:01:04 -07:00 committed by GitHub
parent 4209c8d8cc
commit e51a17574f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 6 deletions

View File

@ -40,6 +40,7 @@ import java.net.HttpURLConnection;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.util.Random;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
/** /**
@ -71,6 +72,7 @@ final class GoogleCloudToProdNameResolver extends NameResolver {
private final Resource<Executor> executorResource; private final Resource<Executor> executorResource;
private final XdsClientPoolFactory xdsClientPoolFactory; private final XdsClientPoolFactory xdsClientPoolFactory;
private final NameResolver delegate; private final NameResolver delegate;
private final Random rand;
private final boolean usingExecutorResource; private final boolean usingExecutorResource;
// It's not possible to use both PSM and DirectPath C2P in the same application. // It's not possible to use both PSM and DirectPath C2P in the same application.
// Delegate to DNS if user-provided bootstrap is found. // Delegate to DNS if user-provided bootstrap is found.
@ -83,15 +85,17 @@ final class GoogleCloudToProdNameResolver extends NameResolver {
GoogleCloudToProdNameResolver(URI targetUri, Args args, Resource<Executor> executorResource, GoogleCloudToProdNameResolver(URI targetUri, Args args, Resource<Executor> executorResource,
XdsClientPoolFactory xdsClientPoolFactory) { XdsClientPoolFactory xdsClientPoolFactory) {
this(targetUri, args, executorResource, xdsClientPoolFactory, this(targetUri, args, executorResource, new Random(), xdsClientPoolFactory,
NameResolverRegistry.getDefaultRegistry().asFactory()); NameResolverRegistry.getDefaultRegistry().asFactory());
} }
@VisibleForTesting @VisibleForTesting
GoogleCloudToProdNameResolver(URI targetUri, Args args, Resource<Executor> executorResource, GoogleCloudToProdNameResolver(URI targetUri, Args args, Resource<Executor> executorResource,
XdsClientPoolFactory xdsClientPoolFactory, NameResolver.Factory nameResolverFactory) { Random rand, XdsClientPoolFactory xdsClientPoolFactory,
NameResolver.Factory nameResolverFactory) {
this.executorResource = checkNotNull(executorResource, "executorResource"); this.executorResource = checkNotNull(executorResource, "executorResource");
this.xdsClientPoolFactory = checkNotNull(xdsClientPoolFactory, "xdsClientPoolFactory"); this.xdsClientPoolFactory = checkNotNull(xdsClientPoolFactory, "xdsClientPoolFactory");
this.rand = checkNotNull(rand, "rand");
String targetPath = checkNotNull(checkNotNull(targetUri, "targetUri").getPath(), "targetPath"); String targetPath = checkNotNull(checkNotNull(targetUri, "targetUri").getPath(), "targetPath");
Preconditions.checkArgument( Preconditions.checkArgument(
targetPath.startsWith("/"), targetPath.startsWith("/"),
@ -169,9 +173,9 @@ final class GoogleCloudToProdNameResolver extends NameResolver {
executor.execute(new Resolve()); executor.execute(new Resolve());
} }
private static ImmutableMap<String, ?> generateBootstrap(String zone, boolean supportIpv6) { private ImmutableMap<String, ?> generateBootstrap(String zone, boolean supportIpv6) {
ImmutableMap.Builder<String, Object> nodeBuilder = ImmutableMap.builder(); ImmutableMap.Builder<String, Object> nodeBuilder = ImmutableMap.builder();
nodeBuilder.put("id", "C2P"); nodeBuilder.put("id", "C2P-" + rand.nextInt());
if (!zone.isEmpty()) { if (!zone.isEmpty()) {
nodeBuilder.put("locality", ImmutableMap.of("zone", zone)); nodeBuilder.put("locality", ImmutableMap.of("zone", zone));
} }

View File

@ -47,6 +47,7 @@ import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -103,6 +104,8 @@ public class GoogleCloudToProdNameResolverTest {
@Mock @Mock
private NameResolver.Listener2 mockListener; private NameResolver.Listener2 mockListener;
@Mock
private Random mockRandom;
@Captor @Captor
private ArgumentCaptor<Status> errorCaptor; private ArgumentCaptor<Status> errorCaptor;
private boolean originalIsOnGcp; private boolean originalIsOnGcp;
@ -111,6 +114,7 @@ public class GoogleCloudToProdNameResolverTest {
@Before @Before
public void setUp() { public void setUp() {
when(mockRandom.nextInt()).thenReturn(123456789);
nsRegistry.register(new FakeNsProvider("dns")); nsRegistry.register(new FakeNsProvider("dns"));
nsRegistry.register(new FakeNsProvider("xds")); nsRegistry.register(new FakeNsProvider("xds"));
originalIsOnGcp = GoogleCloudToProdNameResolver.isOnGcp; originalIsOnGcp = GoogleCloudToProdNameResolver.isOnGcp;
@ -142,7 +146,8 @@ public class GoogleCloudToProdNameResolverTest {
} }
}; };
resolver = new GoogleCloudToProdNameResolver( resolver = new GoogleCloudToProdNameResolver(
TARGET_URI, args, fakeExecutorResource, fakeXdsClientPoolFactory, nsRegistry.asFactory()); TARGET_URI, args, fakeExecutorResource, mockRandom, fakeXdsClientPoolFactory,
nsRegistry.asFactory());
resolver.setHttpConnectionProvider(httpConnections); resolver.setHttpConnectionProvider(httpConnections);
} }
@ -178,7 +183,8 @@ public class GoogleCloudToProdNameResolverTest {
Map<String, ?> bootstrap = fakeXdsClientPoolFactory.bootstrapRef.get(); Map<String, ?> bootstrap = fakeXdsClientPoolFactory.bootstrapRef.get();
Map<String, ?> node = (Map<String, ?>) bootstrap.get("node"); Map<String, ?> node = (Map<String, ?>) bootstrap.get("node");
assertThat(node).containsExactly( assertThat(node).containsExactly(
"id", "C2P", "locality", ImmutableMap.of("zone", ZONE), "id", "C2P-123456789",
"locality", ImmutableMap.of("zone", ZONE),
"metadata", ImmutableMap.of("TRAFFICDIRECTOR_DIRECTPATH_C2P_IPV6_CAPABLE", true)); "metadata", ImmutableMap.of("TRAFFICDIRECTOR_DIRECTPATH_C2P_IPV6_CAPABLE", true));
Map<String, ?> server = Iterables.getOnlyElement( Map<String, ?> server = Iterables.getOnlyElement(
(List<Map<String, ?>>) bootstrap.get("xds_servers")); (List<Map<String, ?>>) bootstrap.get("xds_servers"));