mirror of https://github.com/grpc/grpc-java.git
c2p resolver: use federation if enabled via env var (#9660)
This commit is contained in:
parent
47ddfa4f20
commit
a97db60fd7
|
|
@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.io.CharStreams;
|
import com.google.common.io.CharStreams;
|
||||||
|
|
@ -54,6 +55,7 @@ final class GoogleCloudToProdNameResolver extends NameResolver {
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final String METADATA_URL_SUPPORT_IPV6 =
|
static final String METADATA_URL_SUPPORT_IPV6 =
|
||||||
"http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ipv6s";
|
"http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ipv6s";
|
||||||
|
static final String C2P_AUTHORITY = "traffic-director-c2p.xds.googleapis.com";
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static boolean isOnGcp = InternalCheckGcpEnvironment.isOnGcp();
|
static boolean isOnGcp = InternalCheckGcpEnvironment.isOnGcp();
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
|
@ -62,6 +64,10 @@ final class GoogleCloudToProdNameResolver extends NameResolver {
|
||||||
|| System.getProperty("io.grpc.xds.bootstrap") != null
|
|| System.getProperty("io.grpc.xds.bootstrap") != null
|
||||||
|| System.getenv("GRPC_XDS_BOOTSTRAP_CONFIG") != null
|
|| System.getenv("GRPC_XDS_BOOTSTRAP_CONFIG") != null
|
||||||
|| System.getProperty("io.grpc.xds.bootstrapConfig") != null;
|
|| System.getProperty("io.grpc.xds.bootstrapConfig") != null;
|
||||||
|
@VisibleForTesting
|
||||||
|
static boolean enableFederation =
|
||||||
|
!Strings.isNullOrEmpty(System.getenv("GRPC_EXPERIMENTAL_XDS_FEDERATION"))
|
||||||
|
&& Boolean.parseBoolean(System.getenv("GRPC_EXPERIMENTAL_XDS_FEDERATION"));
|
||||||
|
|
||||||
private static final String serverUriOverride =
|
private static final String serverUriOverride =
|
||||||
System.getenv("GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI");
|
System.getenv("GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI");
|
||||||
|
|
@ -76,7 +82,10 @@ final class GoogleCloudToProdNameResolver extends NameResolver {
|
||||||
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.
|
||||||
private final String schemeOverride = !isOnGcp || xdsBootstrapProvided ? "dns" : "xds";
|
private final String schemeOverride =
|
||||||
|
!isOnGcp
|
||||||
|
|| (xdsBootstrapProvided && !enableFederation)
|
||||||
|
? "dns" : "xds";
|
||||||
private Executor executor;
|
private Executor executor;
|
||||||
private Listener2 listener;
|
private Listener2 listener;
|
||||||
private boolean succeeded;
|
private boolean succeeded;
|
||||||
|
|
@ -103,8 +112,12 @@ final class GoogleCloudToProdNameResolver extends NameResolver {
|
||||||
targetUri);
|
targetUri);
|
||||||
authority = GrpcUtil.checkAuthority(targetPath.substring(1));
|
authority = GrpcUtil.checkAuthority(targetPath.substring(1));
|
||||||
syncContext = checkNotNull(args, "args").getSynchronizationContext();
|
syncContext = checkNotNull(args, "args").getSynchronizationContext();
|
||||||
|
targetUri = overrideUriScheme(targetUri, schemeOverride);
|
||||||
|
if (schemeOverride.equals("xds") && enableFederation) {
|
||||||
|
targetUri = overrideUriAuthority(targetUri, C2P_AUTHORITY);
|
||||||
|
}
|
||||||
delegate = checkNotNull(nameResolverFactory, "nameResolverFactory").newNameResolver(
|
delegate = checkNotNull(nameResolverFactory, "nameResolverFactory").newNameResolver(
|
||||||
overrideUriScheme(targetUri, schemeOverride), args);
|
targetUri, args);
|
||||||
executor = args.getOffloadExecutor();
|
executor = args.getOffloadExecutor();
|
||||||
usingExecutorResource = executor == null;
|
usingExecutorResource = executor == null;
|
||||||
}
|
}
|
||||||
|
|
@ -193,7 +206,7 @@ final class GoogleCloudToProdNameResolver extends NameResolver {
|
||||||
serverBuilder.put("server_features", ImmutableList.of("xds_v3"));
|
serverBuilder.put("server_features", ImmutableList.of("xds_v3"));
|
||||||
ImmutableMap.Builder<String, Object> authoritiesBuilder = ImmutableMap.builder();
|
ImmutableMap.Builder<String, Object> authoritiesBuilder = ImmutableMap.builder();
|
||||||
authoritiesBuilder.put(
|
authoritiesBuilder.put(
|
||||||
"traffic-director-c2p.xds.googleapis.com",
|
C2P_AUTHORITY,
|
||||||
ImmutableMap.of("xds_servers", ImmutableList.of(serverBuilder.buildOrThrow())));
|
ImmutableMap.of("xds_servers", ImmutableList.of(serverBuilder.buildOrThrow())));
|
||||||
return ImmutableMap.of(
|
return ImmutableMap.of(
|
||||||
"node", nodeBuilder.buildOrThrow(),
|
"node", nodeBuilder.buildOrThrow(),
|
||||||
|
|
@ -271,6 +284,16 @@ final class GoogleCloudToProdNameResolver extends NameResolver {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static URI overrideUriAuthority(URI uri, String authority) {
|
||||||
|
URI res;
|
||||||
|
try {
|
||||||
|
res = new URI(uri.getScheme(), authority, uri.getPath(), uri.getQuery(), uri.getFragment());
|
||||||
|
} catch (URISyntaxException ex) {
|
||||||
|
throw new IllegalArgumentException("Invalid authority: " + authority, ex);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
private enum HttpConnectionFactory implements HttpConnectionProvider {
|
private enum HttpConnectionFactory implements HttpConnectionProvider {
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ public class GoogleCloudToProdNameResolverTest {
|
||||||
@Rule
|
@Rule
|
||||||
public final MockitoRule mocks = MockitoJUnit.rule();
|
public final MockitoRule mocks = MockitoJUnit.rule();
|
||||||
|
|
||||||
private static final URI TARGET_URI = URI.create("google-c2p-experimental:///googleapis.com");
|
private static final URI TARGET_URI = URI.create("google-c2p:///googleapis.com");
|
||||||
private static final String ZONE = "us-central1-a";
|
private static final String ZONE = "us-central1-a";
|
||||||
private static final int DEFAULT_PORT = 887;
|
private static final int DEFAULT_PORT = 887;
|
||||||
|
|
||||||
|
|
@ -187,6 +187,40 @@ public class GoogleCloudToProdNameResolverTest {
|
||||||
"server_uri", "directpath-pa.googleapis.com",
|
"server_uri", "directpath-pa.googleapis.com",
|
||||||
"channel_creds", ImmutableList.of(ImmutableMap.of("type", "google_default")),
|
"channel_creds", ImmutableList.of(ImmutableMap.of("type", "google_default")),
|
||||||
"server_features", ImmutableList.of("xds_v3"));
|
"server_features", ImmutableList.of("xds_v3"));
|
||||||
|
Map<String, ?> authorities = (Map<String, ?>) bootstrap.get("authorities");
|
||||||
|
assertThat(authorities).containsExactly(
|
||||||
|
"traffic-director-c2p.xds.googleapis.com",
|
||||||
|
ImmutableMap.of("xds_servers", ImmutableList.of(server)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
public void onGcpAndProvidedBootstrapAndFederationEnabledDelegateToXds() {
|
||||||
|
GoogleCloudToProdNameResolver.isOnGcp = true;
|
||||||
|
GoogleCloudToProdNameResolver.xdsBootstrapProvided = true;
|
||||||
|
GoogleCloudToProdNameResolver.enableFederation = true;
|
||||||
|
createResolver();
|
||||||
|
resolver.start(mockListener);
|
||||||
|
fakeExecutor.runDueTasks();
|
||||||
|
assertThat(delegatedResolver.keySet()).containsExactly("xds");
|
||||||
|
verify(Iterables.getOnlyElement(delegatedResolver.values())).start(mockListener);
|
||||||
|
// check bootstrap
|
||||||
|
Map<String, ?> bootstrap = fakeBootstrapSetter.bootstrapRef.get();
|
||||||
|
Map<String, ?> node = (Map<String, ?>) bootstrap.get("node");
|
||||||
|
assertThat(node).containsExactly(
|
||||||
|
"id", "C2P-991614323",
|
||||||
|
"locality", ImmutableMap.of("zone", ZONE),
|
||||||
|
"metadata", ImmutableMap.of("TRAFFICDIRECTOR_DIRECTPATH_C2P_IPV6_CAPABLE", true));
|
||||||
|
Map<String, ?> server = Iterables.getOnlyElement(
|
||||||
|
(List<Map<String, ?>>) bootstrap.get("xds_servers"));
|
||||||
|
assertThat(server).containsExactly(
|
||||||
|
"server_uri", "directpath-pa.googleapis.com",
|
||||||
|
"channel_creds", ImmutableList.of(ImmutableMap.of("type", "google_default")),
|
||||||
|
"server_features", ImmutableList.of("xds_v3"));
|
||||||
|
Map<String, ?> authorities = (Map<String, ?>) bootstrap.get("authorities");
|
||||||
|
assertThat(authorities).containsExactly(
|
||||||
|
"traffic-director-c2p.xds.googleapis.com",
|
||||||
|
ImmutableMap.of("xds_servers", ImmutableList.of(server)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue