From aebd1392213684adfc10728fae93c8fdb20202cf Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 29 Oct 2024 16:25:39 -0700 Subject: [PATCH 01/51] bump grpc versions. --- .cloudbuild/library_generation/library_generation.Dockerfile | 2 +- gapic-generator-java-pom-parent/pom.xml | 2 +- gax-java/dependencies.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.cloudbuild/library_generation/library_generation.Dockerfile b/.cloudbuild/library_generation/library_generation.Dockerfile index 9a5434bb33..2b1db9df70 100644 --- a/.cloudbuild/library_generation/library_generation.Dockerfile +++ b/.cloudbuild/library_generation/library_generation.Dockerfile @@ -34,7 +34,7 @@ SHELL [ "/bin/bash", "-c" ] ARG OWLBOT_CLI_COMMITTISH=38fe6f89a2339ee75c77739b31b371f601b01bb3 ARG PROTOC_VERSION=25.5 -ARG GRPC_VERSION=1.67.1 +ARG GRPC_VERSION=1.68.1 ARG JAVA_FORMAT_VERSION=1.7 ENV HOME=/home ENV OS_ARCHITECTURE="linux-x86_64" diff --git a/gapic-generator-java-pom-parent/pom.xml b/gapic-generator-java-pom-parent/pom.xml index 15eb60901d..1991f17d01 100644 --- a/gapic-generator-java-pom-parent/pom.xml +++ b/gapic-generator-java-pom-parent/pom.xml @@ -26,7 +26,7 @@ 1.3.2 - 1.67.1 + 1.68.1 1.29.0 1.45.0 2.11.0 diff --git a/gax-java/dependencies.properties b/gax-java/dependencies.properties index 6c6331f518..689a2f9d36 100644 --- a/gax-java/dependencies.properties +++ b/gax-java/dependencies.properties @@ -28,7 +28,7 @@ version.gax_httpjson=2.57.1-SNAPSHOT version.com_google_protobuf=3.25.5 version.google_java_format=1.15.0 -version.io_grpc=1.67.1 +version.io_grpc=1.68.1 # Maven artifacts. # Note, the actual name of each property matters (bazel build scripts depend on it). From b45693530d0747b273d36b9a72fade6d42a7ab60 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 29 Oct 2024 16:34:45 -0700 Subject: [PATCH 02/51] bump auth to local SNAPSHOT. --- gapic-generator-java-pom-parent/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gapic-generator-java-pom-parent/pom.xml b/gapic-generator-java-pom-parent/pom.xml index 1991f17d01..4560e43dc8 100644 --- a/gapic-generator-java-pom-parent/pom.xml +++ b/gapic-generator-java-pom-parent/pom.xml @@ -27,7 +27,7 @@ consistent across modules in this repository --> 1.3.2 1.68.1 - 1.29.0 + 1.29.1-SNAPSHOT 1.45.0 2.11.0 33.3.1-jre From 3510643ba45abad49152fbb168a186de022de58b Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Fri, 1 Nov 2024 07:59:10 -0700 Subject: [PATCH 03/51] implementation. --- gapic-generator-java/pom.xml | 2 + gax-java/gax-grpc/BUILD.bazel | 1 + gax-java/gax-grpc/pom.xml | 4 + .../InstantiatingGrpcChannelProvider.java | 139 +++++++++++++++++- .../grpc/testing/LocalChannelProvider.java | 10 ++ .../InstantiatingHttpJsonChannelProvider.java | 11 ++ gax-java/gax/clirr-ignored-differences.xml | 5 + .../com/google/api/gax/rpc/ClientContext.java | 4 + .../rpc/FixedTransportChannelProvider.java | 11 ++ .../api/gax/rpc/TransportChannelProvider.java | 10 ++ .../google/api/gax/rpc/ClientContextTest.java | 119 +++++++++++---- 11 files changed, 285 insertions(+), 31 deletions(-) diff --git a/gapic-generator-java/pom.xml b/gapic-generator-java/pom.xml index 37fa43c5b2..f98f297358 100644 --- a/gapic-generator-java/pom.xml +++ b/gapic-generator-java/pom.xml @@ -397,10 +397,12 @@ com.google.api gax-grpc + 2.57.1-SNAPSHOT com.google.api gax-grpc + 2.57.1-SNAPSHOT test-jar testlib diff --git a/gax-java/gax-grpc/BUILD.bazel b/gax-java/gax-grpc/BUILD.bazel index be224ff3f8..69db44c7a4 100644 --- a/gax-java/gax-grpc/BUILD.bazel +++ b/gax-java/gax-grpc/BUILD.bazel @@ -28,6 +28,7 @@ _COMPILE_DEPS = [ "@io_grpc_grpc_netty_shaded//jar", "@io_grpc_grpc_grpclb//jar", "@io_grpc_grpc_java//alts:alts", + "@io_grpc_grpc_java//s2a:s2a", "@io_netty_netty_tcnative_boringssl_static//jar", "@javax_annotation_javax_annotation_api//jar", "//gax:gax", diff --git a/gax-java/gax-grpc/pom.xml b/gax-java/gax-grpc/pom.xml index cde6985523..c1e4709303 100644 --- a/gax-java/gax-grpc/pom.xml +++ b/gax-java/gax-grpc/pom.xml @@ -63,6 +63,10 @@ io.grpc grpc-protobuf + + io.grpc + grpc-s2a + io.grpc grpc-stub diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index ae4d7f9e51..0d94c81369 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -46,6 +46,7 @@ import com.google.auth.ApiKeyCredentials; import com.google.auth.Credentials; import com.google.auth.oauth2.ComputeEngineCredentials; +import com.google.auth.oauth2.S2A; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -54,11 +55,13 @@ import io.grpc.CallCredentials; import io.grpc.ChannelCredentials; import io.grpc.Grpc; +import io.grpc.InsecureChannelCredentials; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.TlsChannelCredentials; import io.grpc.alts.GoogleDefaultChannelCredentials; import io.grpc.auth.MoreCallCredentials; +import io.grpc.s2a.S2AChannelCredentials; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -99,6 +102,12 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP @VisibleForTesting static final String DIRECT_PATH_ENV_ENABLE_XDS = "GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS"; + private static final String S2A_ENV_ENABLE_USE_S2A = "EXPERIMENTAL_GOOGLE_API_USE_S2A"; + private static final String MTLS_MDS_ROOT = "/run/google-mds-mtls/root.crt"; + // The mTLS MDS credentials are formatted as the concatenation of a PEM-encoded certificate chain + // followed by a PEM-encoded private key. + private static final String MTLS_MDS_CERT_CHAIN_AND_KEY = "/run/google-mds-mtls/client.key"; + static final long DIRECT_PATH_KEEP_ALIVE_TIME_SECONDS = 3600; static final long DIRECT_PATH_KEEP_ALIVE_TIMEOUT_SECONDS = 20; static final String GCE_PRODUCTION_NAME_PRIOR_2016 = "Google"; @@ -108,6 +117,7 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP private final Executor executor; private final HeaderProvider headerProvider; private final String endpoint; + private final String mtlsEndpoint; // TODO: remove. envProvider currently provides DirectPath environment variable, and is only used // during initial rollout for DirectPath. This provider will be removed once the DirectPath // environment is not used. @@ -136,6 +146,7 @@ private InstantiatingGrpcChannelProvider(Builder builder) { this.executor = builder.executor; this.headerProvider = builder.headerProvider; this.endpoint = builder.endpoint; + this.mtlsEndpoint = builder.mtlsEndpoint; this.mtlsProvider = builder.mtlsProvider; this.envProvider = builder.envProvider; this.interceptorProvider = builder.interceptorProvider; @@ -211,6 +222,10 @@ public boolean needsEndpoint() { return endpoint == null; } + public boolean needsMtlsEndpoint() { + return mtlsEndpoint == null; + } + /** * Specify the endpoint the channel should connect to. * @@ -225,6 +240,20 @@ public TransportChannelProvider withEndpoint(String endpoint) { return toBuilder().setEndpoint(endpoint).build(); } + /** + * Specify the MTLS endpoint. + * + *

The value of {@code mtlsEndpoint} must be of the form {@code host:port}. + * + * @param mtlsEndpoint + * @return A new {@link InstantiatingGrpcChannelProvider} with the specified MTLS endpoint + * configured + */ + public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { + validateEndpoint(mtlsEndpoint); + return toBuilder().setMtlsEndpoint(mtlsEndpoint).build(); + } + /** @deprecated Please modify pool settings via {@link #toBuilder()} */ @Deprecated @Override @@ -410,6 +439,83 @@ ChannelCredentials createMtlsChannelCredentials() throws IOException, GeneralSec return null; } + @VisibleForTesting + boolean isGoogleS2AEnabled() { + String S2AEnv = envProvider.getenv(S2A_ENV_ENABLE_USE_S2A); + boolean isS2AEnv = Boolean.parseBoolean(S2AEnv); + if (isS2AEnv) { + return true; + } + return false; + } + + @VisibleForTesting + boolean shouldUseS2A() { + // If EXPERIMENTAL_GOOGLE_API_USE_S2A is not set to true, skip S2A. + if (!isGoogleS2AEnabled()) { + return false; + } + + // If {@link mtlsEndpoint} is not set, skip S2A. S2A is also skipped when there is endpoint + // override. Endpoint override is respected when the {@link endpoint} is resolved via AIP#4114, + // see EndpointContext.java + if (endpoint != mtlsEndpoint) { + return false; + } + + // mTLS via S2A is not supported in any universe other than googleapis.com. + if (!endpoint.contains(Credentials.GOOGLE_DEFAULT_UNIVERSE)) { + return false; + } + + return true; + } + + @VisibleForTesting + ChannelCredentials createMtlsToS2AChannelCredentials() throws IOException { + if (!isOnComputeEngine()) { + // Currently, MTLS to MDS is only available on GCE. See: + // https://cloud.google.com/compute/docs/metadata/overview#https-mds + return null; + } + File privateKeyFile = new File(MTLS_MDS_CERT_CHAIN_AND_KEY); + File certChainFile = new File(MTLS_MDS_CERT_CHAIN_AND_KEY); + File trustBundleFile = new File(MTLS_MDS_ROOT); + if (!privateKeyFile.isFile() || !certChainFile.isFile() || !trustBundleFile.isFile()) { + return null; + } + return TlsChannelCredentials.newBuilder() + .keyManager(privateKeyFile, certChainFile) + .trustManager(trustBundleFile) + .build(); + } + + @VisibleForTesting + ChannelCredentials createS2ASecuredChannelCredentials() { + S2A s2aUtils = S2A.newBuilder().build(); + String plaintextAddress = s2aUtils.getPlaintextS2AAddress(); + String mtlsAddress = s2aUtils.getMtlsS2AAddress(); + if (!mtlsAddress.isEmpty()) { + try { + // Try to connect to S2A using mTLS. + ChannelCredentials mtlsToS2AChannelCredentials = createMtlsToS2AChannelCredentials(); + if (mtlsToS2AChannelCredentials != null) { + return S2AChannelCredentials.newBuilder(mtlsAddress, mtlsToS2AChannelCredentials).build(); + } + } catch (IOException ignore) { + // Fallback to plaintext connection to S2A. + } + } + + if (!plaintextAddress.isEmpty()) { + // Fallback to plaintext connection to S2A. + return S2AChannelCredentials.newBuilder(plaintextAddress, InsecureChannelCredentials.create()) + .build(); + } + + return null; + } + private ManagedChannel createSingleChannel() throws IOException { GrpcHeaderInterceptor headerInterceptor = new GrpcHeaderInterceptor(headersWithDuplicatesRemoved); @@ -447,6 +553,7 @@ private ManagedChannel createSingleChannel() throws IOException { builder.keepAliveTime(DIRECT_PATH_KEEP_ALIVE_TIME_SECONDS, TimeUnit.SECONDS); builder.keepAliveTimeout(DIRECT_PATH_KEEP_ALIVE_TIMEOUT_SECONDS, TimeUnit.SECONDS); } else { + // Try and create credentials via DCA. See https://google.aip.dev/auth/4114. ChannelCredentials channelCredentials; try { channelCredentials = createMtlsChannelCredentials(); @@ -454,9 +561,22 @@ private ManagedChannel createSingleChannel() throws IOException { throw new IOException(e); } if (channelCredentials != null) { + // Create the channel using channel credentials created via DCA. builder = Grpc.newChannelBuilder(endpoint, channelCredentials); } else { - builder = ManagedChannelBuilder.forAddress(serviceAddress, port); + // Could not create channel credentials via DCA. In accordance with + // https://google.aip.dev/auth/4115, if credentials not available through + // DCA, try mTLS with credentials held by the S2A (Secure Session Agent). + if (shouldUseS2A()) { + channelCredentials = createS2ASecuredChannelCredentials(); + } + if (channelCredentials != null) { + // Create the channel using S2A-secured channel credentials. + builder = Grpc.newChannelBuilder(mtlsEndpoint, channelCredentials); + } else { + // Use default if we cannot initialize channel credentials via DCA or S2A. + builder = ManagedChannelBuilder.forAddress(serviceAddress, port); + } } } // google-c2p resolver requires service config lookup @@ -547,6 +667,11 @@ public String getEndpoint() { return endpoint; } + /** The mTLS endpoint. */ + public String getMtlsEndpoint() { + return mtlsEndpoint; + } + /** This method is obsolete. Use {@link #getKeepAliveTimeDuration()} instead. */ @ObsoleteApi("Use getKeepAliveTimeDuration() instead") public org.threeten.bp.Duration getKeepAliveTime() { @@ -604,6 +729,7 @@ public static final class Builder { private Executor executor; private HeaderProvider headerProvider; private String endpoint; + private String mtlsEndpoint; private EnvironmentProvider envProvider; private MtlsProvider mtlsProvider = new MtlsProvider(); @Nullable private GrpcInterceptorProvider interceptorProvider; @@ -632,6 +758,7 @@ private Builder(InstantiatingGrpcChannelProvider provider) { this.executor = provider.executor; this.headerProvider = provider.headerProvider; this.endpoint = provider.endpoint; + this.mtlsEndpoint = provider.mtlsEndpoint; this.envProvider = provider.envProvider; this.interceptorProvider = provider.interceptorProvider; this.maxInboundMessageSize = provider.maxInboundMessageSize; @@ -700,6 +827,12 @@ public Builder setEndpoint(String endpoint) { return this; } + public Builder setMtlsEndpoint(String mtlsEndpoint) { + validateEndpoint(mtlsEndpoint); + this.mtlsEndpoint = mtlsEndpoint; + return this; + } + @VisibleForTesting Builder setMtlsProvider(MtlsProvider mtlsProvider) { this.mtlsProvider = mtlsProvider; @@ -722,6 +855,10 @@ public String getEndpoint() { return endpoint; } + public String getMtlsEndpoint() { + return mtlsEndpoint; + } + /** The maximum message size allowed to be received on the channel. */ public Builder setMaxInboundMessageSize(Integer max) { this.maxInboundMessageSize = max; diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java index 5e538a06c2..165fc8fcbb 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java @@ -101,11 +101,21 @@ public boolean needsEndpoint() { return false; } + @Override + public boolean needsMtlsEndpoint() { + return false; + } + @Override public TransportChannelProvider withEndpoint(String endpoint) { throw new UnsupportedOperationException("LocalChannelProvider doesn't need an endpoint"); } + @Override + public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { + throw new UnsupportedOperationException("LocalChannelProvider doesn't need an mtlsEndpoint"); + } + @Override @BetaApi("The surface for customizing pool size is not stable yet and may change in the future.") public boolean acceptsPoolSize() { diff --git a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java index f92bdf299c..b183c1d348 100644 --- a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java +++ b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java @@ -119,11 +119,22 @@ public boolean needsEndpoint() { return endpoint == null; } + @Override + public boolean needsMtlsEndpoint() { + return false; + } + @Override public TransportChannelProvider withEndpoint(String endpoint) { return toBuilder().setEndpoint(endpoint).build(); } + @Override + public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { + throw new UnsupportedOperationException( + "InstantiatingHttpJsonChannelProvider doesn't need an mtlsEndpoint"); + } + /** @deprecated REST transport channel doesn't support channel pooling */ @Deprecated @Override diff --git a/gax-java/gax/clirr-ignored-differences.xml b/gax-java/gax/clirr-ignored-differences.xml index af5c5f26a1..ac33d8b58a 100644 --- a/gax-java/gax/clirr-ignored-differences.xml +++ b/gax-java/gax/clirr-ignored-differences.xml @@ -106,4 +106,9 @@ com/google/api/gax/batching/Batcher * + + 7012 + com/google/api/gax/rpc/TransportChannelProvider + * + diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java index 5bce1ac6bb..59911961be 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java @@ -178,6 +178,7 @@ public static ClientContext create(StubSettings settings) throws IOException { // A valid EndpointContext should have been created in the StubSettings EndpointContext endpointContext = settings.getEndpointContext(); String endpoint = endpointContext.resolvedEndpoint(); + String mtlsEndpoint = settings.getMtlsEndpoint(); Credentials credentials = getCredentials(settings); // check if need to adjust credentials/endpoint/endpointContext for GDC-H String settingsGdchApiAudience = settings.getGdchApiAudience(); @@ -222,6 +223,9 @@ public static ClientContext create(StubSettings settings) throws IOException { if (transportChannelProvider.needsEndpoint()) { transportChannelProvider = transportChannelProvider.withEndpoint(endpoint); } + if (transportChannelProvider.needsMtlsEndpoint()) { + transportChannelProvider = transportChannelProvider.withMtlsEndpoint(mtlsEndpoint); + } TransportChannel transportChannel = transportChannelProvider.getTransportChannel(); ApiCallContext defaultCallContext = diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java index 0bf6205dd9..38df360f17 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java @@ -83,12 +83,23 @@ public boolean needsEndpoint() { return false; } + @Override + public boolean needsMtlsEndpoint() { + return false; + } + @Override public TransportChannelProvider withEndpoint(String endpoint) { throw new UnsupportedOperationException( "FixedTransportChannelProvider doesn't need an endpoint"); } + @Override + public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { + throw new UnsupportedOperationException( + "FixedTransportChannelProvider doesn't need an mtlsEndpoint"); + } + /** @deprecated FixedTransportChannelProvider doesn't support ChannelPool configuration */ @Deprecated @Override diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java index 21f3c31f63..30b7441ac1 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java @@ -90,6 +90,9 @@ public interface TransportChannelProvider { /** True if the TransportProvider has no endpoint set. */ boolean needsEndpoint(); + /** True if the TransportProvider has no mtlsEndpoint set. */ + boolean needsMtlsEndpoint(); + /** * Sets the endpoint to use when constructing a new {@link TransportChannel}. * @@ -97,6 +100,13 @@ public interface TransportChannelProvider { */ TransportChannelProvider withEndpoint(String endpoint); + /** + * Sets the mTLS endpoint when constructing a new {@link TransportChannel}. + * + *

This method should only be called if {@link #needsMtlsEndpoint()} returns true. + */ + TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint); + /** * Reports whether this provider allows pool size customization. * diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java index 826864a49c..1dd69e6ebe 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java @@ -74,6 +74,7 @@ class ClientContextTest { private static final String DEFAULT_ENDPOINT = "test.googleapis.com"; + private static final String DEFAULT_MTLS_ENDPOINT = "test.mtls.googleapis.com"; private static final String DEFAULT_UNIVERSE_DOMAIN = "googleapis.com"; private static class InterceptingExecutor extends ScheduledThreadPoolExecutor { @@ -115,6 +116,7 @@ private static class FakeTransportProvider implements TransportChannelProvider { final Map headers; final Credentials credentials; final String endpoint; + final String mtlsEndpoint; FakeTransportProvider( FakeTransportChannel transport, @@ -122,7 +124,8 @@ private static class FakeTransportProvider implements TransportChannelProvider { boolean shouldAutoClose, Map headers, Credentials credentials, - String endpoint) { + String endpoint, + String mtlsEndpoint) { this.transport = transport; this.executor = executor; this.shouldAutoClose = shouldAutoClose; @@ -130,6 +133,7 @@ private static class FakeTransportProvider implements TransportChannelProvider { this.transport.setHeaders(headers); this.credentials = credentials; this.endpoint = endpoint; + this.mtlsEndpoint = mtlsEndpoint; } @Override @@ -155,7 +159,8 @@ public TransportChannelProvider withExecutor(Executor executor) { this.shouldAutoClose, this.headers, this.credentials, - this.endpoint); + this.endpoint, + this.mtlsEndpoint); } @Override @@ -171,7 +176,8 @@ public TransportChannelProvider withHeaders(Map headers) { this.shouldAutoClose, headers, this.credentials, - this.endpoint); + this.endpoint, + this.mtlsEndpoint); } @Override @@ -179,6 +185,11 @@ public boolean needsEndpoint() { return true; } + @Override + public boolean needsMtlsEndpoint() { + return true; + } + @Override public String getEndpoint() { return endpoint; @@ -192,7 +203,20 @@ public TransportChannelProvider withEndpoint(String endpoint) { this.shouldAutoClose, this.headers, this.credentials, - endpoint); + endpoint, + this.mtlsEndpoint); + } + + @Override + public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { + return new FakeTransportProvider( + this.transport, + this.executor, + this.shouldAutoClose, + this.headers, + this.credentials, + this.endpoint, + mtlsEndpoint); } @Override @@ -230,7 +254,8 @@ public TransportChannelProvider withCredentials(Credentials credentials) { this.shouldAutoClose, this.headers, credentials, - this.endpoint); + this.endpoint, + this.mtlsEndpoint); } } @@ -278,7 +303,8 @@ private void runTest( shouldAutoClose, needHeaders ? null : headers, null, - DEFAULT_ENDPOINT); + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT); Credentials credentials = Mockito.mock(Credentials.class); ApiClock clock = Mockito.mock(ApiClock.class); Watchdog watchdog = @@ -352,7 +378,8 @@ void testWatchdogProvider() throws IOException { InterceptingExecutor executor = new InterceptingExecutor(1); FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = - new FakeTransportProvider(transportChannel, executor, true, null, null, DEFAULT_ENDPOINT); + new FakeTransportProvider( + transportChannel, executor, true, null, null, DEFAULT_ENDPOINT, DEFAULT_MTLS_ENDPOINT); ApiClock clock = Mockito.mock(ApiClock.class); builder.setClock(clock); @@ -391,7 +418,8 @@ void testMergeHeaders_getQuotaProjectIdFromHeadersProvider() throws IOException InterceptingExecutor executor = new InterceptingExecutor(1); FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = - new FakeTransportProvider(transportChannel, executor, true, null, null, DEFAULT_ENDPOINT); + new FakeTransportProvider( + transportChannel, executor, true, null, null, DEFAULT_ENDPOINT, DEFAULT_MTLS_ENDPOINT); HeaderProvider headerProvider = Mockito.mock(HeaderProvider.class); Mockito.when(headerProvider.getHeaders()).thenReturn(ImmutableMap.of("header_k1", "v1")); @@ -427,7 +455,8 @@ void testMergeHeaders_getQuotaProjectIdFromSettings() throws IOException { InterceptingExecutor executor = new InterceptingExecutor(1); FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = - new FakeTransportProvider(transportChannel, executor, true, null, null, DEFAULT_ENDPOINT); + new FakeTransportProvider( + transportChannel, executor, true, null, null, DEFAULT_ENDPOINT, DEFAULT_MTLS_ENDPOINT); HeaderProvider headerProvider = new HeaderProvider() { @@ -473,7 +502,8 @@ void testMergeHeaders_noQuotaProjectIdSet() throws IOException { InterceptingExecutor executor = new InterceptingExecutor(1); FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = - new FakeTransportProvider(transportChannel, executor, true, null, null, DEFAULT_ENDPOINT); + new FakeTransportProvider( + transportChannel, executor, true, null, null, DEFAULT_ENDPOINT, DEFAULT_MTLS_ENDPOINT); HeaderProvider headerProvider = Mockito.mock(HeaderProvider.class); Mockito.when(headerProvider.getHeaders()).thenReturn(ImmutableMap.of("header_k1", "v1")); @@ -504,7 +534,8 @@ void testHidingQuotaProjectId_quotaSetFromSetting() throws IOException { InterceptingExecutor executor = new InterceptingExecutor(1); FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = - new FakeTransportProvider(transportChannel, executor, true, null, null, DEFAULT_ENDPOINT); + new FakeTransportProvider( + transportChannel, executor, true, null, null, DEFAULT_ENDPOINT, DEFAULT_MTLS_ENDPOINT); Map> metaDataWithQuota = ImmutableMap.of( "k1", @@ -545,7 +576,8 @@ void testHidingQuotaProjectId_noQuotaSetFromSetting() throws IOException { InterceptingExecutor executor = new InterceptingExecutor(1); FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = - new FakeTransportProvider(transportChannel, executor, true, null, null, DEFAULT_ENDPOINT); + new FakeTransportProvider( + transportChannel, executor, true, null, null, DEFAULT_ENDPOINT, DEFAULT_MTLS_ENDPOINT); Map> metaData = ImmutableMap.of("k1", Collections.singletonList("v1")); final Credentials credentialsWithoutQuotaProjectId = Mockito.mock(GoogleCredentials.class); Mockito.when(credentialsWithoutQuotaProjectId.getRequestMetadata(null)).thenReturn(metaData); @@ -581,7 +613,8 @@ void testQuotaProjectId_worksWithNullCredentials() throws IOException { true, null, Mockito.mock(Credentials.class), - DEFAULT_ENDPOINT); + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT); final FakeClientSettings.Builder settingsBuilder = new FakeClientSettings.Builder(); @@ -602,7 +635,8 @@ void testUserAgentInternalOnly() throws Exception { true, null, null, - DEFAULT_ENDPOINT); + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -630,7 +664,8 @@ void testUserAgentExternalOnly() throws Exception { true, null, null, - DEFAULT_ENDPOINT); + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -658,7 +693,8 @@ void testUserAgentConcat() throws Exception { true, null, null, - DEFAULT_ENDPOINT); + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -743,7 +779,8 @@ private Map setupTestForCredentialTokenUsageMetricsAndGetTranspo true, null, null, - DEFAULT_ENDPOINT); + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -795,7 +832,8 @@ void testExecutorSettings() throws Exception { true, null, null, - DEFAULT_ENDPOINT); + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -842,7 +880,8 @@ void testExecutorSettings() throws Exception { true, null, null, - DEFAULT_ENDPOINT)); + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT)); context = ClientContext.create(builder.build()); transportChannel = (FakeTransportChannel) context.getTransportChannel(); assertThat(transportChannel.getExecutor()).isSameInstanceAs(executorProvider.getExecutor()); @@ -864,7 +903,13 @@ private GdchCredentials getMockGdchCredentials() throws IOException { private TransportChannelProvider getFakeTransportChannelProvider() { return new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), null, true, null, null, DEFAULT_ENDPOINT); + FakeTransportChannel.create(new FakeChannel()), + null, + true, + null, + null, + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT); } // EndpointContext will construct a valid endpoint if nothing is provided @@ -872,7 +917,7 @@ private TransportChannelProvider getFakeTransportChannelProvider() { void testCreateClientContext_withGdchCredentialNoAudienceNoEndpoint() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null); + FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null, null); Credentials creds = getMockGdchCredentials(); CredentialsProvider provider = FixedCredentialsProvider.create(creds); @@ -899,7 +944,7 @@ void testCreateClientContext_withGdchCredentialNoAudienceEmptyEndpoint_throws() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null); + FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null, null); Credentials creds = getMockGdchCredentials(); CredentialsProvider provider = FixedCredentialsProvider.create(creds); @@ -922,7 +967,7 @@ void testCreateClientContext_withGdchCredentialWithoutAudienceWithEndpoint_corre throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null); + FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null, null); Credentials creds = getMockGdchCredentials(); // it should correctly create a client context with gdch creds and null audience @@ -1034,7 +1079,7 @@ void testCreateClientContext_withNonGdchCredentialAndAnyAudience_throws() throws void testCreateClientContext_SetEndpointViaClientSettings() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null); + FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null, null); StubSettings settings = new FakeStubSettings.Builder() .setEndpoint(DEFAULT_ENDPOINT) @@ -1060,7 +1105,8 @@ void testCreateClientContext_SetEndpointViaTransportChannelProvider() throws IOE true, null, null, - transportChannelProviderEndpoint); + transportChannelProviderEndpoint, + null); StubSettings settings = new FakeStubSettings.Builder() .setEndpoint(null) @@ -1088,7 +1134,8 @@ void testCreateClientContext_SetEndpointViaClientSettingsAndTransportChannelProv true, null, null, - transportChannelProviderEndpoint); + transportChannelProviderEndpoint, + null); StubSettings settings = new FakeStubSettings.Builder() .setEndpoint(clientSettingsEndpoint) @@ -1111,7 +1158,7 @@ void testCreateClientContext_SetEndpointViaClientSettingsAndTransportChannelProv void testCreateClientContext_doNotSetUniverseDomain() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null); + FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null, null); StubSettings settings = new FakeStubSettings.Builder() .setEndpoint(null) @@ -1130,7 +1177,7 @@ void testCreateClientContext_doNotSetUniverseDomain() throws IOException { void testCreateClientContext_setUniverseDomain() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null); + FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null, null); String universeDomain = "testdomain.com"; StubSettings settings = new FakeStubSettings.Builder().setEndpoint(null).setUniverseDomain(universeDomain).build(); @@ -1163,7 +1210,13 @@ void testSetApiKey_createsApiCredentials() throws IOException { FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = new FakeTransportProvider( - transportChannel, executor, true, ImmutableMap.of(), null, DEFAULT_ENDPOINT); + transportChannel, + executor, + true, + ImmutableMap.of(), + null, + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT); builder.setTransportChannelProvider(transportProvider); HeaderProvider headerProvider = Mockito.mock(HeaderProvider.class); Mockito.when(headerProvider.getHeaders()).thenReturn(ImmutableMap.of()); @@ -1184,7 +1237,13 @@ void testSetApiKey_withDefaultCredentials_overridesCredentials() throws IOExcept FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = new FakeTransportProvider( - transportChannel, executor, true, ImmutableMap.of(), null, DEFAULT_ENDPOINT); + transportChannel, + executor, + true, + ImmutableMap.of(), + null, + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT); builder.setTransportChannelProvider(transportProvider); HeaderProvider headerProvider = Mockito.mock(HeaderProvider.class); Mockito.when(headerProvider.getHeaders()).thenReturn(ImmutableMap.of()); From e7995263ce8ca4820dcd3419bafbc22f4b7f38fd Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Fri, 1 Nov 2024 12:22:02 -0700 Subject: [PATCH 04/51] tests. --- .../InstantiatingGrpcChannelProvider.java | 56 +++--- .../InstantiatingGrpcChannelProviderTest.java | 170 ++++++++++++++++++ .../gax-grpc/src/test/resources/README.md | 27 +++ .../src/test/resources/client_cert.pem | 20 +++ .../src/test/resources/client_key.pem | 28 +++ .../gax-grpc/src/test/resources/root_cert.pem | 22 +++ 6 files changed, 302 insertions(+), 21 deletions(-) create mode 100644 gax-java/gax-grpc/src/test/resources/README.md create mode 100644 gax-java/gax-grpc/src/test/resources/client_cert.pem create mode 100644 gax-java/gax-grpc/src/test/resources/client_key.pem create mode 100644 gax-java/gax-grpc/src/test/resources/root_cert.pem diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 0d94c81369..3690c58f70 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -63,7 +63,10 @@ import io.grpc.auth.MoreCallCredentials; import io.grpc.s2a.S2AChannelCredentials; import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.security.KeyStore; @@ -102,7 +105,8 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP @VisibleForTesting static final String DIRECT_PATH_ENV_ENABLE_XDS = "GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS"; - private static final String S2A_ENV_ENABLE_USE_S2A = "EXPERIMENTAL_GOOGLE_API_USE_S2A"; + @VisibleForTesting static final String S2A_ENV_ENABLE_USE_S2A = "EXPERIMENTAL_GOOGLE_API_USE_S2A"; + private static final String MTLS_MDS_ROOT = "/run/google-mds-mtls/root.crt"; // The mTLS MDS credentials are formatted as the concatenation of a PEM-encoded certificate chain // followed by a PEM-encoded private key. @@ -118,9 +122,11 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP private final HeaderProvider headerProvider; private final String endpoint; private final String mtlsEndpoint; - // TODO: remove. envProvider currently provides DirectPath environment variable, and is only used - // during initial rollout for DirectPath. This provider will be removed once the DirectPath - // environment is not used. + // TODO: remove. + // envProvider currently provides DirectPath and S2A environment variables, and is only used + // during initial rollout for DirectPath and S2A. This provider will be removed once the + // DirectPath + // and S2A environment variables are not used. private final EnvironmentProvider envProvider; @Nullable private final GrpcInterceptorProvider interceptorProvider; @Nullable private final Integer maxInboundMessageSize; @@ -472,21 +478,14 @@ boolean shouldUseS2A() { } @VisibleForTesting - ChannelCredentials createMtlsToS2AChannelCredentials() throws IOException { - if (!isOnComputeEngine()) { - // Currently, MTLS to MDS is only available on GCE. See: - // https://cloud.google.com/compute/docs/metadata/overview#https-mds - return null; - } - File privateKeyFile = new File(MTLS_MDS_CERT_CHAIN_AND_KEY); - File certChainFile = new File(MTLS_MDS_CERT_CHAIN_AND_KEY); - File trustBundleFile = new File(MTLS_MDS_ROOT); - if (!privateKeyFile.isFile() || !certChainFile.isFile() || !trustBundleFile.isFile()) { + ChannelCredentials createMtlsToS2AChannelCredentials( + InputStream trustBundle, InputStream privateKey, InputStream certChain) throws IOException { + if (trustBundle == null || privateKey == null || certChain == null) { return null; } return TlsChannelCredentials.newBuilder() - .keyManager(privateKeyFile, certChainFile) - .trustManager(trustBundleFile) + .keyManager(privateKey, certChain) + .trustManager(trustBundle) .build(); } @@ -496,14 +495,29 @@ ChannelCredentials createS2ASecuredChannelCredentials() { String plaintextAddress = s2aUtils.getPlaintextS2AAddress(); String mtlsAddress = s2aUtils.getMtlsS2AAddress(); if (!mtlsAddress.isEmpty()) { + // Currently, MTLS to MDS is only available on GCE. See: + // https://cloud.google.com/compute/docs/metadata/overview#https-mds + // Try to load MTLS-MDS creds. + InputStream trustBundle = null; + InputStream privateKey = null; + InputStream certChain = null; + try { + trustBundle = new FileInputStream(MTLS_MDS_ROOT); + privateKey = new FileInputStream(MTLS_MDS_CERT_CHAIN_AND_KEY); + certChain = new FileInputStream(MTLS_MDS_CERT_CHAIN_AND_KEY); + } catch (FileNotFoundException ignore) { + // Fallback to plaintext-to-S2A connection. + } + ChannelCredentials mtlsToS2AChannelCredentials = null; try { // Try to connect to S2A using mTLS. - ChannelCredentials mtlsToS2AChannelCredentials = createMtlsToS2AChannelCredentials(); - if (mtlsToS2AChannelCredentials != null) { - return S2AChannelCredentials.newBuilder(mtlsAddress, mtlsToS2AChannelCredentials).build(); - } + mtlsToS2AChannelCredentials = + createMtlsToS2AChannelCredentials(trustBundle, privateKey, certChain); } catch (IOException ignore) { - // Fallback to plaintext connection to S2A. + // Fallback to plaintext-to-S2A connection. + } + if (mtlsToS2AChannelCredentials != null) { + return S2AChannelCredentials.newBuilder(mtlsAddress, mtlsToS2AChannelCredentials).build(); } } diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index a58f9b8173..8e207d55b8 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -56,8 +56,10 @@ import com.google.common.truth.Truth; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; +import io.grpc.TlsChannelCredentials; import io.grpc.alts.ComputeEngineChannelBuilder; import java.io.IOException; +import java.io.InputStream; import java.security.GeneralSecurityException; import java.time.Duration; import java.util.ArrayList; @@ -83,6 +85,7 @@ class InstantiatingGrpcChannelProviderTest extends AbstractMtlsTransportChannelTest { private static final String DEFAULT_ENDPOINT = "test.googleapis.com:443"; + private static final String DEFAULT_MTLS_ENDPOINT = "test.mtls.googleapis.com:443"; private static final String API_KEY_HEADER_VALUE = "fake_api_key_2"; private static final String API_KEY_AUTH_HEADER_KEY = "x-goog-api-key"; private static String originalOSName; @@ -129,6 +132,35 @@ void testEndpointBadPort() { () -> InstantiatingGrpcChannelProvider.newBuilder().setEndpoint("localhost:abcd")); } + @Test + void testMtlsEndpoint() { + InstantiatingGrpcChannelProvider.Builder builder = + InstantiatingGrpcChannelProvider.newBuilder(); + builder.setMtlsEndpoint(DEFAULT_MTLS_ENDPOINT); + assertEquals(builder.getMtlsEndpoint(), DEFAULT_MTLS_ENDPOINT); + + InstantiatingGrpcChannelProvider provider = builder.build(); + assertEquals(provider.getMtlsEndpoint(), DEFAULT_MTLS_ENDPOINT); + } + + @Test + void testMtlsEndpointNoPort() { + assertThrows( + IllegalArgumentException.class, + () -> + InstantiatingGrpcChannelProvider.newBuilder() + .setMtlsEndpoint("test.mtls.googleapis.com")); + } + + @Test + void testMtlsEndpointBadPort() { + assertThrows( + IllegalArgumentException.class, + () -> + InstantiatingGrpcChannelProvider.newBuilder() + .setEndpoint("test.mtls.googleapis.com:abcd")); + } + @Test void testKeepAlive() { final long millis = 15; @@ -230,6 +262,7 @@ void testToBuilder() { InstantiatingGrpcChannelProvider.newBuilder() .setProcessorCount(2) .setEndpoint("fake.endpoint:443") + .setMtlsEndpoint("fake.endpoint:443") .setMaxInboundMessageSize(12345678) .setMaxInboundMetadataSize(4096) .setKeepAliveTimeDuration(keepaliveTime) @@ -243,6 +276,7 @@ void testToBuilder() { InstantiatingGrpcChannelProvider.Builder builder = provider.toBuilder(); assertThat(builder.getEndpoint()).isEqualTo("fake.endpoint:443"); + assertThat(builder.getMtlsEndpoint()).isEqualTo("fake.endpoint:443"); assertThat(builder.getMaxInboundMessageSize()).isEqualTo(12345678); assertThat(builder.getMaxInboundMetadataSize()).isEqualTo(4096); assertThat(builder.getKeepAliveTimeDuration()).isEqualTo(keepaliveTime); @@ -980,6 +1014,142 @@ private FixedHeaderProvider getHeaderProviderWithApiKeyHeader() { return FixedHeaderProvider.create(header); } + @Test + void isGoogleS2AEnabled_envVarNotSet_returnsFalse() { + EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); + Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) + .thenReturn("false"); + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder().build(); + Truth.assertThat(provider.isGoogleS2AEnabled()).isFalse(); + } + + @Test + void isGoogleS2AEnabled_envVarNotSet_returnsTrue() { + EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); + Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) + .thenReturn("true"); + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder().build(); + Truth.assertThat(provider.isGoogleS2AEnabled()).isFalse(); + } + + @Test + void shouldUseS2A_envVarNotSet_returnsFalse() { + EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); + Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) + .thenReturn("false"); + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder() + .setEndpoint(DEFAULT_MTLS_ENDPOINT) + .setMtlsEndpoint(DEFAULT_MTLS_ENDPOINT) + .setEnvProvider(envProvider) + .build(); + Truth.assertThat(provider.shouldUseS2A()).isFalse(); + } + + @Test + void shouldUseS2A_mtlsEndpointNotSet_returnsFalse() { + EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); + Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) + .thenReturn("true"); + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder() + .setEndpoint(DEFAULT_ENDPOINT) + .setEnvProvider(envProvider) + .build(); + Truth.assertThat(provider.shouldUseS2A()).isFalse(); + } + + @Test + void shouldUseS2A_endpointOverrideIsSet_returnsFalse() { + EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); + Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) + .thenReturn("true"); + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder() + .setEndpoint(DEFAULT_ENDPOINT) + .setMtlsEndpoint(DEFAULT_MTLS_ENDPOINT) + .setEnvProvider(envProvider) + .build(); + Truth.assertThat(provider.shouldUseS2A()).isFalse(); + } + + @Test + void shouldUseS2A_nonGDUUniverse_returnsFalse() { + EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); + Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) + .thenReturn("true"); + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder() + .setEndpoint("test.mtls.abcd.com:443") + .setMtlsEndpoint("test.mtls.abcd.com:443") + .setEnvProvider(envProvider) + .build(); + Truth.assertThat(provider.shouldUseS2A()).isFalse(); + } + + @Test + void shouldUseS2A_returnsTrue() { + EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); + Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) + .thenReturn("true"); + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder() + .setEndpoint(DEFAULT_MTLS_ENDPOINT) + .setMtlsEndpoint(DEFAULT_MTLS_ENDPOINT) + .setEnvProvider(envProvider) + .build(); + Truth.assertThat(provider.shouldUseS2A()).isTrue(); + } + + @Test + void createMtlsToS2AChannelCredentials_missingAllFiles_throws() throws IOException { + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder().build(); + assertThat(provider.createMtlsToS2AChannelCredentials(null, null, null)).isNull(); + } + + @Test + void createMtlsToS2AChannelCredentials_missingRootFile_throws() throws IOException { + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder().build(); + InputStream privateKey = this.getClass().getClassLoader().getResourceAsStream("client_key.pem"); + InputStream certChain = this.getClass().getClassLoader().getResourceAsStream("client_cert.pem"); + assertThat(provider.createMtlsToS2AChannelCredentials(null, privateKey, certChain)).isNull(); + } + + @Test + void createMtlsToS2AChannelCredentials_missingKeyFile_throws() throws IOException { + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder().build(); + InputStream trustBundle = this.getClass().getClassLoader().getResourceAsStream("root_cert.pem"); + InputStream certChain = this.getClass().getClassLoader().getResourceAsStream("client_cert.pem"); + assertThat(provider.createMtlsToS2AChannelCredentials(trustBundle, null, certChain)).isNull(); + } + + @Test + void createMtlsToS2AChannelCredentials_missingCertChainFile_throws() throws IOException { + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder().build(); + InputStream trustBundle = this.getClass().getClassLoader().getResourceAsStream("root_cert.pem"); + InputStream privateKey = this.getClass().getClassLoader().getResourceAsStream("client_key.pem"); + assertThat(provider.createMtlsToS2AChannelCredentials(trustBundle, privateKey, null)).isNull(); + } + + @Test + void createMtlsToS2AChannelCredentials_success() throws IOException { + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder().build(); + InputStream trustBundle = this.getClass().getClassLoader().getResourceAsStream("root_cert.pem"); + InputStream privateKey = this.getClass().getClassLoader().getResourceAsStream("client_key.pem"); + InputStream certChain = this.getClass().getClassLoader().getResourceAsStream("client_cert.pem"); + assertThat(trustBundle).isNotNull(); + assertEquals( + provider.createMtlsToS2AChannelCredentials(trustBundle, privateKey, certChain).getClass(), + TlsChannelCredentials.class); + } + private static class FakeLogHandler extends Handler { List records = new ArrayList<>(); diff --git a/gax-java/gax-grpc/src/test/resources/README.md b/gax-java/gax-grpc/src/test/resources/README.md new file mode 100644 index 0000000000..3335ba1b3a --- /dev/null +++ b/gax-java/gax-grpc/src/test/resources/README.md @@ -0,0 +1,27 @@ +# Generating certificates and keys for testing mTLS-S2A + +Create root CA + +``` +openssl req -x509 -sha256 -days 7305 -newkey rsa:2048 -keyout root_key.pem -out +root_cert.pem +``` + +Generate private key + +``` +openssl genrsa -out client_key.pem 2048 +``` + +Generate CSR (set Common Name to localhost, leave all +other fields blank) + +``` +openssl req -key client_key.pem -new -out client.csr -config config.cnf +``` + +Sign CSR for client + +``` +openssl x509 -req -CA root_cert.pem -CAkey root_key.pem -in client.csr -out client_cert.pem -days 7305 +``` diff --git a/gax-java/gax-grpc/src/test/resources/client_cert.pem b/gax-java/gax-grpc/src/test/resources/client_cert.pem new file mode 100644 index 0000000000..837f8bb501 --- /dev/null +++ b/gax-java/gax-grpc/src/test/resources/client_cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPTCCAiWgAwIBAgIUaarddwSWeE4jDC9kwxEr446ehqUwDQYJKoZIhvcNAQEL +BQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X +DTI0MTAwMTIxNTk1NFoXDTQ0MTAwMTIxNTk1NFowFDESMBAGA1UEAwwJbG9jYWxo +b3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxlNsldt7yAU4KRuS +2D2/FjNIE1US5olBm4HteTr++41WaELZJqNLRPPp052jEQU3aKSYNGZvUUO6buu7 +eFpz2SBNUVMyvmzzocjVAyyf4NQvDazYHWOb+/YCeUppTRWriz4V5sn47qJTQ8cd +CGrTFeLHxUjx4nh/OiqVXP/KnF3EqPEuqph0ky7+GirnJgPRe+C5ERuGkJye8dmP +yWGA2lSS6MeDe7JZTAMi08bAn7BuNpeBkOzz1msGGI9PnUanUs7GOPWTDdcQAVY8 +KMvHCuGaNMGpb4rOR2mm8LlbAbpTPz8Pkw4QtMCLkgsrz2CzXpVwnLsU7nDXJAIO +B155lQIDAQABo0IwQDAdBgNVHQ4EFgQUSZEyIHLzkIw7AwkBaUjYfIrGVR4wHwYD +VR0jBBgwFoAUcq3dtxAVA410YWyM0B4e+4umbiwwDQYJKoZIhvcNAQELBQADggEB +AAz0bZ4ayrZLhA45xn0yvdpdqiCtiWikCRtxgE7VXHg/ziZJVMpBpAhbIGO5tIyd +lttnRXHwz5DUwKiba4/bCEFe229BshQEql5qaqcbGbFfSly11WeqqnwR1N7c8Gpv +pD9sVrx22seN0rTUk87MY/S7mzCxHqAx35zm/LTW3pWcgCTMKFHy4Gt4mpTnXkNA +WkhP2OhW5RLiu6Whi0BEdb2TGG1+ctamgijKXb+gJeef5ehlHXG8eU862KF5UlEA +NeQKBm/PpQxOMe0NdpatjN8QRoczku0Itiodng+OZ1o+2iSNG988uFRb3CUSnjtE +R/HL6ULAFzo59EpIYxruU/w= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/gax-java/gax-grpc/src/test/resources/client_key.pem b/gax-java/gax-grpc/src/test/resources/client_key.pem new file mode 100644 index 0000000000..38b93eb65c --- /dev/null +++ b/gax-java/gax-grpc/src/test/resources/client_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDGU2yV23vIBTgp +G5LYPb8WM0gTVRLmiUGbge15Ov77jVZoQtkmo0tE8+nTnaMRBTdopJg0Zm9RQ7pu +67t4WnPZIE1RUzK+bPOhyNUDLJ/g1C8NrNgdY5v79gJ5SmlNFauLPhXmyfjuolND +xx0IatMV4sfFSPHieH86KpVc/8qcXcSo8S6qmHSTLv4aKucmA9F74LkRG4aQnJ7x +2Y/JYYDaVJLox4N7sllMAyLTxsCfsG42l4GQ7PPWawYYj0+dRqdSzsY49ZMN1xAB +Vjwoy8cK4Zo0walvis5HaabwuVsBulM/Pw+TDhC0wIuSCyvPYLNelXCcuxTucNck +Ag4HXnmVAgMBAAECggEAKuW9jXaBgiS63o1jyFkmvWcPNntG0M2sfrXuRzQfFgse +vwOCk8xrSflWQNsOe+58ayp6746ekl3LdBWSIbiy6SqG/sm3pp/LXNmjVYHv/QH4 +QYV643R5t1ihdVnGiBFhXwdpVleme/tpdjYZzgnJKak5W69o/nrgzhSK5ShAy2xM +j0XXbgdqG+4JxPb5BZmjHHfXAXUfgSORMdfArkbgFBRc9wL/6JVTXjeAMy5WX9qe +5UQsSOYkwc9P2snifC/jdIhjHQOkkx59O0FgukJEFZPoagVG1duWQbnNDr7QVHCJ +jV6dg9tIT4SXD3uPSPbgNGlRUseIakCzrhHARJuA2wKBgQD/h8zoh0KaqKyViCYw +XKOFpm1pAFnp2GiDOblxNubNFAXEWnC+FlkvO/z1s0zVuYELUqfxcYMSXJFEVelK +rfjZtoC5oxqWGqLo9iCj7pa8t+ipulYcLt2SWc7eZPD4T4lzeEf1Qz77aKcz34sa +dv9lzQkDvhR/Mv1VeEGFHiq2VwKBgQDGsLcTGH5Yxs//LRSY8TigBkQEDrH5NvXu +2jtAzZhy1Yhsoa5eiZkhnnzM6+n05ovfZLcy6s7dnwP1Y+C79vs+DKMBsodtDG5z +YpsB0VrXYa6P6pCqkcz0Bz9xdo5sOhAK3AKnX6jd29XBDdeYsw/lxHLG24wProTD +cCYFqtaj8wKBgQCaqKT68DL9zK14a8lBaDCIyexaqx3AjXzkP+Hfhi03XrEG4P5v +7rLYBeTbCUSt7vMN2V9QoTWFvYUm6SCkVJvTmcRblz6WL1T+z0l+LwAJBP7LC77m +m+77j2PH8yxt/iXhP6G97o+GNxdMLDbTM8bs5KZaH4fkXQY73uc5HMMZTQKBgEZS +7blYhf+t/ph2wD+RwVUCYrh86wkmJs2veCFro3WhlnO8lhbn5Mc9bTaqmVgQ8ZjT +8POYoDdYvPHxs+1TcYF4v4kuQziZmc5FLE/sZZauADb38tQsXrpQhmgGakpsEpmF +XXsYJJDB6lo2KATn+8x7R5SSyHQUdPEnlI2U9ft5AoGBAJw0NJiM1EzRS8xq0DmO +AvQaPjo01o2hH6wghws8gDQwrj0eHraHgVi7zo0VkaHJbO7ahKPudset3N7owJhA +CUAPPRtv5wn0amAyNz77f1dz4Gys3AkcchflqhbEaQpzKYx4kX0adclur4WJ/DVm +P7DI977SHCVB4FVMbXMEkBjN +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/gax-java/gax-grpc/src/test/resources/root_cert.pem b/gax-java/gax-grpc/src/test/resources/root_cert.pem new file mode 100644 index 0000000000..ccd0a46bc2 --- /dev/null +++ b/gax-java/gax-grpc/src/test/resources/root_cert.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkzCCAnugAwIBAgIUWemeXZdfqcqkP8/Eyj74oTJtoNQwDQYJKoZIhvcNAQEL +BQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X +DTI0MTAwMTIxNTkxMVoXDTQ0MTAwMTIxNTkxMVowWTELMAkGA1UEBhMCQVUxEzAR +BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 +IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAt3A04hy5lljv86Nu0LLQZ2hA+fcImHjt1p1Mxgcta/5oxfVLcerE +ZH+DAQLDtWzp9Up/vI57MM419GIL8Iszk7hnZRS/HWJ+2jewZJtz4i/g15dLr6+1 +uabMdPOWos60BwcLMxKEe6lJO1mV4z9d4NH4mAuMIHyM+ty0Klp9MfeDJtYEh0+z +AxJUHCixDTsnKJro7My7A3ZT7bvaMfXxS7XN6qlRgBfiCmXo/GKTFfmfBW/EZGkG +XOCxE2D79wYNhC41Q/ix0kwjEeOj2vgGFoiyblSdHdzvRXzsoQTEiZSM8lJDR2IT +ZbpgbBlknMU6efNWlS8P5damB9ZWXg3x4wIDAQABo1MwUTAdBgNVHQ4EFgQUcq3d +txAVA410YWyM0B4e+4umbiwwHwYDVR0jBBgwFoAUcq3dtxAVA410YWyM0B4e+4um +biwwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEApZvaI9y7vjX/ +RRdvwf2Db9KlTE9nuVQ3AsrmG9Ml0p2X6U5aTetxdYBo2PuaaYHheF03JOH8zjpL +UfFzvbi52DPbfFAaDw/6NIAenXlg492leNvUFNjGGRyJO9R5/aDfv40/fT3Em5G5 +DnR8SeGQ9tI1t6xBBT+d+/MilSiEKVu8IIF/p0SwvEyR4pKo6wFVZR0ZiIj2v/FZ +P5Qk0Xhb+slpmaR3Wtx/mPl9Wb3kpPD4CAwhWDqFkKJql9/n9FvMjdwlCQKQGB26 +ZDXY3C0UTdktK5biNWRgAUVJEWBX6Q2amrxQHIn2d9RJ8uxCME/KBAntK+VxZE78 +w0JOvQ4Dpw== +-----END CERTIFICATE----- \ No newline at end of file From 70ae8d03d82aabfcefaefb7d74f5a262975cee9b Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Fri, 1 Nov 2024 14:13:28 -0700 Subject: [PATCH 05/51] use endpoint override. --- .../InstantiatingGrpcChannelProvider.java | 61 +++++- .../InstantiatingGrpcChannelProviderTest.java | 39 +++- .../grpc/testing/LocalChannelProvider.java | 11 ++ .../InstantiatingHttpJsonChannelProvider.java | 11 ++ .../com/google/api/gax/rpc/ClientContext.java | 11 +- .../rpc/FixedTransportChannelProvider.java | 11 ++ .../api/gax/rpc/TransportChannelProvider.java | 10 + .../google/api/gax/rpc/ClientContextTest.java | 182 +++++++++++++++--- 8 files changed, 296 insertions(+), 40 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 3690c58f70..1ec74ec7f4 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -122,6 +122,7 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP private final HeaderProvider headerProvider; private final String endpoint; private final String mtlsEndpoint; + private final String endpointOverride; // TODO: remove. // envProvider currently provides DirectPath and S2A environment variables, and is only used // during initial rollout for DirectPath and S2A. This provider will be removed once the @@ -153,6 +154,7 @@ private InstantiatingGrpcChannelProvider(Builder builder) { this.headerProvider = builder.headerProvider; this.endpoint = builder.endpoint; this.mtlsEndpoint = builder.mtlsEndpoint; + this.endpointOverride = builder.endpointOverride; this.mtlsProvider = builder.mtlsProvider; this.envProvider = builder.envProvider; this.interceptorProvider = builder.interceptorProvider; @@ -228,10 +230,16 @@ public boolean needsEndpoint() { return endpoint == null; } + @Override public boolean needsMtlsEndpoint() { return mtlsEndpoint == null; } + @Override + public boolean needsEndpointOverride() { + return endpointOverride == null; + } + /** * Specify the endpoint the channel should connect to. * @@ -255,11 +263,31 @@ public TransportChannelProvider withEndpoint(String endpoint) { * @return A new {@link InstantiatingGrpcChannelProvider} with the specified MTLS endpoint * configured */ + @Override public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { - validateEndpoint(mtlsEndpoint); + if (!mtlsEndpoint.isEmpty()) { + validateEndpoint(mtlsEndpoint); + } return toBuilder().setMtlsEndpoint(mtlsEndpoint).build(); } + /** + * Specify the endpoint override. + * + *

The value of {@code endpointOverride} must be of the form {@code host:port}. + * + * @param endpointOverride + * @return A new {@link InstantiatingGrpcChannelProvider} with the specified endpoint Override + * configured + */ + @Override + public TransportChannelProvider withEndpointOverride(String endpointOverride) { + if (!endpointOverride.isEmpty()) { + validateEndpoint(endpointOverride); + } + return toBuilder().setEndpointOverride(endpointOverride).build(); + } + /** @deprecated Please modify pool settings via {@link #toBuilder()} */ @Deprecated @Override @@ -462,15 +490,13 @@ boolean shouldUseS2A() { return false; } - // If {@link mtlsEndpoint} is not set, skip S2A. S2A is also skipped when there is endpoint - // override. Endpoint override is respected when the {@link endpoint} is resolved via AIP#4114, - // see EndpointContext.java - if (endpoint != mtlsEndpoint) { + // If {@code mtlsEndpoint} is not set, or {@code endpointOverride} is specified, skip S2A. + if (mtlsEndpoint.isEmpty() || !endpointOverride.isEmpty()) { return false; } // mTLS via S2A is not supported in any universe other than googleapis.com. - if (!endpoint.contains(Credentials.GOOGLE_DEFAULT_UNIVERSE)) { + if (!mtlsEndpoint.contains(Credentials.GOOGLE_DEFAULT_UNIVERSE)) { return false; } @@ -686,6 +712,11 @@ public String getMtlsEndpoint() { return mtlsEndpoint; } + /** The endpoint override */ + public String getEndpointOverride() { + return endpointOverride; + } + /** This method is obsolete. Use {@link #getKeepAliveTimeDuration()} instead. */ @ObsoleteApi("Use getKeepAliveTimeDuration() instead") public org.threeten.bp.Duration getKeepAliveTime() { @@ -744,6 +775,7 @@ public static final class Builder { private HeaderProvider headerProvider; private String endpoint; private String mtlsEndpoint; + private String endpointOverride; private EnvironmentProvider envProvider; private MtlsProvider mtlsProvider = new MtlsProvider(); @Nullable private GrpcInterceptorProvider interceptorProvider; @@ -773,6 +805,7 @@ private Builder(InstantiatingGrpcChannelProvider provider) { this.headerProvider = provider.headerProvider; this.endpoint = provider.endpoint; this.mtlsEndpoint = provider.mtlsEndpoint; + this.endpointOverride = provider.endpointOverride; this.envProvider = provider.envProvider; this.interceptorProvider = provider.interceptorProvider; this.maxInboundMessageSize = provider.maxInboundMessageSize; @@ -842,11 +875,21 @@ public Builder setEndpoint(String endpoint) { } public Builder setMtlsEndpoint(String mtlsEndpoint) { - validateEndpoint(mtlsEndpoint); + if (!mtlsEndpoint.isEmpty()) { + validateEndpoint(mtlsEndpoint); + } this.mtlsEndpoint = mtlsEndpoint; return this; } + public Builder setEndpointOverride(String endpointOverride) { + if (!endpointOverride.isEmpty()) { + validateEndpoint(endpointOverride); + } + this.endpointOverride = endpointOverride; + return this; + } + @VisibleForTesting Builder setMtlsProvider(MtlsProvider mtlsProvider) { this.mtlsProvider = mtlsProvider; @@ -873,6 +916,10 @@ public String getMtlsEndpoint() { return mtlsEndpoint; } + public String getEndpointOverride() { + return endpointOverride; + } + /** The maximum message size allowed to be received on the channel. */ public Builder setMaxInboundMessageSize(Integer max) { this.maxInboundMessageSize = max; diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index 8e207d55b8..a30b9ed244 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -86,6 +86,7 @@ class InstantiatingGrpcChannelProviderTest extends AbstractMtlsTransportChannelTest { private static final String DEFAULT_ENDPOINT = "test.googleapis.com:443"; private static final String DEFAULT_MTLS_ENDPOINT = "test.mtls.googleapis.com:443"; + private static final String DEFAULT_ENDPOINT_OVERRIDE = "test.endpoint.com:443"; private static final String API_KEY_HEADER_VALUE = "fake_api_key_2"; private static final String API_KEY_AUTH_HEADER_KEY = "x-goog-api-key"; private static String originalOSName; @@ -161,6 +162,32 @@ void testMtlsEndpointBadPort() { .setEndpoint("test.mtls.googleapis.com:abcd")); } + @Test + void testEndpointOverrideEndpoint() { + InstantiatingGrpcChannelProvider.Builder builder = + InstantiatingGrpcChannelProvider.newBuilder(); + builder.setEndpointOverride(DEFAULT_ENDPOINT_OVERRIDE); + assertEquals(builder.getEndpointOverride(), DEFAULT_ENDPOINT_OVERRIDE); + + InstantiatingGrpcChannelProvider provider = builder.build(); + assertEquals(provider.getEndpointOverride(), DEFAULT_ENDPOINT_OVERRIDE); + } + + @Test + void testEndpointOverrideNoPort() { + assertThrows( + IllegalArgumentException.class, + () -> + InstantiatingGrpcChannelProvider.newBuilder().setEndpointOverride("test.endpoint.com")); + } + + @Test + void testEndpointOverrideBadPort() { + assertThrows( + IllegalArgumentException.class, + () -> InstantiatingGrpcChannelProvider.newBuilder().setEndpoint("test.endpoint.com:abcd")); + } + @Test void testKeepAlive() { final long millis = 15; @@ -1041,8 +1068,9 @@ void shouldUseS2A_envVarNotSet_returnsFalse() { .thenReturn("false"); InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() - .setEndpoint(DEFAULT_MTLS_ENDPOINT) + .setEndpoint(DEFAULT_ENDPOINT) .setMtlsEndpoint(DEFAULT_MTLS_ENDPOINT) + .setEndpointOverride("") .setEnvProvider(envProvider) .build(); Truth.assertThat(provider.shouldUseS2A()).isFalse(); @@ -1056,6 +1084,8 @@ void shouldUseS2A_mtlsEndpointNotSet_returnsFalse() { InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setEndpoint(DEFAULT_ENDPOINT) + .setMtlsEndpoint("") + .setEndpointOverride("") .setEnvProvider(envProvider) .build(); Truth.assertThat(provider.shouldUseS2A()).isFalse(); @@ -1070,6 +1100,7 @@ void shouldUseS2A_endpointOverrideIsSet_returnsFalse() { InstantiatingGrpcChannelProvider.newBuilder() .setEndpoint(DEFAULT_ENDPOINT) .setMtlsEndpoint(DEFAULT_MTLS_ENDPOINT) + .setEndpointOverride(DEFAULT_ENDPOINT_OVERRIDE) .setEnvProvider(envProvider) .build(); Truth.assertThat(provider.shouldUseS2A()).isFalse(); @@ -1082,8 +1113,9 @@ void shouldUseS2A_nonGDUUniverse_returnsFalse() { .thenReturn("true"); InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() - .setEndpoint("test.mtls.abcd.com:443") + .setEndpoint("test.abcd.com:443") .setMtlsEndpoint("test.mtls.abcd.com:443") + .setEndpointOverride("") .setEnvProvider(envProvider) .build(); Truth.assertThat(provider.shouldUseS2A()).isFalse(); @@ -1096,8 +1128,9 @@ void shouldUseS2A_returnsTrue() { .thenReturn("true"); InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() - .setEndpoint(DEFAULT_MTLS_ENDPOINT) + .setEndpoint(DEFAULT_ENDPOINT) .setMtlsEndpoint(DEFAULT_MTLS_ENDPOINT) + .setEndpointOverride("") .setEnvProvider(envProvider) .build(); Truth.assertThat(provider.shouldUseS2A()).isTrue(); diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java index 165fc8fcbb..13195b8b11 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java @@ -106,6 +106,11 @@ public boolean needsMtlsEndpoint() { return false; } + @Override + public boolean needsEndpointOverride() { + return false; + } + @Override public TransportChannelProvider withEndpoint(String endpoint) { throw new UnsupportedOperationException("LocalChannelProvider doesn't need an endpoint"); @@ -116,6 +121,12 @@ public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { throw new UnsupportedOperationException("LocalChannelProvider doesn't need an mtlsEndpoint"); } + @Override + public TransportChannelProvider withEndpointOverride(String endpointOverride) { + throw new UnsupportedOperationException( + "LocalChannelProvider doesn't need an endpointOverride"); + } + @Override @BetaApi("The surface for customizing pool size is not stable yet and may change in the future.") public boolean acceptsPoolSize() { diff --git a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java index b183c1d348..be673ff20c 100644 --- a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java +++ b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java @@ -124,6 +124,11 @@ public boolean needsMtlsEndpoint() { return false; } + @Override + public boolean needsEndpointOverride() { + return false; + } + @Override public TransportChannelProvider withEndpoint(String endpoint) { return toBuilder().setEndpoint(endpoint).build(); @@ -135,6 +140,12 @@ public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { "InstantiatingHttpJsonChannelProvider doesn't need an mtlsEndpoint"); } + @Override + public TransportChannelProvider withEndpointOverride(String endpointOverride) { + throw new UnsupportedOperationException( + "InstantiatingHttpJsonChannelProvider doesn't need an endpointOverride"); + } + /** @deprecated REST transport channel doesn't support channel pooling */ @Deprecated @Override diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java index 59911961be..54f49cb68f 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java @@ -178,7 +178,10 @@ public static ClientContext create(StubSettings settings) throws IOException { // A valid EndpointContext should have been created in the StubSettings EndpointContext endpointContext = settings.getEndpointContext(); String endpoint = endpointContext.resolvedEndpoint(); - String mtlsEndpoint = settings.getMtlsEndpoint(); + String mtlsEndpoint = ""; + mtlsEndpoint = settings.getMtlsEndpoint(); + String endpointOverride = ""; + endpointOverride = settings.getEndpointContext().transportChannelProviderEndpoint(); Credentials credentials = getCredentials(settings); // check if need to adjust credentials/endpoint/endpointContext for GDC-H String settingsGdchApiAudience = settings.getGdchApiAudience(); @@ -190,6 +193,9 @@ public static ClientContext create(StubSettings settings) throws IOException { endpointContext = endpointContext.withGDCH(); // Resolve the new endpoint with the GDC-H flow endpoint = endpointContext.resolvedEndpoint(); + // Skip S2A in GDC-H. + mtlsEndpoint = ""; + endpointOverride = ""; // We recompute the GdchCredentials with the audience credentials = getGdchCredentials(settingsGdchApiAudience, endpoint, credentials); } else if (!Strings.isNullOrEmpty(settingsGdchApiAudience)) { @@ -226,6 +232,9 @@ public static ClientContext create(StubSettings settings) throws IOException { if (transportChannelProvider.needsMtlsEndpoint()) { transportChannelProvider = transportChannelProvider.withMtlsEndpoint(mtlsEndpoint); } + if (transportChannelProvider.needsMtlsEndpoint()) { + transportChannelProvider = transportChannelProvider.withEndpointOverride(endpointOverride); + } TransportChannel transportChannel = transportChannelProvider.getTransportChannel(); ApiCallContext defaultCallContext = diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java index 38df360f17..50276efa68 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java @@ -88,6 +88,11 @@ public boolean needsMtlsEndpoint() { return false; } + @Override + public boolean needsEndpointOverride() { + return false; + } + @Override public TransportChannelProvider withEndpoint(String endpoint) { throw new UnsupportedOperationException( @@ -100,6 +105,12 @@ public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { "FixedTransportChannelProvider doesn't need an mtlsEndpoint"); } + @Override + public TransportChannelProvider withEndpointOverride(String endpointOverride) { + throw new UnsupportedOperationException( + "FixedTransportChannelProvider doesn't need an endpointOverride"); + } + /** @deprecated FixedTransportChannelProvider doesn't support ChannelPool configuration */ @Deprecated @Override diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java index 30b7441ac1..e3fc61265b 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java @@ -93,6 +93,9 @@ public interface TransportChannelProvider { /** True if the TransportProvider has no mtlsEndpoint set. */ boolean needsMtlsEndpoint(); + /** True if the TransportProvider has no endpointOverride set */ + boolean needsEndpointOverride(); + /** * Sets the endpoint to use when constructing a new {@link TransportChannel}. * @@ -107,6 +110,13 @@ public interface TransportChannelProvider { */ TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint); + /** + * Sets the endpoint override when constructing a new {@link TransportChannel}. + * + *

This method should only be called if {@link #needsEndpointOverride()} returns true. + */ + TransportChannelProvider withEndpointOverride(String endpointOverride); + /** * Reports whether this provider allows pool size customization. * diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java index 1dd69e6ebe..c0b21dc070 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java @@ -75,6 +75,7 @@ class ClientContextTest { private static final String DEFAULT_ENDPOINT = "test.googleapis.com"; private static final String DEFAULT_MTLS_ENDPOINT = "test.mtls.googleapis.com"; + private static final String DEFAULT_ENDPOINT_OVERRIDE = "transport.endpoint.com"; private static final String DEFAULT_UNIVERSE_DOMAIN = "googleapis.com"; private static class InterceptingExecutor extends ScheduledThreadPoolExecutor { @@ -117,6 +118,7 @@ private static class FakeTransportProvider implements TransportChannelProvider { final Credentials credentials; final String endpoint; final String mtlsEndpoint; + final String endpointOverride; FakeTransportProvider( FakeTransportChannel transport, @@ -125,7 +127,8 @@ private static class FakeTransportProvider implements TransportChannelProvider { Map headers, Credentials credentials, String endpoint, - String mtlsEndpoint) { + String mtlsEndpoint, + String endpointOverride) { this.transport = transport; this.executor = executor; this.shouldAutoClose = shouldAutoClose; @@ -134,6 +137,7 @@ private static class FakeTransportProvider implements TransportChannelProvider { this.credentials = credentials; this.endpoint = endpoint; this.mtlsEndpoint = mtlsEndpoint; + this.endpointOverride = endpointOverride; } @Override @@ -160,7 +164,8 @@ public TransportChannelProvider withExecutor(Executor executor) { this.headers, this.credentials, this.endpoint, - this.mtlsEndpoint); + this.mtlsEndpoint, + this.endpointOverride); } @Override @@ -177,7 +182,8 @@ public TransportChannelProvider withHeaders(Map headers) { headers, this.credentials, this.endpoint, - this.mtlsEndpoint); + this.mtlsEndpoint, + this.endpointOverride); } @Override @@ -190,6 +196,11 @@ public boolean needsMtlsEndpoint() { return true; } + @Override + public boolean needsEndpointOverride() { + return true; + } + @Override public String getEndpoint() { return endpoint; @@ -204,7 +215,8 @@ public TransportChannelProvider withEndpoint(String endpoint) { this.headers, this.credentials, endpoint, - this.mtlsEndpoint); + this.mtlsEndpoint, + this.endpointOverride); } @Override @@ -216,7 +228,21 @@ public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { this.headers, this.credentials, this.endpoint, - mtlsEndpoint); + mtlsEndpoint, + this.endpointOverride); + } + + @Override + public TransportChannelProvider withEndpointOverride(String endpointOverride) { + return new FakeTransportProvider( + this.transport, + this.executor, + this.shouldAutoClose, + this.headers, + this.credentials, + this.endpoint, + this.mtlsEndpoint, + endpointOverride); } @Override @@ -255,7 +281,8 @@ public TransportChannelProvider withCredentials(Credentials credentials) { this.headers, credentials, this.endpoint, - this.mtlsEndpoint); + this.mtlsEndpoint, + this.endpointOverride); } } @@ -304,7 +331,8 @@ private void runTest( needHeaders ? null : headers, null, DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT); + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); Credentials credentials = Mockito.mock(Credentials.class); ApiClock clock = Mockito.mock(ApiClock.class); Watchdog watchdog = @@ -379,7 +407,14 @@ void testWatchdogProvider() throws IOException { FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = new FakeTransportProvider( - transportChannel, executor, true, null, null, DEFAULT_ENDPOINT, DEFAULT_MTLS_ENDPOINT); + transportChannel, + executor, + true, + null, + null, + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); ApiClock clock = Mockito.mock(ApiClock.class); builder.setClock(clock); @@ -419,7 +454,14 @@ void testMergeHeaders_getQuotaProjectIdFromHeadersProvider() throws IOException FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = new FakeTransportProvider( - transportChannel, executor, true, null, null, DEFAULT_ENDPOINT, DEFAULT_MTLS_ENDPOINT); + transportChannel, + executor, + true, + null, + null, + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); HeaderProvider headerProvider = Mockito.mock(HeaderProvider.class); Mockito.when(headerProvider.getHeaders()).thenReturn(ImmutableMap.of("header_k1", "v1")); @@ -456,7 +498,14 @@ void testMergeHeaders_getQuotaProjectIdFromSettings() throws IOException { FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = new FakeTransportProvider( - transportChannel, executor, true, null, null, DEFAULT_ENDPOINT, DEFAULT_MTLS_ENDPOINT); + transportChannel, + executor, + true, + null, + null, + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); HeaderProvider headerProvider = new HeaderProvider() { @@ -503,7 +552,14 @@ void testMergeHeaders_noQuotaProjectIdSet() throws IOException { FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = new FakeTransportProvider( - transportChannel, executor, true, null, null, DEFAULT_ENDPOINT, DEFAULT_MTLS_ENDPOINT); + transportChannel, + executor, + true, + null, + null, + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); HeaderProvider headerProvider = Mockito.mock(HeaderProvider.class); Mockito.when(headerProvider.getHeaders()).thenReturn(ImmutableMap.of("header_k1", "v1")); @@ -535,7 +591,14 @@ void testHidingQuotaProjectId_quotaSetFromSetting() throws IOException { FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = new FakeTransportProvider( - transportChannel, executor, true, null, null, DEFAULT_ENDPOINT, DEFAULT_MTLS_ENDPOINT); + transportChannel, + executor, + true, + null, + null, + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); Map> metaDataWithQuota = ImmutableMap.of( "k1", @@ -577,7 +640,14 @@ void testHidingQuotaProjectId_noQuotaSetFromSetting() throws IOException { FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = new FakeTransportProvider( - transportChannel, executor, true, null, null, DEFAULT_ENDPOINT, DEFAULT_MTLS_ENDPOINT); + transportChannel, + executor, + true, + null, + null, + DEFAULT_ENDPOINT, + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); Map> metaData = ImmutableMap.of("k1", Collections.singletonList("v1")); final Credentials credentialsWithoutQuotaProjectId = Mockito.mock(GoogleCredentials.class); Mockito.when(credentialsWithoutQuotaProjectId.getRequestMetadata(null)).thenReturn(metaData); @@ -614,7 +684,8 @@ void testQuotaProjectId_worksWithNullCredentials() throws IOException { null, Mockito.mock(Credentials.class), DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT); + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); final FakeClientSettings.Builder settingsBuilder = new FakeClientSettings.Builder(); @@ -636,7 +707,8 @@ void testUserAgentInternalOnly() throws Exception { null, null, DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT); + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -665,7 +737,8 @@ void testUserAgentExternalOnly() throws Exception { null, null, DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT); + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -694,7 +767,8 @@ void testUserAgentConcat() throws Exception { null, null, DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT); + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -780,7 +854,8 @@ private Map setupTestForCredentialTokenUsageMetricsAndGetTranspo null, null, DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT); + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -833,7 +908,8 @@ void testExecutorSettings() throws Exception { null, null, DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT); + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -881,7 +957,8 @@ void testExecutorSettings() throws Exception { null, null, DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT)); + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE)); context = ClientContext.create(builder.build()); transportChannel = (FakeTransportChannel) context.getTransportChannel(); assertThat(transportChannel.getExecutor()).isSameInstanceAs(executorProvider.getExecutor()); @@ -909,7 +986,8 @@ private TransportChannelProvider getFakeTransportChannelProvider() { null, null, DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT); + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); } // EndpointContext will construct a valid endpoint if nothing is provided @@ -917,7 +995,14 @@ private TransportChannelProvider getFakeTransportChannelProvider() { void testCreateClientContext_withGdchCredentialNoAudienceNoEndpoint() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null, null); + FakeTransportChannel.create(new FakeChannel()), + null, + true, + null, + null, + null, + null, + null); Credentials creds = getMockGdchCredentials(); CredentialsProvider provider = FixedCredentialsProvider.create(creds); @@ -944,7 +1029,14 @@ void testCreateClientContext_withGdchCredentialNoAudienceEmptyEndpoint_throws() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null, null); + FakeTransportChannel.create(new FakeChannel()), + null, + true, + null, + null, + null, + null, + null); Credentials creds = getMockGdchCredentials(); CredentialsProvider provider = FixedCredentialsProvider.create(creds); @@ -967,7 +1059,14 @@ void testCreateClientContext_withGdchCredentialWithoutAudienceWithEndpoint_corre throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null, null); + FakeTransportChannel.create(new FakeChannel()), + null, + true, + null, + null, + null, + null, + null); Credentials creds = getMockGdchCredentials(); // it should correctly create a client context with gdch creds and null audience @@ -1079,7 +1178,14 @@ void testCreateClientContext_withNonGdchCredentialAndAnyAudience_throws() throws void testCreateClientContext_SetEndpointViaClientSettings() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null, null); + FakeTransportChannel.create(new FakeChannel()), + null, + true, + null, + null, + null, + null, + null); StubSettings settings = new FakeStubSettings.Builder() .setEndpoint(DEFAULT_ENDPOINT) @@ -1106,6 +1212,7 @@ void testCreateClientContext_SetEndpointViaTransportChannelProvider() throws IOE null, null, transportChannelProviderEndpoint, + null, null); StubSettings settings = new FakeStubSettings.Builder() @@ -1135,6 +1242,7 @@ void testCreateClientContext_SetEndpointViaClientSettingsAndTransportChannelProv null, null, transportChannelProviderEndpoint, + null, null); StubSettings settings = new FakeStubSettings.Builder() @@ -1158,7 +1266,14 @@ void testCreateClientContext_SetEndpointViaClientSettingsAndTransportChannelProv void testCreateClientContext_doNotSetUniverseDomain() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null, null); + FakeTransportChannel.create(new FakeChannel()), + null, + true, + null, + null, + null, + null, + null); StubSettings settings = new FakeStubSettings.Builder() .setEndpoint(null) @@ -1177,7 +1292,14 @@ void testCreateClientContext_doNotSetUniverseDomain() throws IOException { void testCreateClientContext_setUniverseDomain() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null, null); + FakeTransportChannel.create(new FakeChannel()), + null, + true, + null, + null, + null, + null, + null); String universeDomain = "testdomain.com"; StubSettings settings = new FakeStubSettings.Builder().setEndpoint(null).setUniverseDomain(universeDomain).build(); @@ -1216,7 +1338,8 @@ void testSetApiKey_createsApiCredentials() throws IOException { ImmutableMap.of(), null, DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT); + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); builder.setTransportChannelProvider(transportProvider); HeaderProvider headerProvider = Mockito.mock(HeaderProvider.class); Mockito.when(headerProvider.getHeaders()).thenReturn(ImmutableMap.of()); @@ -1243,7 +1366,8 @@ void testSetApiKey_withDefaultCredentials_overridesCredentials() throws IOExcept ImmutableMap.of(), null, DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT); + DEFAULT_MTLS_ENDPOINT, + DEFAULT_ENDPOINT_OVERRIDE); builder.setTransportChannelProvider(transportProvider); HeaderProvider headerProvider = Mockito.mock(HeaderProvider.class); Mockito.when(headerProvider.getHeaders()).thenReturn(ImmutableMap.of()); From 7ef73130ed380dbe3df2bc3b4a60cf41d9a4ec0e Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Fri, 1 Nov 2024 15:47:01 -0700 Subject: [PATCH 06/51] fix typo --- .../gax/src/main/java/com/google/api/gax/rpc/ClientContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java index 54f49cb68f..cdaef6cb9c 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java @@ -232,7 +232,7 @@ public static ClientContext create(StubSettings settings) throws IOException { if (transportChannelProvider.needsMtlsEndpoint()) { transportChannelProvider = transportChannelProvider.withMtlsEndpoint(mtlsEndpoint); } - if (transportChannelProvider.needsMtlsEndpoint()) { + if (transportChannelProvider.needsEndpointOverride()) { transportChannelProvider = transportChannelProvider.withEndpointOverride(endpointOverride); } TransportChannel transportChannel = transportChannelProvider.getTransportChannel(); From 6d98115303f98decd5a9c151e85f8c8d52e2f01f Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Mon, 4 Nov 2024 05:26:38 -0800 Subject: [PATCH 07/51] cleanup. --- .../api/gax/grpc/InstantiatingGrpcChannelProvider.java | 7 +------ .../gax/grpc/InstantiatingGrpcChannelProviderTest.java | 10 ++++++---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 1ec74ec7f4..c1620a87ac 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -476,11 +476,7 @@ ChannelCredentials createMtlsChannelCredentials() throws IOException, GeneralSec @VisibleForTesting boolean isGoogleS2AEnabled() { String S2AEnv = envProvider.getenv(S2A_ENV_ENABLE_USE_S2A); - boolean isS2AEnv = Boolean.parseBoolean(S2AEnv); - if (isS2AEnv) { - return true; - } - return false; + return Boolean.parseBoolean(S2AEnv); } @VisibleForTesting @@ -515,7 +511,6 @@ ChannelCredentials createMtlsToS2AChannelCredentials( .build(); } - @VisibleForTesting ChannelCredentials createS2ASecuredChannelCredentials() { S2A s2aUtils = S2A.newBuilder().build(); String plaintextAddress = s2aUtils.getPlaintextS2AAddress(); diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index a30b9ed244..82e0673814 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -290,6 +290,7 @@ void testToBuilder() { .setProcessorCount(2) .setEndpoint("fake.endpoint:443") .setMtlsEndpoint("fake.endpoint:443") + .setEndpointOverride("fake.endpoint.override:443") .setMaxInboundMessageSize(12345678) .setMaxInboundMetadataSize(4096) .setKeepAliveTimeDuration(keepaliveTime) @@ -304,6 +305,7 @@ void testToBuilder() { assertThat(builder.getEndpoint()).isEqualTo("fake.endpoint:443"); assertThat(builder.getMtlsEndpoint()).isEqualTo("fake.endpoint:443"); + assertThat(builder.getEndpointOverride()).isEqualTo("fake.endpoint.override:443"); assertThat(builder.getMaxInboundMessageSize()).isEqualTo(12345678); assertThat(builder.getMaxInboundMetadataSize()).isEqualTo(4096); assertThat(builder.getKeepAliveTimeDuration()).isEqualTo(keepaliveTime); @@ -1047,18 +1049,18 @@ void isGoogleS2AEnabled_envVarNotSet_returnsFalse() { Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) .thenReturn("false"); InstantiatingGrpcChannelProvider provider = - InstantiatingGrpcChannelProvider.newBuilder().build(); + InstantiatingGrpcChannelProvider.newBuilder().setEnvProvider(envProvider).build(); Truth.assertThat(provider.isGoogleS2AEnabled()).isFalse(); } @Test - void isGoogleS2AEnabled_envVarNotSet_returnsTrue() { + void isGoogleS2AEnabled_envVarSet_returnsTrue() { EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) .thenReturn("true"); InstantiatingGrpcChannelProvider provider = - InstantiatingGrpcChannelProvider.newBuilder().build(); - Truth.assertThat(provider.isGoogleS2AEnabled()).isFalse(); + InstantiatingGrpcChannelProvider.newBuilder().setEnvProvider(envProvider).build(); + Truth.assertThat(provider.isGoogleS2AEnabled()).isTrue(); } @Test From e880fbe1c1a34d7496dd8a4a9d16c0c10d26f9ab Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Mon, 4 Nov 2024 10:40:48 -0800 Subject: [PATCH 08/51] remove unnecessary dependency. --- gapic-generator-java/pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/gapic-generator-java/pom.xml b/gapic-generator-java/pom.xml index f98f297358..37fa43c5b2 100644 --- a/gapic-generator-java/pom.xml +++ b/gapic-generator-java/pom.xml @@ -397,12 +397,10 @@ com.google.api gax-grpc - 2.57.1-SNAPSHOT com.google.api gax-grpc - 2.57.1-SNAPSHOT test-jar testlib From 28adb31ba9fe6ff5d5249189c776acc39c6ca503 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Mon, 4 Nov 2024 11:53:27 -0800 Subject: [PATCH 09/51] add mtlsEndpoint to ClientSettings. --- .../com/google/api/gax/rpc/ClientSettings.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java index 234fd4d19d..88c32a724a 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java @@ -103,6 +103,10 @@ public final String getEndpoint() { return stubSettings.getEndpoint(); } + public final String getMtlsEndpoint() { + return stubSettings.getMtlsEndpoint(); + } + public final String getQuotaProjectId() { return stubSettings.getQuotaProjectId(); } @@ -145,6 +149,7 @@ public String toString() { .add("clock", getClock()) .add("universeDomain", getUniverseDomain()) .add("endpoint", getEndpoint()) + .add("mtlsEndpoint", getMtlsEndpoint()) .add("quotaProjectId", getQuotaProjectId()) .add("watchdogProvider", getWatchdogProvider()) .add("watchdogCheckInterval", getWatchdogCheckInterval()) @@ -272,6 +277,11 @@ public B setEndpoint(String endpoint) { return self(); } + public B setMtlsEndpoint(String mtlsEndpoint) { + stubSettings.setMtlsEndpoint(mtlsEndpoint); + return self(); + } + public B setQuotaProjectId(String quotaProjectId) { stubSettings.setQuotaProjectId(quotaProjectId); return self(); @@ -375,6 +385,10 @@ public String getEndpoint() { return stubSettings.getEndpoint(); } + public String getMtlsEndpoint() { + return stubSettings.getMtlsEndpoint(); + } + /** Gets the QuotaProjectId that was previously set on this Builder. */ public String getQuotaProjectId() { return stubSettings.getQuotaProjectId(); @@ -427,6 +441,7 @@ public String toString() { .add("internalHeaderProvider", getInternalHeaderProvider()) .add("clock", getClock()) .add("endpoint", getEndpoint()) + .add("mtlsEndpoint", getMtlsEndpoint()) .add("quotaProjectId", getQuotaProjectId()) .add("watchdogProvider", getWatchdogProvider()) .add("watchdogCheckInterval", getWatchdogCheckIntervalDuration()) From b3e2e06533cb342dcaed2151e273eb202ab2dca7 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Mon, 4 Nov 2024 12:04:51 -0800 Subject: [PATCH 10/51] add logs. --- .../api/gax/grpc/InstantiatingGrpcChannelProvider.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index c1620a87ac..87f4c2de13 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -528,6 +528,10 @@ ChannelCredentials createS2ASecuredChannelCredentials() { certChain = new FileInputStream(MTLS_MDS_CERT_CHAIN_AND_KEY); } catch (FileNotFoundException ignore) { // Fallback to plaintext-to-S2A connection. + LOG.log( + Level.INFO, + "Cannot establish an mTLS connection to S2A due to error loading MTLS to MDS credentials, falling back to plaintext connection to S2A: " + + ignore.getMessage()); } ChannelCredentials mtlsToS2AChannelCredentials = null; try { @@ -536,6 +540,10 @@ ChannelCredentials createS2ASecuredChannelCredentials() { createMtlsToS2AChannelCredentials(trustBundle, privateKey, certChain); } catch (IOException ignore) { // Fallback to plaintext-to-S2A connection. + LOG.log( + Level.INFO, + "Cannot establish an mTLS connection to S2A due to error creating MTLS to MDS TlsChannelCredentials credentials, falling back to plaintext connection to S2A: " + + ignore.getMessage()); } if (mtlsToS2AChannelCredentials != null) { return S2AChannelCredentials.newBuilder(mtlsAddress, mtlsToS2AChannelCredentials).build(); From 90892ef18cbe99e588d62974b9fcebd6508d1399 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Mon, 4 Nov 2024 12:14:33 -0800 Subject: [PATCH 11/51] remove ignore rule. --- gax-java/gax/clirr-ignored-differences.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/gax-java/gax/clirr-ignored-differences.xml b/gax-java/gax/clirr-ignored-differences.xml index ac33d8b58a..af5c5f26a1 100644 --- a/gax-java/gax/clirr-ignored-differences.xml +++ b/gax-java/gax/clirr-ignored-differences.xml @@ -106,9 +106,4 @@ com/google/api/gax/batching/Batcher * - - 7012 - com/google/api/gax/rpc/TransportChannelProvider - * - From 33b710ce448f13987176ca44bcaf1338a7982fc3 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Mon, 4 Nov 2024 12:20:53 -0800 Subject: [PATCH 12/51] separate into single condition if statements. --- .../api/gax/grpc/InstantiatingGrpcChannelProvider.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 87f4c2de13..bc13ba4ebe 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -486,8 +486,13 @@ boolean shouldUseS2A() { return false; } - // If {@code mtlsEndpoint} is not set, or {@code endpointOverride} is specified, skip S2A. - if (mtlsEndpoint.isEmpty() || !endpointOverride.isEmpty()) { + // If {@code mtlsEndpoint} is not set, skip S2A. + if (mtlsEndpoint.isEmpty()) { + return false; + } + + // If {@code endpointOverride} is specified, skip S2A. + if (!endpointOverride.isEmpty()) { return false; } From b320cc2ee8e0b1ae7a9cc711a20e95b8e827e7d4 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Mon, 4 Nov 2024 13:12:52 -0800 Subject: [PATCH 13/51] add logic to resolve endpointOverride / customEndpoint in EndpointContext.java. --- .../com/google/api/gax/rpc/ClientContext.java | 2 +- .../google/api/gax/rpc/EndpointContext.java | 21 ++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java index cdaef6cb9c..ae7e566f41 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java @@ -181,7 +181,7 @@ public static ClientContext create(StubSettings settings) throws IOException { String mtlsEndpoint = ""; mtlsEndpoint = settings.getMtlsEndpoint(); String endpointOverride = ""; - endpointOverride = settings.getEndpointContext().transportChannelProviderEndpoint(); + endpointOverride = settings.getEndpointContext().customEndpoint(); Credentials credentials = getCredentials(settings); // check if need to adjust credentials/endpoint/endpointContext for GDC-H String settingsGdchApiAudience = settings.getGdchApiAudience(); diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java index dd6c199b35..0c8a97c886 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java @@ -100,6 +100,9 @@ public static EndpointContext getDefaultInstance() { @Nullable public abstract String transportChannelProviderEndpoint(); + @Nullable + public abstract String customEndpoint(); + @Nullable public abstract String mtlsEndpoint(); @@ -196,6 +199,8 @@ public abstract static class Builder { */ public abstract Builder setTransportChannelProviderEndpoint(String transportChannelEndpoint); + public abstract Builder setCustomEndpoint(String customEndpoint); + public abstract Builder setMtlsEndpoint(String mtlsEndpoint); public abstract Builder setSwitchToMtlsEndpointAllowed(boolean switchToMtlsEndpointAllowed); @@ -216,6 +221,8 @@ public abstract static class Builder { abstract String transportChannelProviderEndpoint(); + abstract String customEndpoint(); + abstract String mtlsEndpoint(); abstract boolean switchToMtlsEndpointAllowed(); @@ -255,11 +262,7 @@ private String determineUniverseDomain() { /** Determines the fully resolved endpoint and universe domain values */ private String determineEndpoint() throws IOException { MtlsProvider mtlsProvider = mtlsProvider() == null ? new MtlsProvider() : mtlsProvider(); - // TransportChannelProvider's endpoint will override the ClientSettings' endpoint - String customEndpoint = - transportChannelProviderEndpoint() == null - ? clientSettingsEndpoint() - : transportChannelProviderEndpoint(); + String customEndpoint = customEndpoint(); // GDC-H has a separate flow if (usingGDCH()) { @@ -288,6 +291,13 @@ private String determineEndpoint() throws IOException { return endpoint; } + private String determineCustomEndpoint() { + // TransportChannelProvider's endpoint will override the ClientSettings' endpoint. + return transportChannelProviderEndpoint() == null + ? clientSettingsEndpoint() + : transportChannelProviderEndpoint(); + } + // Default to port 443 for HTTPS. Using HTTP requires explicitly setting the endpoint private String buildEndpointTemplate(String serviceName, String resolvedUniverseDomain) { return serviceName + "." + resolvedUniverseDomain + ":443"; @@ -320,6 +330,7 @@ String mtlsEndpointResolver( public EndpointContext build() throws IOException { // The Universe Domain is used to resolve the Endpoint. It should be resolved first setResolvedUniverseDomain(determineUniverseDomain()); + setCustomEndpoint(determineCustomEndpoint()); setResolvedEndpoint(determineEndpoint()); return autoBuild(); } From 035e17eb56a4c4d74b31994df889593b87e61192 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Mon, 4 Nov 2024 13:23:01 -0800 Subject: [PATCH 14/51] add javadocs. --- .../src/main/java/com/google/api/gax/rpc/ClientSettings.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java index 88c32a724a..4140b5da40 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java @@ -103,6 +103,7 @@ public final String getEndpoint() { return stubSettings.getEndpoint(); } + /** Gets the MTLS endpoint for the service */ public final String getMtlsEndpoint() { return stubSettings.getMtlsEndpoint(); } @@ -277,6 +278,7 @@ public B setEndpoint(String endpoint) { return self(); } + /** Sets the MTLS endpoint for the service */ public B setMtlsEndpoint(String mtlsEndpoint) { stubSettings.setMtlsEndpoint(mtlsEndpoint); return self(); @@ -385,6 +387,7 @@ public String getEndpoint() { return stubSettings.getEndpoint(); } + /** Gets the MTLS endpoint for the service that was previously set on this Builder. */ public String getMtlsEndpoint() { return stubSettings.getMtlsEndpoint(); } From 759c3df3440a09a02077bff21444b1ccb34a204f Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 5 Nov 2024 07:26:03 -0800 Subject: [PATCH 15/51] mtlsendpoint changes. --- .../InstantiatingGrpcChannelProvider.java | 18 +++++++++--------- .../InstantiatingGrpcChannelProviderTest.java | 19 ++++++++++--------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index bc13ba4ebe..66dbbe71ac 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -49,6 +49,7 @@ import com.google.auth.oauth2.S2A; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.io.Files; @@ -265,9 +266,7 @@ public TransportChannelProvider withEndpoint(String endpoint) { */ @Override public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { - if (!mtlsEndpoint.isEmpty()) { - validateEndpoint(mtlsEndpoint); - } + validateEndpoint(mtlsEndpoint); return toBuilder().setMtlsEndpoint(mtlsEndpoint).build(); } @@ -486,13 +485,16 @@ boolean shouldUseS2A() { return false; } - // If {@code mtlsEndpoint} is not set, skip S2A. - if (mtlsEndpoint.isEmpty()) { + // If {@code mtlsEndpoint} is not set, skip S2A. GAPIC clients have + // an auto-populated default mTLS endpoint, so this check is technically + // not needed. It is kept to ensure that initialization code + // sets the {@code mtlsEndpoint} needed to use S2A. + if (Strings.isNullOrEmpty(mtlsEndpoint)) { return false; } // If {@code endpointOverride} is specified, skip S2A. - if (!endpointOverride.isEmpty()) { + if (!Strings.isNullOrEmpty(endpointOverride)) { return false; } @@ -883,9 +885,7 @@ public Builder setEndpoint(String endpoint) { } public Builder setMtlsEndpoint(String mtlsEndpoint) { - if (!mtlsEndpoint.isEmpty()) { - validateEndpoint(mtlsEndpoint); - } + validateEndpoint(mtlsEndpoint); this.mtlsEndpoint = mtlsEndpoint; return this; } diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index 82e0673814..dde5e4ad34 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -1079,18 +1079,19 @@ void shouldUseS2A_envVarNotSet_returnsFalse() { } @Test - void shouldUseS2A_mtlsEndpointNotSet_returnsFalse() { + void shouldUseS2A_mtlsEndpointNotSet_throws() { EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) .thenReturn("true"); - InstantiatingGrpcChannelProvider provider = - InstantiatingGrpcChannelProvider.newBuilder() - .setEndpoint(DEFAULT_ENDPOINT) - .setMtlsEndpoint("") - .setEndpointOverride("") - .setEnvProvider(envProvider) - .build(); - Truth.assertThat(provider.shouldUseS2A()).isFalse(); + assertThrows( + IllegalArgumentException.class, + () -> + InstantiatingGrpcChannelProvider.newBuilder() + .setEndpoint(DEFAULT_ENDPOINT) + .setMtlsEndpoint("") + .setEndpointOverride("") + .setEnvProvider(envProvider) + .build()); } @Test From c096cb7769234fa387fe6eb8bebc71d2369261ba Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 5 Nov 2024 07:32:38 -0800 Subject: [PATCH 16/51] isS2AEnabled. --- .../api/gax/grpc/InstantiatingGrpcChannelProvider.java | 4 ++-- .../gax/grpc/InstantiatingGrpcChannelProviderTest.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 66dbbe71ac..3ebcd10375 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -473,7 +473,7 @@ ChannelCredentials createMtlsChannelCredentials() throws IOException, GeneralSec } @VisibleForTesting - boolean isGoogleS2AEnabled() { + boolean isS2AEnabled() { String S2AEnv = envProvider.getenv(S2A_ENV_ENABLE_USE_S2A); return Boolean.parseBoolean(S2AEnv); } @@ -481,7 +481,7 @@ boolean isGoogleS2AEnabled() { @VisibleForTesting boolean shouldUseS2A() { // If EXPERIMENTAL_GOOGLE_API_USE_S2A is not set to true, skip S2A. - if (!isGoogleS2AEnabled()) { + if (!isS2AEnabled()) { return false; } diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index dde5e4ad34..cdefa485e7 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -1044,23 +1044,23 @@ private FixedHeaderProvider getHeaderProviderWithApiKeyHeader() { } @Test - void isGoogleS2AEnabled_envVarNotSet_returnsFalse() { + void isS2AEnabled_envVarNotSet_returnsFalse() { EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) .thenReturn("false"); InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder().setEnvProvider(envProvider).build(); - Truth.assertThat(provider.isGoogleS2AEnabled()).isFalse(); + Truth.assertThat(provider.isS2AEnabled()).isFalse(); } @Test - void isGoogleS2AEnabled_envVarSet_returnsTrue() { + void isS2AEnabled_envVarSet_returnsTrue() { EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) .thenReturn("true"); InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder().setEnvProvider(envProvider).build(); - Truth.assertThat(provider.isGoogleS2AEnabled()).isTrue(); + Truth.assertThat(provider.isS2AEnabled()).isTrue(); } @Test From dc4b61e5dfacb93a80e827a245c45d83d1b87707 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 5 Nov 2024 12:05:47 -0800 Subject: [PATCH 17/51] expose endpointContext. --- .../InstantiatingGrpcChannelProvider.java | 134 ++-------- .../InstantiatingGrpcChannelProviderTest.java | 157 ------------ .../grpc/testing/LocalChannelProvider.java | 26 +- .../InstantiatingHttpJsonChannelProvider.java | 18 +- .../com/google/api/gax/rpc/ClientContext.java | 14 +- .../google/api/gax/rpc/ClientSettings.java | 18 -- .../google/api/gax/rpc/EndpointContext.java | 55 +++- .../rpc/FixedTransportChannelProvider.java | 17 +- .../api/gax/rpc/TransportChannelProvider.java | 22 +- .../google/api/gax/rpc/ClientContextTest.java | 235 +++--------------- .../api/gax/rpc/EndpointContextTest.java | 94 +++++++ 11 files changed, 218 insertions(+), 572 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 3ebcd10375..2b17b43326 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -37,6 +37,7 @@ import com.google.api.core.InternalApi; import com.google.api.core.ObsoleteApi; import com.google.api.gax.core.ExecutorProvider; +import com.google.api.gax.rpc.EndpointContext; import com.google.api.gax.rpc.FixedHeaderProvider; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.TransportChannel; @@ -49,7 +50,6 @@ import com.google.auth.oauth2.S2A; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; -import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.io.Files; @@ -106,8 +106,6 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP @VisibleForTesting static final String DIRECT_PATH_ENV_ENABLE_XDS = "GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS"; - @VisibleForTesting static final String S2A_ENV_ENABLE_USE_S2A = "EXPERIMENTAL_GOOGLE_API_USE_S2A"; - private static final String MTLS_MDS_ROOT = "/run/google-mds-mtls/root.crt"; // The mTLS MDS credentials are formatted as the concatenation of a PEM-encoded certificate chain // followed by a PEM-encoded private key. @@ -121,14 +119,11 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP private final int processorCount; private final Executor executor; private final HeaderProvider headerProvider; + private final EndpointContext endpointContext; private final String endpoint; - private final String mtlsEndpoint; - private final String endpointOverride; - // TODO: remove. - // envProvider currently provides DirectPath and S2A environment variables, and is only used - // during initial rollout for DirectPath and S2A. This provider will be removed once the - // DirectPath - // and S2A environment variables are not used. + // TODO: remove. envProvider currently provides DirectPath environment variable, and is only used + // during initial rollout for DirectPath. This provider will be removed once the DirectPath + // environment is not used. private final EnvironmentProvider envProvider; @Nullable private final GrpcInterceptorProvider interceptorProvider; @Nullable private final Integer maxInboundMessageSize; @@ -154,8 +149,7 @@ private InstantiatingGrpcChannelProvider(Builder builder) { this.executor = builder.executor; this.headerProvider = builder.headerProvider; this.endpoint = builder.endpoint; - this.mtlsEndpoint = builder.mtlsEndpoint; - this.endpointOverride = builder.endpointOverride; + this.endpointContext = builder.endpointContext; this.mtlsProvider = builder.mtlsProvider; this.envProvider = builder.envProvider; this.interceptorProvider = builder.interceptorProvider; @@ -232,13 +226,8 @@ public boolean needsEndpoint() { } @Override - public boolean needsMtlsEndpoint() { - return mtlsEndpoint == null; - } - - @Override - public boolean needsEndpointOverride() { - return endpointOverride == null; + public boolean needsEndpointContext() { + return endpointContext == null; } /** @@ -256,35 +245,14 @@ public TransportChannelProvider withEndpoint(String endpoint) { } /** - * Specify the MTLS endpoint. - * - *

The value of {@code mtlsEndpoint} must be of the form {@code host:port}. - * - * @param mtlsEndpoint - * @return A new {@link InstantiatingGrpcChannelProvider} with the specified MTLS endpoint - * configured - */ - @Override - public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { - validateEndpoint(mtlsEndpoint); - return toBuilder().setMtlsEndpoint(mtlsEndpoint).build(); - } - - /** - * Specify the endpoint override. - * - *

The value of {@code endpointOverride} must be of the form {@code host:port}. + * Specify the {@link EndpointContext}. * - * @param endpointOverride - * @return A new {@link InstantiatingGrpcChannelProvider} with the specified endpoint Override - * configured + * @param endpointContext + * @return A new {@link InstantiatingGrpcChannelProvider} with the endpointContext */ @Override - public TransportChannelProvider withEndpointOverride(String endpointOverride) { - if (!endpointOverride.isEmpty()) { - validateEndpoint(endpointOverride); - } - return toBuilder().setEndpointOverride(endpointOverride).build(); + public TransportChannelProvider withEndpointContext(EndpointContext endpointContext) { + return toBuilder().setEndpointContext(endpointContext).build(); } /** @deprecated Please modify pool settings via {@link #toBuilder()} */ @@ -472,40 +440,6 @@ ChannelCredentials createMtlsChannelCredentials() throws IOException, GeneralSec return null; } - @VisibleForTesting - boolean isS2AEnabled() { - String S2AEnv = envProvider.getenv(S2A_ENV_ENABLE_USE_S2A); - return Boolean.parseBoolean(S2AEnv); - } - - @VisibleForTesting - boolean shouldUseS2A() { - // If EXPERIMENTAL_GOOGLE_API_USE_S2A is not set to true, skip S2A. - if (!isS2AEnabled()) { - return false; - } - - // If {@code mtlsEndpoint} is not set, skip S2A. GAPIC clients have - // an auto-populated default mTLS endpoint, so this check is technically - // not needed. It is kept to ensure that initialization code - // sets the {@code mtlsEndpoint} needed to use S2A. - if (Strings.isNullOrEmpty(mtlsEndpoint)) { - return false; - } - - // If {@code endpointOverride} is specified, skip S2A. - if (!Strings.isNullOrEmpty(endpointOverride)) { - return false; - } - - // mTLS via S2A is not supported in any universe other than googleapis.com. - if (!mtlsEndpoint.contains(Credentials.GOOGLE_DEFAULT_UNIVERSE)) { - return false; - } - - return true; - } - @VisibleForTesting ChannelCredentials createMtlsToS2AChannelCredentials( InputStream trustBundle, InputStream privateKey, InputStream certChain) throws IOException { @@ -617,12 +551,12 @@ private ManagedChannel createSingleChannel() throws IOException { // Could not create channel credentials via DCA. In accordance with // https://google.aip.dev/auth/4115, if credentials not available through // DCA, try mTLS with credentials held by the S2A (Secure Session Agent). - if (shouldUseS2A()) { + if ((endpointContext != null) && endpointContext.useS2A()) { channelCredentials = createS2ASecuredChannelCredentials(); } if (channelCredentials != null) { // Create the channel using S2A-secured channel credentials. - builder = Grpc.newChannelBuilder(mtlsEndpoint, channelCredentials); + builder = Grpc.newChannelBuilder(endpointContext.mtlsEndpoint(), channelCredentials); } else { // Use default if we cannot initialize channel credentials via DCA or S2A. builder = ManagedChannelBuilder.forAddress(serviceAddress, port); @@ -717,14 +651,9 @@ public String getEndpoint() { return endpoint; } - /** The mTLS endpoint. */ - public String getMtlsEndpoint() { - return mtlsEndpoint; - } - - /** The endpoint override */ - public String getEndpointOverride() { - return endpointOverride; + /** The endpoint context. */ + public EndpointContext getEndpointContext() { + return endpointContext; } /** This method is obsolete. Use {@link #getKeepAliveTimeDuration()} instead. */ @@ -784,8 +713,7 @@ public static final class Builder { private Executor executor; private HeaderProvider headerProvider; private String endpoint; - private String mtlsEndpoint; - private String endpointOverride; + private EndpointContext endpointContext; private EnvironmentProvider envProvider; private MtlsProvider mtlsProvider = new MtlsProvider(); @Nullable private GrpcInterceptorProvider interceptorProvider; @@ -814,8 +742,7 @@ private Builder(InstantiatingGrpcChannelProvider provider) { this.executor = provider.executor; this.headerProvider = provider.headerProvider; this.endpoint = provider.endpoint; - this.mtlsEndpoint = provider.mtlsEndpoint; - this.endpointOverride = provider.endpointOverride; + this.endpointContext = provider.endpointContext; this.envProvider = provider.envProvider; this.interceptorProvider = provider.interceptorProvider; this.maxInboundMessageSize = provider.maxInboundMessageSize; @@ -884,17 +811,8 @@ public Builder setEndpoint(String endpoint) { return this; } - public Builder setMtlsEndpoint(String mtlsEndpoint) { - validateEndpoint(mtlsEndpoint); - this.mtlsEndpoint = mtlsEndpoint; - return this; - } - - public Builder setEndpointOverride(String endpointOverride) { - if (!endpointOverride.isEmpty()) { - validateEndpoint(endpointOverride); - } - this.endpointOverride = endpointOverride; + public Builder setEndpointContext(EndpointContext endpointContext) { + this.endpointContext = endpointContext; return this; } @@ -920,12 +838,8 @@ public String getEndpoint() { return endpoint; } - public String getMtlsEndpoint() { - return mtlsEndpoint; - } - - public String getEndpointOverride() { - return endpointOverride; + public EndpointContext getEndpointContext() { + return endpointContext; } /** The maximum message size allowed to be received on the channel. */ diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index cdefa485e7..c920937e6c 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -85,8 +85,6 @@ class InstantiatingGrpcChannelProviderTest extends AbstractMtlsTransportChannelTest { private static final String DEFAULT_ENDPOINT = "test.googleapis.com:443"; - private static final String DEFAULT_MTLS_ENDPOINT = "test.mtls.googleapis.com:443"; - private static final String DEFAULT_ENDPOINT_OVERRIDE = "test.endpoint.com:443"; private static final String API_KEY_HEADER_VALUE = "fake_api_key_2"; private static final String API_KEY_AUTH_HEADER_KEY = "x-goog-api-key"; private static String originalOSName; @@ -133,61 +131,6 @@ void testEndpointBadPort() { () -> InstantiatingGrpcChannelProvider.newBuilder().setEndpoint("localhost:abcd")); } - @Test - void testMtlsEndpoint() { - InstantiatingGrpcChannelProvider.Builder builder = - InstantiatingGrpcChannelProvider.newBuilder(); - builder.setMtlsEndpoint(DEFAULT_MTLS_ENDPOINT); - assertEquals(builder.getMtlsEndpoint(), DEFAULT_MTLS_ENDPOINT); - - InstantiatingGrpcChannelProvider provider = builder.build(); - assertEquals(provider.getMtlsEndpoint(), DEFAULT_MTLS_ENDPOINT); - } - - @Test - void testMtlsEndpointNoPort() { - assertThrows( - IllegalArgumentException.class, - () -> - InstantiatingGrpcChannelProvider.newBuilder() - .setMtlsEndpoint("test.mtls.googleapis.com")); - } - - @Test - void testMtlsEndpointBadPort() { - assertThrows( - IllegalArgumentException.class, - () -> - InstantiatingGrpcChannelProvider.newBuilder() - .setEndpoint("test.mtls.googleapis.com:abcd")); - } - - @Test - void testEndpointOverrideEndpoint() { - InstantiatingGrpcChannelProvider.Builder builder = - InstantiatingGrpcChannelProvider.newBuilder(); - builder.setEndpointOverride(DEFAULT_ENDPOINT_OVERRIDE); - assertEquals(builder.getEndpointOverride(), DEFAULT_ENDPOINT_OVERRIDE); - - InstantiatingGrpcChannelProvider provider = builder.build(); - assertEquals(provider.getEndpointOverride(), DEFAULT_ENDPOINT_OVERRIDE); - } - - @Test - void testEndpointOverrideNoPort() { - assertThrows( - IllegalArgumentException.class, - () -> - InstantiatingGrpcChannelProvider.newBuilder().setEndpointOverride("test.endpoint.com")); - } - - @Test - void testEndpointOverrideBadPort() { - assertThrows( - IllegalArgumentException.class, - () -> InstantiatingGrpcChannelProvider.newBuilder().setEndpoint("test.endpoint.com:abcd")); - } - @Test void testKeepAlive() { final long millis = 15; @@ -289,8 +232,6 @@ void testToBuilder() { InstantiatingGrpcChannelProvider.newBuilder() .setProcessorCount(2) .setEndpoint("fake.endpoint:443") - .setMtlsEndpoint("fake.endpoint:443") - .setEndpointOverride("fake.endpoint.override:443") .setMaxInboundMessageSize(12345678) .setMaxInboundMetadataSize(4096) .setKeepAliveTimeDuration(keepaliveTime) @@ -304,8 +245,6 @@ void testToBuilder() { InstantiatingGrpcChannelProvider.Builder builder = provider.toBuilder(); assertThat(builder.getEndpoint()).isEqualTo("fake.endpoint:443"); - assertThat(builder.getMtlsEndpoint()).isEqualTo("fake.endpoint:443"); - assertThat(builder.getEndpointOverride()).isEqualTo("fake.endpoint.override:443"); assertThat(builder.getMaxInboundMessageSize()).isEqualTo(12345678); assertThat(builder.getMaxInboundMetadataSize()).isEqualTo(4096); assertThat(builder.getKeepAliveTimeDuration()).isEqualTo(keepaliveTime); @@ -1043,102 +982,6 @@ private FixedHeaderProvider getHeaderProviderWithApiKeyHeader() { return FixedHeaderProvider.create(header); } - @Test - void isS2AEnabled_envVarNotSet_returnsFalse() { - EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); - Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) - .thenReturn("false"); - InstantiatingGrpcChannelProvider provider = - InstantiatingGrpcChannelProvider.newBuilder().setEnvProvider(envProvider).build(); - Truth.assertThat(provider.isS2AEnabled()).isFalse(); - } - - @Test - void isS2AEnabled_envVarSet_returnsTrue() { - EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); - Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) - .thenReturn("true"); - InstantiatingGrpcChannelProvider provider = - InstantiatingGrpcChannelProvider.newBuilder().setEnvProvider(envProvider).build(); - Truth.assertThat(provider.isS2AEnabled()).isTrue(); - } - - @Test - void shouldUseS2A_envVarNotSet_returnsFalse() { - EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); - Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) - .thenReturn("false"); - InstantiatingGrpcChannelProvider provider = - InstantiatingGrpcChannelProvider.newBuilder() - .setEndpoint(DEFAULT_ENDPOINT) - .setMtlsEndpoint(DEFAULT_MTLS_ENDPOINT) - .setEndpointOverride("") - .setEnvProvider(envProvider) - .build(); - Truth.assertThat(provider.shouldUseS2A()).isFalse(); - } - - @Test - void shouldUseS2A_mtlsEndpointNotSet_throws() { - EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); - Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) - .thenReturn("true"); - assertThrows( - IllegalArgumentException.class, - () -> - InstantiatingGrpcChannelProvider.newBuilder() - .setEndpoint(DEFAULT_ENDPOINT) - .setMtlsEndpoint("") - .setEndpointOverride("") - .setEnvProvider(envProvider) - .build()); - } - - @Test - void shouldUseS2A_endpointOverrideIsSet_returnsFalse() { - EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); - Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) - .thenReturn("true"); - InstantiatingGrpcChannelProvider provider = - InstantiatingGrpcChannelProvider.newBuilder() - .setEndpoint(DEFAULT_ENDPOINT) - .setMtlsEndpoint(DEFAULT_MTLS_ENDPOINT) - .setEndpointOverride(DEFAULT_ENDPOINT_OVERRIDE) - .setEnvProvider(envProvider) - .build(); - Truth.assertThat(provider.shouldUseS2A()).isFalse(); - } - - @Test - void shouldUseS2A_nonGDUUniverse_returnsFalse() { - EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); - Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) - .thenReturn("true"); - InstantiatingGrpcChannelProvider provider = - InstantiatingGrpcChannelProvider.newBuilder() - .setEndpoint("test.abcd.com:443") - .setMtlsEndpoint("test.mtls.abcd.com:443") - .setEndpointOverride("") - .setEnvProvider(envProvider) - .build(); - Truth.assertThat(provider.shouldUseS2A()).isFalse(); - } - - @Test - void shouldUseS2A_returnsTrue() { - EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); - Mockito.when(envProvider.getenv(InstantiatingGrpcChannelProvider.S2A_ENV_ENABLE_USE_S2A)) - .thenReturn("true"); - InstantiatingGrpcChannelProvider provider = - InstantiatingGrpcChannelProvider.newBuilder() - .setEndpoint(DEFAULT_ENDPOINT) - .setMtlsEndpoint(DEFAULT_MTLS_ENDPOINT) - .setEndpointOverride("") - .setEnvProvider(envProvider) - .build(); - Truth.assertThat(provider.shouldUseS2A()).isTrue(); - } - @Test void createMtlsToS2AChannelCredentials_missingAllFiles_throws() throws IOException { InstantiatingGrpcChannelProvider provider = diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java index 13195b8b11..84ec47b4b4 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java @@ -32,6 +32,7 @@ import com.google.api.core.BetaApi; import com.google.api.gax.grpc.GrpcHeaderInterceptor; import com.google.api.gax.grpc.GrpcTransportChannel; +import com.google.api.gax.rpc.EndpointContext; import com.google.api.gax.rpc.FixedHeaderProvider; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.TransportChannel; @@ -80,6 +81,11 @@ public boolean needsExecutor() { return false; } + @Override + public boolean needsEndpointContext() { + return false; + } + @Deprecated @Override public TransportChannelProvider withExecutor(ScheduledExecutorService executor) { @@ -101,30 +107,14 @@ public boolean needsEndpoint() { return false; } - @Override - public boolean needsMtlsEndpoint() { - return false; - } - - @Override - public boolean needsEndpointOverride() { - return false; - } - @Override public TransportChannelProvider withEndpoint(String endpoint) { throw new UnsupportedOperationException("LocalChannelProvider doesn't need an endpoint"); } @Override - public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { - throw new UnsupportedOperationException("LocalChannelProvider doesn't need an mtlsEndpoint"); - } - - @Override - public TransportChannelProvider withEndpointOverride(String endpointOverride) { - throw new UnsupportedOperationException( - "LocalChannelProvider doesn't need an endpointOverride"); + public TransportChannelProvider withEndpointContext(EndpointContext endpointContext) { + throw new UnsupportedOperationException("LocalChannelProvider doesn't need an endpointContext"); } @Override diff --git a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java index be673ff20c..c2fd3578c1 100644 --- a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java +++ b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java @@ -33,6 +33,7 @@ import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.core.InternalExtensionOnly; import com.google.api.gax.core.ExecutorProvider; +import com.google.api.gax.rpc.EndpointContext; import com.google.api.gax.rpc.FixedHeaderProvider; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.TransportChannelProvider; @@ -120,12 +121,7 @@ public boolean needsEndpoint() { } @Override - public boolean needsMtlsEndpoint() { - return false; - } - - @Override - public boolean needsEndpointOverride() { + public boolean needsEndpointContext() { return false; } @@ -135,15 +131,9 @@ public TransportChannelProvider withEndpoint(String endpoint) { } @Override - public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { - throw new UnsupportedOperationException( - "InstantiatingHttpJsonChannelProvider doesn't need an mtlsEndpoint"); - } - - @Override - public TransportChannelProvider withEndpointOverride(String endpointOverride) { + public TransportChannelProvider withEndpointContext(EndpointContext endpointContext) { throw new UnsupportedOperationException( - "InstantiatingHttpJsonChannelProvider doesn't need an endpointOverride"); + "InstantiatingHttpJsonChannelProvider doesn't need an endpointContext"); } /** @deprecated REST transport channel doesn't support channel pooling */ diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java index ae7e566f41..109200d8ec 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java @@ -178,10 +178,6 @@ public static ClientContext create(StubSettings settings) throws IOException { // A valid EndpointContext should have been created in the StubSettings EndpointContext endpointContext = settings.getEndpointContext(); String endpoint = endpointContext.resolvedEndpoint(); - String mtlsEndpoint = ""; - mtlsEndpoint = settings.getMtlsEndpoint(); - String endpointOverride = ""; - endpointOverride = settings.getEndpointContext().customEndpoint(); Credentials credentials = getCredentials(settings); // check if need to adjust credentials/endpoint/endpointContext for GDC-H String settingsGdchApiAudience = settings.getGdchApiAudience(); @@ -193,9 +189,6 @@ public static ClientContext create(StubSettings settings) throws IOException { endpointContext = endpointContext.withGDCH(); // Resolve the new endpoint with the GDC-H flow endpoint = endpointContext.resolvedEndpoint(); - // Skip S2A in GDC-H. - mtlsEndpoint = ""; - endpointOverride = ""; // We recompute the GdchCredentials with the audience credentials = getGdchCredentials(settingsGdchApiAudience, endpoint, credentials); } else if (!Strings.isNullOrEmpty(settingsGdchApiAudience)) { @@ -229,11 +222,8 @@ public static ClientContext create(StubSettings settings) throws IOException { if (transportChannelProvider.needsEndpoint()) { transportChannelProvider = transportChannelProvider.withEndpoint(endpoint); } - if (transportChannelProvider.needsMtlsEndpoint()) { - transportChannelProvider = transportChannelProvider.withMtlsEndpoint(mtlsEndpoint); - } - if (transportChannelProvider.needsEndpointOverride()) { - transportChannelProvider = transportChannelProvider.withEndpointOverride(endpointOverride); + if (transportChannelProvider.needsEndpointContext()) { + transportChannelProvider = transportChannelProvider.withEndpointContext(endpointContext); } TransportChannel transportChannel = transportChannelProvider.getTransportChannel(); diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java index 4140b5da40..234fd4d19d 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java @@ -103,11 +103,6 @@ public final String getEndpoint() { return stubSettings.getEndpoint(); } - /** Gets the MTLS endpoint for the service */ - public final String getMtlsEndpoint() { - return stubSettings.getMtlsEndpoint(); - } - public final String getQuotaProjectId() { return stubSettings.getQuotaProjectId(); } @@ -150,7 +145,6 @@ public String toString() { .add("clock", getClock()) .add("universeDomain", getUniverseDomain()) .add("endpoint", getEndpoint()) - .add("mtlsEndpoint", getMtlsEndpoint()) .add("quotaProjectId", getQuotaProjectId()) .add("watchdogProvider", getWatchdogProvider()) .add("watchdogCheckInterval", getWatchdogCheckInterval()) @@ -278,12 +272,6 @@ public B setEndpoint(String endpoint) { return self(); } - /** Sets the MTLS endpoint for the service */ - public B setMtlsEndpoint(String mtlsEndpoint) { - stubSettings.setMtlsEndpoint(mtlsEndpoint); - return self(); - } - public B setQuotaProjectId(String quotaProjectId) { stubSettings.setQuotaProjectId(quotaProjectId); return self(); @@ -387,11 +375,6 @@ public String getEndpoint() { return stubSettings.getEndpoint(); } - /** Gets the MTLS endpoint for the service that was previously set on this Builder. */ - public String getMtlsEndpoint() { - return stubSettings.getMtlsEndpoint(); - } - /** Gets the QuotaProjectId that was previously set on this Builder. */ public String getQuotaProjectId() { return stubSettings.getQuotaProjectId(); @@ -444,7 +427,6 @@ public String toString() { .add("internalHeaderProvider", getInternalHeaderProvider()) .add("clock", getClock()) .add("endpoint", getEndpoint()) - .add("mtlsEndpoint", getMtlsEndpoint()) .add("quotaProjectId", getQuotaProjectId()) .add("watchdogProvider", getWatchdogProvider()) .add("watchdogCheckInterval", getWatchdogCheckIntervalDuration()) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java index 0c8a97c886..f28d2b8b5b 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java @@ -30,6 +30,7 @@ package com.google.api.gax.rpc; import com.google.api.core.InternalApi; +import com.google.api.gax.rpc.internal.EnvironmentProvider; import com.google.api.gax.rpc.mtls.MtlsProvider; import com.google.auth.Credentials; import com.google.auth.oauth2.ComputeEngineCredentials; @@ -65,6 +66,7 @@ public abstract class EndpointContext { "The configured universe domain (%s) does not match the universe domain found in the credentials (%s). If you haven't configured the universe domain explicitly, `googleapis.com` is the default."; public static final String UNABLE_TO_RETRIEVE_CREDENTIALS_ERROR_MESSAGE = "Unable to retrieve the Universe Domain from the Credentials."; + public static final String S2A_ENV_ENABLE_USE_S2A = "EXPERIMENTAL_GOOGLE_API_USE_S2A"; public static EndpointContext getDefaultInstance() { return INSTANCE; @@ -100,8 +102,10 @@ public static EndpointContext getDefaultInstance() { @Nullable public abstract String transportChannelProviderEndpoint(); + public abstract boolean useS2A(); + @Nullable - public abstract String customEndpoint(); + public abstract EnvironmentProvider envProvider(); @Nullable public abstract String mtlsEndpoint(); @@ -199,7 +203,9 @@ public abstract static class Builder { */ public abstract Builder setTransportChannelProviderEndpoint(String transportChannelEndpoint); - public abstract Builder setCustomEndpoint(String customEndpoint); + public abstract Builder setUseS2A(boolean useS2A); + + public abstract Builder setEnvProvider(EnvironmentProvider envProvider); public abstract Builder setMtlsEndpoint(String mtlsEndpoint); @@ -221,7 +227,9 @@ public abstract static class Builder { abstract String transportChannelProviderEndpoint(); - abstract String customEndpoint(); + abstract boolean useS2A(); + + abstract EnvironmentProvider envProvider(); abstract String mtlsEndpoint(); @@ -262,7 +270,11 @@ private String determineUniverseDomain() { /** Determines the fully resolved endpoint and universe domain values */ private String determineEndpoint() throws IOException { MtlsProvider mtlsProvider = mtlsProvider() == null ? new MtlsProvider() : mtlsProvider(); - String customEndpoint = customEndpoint(); + // TransportChannelProvider's endpoint will override the ClientSettings' endpoint + String customEndpoint = + transportChannelProviderEndpoint() == null + ? clientSettingsEndpoint() + : transportChannelProviderEndpoint(); // GDC-H has a separate flow if (usingGDCH()) { @@ -291,11 +303,34 @@ private String determineEndpoint() throws IOException { return endpoint; } - private String determineCustomEndpoint() { - // TransportChannelProvider's endpoint will override the ClientSettings' endpoint. - return transportChannelProviderEndpoint() == null - ? clientSettingsEndpoint() - : transportChannelProviderEndpoint(); + /** Determine if S2A can be used */ + @VisibleForTesting + boolean shouldUseS2A() { + // If EXPERIMENTAL_GOOGLE_API_USE_S2A is not set to true, skip S2A. + String s2AEnv; + if (envProvider() != null) { + s2AEnv = envProvider().getenv(S2A_ENV_ENABLE_USE_S2A); + } else { + s2AEnv = System.getenv(S2A_ENV_ENABLE_USE_S2A); + } + boolean s2AEnabled = Boolean.parseBoolean(s2AEnv); + if (!s2AEnabled) { + return false; + } + + // Skip S2A when using GDC-H + if (usingGDCH()) { + return false; + } + + // If a custom endpoint is being used, skip S2A. + if (!Strings.isNullOrEmpty(clientSettingsEndpoint()) + || !Strings.isNullOrEmpty(transportChannelProviderEndpoint())) { + return false; + } + + // mTLS via S2A is not supported in any universe other than googleapis.com. + return mtlsEndpoint().contains(Credentials.GOOGLE_DEFAULT_UNIVERSE); } // Default to port 443 for HTTPS. Using HTTP requires explicitly setting the endpoint @@ -330,8 +365,8 @@ String mtlsEndpointResolver( public EndpointContext build() throws IOException { // The Universe Domain is used to resolve the Endpoint. It should be resolved first setResolvedUniverseDomain(determineUniverseDomain()); - setCustomEndpoint(determineCustomEndpoint()); setResolvedEndpoint(determineEndpoint()); + setUseS2A(shouldUseS2A()); return autoBuild(); } } diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java index 50276efa68..b2f39d63b5 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java @@ -84,12 +84,7 @@ public boolean needsEndpoint() { } @Override - public boolean needsMtlsEndpoint() { - return false; - } - - @Override - public boolean needsEndpointOverride() { + public boolean needsEndpointContext() { return false; } @@ -100,15 +95,9 @@ public TransportChannelProvider withEndpoint(String endpoint) { } @Override - public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { - throw new UnsupportedOperationException( - "FixedTransportChannelProvider doesn't need an mtlsEndpoint"); - } - - @Override - public TransportChannelProvider withEndpointOverride(String endpointOverride) { + public TransportChannelProvider withEndpointContext(EndpointContext endpointContext) { throw new UnsupportedOperationException( - "FixedTransportChannelProvider doesn't need an endpointOverride"); + "FixedTransportChannelProvider doesn't need an endpointContext"); } /** @deprecated FixedTransportChannelProvider doesn't support ChannelPool configuration */ diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java index e3fc61265b..daf5f814b1 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java @@ -90,11 +90,8 @@ public interface TransportChannelProvider { /** True if the TransportProvider has no endpoint set. */ boolean needsEndpoint(); - /** True if the TransportProvider has no mtlsEndpoint set. */ - boolean needsMtlsEndpoint(); - - /** True if the TransportProvider has no endpointOverride set */ - boolean needsEndpointOverride(); + /** True if the TransportProvider needs an {@link EndpointContext} */ + boolean needsEndpointContext(); /** * Sets the endpoint to use when constructing a new {@link TransportChannel}. @@ -103,19 +100,8 @@ public interface TransportChannelProvider { */ TransportChannelProvider withEndpoint(String endpoint); - /** - * Sets the mTLS endpoint when constructing a new {@link TransportChannel}. - * - *

This method should only be called if {@link #needsMtlsEndpoint()} returns true. - */ - TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint); - - /** - * Sets the endpoint override when constructing a new {@link TransportChannel}. - * - *

This method should only be called if {@link #needsEndpointOverride()} returns true. - */ - TransportChannelProvider withEndpointOverride(String endpointOverride); + /** Sets the {@link EndpointContext} when constructing a new {@link TransportChannel}. */ + TransportChannelProvider withEndpointContext(EndpointContext endpointContext); /** * Reports whether this provider allows pool size customization. diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java index c0b21dc070..e3edf9aef1 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java @@ -74,8 +74,6 @@ class ClientContextTest { private static final String DEFAULT_ENDPOINT = "test.googleapis.com"; - private static final String DEFAULT_MTLS_ENDPOINT = "test.mtls.googleapis.com"; - private static final String DEFAULT_ENDPOINT_OVERRIDE = "transport.endpoint.com"; private static final String DEFAULT_UNIVERSE_DOMAIN = "googleapis.com"; private static class InterceptingExecutor extends ScheduledThreadPoolExecutor { @@ -117,8 +115,6 @@ private static class FakeTransportProvider implements TransportChannelProvider { final Map headers; final Credentials credentials; final String endpoint; - final String mtlsEndpoint; - final String endpointOverride; FakeTransportProvider( FakeTransportChannel transport, @@ -126,9 +122,7 @@ private static class FakeTransportProvider implements TransportChannelProvider { boolean shouldAutoClose, Map headers, Credentials credentials, - String endpoint, - String mtlsEndpoint, - String endpointOverride) { + String endpoint) { this.transport = transport; this.executor = executor; this.shouldAutoClose = shouldAutoClose; @@ -136,8 +130,6 @@ private static class FakeTransportProvider implements TransportChannelProvider { this.transport.setHeaders(headers); this.credentials = credentials; this.endpoint = endpoint; - this.mtlsEndpoint = mtlsEndpoint; - this.endpointOverride = endpointOverride; } @Override @@ -163,9 +155,7 @@ public TransportChannelProvider withExecutor(Executor executor) { this.shouldAutoClose, this.headers, this.credentials, - this.endpoint, - this.mtlsEndpoint, - this.endpointOverride); + this.endpoint); } @Override @@ -181,9 +171,7 @@ public TransportChannelProvider withHeaders(Map headers) { this.shouldAutoClose, headers, this.credentials, - this.endpoint, - this.mtlsEndpoint, - this.endpointOverride); + this.endpoint); } @Override @@ -192,13 +180,8 @@ public boolean needsEndpoint() { } @Override - public boolean needsMtlsEndpoint() { - return true; - } - - @Override - public boolean needsEndpointOverride() { - return true; + public boolean needsEndpointContext() { + return false; } @Override @@ -214,35 +197,18 @@ public TransportChannelProvider withEndpoint(String endpoint) { this.shouldAutoClose, this.headers, this.credentials, - endpoint, - this.mtlsEndpoint, - this.endpointOverride); - } - - @Override - public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { - return new FakeTransportProvider( - this.transport, - this.executor, - this.shouldAutoClose, - this.headers, - this.credentials, - this.endpoint, - mtlsEndpoint, - this.endpointOverride); + endpoint); } @Override - public TransportChannelProvider withEndpointOverride(String endpointOverride) { + public TransportChannelProvider withEndpointContext(EndpointContext endpointContext) { return new FakeTransportProvider( this.transport, this.executor, this.shouldAutoClose, this.headers, this.credentials, - this.endpoint, - this.mtlsEndpoint, - endpointOverride); + this.endpoint); } @Override @@ -280,9 +246,7 @@ public TransportChannelProvider withCredentials(Credentials credentials) { this.shouldAutoClose, this.headers, credentials, - this.endpoint, - this.mtlsEndpoint, - this.endpointOverride); + this.endpoint); } } @@ -330,9 +294,7 @@ private void runTest( shouldAutoClose, needHeaders ? null : headers, null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + DEFAULT_ENDPOINT); Credentials credentials = Mockito.mock(Credentials.class); ApiClock clock = Mockito.mock(ApiClock.class); Watchdog watchdog = @@ -406,15 +368,7 @@ void testWatchdogProvider() throws IOException { InterceptingExecutor executor = new InterceptingExecutor(1); FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = - new FakeTransportProvider( - transportChannel, - executor, - true, - null, - null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + new FakeTransportProvider(transportChannel, executor, true, null, null, DEFAULT_ENDPOINT); ApiClock clock = Mockito.mock(ApiClock.class); builder.setClock(clock); @@ -453,15 +407,7 @@ void testMergeHeaders_getQuotaProjectIdFromHeadersProvider() throws IOException InterceptingExecutor executor = new InterceptingExecutor(1); FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = - new FakeTransportProvider( - transportChannel, - executor, - true, - null, - null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + new FakeTransportProvider(transportChannel, executor, true, null, null, DEFAULT_ENDPOINT); HeaderProvider headerProvider = Mockito.mock(HeaderProvider.class); Mockito.when(headerProvider.getHeaders()).thenReturn(ImmutableMap.of("header_k1", "v1")); @@ -497,15 +443,7 @@ void testMergeHeaders_getQuotaProjectIdFromSettings() throws IOException { InterceptingExecutor executor = new InterceptingExecutor(1); FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = - new FakeTransportProvider( - transportChannel, - executor, - true, - null, - null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + new FakeTransportProvider(transportChannel, executor, true, null, null, DEFAULT_ENDPOINT); HeaderProvider headerProvider = new HeaderProvider() { @@ -551,15 +489,7 @@ void testMergeHeaders_noQuotaProjectIdSet() throws IOException { InterceptingExecutor executor = new InterceptingExecutor(1); FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = - new FakeTransportProvider( - transportChannel, - executor, - true, - null, - null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + new FakeTransportProvider(transportChannel, executor, true, null, null, DEFAULT_ENDPOINT); HeaderProvider headerProvider = Mockito.mock(HeaderProvider.class); Mockito.when(headerProvider.getHeaders()).thenReturn(ImmutableMap.of("header_k1", "v1")); @@ -590,15 +520,7 @@ void testHidingQuotaProjectId_quotaSetFromSetting() throws IOException { InterceptingExecutor executor = new InterceptingExecutor(1); FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = - new FakeTransportProvider( - transportChannel, - executor, - true, - null, - null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + new FakeTransportProvider(transportChannel, executor, true, null, null, DEFAULT_ENDPOINT); Map> metaDataWithQuota = ImmutableMap.of( "k1", @@ -639,15 +561,7 @@ void testHidingQuotaProjectId_noQuotaSetFromSetting() throws IOException { InterceptingExecutor executor = new InterceptingExecutor(1); FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = - new FakeTransportProvider( - transportChannel, - executor, - true, - null, - null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + new FakeTransportProvider(transportChannel, executor, true, null, null, DEFAULT_ENDPOINT); Map> metaData = ImmutableMap.of("k1", Collections.singletonList("v1")); final Credentials credentialsWithoutQuotaProjectId = Mockito.mock(GoogleCredentials.class); Mockito.when(credentialsWithoutQuotaProjectId.getRequestMetadata(null)).thenReturn(metaData); @@ -683,9 +597,7 @@ void testQuotaProjectId_worksWithNullCredentials() throws IOException { true, null, Mockito.mock(Credentials.class), - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + DEFAULT_ENDPOINT); final FakeClientSettings.Builder settingsBuilder = new FakeClientSettings.Builder(); @@ -706,9 +618,7 @@ void testUserAgentInternalOnly() throws Exception { true, null, null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + DEFAULT_ENDPOINT); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -736,9 +646,7 @@ void testUserAgentExternalOnly() throws Exception { true, null, null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + DEFAULT_ENDPOINT); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -766,9 +674,7 @@ void testUserAgentConcat() throws Exception { true, null, null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + DEFAULT_ENDPOINT); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -853,9 +759,7 @@ private Map setupTestForCredentialTokenUsageMetricsAndGetTranspo true, null, null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + DEFAULT_ENDPOINT); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -907,9 +811,7 @@ void testExecutorSettings() throws Exception { true, null, null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + DEFAULT_ENDPOINT); ClientSettings.Builder builder = new FakeClientSettings.Builder() @@ -956,9 +858,7 @@ void testExecutorSettings() throws Exception { true, null, null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE)); + DEFAULT_ENDPOINT)); context = ClientContext.create(builder.build()); transportChannel = (FakeTransportChannel) context.getTransportChannel(); assertThat(transportChannel.getExecutor()).isSameInstanceAs(executorProvider.getExecutor()); @@ -980,14 +880,7 @@ private GdchCredentials getMockGdchCredentials() throws IOException { private TransportChannelProvider getFakeTransportChannelProvider() { return new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), - null, - true, - null, - null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + FakeTransportChannel.create(new FakeChannel()), null, true, null, null, DEFAULT_ENDPOINT); } // EndpointContext will construct a valid endpoint if nothing is provided @@ -995,14 +888,7 @@ private TransportChannelProvider getFakeTransportChannelProvider() { void testCreateClientContext_withGdchCredentialNoAudienceNoEndpoint() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), - null, - true, - null, - null, - null, - null, - null); + FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null); Credentials creds = getMockGdchCredentials(); CredentialsProvider provider = FixedCredentialsProvider.create(creds); @@ -1029,14 +915,7 @@ void testCreateClientContext_withGdchCredentialNoAudienceEmptyEndpoint_throws() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), - null, - true, - null, - null, - null, - null, - null); + FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null); Credentials creds = getMockGdchCredentials(); CredentialsProvider provider = FixedCredentialsProvider.create(creds); @@ -1059,14 +938,7 @@ void testCreateClientContext_withGdchCredentialWithoutAudienceWithEndpoint_corre throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), - null, - true, - null, - null, - null, - null, - null); + FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null); Credentials creds = getMockGdchCredentials(); // it should correctly create a client context with gdch creds and null audience @@ -1178,14 +1050,7 @@ void testCreateClientContext_withNonGdchCredentialAndAnyAudience_throws() throws void testCreateClientContext_SetEndpointViaClientSettings() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), - null, - true, - null, - null, - null, - null, - null); + FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null); StubSettings settings = new FakeStubSettings.Builder() .setEndpoint(DEFAULT_ENDPOINT) @@ -1211,9 +1076,7 @@ void testCreateClientContext_SetEndpointViaTransportChannelProvider() throws IOE true, null, null, - transportChannelProviderEndpoint, - null, - null); + transportChannelProviderEndpoint); StubSettings settings = new FakeStubSettings.Builder() .setEndpoint(null) @@ -1241,9 +1104,7 @@ void testCreateClientContext_SetEndpointViaClientSettingsAndTransportChannelProv true, null, null, - transportChannelProviderEndpoint, - null, - null); + transportChannelProviderEndpoint); StubSettings settings = new FakeStubSettings.Builder() .setEndpoint(clientSettingsEndpoint) @@ -1266,14 +1127,7 @@ void testCreateClientContext_SetEndpointViaClientSettingsAndTransportChannelProv void testCreateClientContext_doNotSetUniverseDomain() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), - null, - true, - null, - null, - null, - null, - null); + FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null); StubSettings settings = new FakeStubSettings.Builder() .setEndpoint(null) @@ -1292,14 +1146,7 @@ void testCreateClientContext_doNotSetUniverseDomain() throws IOException { void testCreateClientContext_setUniverseDomain() throws IOException { TransportChannelProvider transportChannelProvider = new FakeTransportProvider( - FakeTransportChannel.create(new FakeChannel()), - null, - true, - null, - null, - null, - null, - null); + FakeTransportChannel.create(new FakeChannel()), null, true, null, null, null); String universeDomain = "testdomain.com"; StubSettings settings = new FakeStubSettings.Builder().setEndpoint(null).setUniverseDomain(universeDomain).build(); @@ -1332,14 +1179,7 @@ void testSetApiKey_createsApiCredentials() throws IOException { FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = new FakeTransportProvider( - transportChannel, - executor, - true, - ImmutableMap.of(), - null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + transportChannel, executor, true, ImmutableMap.of(), null, DEFAULT_ENDPOINT); builder.setTransportChannelProvider(transportProvider); HeaderProvider headerProvider = Mockito.mock(HeaderProvider.class); Mockito.when(headerProvider.getHeaders()).thenReturn(ImmutableMap.of()); @@ -1360,14 +1200,7 @@ void testSetApiKey_withDefaultCredentials_overridesCredentials() throws IOExcept FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); FakeTransportProvider transportProvider = new FakeTransportProvider( - transportChannel, - executor, - true, - ImmutableMap.of(), - null, - DEFAULT_ENDPOINT, - DEFAULT_MTLS_ENDPOINT, - DEFAULT_ENDPOINT_OVERRIDE); + transportChannel, executor, true, ImmutableMap.of(), null, DEFAULT_ENDPOINT); builder.setTransportChannelProvider(transportProvider); HeaderProvider headerProvider = Mockito.mock(HeaderProvider.class); Mockito.when(headerProvider.getHeaders()).thenReturn(ImmutableMap.of()); diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/EndpointContextTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/EndpointContextTest.java index 3276e4a73e..5561427dde 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/EndpointContextTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/EndpointContextTest.java @@ -33,6 +33,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import com.google.api.gax.core.NoCredentialsProvider; +import com.google.api.gax.rpc.internal.EnvironmentProvider; import com.google.api.gax.rpc.mtls.MtlsProvider; import com.google.api.gax.rpc.testing.FakeMtlsProvider; import com.google.auth.Credentials; @@ -454,4 +455,97 @@ void hasValidUniverseDomain_computeEngineCredentials_noValidationOnUniverseDomai .build(); assertDoesNotThrow(() -> endpointContext.validateUniverseDomain(credentials, statusCode)); } + + @Test + void shouldUseS2A_envVarNotSet_returnsFalse() throws IOException { + EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); + Mockito.when(envProvider.getenv(EndpointContext.S2A_ENV_ENABLE_USE_S2A)).thenReturn("false"); + defaultEndpointContextBuilder = + defaultEndpointContextBuilder + .setEnvProvider(envProvider) + .setClientSettingsEndpoint("") + .setTransportChannelProviderEndpoint("") + .setUsingGDCH(false); + Truth.assertThat(defaultEndpointContextBuilder.shouldUseS2A()).isFalse(); + } + + @Test + void shouldUseS2A_UsingGDCH_returnsFalse() throws IOException { + EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); + Mockito.when(envProvider.getenv(EndpointContext.S2A_ENV_ENABLE_USE_S2A)).thenReturn("true"); + defaultEndpointContextBuilder = + defaultEndpointContextBuilder + .setEnvProvider(envProvider) + .setClientSettingsEndpoint("") + .setTransportChannelProviderEndpoint("") + .setUsingGDCH(true); + Truth.assertThat(defaultEndpointContextBuilder.shouldUseS2A()).isFalse(); + } + + @Test + void shouldUseS2A_customEndpointSetViaClientSettings_returnsFalse() throws IOException { + EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); + Mockito.when(envProvider.getenv(EndpointContext.S2A_ENV_ENABLE_USE_S2A)).thenReturn("true"); + defaultEndpointContextBuilder = + defaultEndpointContextBuilder + .setEnvProvider(envProvider) + .setClientSettingsEndpoint("test.endpoint.com:443") + .setTransportChannelProviderEndpoint("") + .setUsingGDCH(false); + Truth.assertThat(defaultEndpointContextBuilder.shouldUseS2A()).isFalse(); + } + + @Test + void shouldUseS2A_customEndpointSetViaTransportChannelProvider_returnsFalse() throws IOException { + EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); + Mockito.when(envProvider.getenv(EndpointContext.S2A_ENV_ENABLE_USE_S2A)).thenReturn("true"); + defaultEndpointContextBuilder = + defaultEndpointContextBuilder + .setEnvProvider(envProvider) + .setClientSettingsEndpoint("") + .setTransportChannelProviderEndpoint("test.endpoint.com:443") + .setUsingGDCH(false); + Truth.assertThat(defaultEndpointContextBuilder.shouldUseS2A()).isFalse(); + } + + @Test + void shouldUseS2A_mtlsEndpointEmpty_returnsFalse() throws IOException { + EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); + Mockito.when(envProvider.getenv(EndpointContext.S2A_ENV_ENABLE_USE_S2A)).thenReturn("true"); + defaultEndpointContextBuilder = + defaultEndpointContextBuilder + .setEnvProvider(envProvider) + .setClientSettingsEndpoint("") + .setTransportChannelProviderEndpoint("") + .setMtlsEndpoint("") + .setUsingGDCH(false); + Truth.assertThat(defaultEndpointContextBuilder.shouldUseS2A()).isFalse(); + } + + @Test + void shouldUseS2A_mtlsEndpointNotGoogleDefaultUniverse_returnsFalse() throws IOException { + EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); + Mockito.when(envProvider.getenv(EndpointContext.S2A_ENV_ENABLE_USE_S2A)).thenReturn("true"); + defaultEndpointContextBuilder = + defaultEndpointContextBuilder + .setEnvProvider(envProvider) + .setClientSettingsEndpoint("") + .setTransportChannelProviderEndpoint("") + .setMtlsEndpoint("test.mtls.abcd.com:443") + .setUsingGDCH(false); + Truth.assertThat(defaultEndpointContextBuilder.shouldUseS2A()).isFalse(); + } + + @Test + void shouldUseS2A_success() throws IOException { + EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); + Mockito.when(envProvider.getenv(EndpointContext.S2A_ENV_ENABLE_USE_S2A)).thenReturn("true"); + defaultEndpointContextBuilder = + defaultEndpointContextBuilder + .setEnvProvider(envProvider) + .setClientSettingsEndpoint("") + .setTransportChannelProviderEndpoint("") + .setUsingGDCH(false); + Truth.assertThat(defaultEndpointContextBuilder.shouldUseS2A()).isTrue(); + } } From 393190a1ad03838ff5a3e13222c75e349f0be72e Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 5 Nov 2024 16:01:51 -0800 Subject: [PATCH 18/51] remove needsEndpointContext. --- .../InstantiatingGrpcChannelProvider.java | 5 ---- .../api/gax/grpc/GrpcLongRunningTest.java | 2 ++ .../grpc/testing/LocalChannelProvider.java | 9 +++---- .../InstantiatingHttpJsonChannelProvider.java | 27 +++++++++++++------ .../com/google/api/gax/rpc/ClientContext.java | 4 +-- .../rpc/FixedTransportChannelProvider.java | 10 +++---- .../api/gax/rpc/TransportChannelProvider.java | 3 --- .../google/api/gax/rpc/ClientContextTest.java | 5 ---- 8 files changed, 28 insertions(+), 37 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 2b17b43326..89dea00d5b 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -225,11 +225,6 @@ public boolean needsEndpoint() { return endpoint == null; } - @Override - public boolean needsEndpointContext() { - return endpointContext == null; - } - /** * Specify the endpoint the channel should connect to. * diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcLongRunningTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcLongRunningTest.java index 241f90b08a..fe2c2f7293 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcLongRunningTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcLongRunningTest.java @@ -101,6 +101,8 @@ void setUp() throws IOException { TransportChannel transportChannel = GrpcTransportChannel.newBuilder().setManagedChannel(channel).build(); when(operationsChannelProvider.getTransportChannel()).thenReturn(transportChannel); + when(operationsChannelProvider.withEndpointContext(Mockito.any(EndpointContext.class))) + .thenReturn(operationsChannelProvider); clock = new FakeApiClock(0L); executor = RecordingScheduler.create(clock); diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java index 84ec47b4b4..dcaae0c706 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java @@ -61,6 +61,7 @@ public class LocalChannelProvider implements TransportChannelProvider { private final List interceptors; private final String address; + private EndpointContext endpointContext; private volatile HeaderProvider headerProvider; @@ -81,11 +82,6 @@ public boolean needsExecutor() { return false; } - @Override - public boolean needsEndpointContext() { - return false; - } - @Deprecated @Override public TransportChannelProvider withExecutor(ScheduledExecutorService executor) { @@ -114,7 +110,8 @@ public TransportChannelProvider withEndpoint(String endpoint) { @Override public TransportChannelProvider withEndpointContext(EndpointContext endpointContext) { - throw new UnsupportedOperationException("LocalChannelProvider doesn't need an endpointContext"); + this.endpointContext = endpointContext; + return this; } @Override diff --git a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java index c2fd3578c1..3af6eb323d 100644 --- a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java +++ b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java @@ -66,6 +66,7 @@ public final class InstantiatingHttpJsonChannelProvider implements TransportChan private final HeaderProvider headerProvider; private final HttpJsonInterceptorProvider interceptorProvider; private final String endpoint; + private final EndpointContext endpointContext; private final HttpTransport httpTransport; private final MtlsProvider mtlsProvider; @@ -74,12 +75,14 @@ private InstantiatingHttpJsonChannelProvider( HeaderProvider headerProvider, HttpJsonInterceptorProvider interceptorProvider, String endpoint, + EndpointContext endpointContext, HttpTransport httpTransport, MtlsProvider mtlsProvider) { this.executor = executor; this.headerProvider = headerProvider; this.interceptorProvider = interceptorProvider; this.endpoint = endpoint; + this.endpointContext = endpointContext; this.httpTransport = httpTransport; this.mtlsProvider = mtlsProvider; } @@ -120,11 +123,6 @@ public boolean needsEndpoint() { return endpoint == null; } - @Override - public boolean needsEndpointContext() { - return false; - } - @Override public TransportChannelProvider withEndpoint(String endpoint) { return toBuilder().setEndpoint(endpoint).build(); @@ -132,8 +130,7 @@ public TransportChannelProvider withEndpoint(String endpoint) { @Override public TransportChannelProvider withEndpointContext(EndpointContext endpointContext) { - throw new UnsupportedOperationException( - "InstantiatingHttpJsonChannelProvider doesn't need an endpointContext"); + return toBuilder().setEndpointContext(endpointContext).build(); } /** @deprecated REST transport channel doesn't support channel pooling */ @@ -243,6 +240,7 @@ public static final class Builder { private HeaderProvider headerProvider; private HttpJsonInterceptorProvider interceptorProvider; private String endpoint; + private EndpointContext endpointContext; private HttpTransport httpTransport; private MtlsProvider mtlsProvider = new MtlsProvider(); @@ -252,6 +250,7 @@ private Builder(InstantiatingHttpJsonChannelProvider provider) { this.executor = provider.executor; this.headerProvider = provider.headerProvider; this.endpoint = provider.endpoint; + this.endpointContext = provider.endpointContext; this.httpTransport = provider.httpTransport; this.mtlsProvider = provider.mtlsProvider; this.interceptorProvider = provider.interceptorProvider; @@ -306,6 +305,12 @@ public Builder setEndpoint(String endpoint) { return this; } + /** Sets the {@link EndpointContext} */ + public Builder setEndpointContext(EndpointContext endpointContext) { + this.endpointContext = endpointContext; + return this; + } + /** Sets the HTTP transport to be used. */ public Builder setHttpTransport(HttpTransport httpTransport) { this.httpTransport = httpTransport; @@ -324,7 +329,13 @@ Builder setMtlsProvider(MtlsProvider mtlsProvider) { public InstantiatingHttpJsonChannelProvider build() { return new InstantiatingHttpJsonChannelProvider( - executor, headerProvider, interceptorProvider, endpoint, httpTransport, mtlsProvider); + executor, + headerProvider, + interceptorProvider, + endpoint, + endpointContext, + httpTransport, + mtlsProvider); } } } diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java index 109200d8ec..7c50c7a255 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java @@ -222,9 +222,7 @@ public static ClientContext create(StubSettings settings) throws IOException { if (transportChannelProvider.needsEndpoint()) { transportChannelProvider = transportChannelProvider.withEndpoint(endpoint); } - if (transportChannelProvider.needsEndpointContext()) { - transportChannelProvider = transportChannelProvider.withEndpointContext(endpointContext); - } + transportChannelProvider = transportChannelProvider.withEndpointContext(endpointContext); TransportChannel transportChannel = transportChannelProvider.getTransportChannel(); ApiCallContext defaultCallContext = diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java index b2f39d63b5..caec3d7b08 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java @@ -42,6 +42,7 @@ public class FixedTransportChannelProvider implements TransportChannelProvider { private final TransportChannel transportChannel; + private EndpointContext endpointContext; private FixedTransportChannelProvider(TransportChannel transportChannel) { this.transportChannel = Preconditions.checkNotNull(transportChannel); @@ -83,11 +84,6 @@ public boolean needsEndpoint() { return false; } - @Override - public boolean needsEndpointContext() { - return false; - } - @Override public TransportChannelProvider withEndpoint(String endpoint) { throw new UnsupportedOperationException( @@ -96,8 +92,8 @@ public TransportChannelProvider withEndpoint(String endpoint) { @Override public TransportChannelProvider withEndpointContext(EndpointContext endpointContext) { - throw new UnsupportedOperationException( - "FixedTransportChannelProvider doesn't need an endpointContext"); + this.endpointContext = endpointContext; + return this; } /** @deprecated FixedTransportChannelProvider doesn't support ChannelPool configuration */ diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java index daf5f814b1..5aa3b2cb6e 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java @@ -90,9 +90,6 @@ public interface TransportChannelProvider { /** True if the TransportProvider has no endpoint set. */ boolean needsEndpoint(); - /** True if the TransportProvider needs an {@link EndpointContext} */ - boolean needsEndpointContext(); - /** * Sets the endpoint to use when constructing a new {@link TransportChannel}. * diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java index e3edf9aef1..48d1a342c5 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java @@ -179,11 +179,6 @@ public boolean needsEndpoint() { return true; } - @Override - public boolean needsEndpointContext() { - return false; - } - @Override public String getEndpoint() { return endpoint; From 30a37c221432cbf312ccdc8728dad5da23cf316e Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 5 Nov 2024 16:25:31 -0800 Subject: [PATCH 19/51] reduce nesting. --- .../InstantiatingGrpcChannelProvider.java | 87 ++++++++++--------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 89dea00d5b..e22709b216 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -447,52 +447,59 @@ ChannelCredentials createMtlsToS2AChannelCredentials( .build(); } + ChannelCredentials createPlaintextToS2AChannelCredentials(String plaintextAddress) { + if (plaintextAddress.isEmpty()) { + return null; + } + return S2AChannelCredentials.newBuilder(plaintextAddress, InsecureChannelCredentials.create()) + .build(); + } + ChannelCredentials createS2ASecuredChannelCredentials() { S2A s2aUtils = S2A.newBuilder().build(); String plaintextAddress = s2aUtils.getPlaintextS2AAddress(); String mtlsAddress = s2aUtils.getMtlsS2AAddress(); - if (!mtlsAddress.isEmpty()) { - // Currently, MTLS to MDS is only available on GCE. See: - // https://cloud.google.com/compute/docs/metadata/overview#https-mds - // Try to load MTLS-MDS creds. - InputStream trustBundle = null; - InputStream privateKey = null; - InputStream certChain = null; - try { - trustBundle = new FileInputStream(MTLS_MDS_ROOT); - privateKey = new FileInputStream(MTLS_MDS_CERT_CHAIN_AND_KEY); - certChain = new FileInputStream(MTLS_MDS_CERT_CHAIN_AND_KEY); - } catch (FileNotFoundException ignore) { - // Fallback to plaintext-to-S2A connection. - LOG.log( - Level.INFO, - "Cannot establish an mTLS connection to S2A due to error loading MTLS to MDS credentials, falling back to plaintext connection to S2A: " - + ignore.getMessage()); - } - ChannelCredentials mtlsToS2AChannelCredentials = null; - try { - // Try to connect to S2A using mTLS. - mtlsToS2AChannelCredentials = - createMtlsToS2AChannelCredentials(trustBundle, privateKey, certChain); - } catch (IOException ignore) { - // Fallback to plaintext-to-S2A connection. - LOG.log( - Level.INFO, - "Cannot establish an mTLS connection to S2A due to error creating MTLS to MDS TlsChannelCredentials credentials, falling back to plaintext connection to S2A: " - + ignore.getMessage()); - } - if (mtlsToS2AChannelCredentials != null) { - return S2AChannelCredentials.newBuilder(mtlsAddress, mtlsToS2AChannelCredentials).build(); - } - } - - if (!plaintextAddress.isEmpty()) { + if (mtlsAddress.isEmpty()) { + // Fallback to plaintext connection to S2A. + return createPlaintextToS2AChannelCredentials(plaintextAddress); + } + // Currently, MTLS to MDS is only available on GCE. See: + // https://cloud.google.com/compute/docs/metadata/overview#https-mds + // Try to load MTLS-MDS creds. + InputStream trustBundle = null; + InputStream privateKey = null; + InputStream certChain = null; + try { + trustBundle = new FileInputStream(MTLS_MDS_ROOT); + privateKey = new FileInputStream(MTLS_MDS_CERT_CHAIN_AND_KEY); + certChain = new FileInputStream(MTLS_MDS_CERT_CHAIN_AND_KEY); + } catch (FileNotFoundException ignore) { + // Fallback to plaintext-to-S2A connection. + LOG.log( + Level.INFO, + "Cannot establish an mTLS connection to S2A due to error loading MTLS to MDS credentials, falling back to plaintext connection to S2A: " + + ignore.getMessage()); // Fallback to plaintext connection to S2A. - return S2AChannelCredentials.newBuilder(plaintextAddress, InsecureChannelCredentials.create()) - .build(); + return createPlaintextToS2AChannelCredentials(plaintextAddress); } - - return null; + ChannelCredentials mtlsToS2AChannelCredentials = null; + try { + // Try to connect to S2A using mTLS. + mtlsToS2AChannelCredentials = + createMtlsToS2AChannelCredentials(trustBundle, privateKey, certChain); + } catch (IOException ignore) { + // Fallback to plaintext-to-S2A connection. + LOG.log( + Level.INFO, + "Cannot establish an mTLS connection to S2A due to error creating MTLS to MDS TlsChannelCredentials credentials, falling back to plaintext connection to S2A: " + + ignore.getMessage()); + return createPlaintextToS2AChannelCredentials(plaintextAddress); + } + if (mtlsToS2AChannelCredentials == null) { + // Fallback to plaintext-to-S2A connection. + return createPlaintextToS2AChannelCredentials(plaintextAddress); + } + return S2AChannelCredentials.newBuilder(mtlsAddress, mtlsToS2AChannelCredentials).build(); } private ManagedChannel createSingleChannel() throws IOException { From c3b93a02f012a144468e0fe00d46d119dffc2864 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 5 Nov 2024 16:32:22 -0800 Subject: [PATCH 20/51] check Strings null or empty. --- .../api/gax/grpc/InstantiatingGrpcChannelProvider.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index e22709b216..a91f829551 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -50,6 +50,7 @@ import com.google.auth.oauth2.S2A; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.io.Files; @@ -448,7 +449,7 @@ ChannelCredentials createMtlsToS2AChannelCredentials( } ChannelCredentials createPlaintextToS2AChannelCredentials(String plaintextAddress) { - if (plaintextAddress.isEmpty()) { + if (Strings.isNullOrEmpty(plaintextAddress)) { return null; } return S2AChannelCredentials.newBuilder(plaintextAddress, InsecureChannelCredentials.create()) @@ -459,7 +460,7 @@ ChannelCredentials createS2ASecuredChannelCredentials() { S2A s2aUtils = S2A.newBuilder().build(); String plaintextAddress = s2aUtils.getPlaintextS2AAddress(); String mtlsAddress = s2aUtils.getMtlsS2AAddress(); - if (mtlsAddress.isEmpty()) { + if (Strings.isNullOrEmpty(mtlsAddress)) { // Fallback to plaintext connection to S2A. return createPlaintextToS2AChannelCredentials(plaintextAddress); } From 18a4cf268f1a5d4a4508054b614c429a9606fc2a Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 5 Nov 2024 16:41:27 -0800 Subject: [PATCH 21/51] remove unecessary check. --- .../google/api/gax/grpc/InstantiatingGrpcChannelProvider.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index a91f829551..10ead5cb23 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -496,10 +496,6 @@ ChannelCredentials createS2ASecuredChannelCredentials() { + ignore.getMessage()); return createPlaintextToS2AChannelCredentials(plaintextAddress); } - if (mtlsToS2AChannelCredentials == null) { - // Fallback to plaintext-to-S2A connection. - return createPlaintextToS2AChannelCredentials(plaintextAddress); - } return S2AChannelCredentials.newBuilder(mtlsAddress, mtlsToS2AChannelCredentials).build(); } From 089773020f2324c8bb75dbc98954f3379dd28b56 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 5 Nov 2024 17:40:03 -0800 Subject: [PATCH 22/51] set endpointContext in grpc transport provider tests. --- .../InstantiatingGrpcChannelProvider.java | 2 +- .../InstantiatingGrpcChannelProviderTest.java | 64 ++++++++++++++++--- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 10ead5cb23..f9737748f1 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -550,7 +550,7 @@ private ManagedChannel createSingleChannel() throws IOException { // Could not create channel credentials via DCA. In accordance with // https://google.aip.dev/auth/4115, if credentials not available through // DCA, try mTLS with credentials held by the S2A (Secure Session Agent). - if ((endpointContext != null) && endpointContext.useS2A()) { + if (endpointContext.useS2A()) { channelCredentials = createS2ASecuredChannelCredentials(); } if (channelCredentials != null) { diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index c920937e6c..48a8590ef4 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -39,6 +39,7 @@ import com.google.api.core.ApiFunction; import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.Builder; +import com.google.api.gax.rpc.EndpointContext; import com.google.api.gax.rpc.FixedHeaderProvider; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.TransportChannel; @@ -202,13 +203,15 @@ void testCpuPoolSize() { void testWithPoolSize() throws IOException { ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1); executor.shutdown(); - + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.useS2A()).thenReturn(false); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .build() .withExecutor((Executor) executor) .withHeaders(Collections.emptyMap()) - .withEndpoint("localhost:8080"); + .withEndpoint("localhost:8080") + .withEndpointContext(endpointContext); assertThat(provider.acceptsPoolSize()).isTrue(); // Make sure we can create channels OK. @@ -267,9 +270,13 @@ void testWithInterceptorsAndMultipleChannels() throws Exception { private void testWithInterceptors(int numChannels) throws Exception { final GrpcInterceptorProvider interceptorProvider = Mockito.mock(GrpcInterceptorProvider.class); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.useS2A()).thenReturn(false); + InstantiatingGrpcChannelProvider channelProvider = InstantiatingGrpcChannelProvider.newBuilder() .setEndpoint("localhost:8080") + .setEndpointContext(endpointContext) .setPoolSize(numChannels) .setHeaderProvider(Mockito.mock(HeaderProvider.class)) .setExecutor(Mockito.mock(Executor.class)) @@ -300,9 +307,13 @@ void testChannelConfigurator() throws IOException { Mockito.when(channelConfigurator.apply(channelBuilderCaptor.capture())) .thenReturn(swappedBuilder); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.useS2A()).thenReturn(false); + // Invoke the provider InstantiatingGrpcChannelProvider.newBuilder() .setEndpoint("localhost:8080") + .setEndpointContext(endpointContext) .setHeaderProvider(Mockito.mock(HeaderProvider.class)) .setExecutor(Mockito.mock(Executor.class)) .setChannelConfigurator(channelConfigurator) @@ -321,13 +332,17 @@ void testWithGCECredentials() throws IOException { ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1); executor.shutdown(); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.useS2A()).thenReturn(false); + TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .build() .withExecutor((Executor) executor) .withHeaders(Collections.emptyMap()) - .withEndpoint("localhost:8080"); + .withEndpoint("localhost:8080") + .withEndpointContext(endpointContext); assertThat(provider.needsCredentials()).isTrue(); if (InstantiatingGrpcChannelProvider.isOnComputeEngine()) { @@ -402,6 +417,9 @@ void testWithNonGCECredentials() throws IOException { return channelBuilder; }; + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.useS2A()).thenReturn(false); + TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) @@ -409,7 +427,8 @@ void testWithNonGCECredentials() throws IOException { .build() .withExecutor((Executor) executor) .withHeaders(Collections.emptyMap()) - .withEndpoint("localhost:8080"); + .withEndpoint("localhost:8080") + .withEndpointContext(endpointContext); assertThat(provider.needsCredentials()).isTrue(); provider = provider.withCredentials(CloudShellCredentials.create(3000)); @@ -430,6 +449,9 @@ void testWithDirectPathDisabled() throws IOException { return channelBuilder; }; + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.useS2A()).thenReturn(false); + TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(false) @@ -437,7 +459,8 @@ void testWithDirectPathDisabled() throws IOException { .build() .withExecutor((Executor) executor) .withHeaders(Collections.emptyMap()) - .withEndpoint("localhost:8080"); + .withEndpoint("localhost:8080") + .withEndpointContext(endpointContext); assertThat(provider.needsCredentials()).isTrue(); provider = provider.withCredentials(ComputeEngineCredentials.create()); @@ -458,13 +481,17 @@ void testWithNoDirectPathFlagSet() throws IOException { return channelBuilder; }; + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.useS2A()).thenReturn(false); + TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setChannelConfigurator(channelConfigurator) .build() .withExecutor((Executor) executor) .withHeaders(Collections.emptyMap()) - .withEndpoint("localhost:8080"); + .withEndpoint("localhost:8080") + .withEndpointContext(endpointContext); assertThat(provider.needsCredentials()).isTrue(); provider = provider.withCredentials(ComputeEngineCredentials.create()); @@ -478,12 +505,16 @@ void testWithIPv6Address() throws IOException { ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1); executor.shutdown(); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.useS2A()).thenReturn(false); + TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .build() .withExecutor((Executor) executor) .withHeaders(Collections.emptyMap()) - .withEndpoint("[::1]:8080"); + .withEndpoint("[::1]:8080") + .withEndpointContext(endpointContext); assertThat(provider.needsEndpoint()).isFalse(); // Make sure we can create channels OK. @@ -493,6 +524,8 @@ void testWithIPv6Address() throws IOException { // Test that if ChannelPrimer is provided, it is called during creation @Test void testWithPrimeChannel() throws IOException { + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.useS2A()).thenReturn(false); // create channelProvider with different pool sizes to verify ChannelPrimer is called the // correct number of times for (int poolSize = 1; poolSize < 5; poolSize++) { @@ -501,6 +534,7 @@ void testWithPrimeChannel() throws IOException { InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setEndpoint("localhost:8080") + .setEndpointContext(endpointContext) .setPoolSize(poolSize) .setHeaderProvider(Mockito.mock(HeaderProvider.class)) .setExecutor(Mockito.mock(Executor.class)) @@ -623,8 +657,13 @@ private void createAndCloseTransportChannel(InstantiatingGrpcChannelProvider pro throws Exception { FakeLogHandler logHandler = new FakeLogHandler(); InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.useS2A()).thenReturn(false); InstantiatingGrpcChannelProvider provider = - createChannelProviderBuilderForDirectPathLogTests().setAttemptDirectPathXds().build(); + createChannelProviderBuilderForDirectPathLogTests() + .setAttemptDirectPathXds() + .setEndpointContext(endpointContext) + .build(); createAndCloseTransportChannel(provider); assertThat(logHandler.getAllMessages()) .contains( @@ -665,6 +704,8 @@ void testLogDirectPathMisconfig_shouldNotLogInTheBuilder() { void testLogDirectPathMisconfigWrongCredential() throws Exception { FakeLogHandler logHandler = new FakeLogHandler(); InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.useS2A()).thenReturn(false); InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPathXds() @@ -672,6 +713,7 @@ void testLogDirectPathMisconfigWrongCredential() throws Exception { .setHeaderProvider(Mockito.mock(HeaderProvider.class)) .setExecutor(Mockito.mock(Executor.class)) .setEndpoint(DEFAULT_ENDPOINT) + .setEndpointContext(endpointContext) .build(); TransportChannel transportChannel = provider.getTransportChannel(); @@ -690,6 +732,8 @@ void testLogDirectPathMisconfigWrongCredential() throws Exception { void testLogDirectPathMisconfigNotOnGCE() throws Exception { FakeLogHandler logHandler = new FakeLogHandler(); InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.useS2A()).thenReturn(false); InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPathXds() @@ -698,6 +742,7 @@ void testLogDirectPathMisconfigNotOnGCE() throws Exception { .setHeaderProvider(Mockito.mock(HeaderProvider.class)) .setExecutor(Mockito.mock(Executor.class)) .setEndpoint(DEFAULT_ENDPOINT) + .setEndpointContext(endpointContext) .build(); TransportChannel transportChannel = provider.getTransportChannel(); @@ -746,11 +791,14 @@ public void canUseDirectPath_directPathEnvVarDisabled() throws IOException { envProvider.getenv( InstantiatingGrpcChannelProvider.DIRECT_PATH_ENV_DISABLE_DIRECT_PATH)) .thenReturn("true"); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.useS2A()).thenReturn(false); InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setCredentials(computeEngineCredentials) .setEndpoint(DEFAULT_ENDPOINT) + .setEndpointContext(endpointContext) .setEnvProvider(envProvider) .setHeaderProvider(Mockito.mock(HeaderProvider.class)); InstantiatingGrpcChannelProvider provider = From 9901656a2714d58cc6b2c0775da1bfdd70a4ddec Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 5 Nov 2024 17:50:16 -0800 Subject: [PATCH 23/51] package private. --- .../main/java/com/google/api/gax/rpc/EndpointContext.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java index f28d2b8b5b..954fc4bd2c 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java @@ -203,10 +203,6 @@ public abstract static class Builder { */ public abstract Builder setTransportChannelProviderEndpoint(String transportChannelEndpoint); - public abstract Builder setUseS2A(boolean useS2A); - - public abstract Builder setEnvProvider(EnvironmentProvider envProvider); - public abstract Builder setMtlsEndpoint(String mtlsEndpoint); public abstract Builder setSwitchToMtlsEndpointAllowed(boolean switchToMtlsEndpointAllowed); @@ -219,6 +215,10 @@ public abstract static class Builder { public abstract Builder setResolvedUniverseDomain(String resolvedUniverseDomain); + abstract Builder setUseS2A(boolean useS2A); + + abstract Builder setEnvProvider(EnvironmentProvider envProvider); + abstract String serviceName(); abstract String universeDomain(); From 257c51578b71d86043576a234480ce7029c11738 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 5 Nov 2024 17:55:27 -0800 Subject: [PATCH 24/51] set System::getenv as envProvider. --- .../java/com/google/api/gax/rpc/EndpointContext.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java index 954fc4bd2c..476fb54cee 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java @@ -126,7 +126,8 @@ public static EndpointContext getDefaultInstance() { public static Builder newBuilder() { return new AutoValue_EndpointContext.Builder() .setSwitchToMtlsEndpointAllowed(false) - .setUsingGDCH(false); + .setUsingGDCH(false) + .setEnvProvider(System::getenv); } /** Configure the existing EndpointContext to be using GDC-H */ @@ -308,11 +309,7 @@ private String determineEndpoint() throws IOException { boolean shouldUseS2A() { // If EXPERIMENTAL_GOOGLE_API_USE_S2A is not set to true, skip S2A. String s2AEnv; - if (envProvider() != null) { - s2AEnv = envProvider().getenv(S2A_ENV_ENABLE_USE_S2A); - } else { - s2AEnv = System.getenv(S2A_ENV_ENABLE_USE_S2A); - } + s2AEnv = envProvider().getenv(S2A_ENV_ENABLE_USE_S2A); boolean s2AEnabled = Boolean.parseBoolean(s2AEnv); if (!s2AEnabled) { return false; From e4565f49eefada0d4a760098c2b4cba1e2cefee9 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 6 Nov 2024 05:53:38 -0800 Subject: [PATCH 25/51] add javadoc. --- .../gax/grpc/InstantiatingGrpcChannelProvider.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index f9737748f1..7155119567 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -456,6 +456,18 @@ ChannelCredentials createPlaintextToS2AChannelCredentials(String plaintextAddres .build(); } + /** + * This method creates gRPC {@link ChannelCredentials} configured to use S2A to estbalish a mTLS + * connection. First, the address of S2A is discovered by using the {@link S2A} utility to learn + * the {@code mtlsAddress} to reach S2A and the {@code plaintextAddress} to reach S2A. Prefer to + * use the {@code mtlsAddress} address to reach S2A if it is non-empty and the MTLS-MDS + * credentials can successfully be discovered and used to create {@link TlsChannelCredentials}. If + * there is any failure using mTLS-to-S2A, fallback to using a plaintext connection to S2A using + * the {@code plaintextAddress}. + * + * @return {@link ChannelCredentials} configured to use S2A to create mTLS connection to + * mtlsEndpoint. + */ ChannelCredentials createS2ASecuredChannelCredentials() { S2A s2aUtils = S2A.newBuilder().build(); String plaintextAddress = s2aUtils.getPlaintextS2AAddress(); From 33bd7a6be4f8ab28621956a80f1f166893591408 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 6 Nov 2024 08:00:47 -0800 Subject: [PATCH 26/51] no getters for endpointcontext. --- .../api/gax/grpc/InstantiatingGrpcChannelProvider.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 7155119567..0cd8138fdc 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -662,11 +662,6 @@ public String getEndpoint() { return endpoint; } - /** The endpoint context. */ - public EndpointContext getEndpointContext() { - return endpointContext; - } - /** This method is obsolete. Use {@link #getKeepAliveTimeDuration()} instead. */ @ObsoleteApi("Use getKeepAliveTimeDuration() instead") public org.threeten.bp.Duration getKeepAliveTime() { @@ -849,10 +844,6 @@ public String getEndpoint() { return endpoint; } - public EndpointContext getEndpointContext() { - return endpointContext; - } - /** The maximum message size allowed to be received on the channel. */ public Builder setMaxInboundMessageSize(Integer max) { this.maxInboundMessageSize = max; From f9eef5b0e0ef3f2df1ba659693d836f5ba547eb7 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 6 Nov 2024 08:05:36 -0800 Subject: [PATCH 27/51] nits + package private. --- .../google/api/gax/grpc/InstantiatingGrpcChannelProvider.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 0cd8138fdc..480357d6ea 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -492,7 +492,6 @@ ChannelCredentials createS2ASecuredChannelCredentials() { Level.INFO, "Cannot establish an mTLS connection to S2A due to error loading MTLS to MDS credentials, falling back to plaintext connection to S2A: " + ignore.getMessage()); - // Fallback to plaintext connection to S2A. return createPlaintextToS2AChannelCredentials(plaintextAddress); } ChannelCredentials mtlsToS2AChannelCredentials = null; @@ -817,7 +816,7 @@ public Builder setEndpoint(String endpoint) { return this; } - public Builder setEndpointContext(EndpointContext endpointContext) { + Builder setEndpointContext(EndpointContext endpointContext) { this.endpointContext = endpointContext; return this; } From a7af12e44b987e2edd7a7f7a1113a14cf5527001 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 6 Nov 2024 08:34:56 -0800 Subject: [PATCH 28/51] update javadocs + add mtlsServiceAddress. --- .../InstantiatingGrpcChannelProvider.java | 16 ++++++++++++++-- .../InstantiatingGrpcChannelProviderTest.java | 19 ++++++++++++++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 480357d6ea..e6a7a2750b 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -107,6 +107,8 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP @VisibleForTesting static final String DIRECT_PATH_ENV_ENABLE_XDS = "GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS"; + // The public portion of the mTLS MDS root certificate is stored for performing + // cert verification when establishing an mTLS connection with the MDS. private static final String MTLS_MDS_ROOT = "/run/google-mds-mtls/root.crt"; // The mTLS MDS credentials are formatted as the concatenation of a PEM-encoded certificate chain // followed by a PEM-encoded private key. @@ -463,7 +465,9 @@ ChannelCredentials createPlaintextToS2AChannelCredentials(String plaintextAddres * use the {@code mtlsAddress} address to reach S2A if it is non-empty and the MTLS-MDS * credentials can successfully be discovered and used to create {@link TlsChannelCredentials}. If * there is any failure using mTLS-to-S2A, fallback to using a plaintext connection to S2A using - * the {@code plaintextAddress}. + * the {@code plaintextAddress}. If {@code plaintextAddress} is not available, this function + * returns null; in this case S2A will not be used, and a TLS connection to the service will be + * established. * * @return {@link ChannelCredentials} configured to use S2A to create mTLS connection to * mtlsEndpoint. @@ -524,6 +528,14 @@ private ManagedChannel createSingleChannel() throws IOException { int port = Integer.parseInt(endpoint.substring(colon + 1)); String serviceAddress = endpoint.substring(0, colon); + int mtlsColon = endpointContext.mtlsEndpoint().lastIndexOf(':'); + if (mtlsColon < 0) { + throw new IllegalStateException( + "invalid mtlsEndpoint - should have been validated: " + endpointContext.mtlsEndpoint()); + } + int mtlsPort = Integer.parseInt(endpointContext.mtlsEndpoint().substring(mtlsColon + 1)); + String mtlsServiceAddress = endpointContext.mtlsEndpoint().substring(0, mtlsColon); + ManagedChannelBuilder builder; // Check DirectPath traffic. @@ -566,7 +578,7 @@ private ManagedChannel createSingleChannel() throws IOException { } if (channelCredentials != null) { // Create the channel using S2A-secured channel credentials. - builder = Grpc.newChannelBuilder(endpointContext.mtlsEndpoint(), channelCredentials); + builder = Grpc.newChannelBuilder(mtlsServiceAddress, channelCredentials); } else { // Use default if we cannot initialize channel credentials via DCA or S2A. builder = ManagedChannelBuilder.forAddress(serviceAddress, port); diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index 48a8590ef4..3b30a869e8 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -86,6 +86,7 @@ class InstantiatingGrpcChannelProviderTest extends AbstractMtlsTransportChannelTest { private static final String DEFAULT_ENDPOINT = "test.googleapis.com:443"; + private static final String DEFAULT_MTLS_ENDPOINT = "test.mtls.googleapis.com:443"; private static final String API_KEY_HEADER_VALUE = "fake_api_key_2"; private static final String API_KEY_AUTH_HEADER_KEY = "x-goog-api-key"; private static String originalOSName; @@ -205,6 +206,7 @@ void testWithPoolSize() throws IOException { executor.shutdown(); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); + Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .build() @@ -272,6 +274,7 @@ private void testWithInterceptors(int numChannels) throws Exception { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); + Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); InstantiatingGrpcChannelProvider channelProvider = InstantiatingGrpcChannelProvider.newBuilder() @@ -309,6 +312,7 @@ void testChannelConfigurator() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); + Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); // Invoke the provider InstantiatingGrpcChannelProvider.newBuilder() @@ -334,6 +338,7 @@ void testWithGCECredentials() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); + Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -419,6 +424,7 @@ void testWithNonGCECredentials() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); + Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -451,6 +457,7 @@ void testWithDirectPathDisabled() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); + Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -483,6 +490,7 @@ void testWithNoDirectPathFlagSet() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); + Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -507,6 +515,7 @@ void testWithIPv6Address() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); + Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -526,6 +535,7 @@ void testWithIPv6Address() throws IOException { void testWithPrimeChannel() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); + Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); // create channelProvider with different pool sizes to verify ChannelPrimer is called the // correct number of times for (int poolSize = 1; poolSize < 5; poolSize++) { @@ -659,6 +669,7 @@ private void createAndCloseTransportChannel(InstantiatingGrpcChannelProvider pro InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); + Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); InstantiatingGrpcChannelProvider provider = createChannelProviderBuilderForDirectPathLogTests() .setAttemptDirectPathXds() @@ -706,6 +717,7 @@ void testLogDirectPathMisconfigWrongCredential() throws Exception { InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); + Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPathXds() @@ -734,6 +746,7 @@ void testLogDirectPathMisconfigNotOnGCE() throws Exception { InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); + Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPathXds() @@ -766,13 +779,16 @@ public void canUseDirectPath_happyPath() throws IOException { envProvider.getenv( InstantiatingGrpcChannelProvider.DIRECT_PATH_ENV_DISABLE_DIRECT_PATH)) .thenReturn("false"); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setCredentials(computeEngineCredentials) .setEndpoint(DEFAULT_ENDPOINT) .setEnvProvider(envProvider) - .setHeaderProvider(Mockito.mock(HeaderProvider.class)); + .setHeaderProvider(Mockito.mock(HeaderProvider.class)) + .setEndpointContext(endpointContext); InstantiatingGrpcChannelProvider provider = new InstantiatingGrpcChannelProvider(builder, GCE_PRODUCTION_NAME_AFTER_2016); Truth.assertThat(provider.canUseDirectPath()).isTrue(); @@ -793,6 +809,7 @@ public void canUseDirectPath_directPathEnvVarDisabled() throws IOException { .thenReturn("true"); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); + Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) From eb7022524c87eb98b2faf7b2770e080e20bed2c2 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 6 Nov 2024 08:49:54 -0800 Subject: [PATCH 29/51] add javadocs. --- .../InstantiatingGrpcChannelProvider.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index e6a7a2750b..285da8b2e8 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -438,6 +438,19 @@ ChannelCredentials createMtlsChannelCredentials() throws IOException, GeneralSec return null; } + /** + * This method creates {@link TlsChannelCredentials} to be used by the client to establish an mTLS + * connection to S2A. Returns null if any of {@param trustBundle}, {@param privateKey} or {@param + * certChain} are missing. + * + * @param trustBundle the trust bundle to be used to establish the client -> S2A mTLS connection + * @param privateKey the client's private key to be used to establish the client -> S2A mtls + * connection + * @param certChain the client's cert chain to be used to establish the client -> S2A mtls + * connection + * @return {@link ChannelCredentials} to use to create an mtls connection between client and S2A + * @throws IOException on error + */ @VisibleForTesting ChannelCredentials createMtlsToS2AChannelCredentials( InputStream trustBundle, InputStream privateKey, InputStream certChain) throws IOException { @@ -450,6 +463,14 @@ ChannelCredentials createMtlsToS2AChannelCredentials( .build(); } + /** + * This method creates {@link ChannelCredentials} to be used by client to establish a plaintext + * connection to S2A. if {@param plaintextAddress} is not present, returns null. + * + * @param plaintextAddress the address to reach S2A which accepts plaintext connections + * @return {@link ChannelCredentials} to use to create a plaintext connection between client and + * S2A + */ ChannelCredentials createPlaintextToS2AChannelCredentials(String plaintextAddress) { if (Strings.isNullOrEmpty(plaintextAddress)) { return null; From 2a50985211d44ca87423b580c617c5b1e92e3d22 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 6 Nov 2024 08:55:22 -0800 Subject: [PATCH 30/51] update readme. --- gax-java/gax-grpc/src/test/resources/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gax-java/gax-grpc/src/test/resources/README.md b/gax-java/gax-grpc/src/test/resources/README.md index 3335ba1b3a..cca31f3de7 100644 --- a/gax-java/gax-grpc/src/test/resources/README.md +++ b/gax-java/gax-grpc/src/test/resources/README.md @@ -1,4 +1,6 @@ # Generating certificates and keys for testing mTLS-S2A +Below are the commands which can be used to refresh the certs used in tests. This is the same process +used to generate test certs for S2A client in grpc-java: https://github.com/grpc/grpc-java/blob/master/s2a/src/test/resources/README.md Create root CA From 943683db2e9996dc1d767bb5a8cd26b532fba3e2 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 6 Nov 2024 09:00:06 -0800 Subject: [PATCH 31/51] private + readme updates. --- gax-java/gax-grpc/src/test/resources/README.md | 4 ++-- .../src/main/java/com/google/api/gax/rpc/EndpointContext.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gax-java/gax-grpc/src/test/resources/README.md b/gax-java/gax-grpc/src/test/resources/README.md index cca31f3de7..a9a9b0efe9 100644 --- a/gax-java/gax-grpc/src/test/resources/README.md +++ b/gax-java/gax-grpc/src/test/resources/README.md @@ -1,5 +1,5 @@ -# Generating certificates and keys for testing mTLS-S2A -Below are the commands which can be used to refresh the certs used in tests. This is the same process +# Regenerate certificates and keys for testing mTLS-S2A +Below are the commands which can be used to regenerate the certs used in tests. This is the same process used to generate test certs for S2A client in grpc-java: https://github.com/grpc/grpc-java/blob/master/s2a/src/test/resources/README.md Create root CA diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java index 476fb54cee..483618ae14 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java @@ -105,7 +105,7 @@ public static EndpointContext getDefaultInstance() { public abstract boolean useS2A(); @Nullable - public abstract EnvironmentProvider envProvider(); + abstract EnvironmentProvider envProvider(); @Nullable public abstract String mtlsEndpoint(); From fb3d608fc254305d195f4fd1aa7aa34b1d86de26 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 6 Nov 2024 09:16:49 -0800 Subject: [PATCH 32/51] update CLIRR-ignored-differences. --- gax-java/gax/clirr-ignored-differences.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gax-java/gax/clirr-ignored-differences.xml b/gax-java/gax/clirr-ignored-differences.xml index af5c5f26a1..67ab069abd 100644 --- a/gax-java/gax/clirr-ignored-differences.xml +++ b/gax-java/gax/clirr-ignored-differences.xml @@ -106,4 +106,16 @@ com/google/api/gax/batching/Batcher * + + + 7013 + com/google/api/gax/rpc/EndpointContext + * useS2A() + + + + 7012 + com/google/api/gax/rpc/TransportChannelProvider + * withEndpointContext(*) + From 926facae0f29ef653a75c63a793908440cf4b3e3 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 6 Nov 2024 09:34:18 -0800 Subject: [PATCH 33/51] mark endpoint as Obsolete. --- .../InstantiatingGrpcChannelProvider.java | 21 +++++--------- .../InstantiatingGrpcChannelProviderTest.java | 29 +++++++++---------- .../InstantiatingHttpJsonChannelProvider.java | 2 +- .../api/gax/rpc/TransportChannelProvider.java | 3 ++ 4 files changed, 25 insertions(+), 30 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 285da8b2e8..efc81be98b 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -421,7 +421,7 @@ private static String getSystemProductName() { // Universe Domain configuration is currently only supported in the GDU @VisibleForTesting boolean canUseDirectPathWithUniverseDomain() { - return endpoint.contains(Credentials.GOOGLE_DEFAULT_UNIVERSE); + return endpointContext.resolvedEndpoint().contains(Credentials.GOOGLE_DEFAULT_UNIVERSE); } @VisibleForTesting @@ -542,20 +542,13 @@ private ManagedChannel createSingleChannel() throws IOException { GrpcMetadataHandlerInterceptor metadataHandlerInterceptor = new GrpcMetadataHandlerInterceptor(); - int colon = endpoint.lastIndexOf(':'); + int colon = endpointContext.resolvedEndpoint().lastIndexOf(':'); if (colon < 0) { - throw new IllegalStateException("invalid endpoint - should have been validated: " + endpoint); - } - int port = Integer.parseInt(endpoint.substring(colon + 1)); - String serviceAddress = endpoint.substring(0, colon); - - int mtlsColon = endpointContext.mtlsEndpoint().lastIndexOf(':'); - if (mtlsColon < 0) { throw new IllegalStateException( - "invalid mtlsEndpoint - should have been validated: " + endpointContext.mtlsEndpoint()); + "invalid endpoint - should have been validated: " + endpointContext.resolvedEndpoint()); } - int mtlsPort = Integer.parseInt(endpointContext.mtlsEndpoint().substring(mtlsColon + 1)); - String mtlsServiceAddress = endpointContext.mtlsEndpoint().substring(0, mtlsColon); + int port = Integer.parseInt(endpointContext.resolvedEndpoint().substring(colon + 1)); + String serviceAddress = endpointContext.resolvedEndpoint().substring(0, colon); ManagedChannelBuilder builder; @@ -589,7 +582,7 @@ private ManagedChannel createSingleChannel() throws IOException { } if (channelCredentials != null) { // Create the channel using channel credentials created via DCA. - builder = Grpc.newChannelBuilder(endpoint, channelCredentials); + builder = Grpc.newChannelBuilder(endpointContext.resolvedEndpoint(), channelCredentials); } else { // Could not create channel credentials via DCA. In accordance with // https://google.aip.dev/auth/4115, if credentials not available through @@ -599,7 +592,7 @@ private ManagedChannel createSingleChannel() throws IOException { } if (channelCredentials != null) { // Create the channel using S2A-secured channel credentials. - builder = Grpc.newChannelBuilder(mtlsServiceAddress, channelCredentials); + builder = Grpc.newChannelBuilder(endpointContext.mtlsEndpoint(), channelCredentials); } else { // Use default if we cannot initialize channel credentials via DCA or S2A. builder = ManagedChannelBuilder.forAddress(serviceAddress, port); diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index 3b30a869e8..7711e60d83 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -86,7 +86,6 @@ class InstantiatingGrpcChannelProviderTest extends AbstractMtlsTransportChannelTest { private static final String DEFAULT_ENDPOINT = "test.googleapis.com:443"; - private static final String DEFAULT_MTLS_ENDPOINT = "test.mtls.googleapis.com:443"; private static final String API_KEY_HEADER_VALUE = "fake_api_key_2"; private static final String API_KEY_AUTH_HEADER_KEY = "x-goog-api-key"; private static String originalOSName; @@ -206,7 +205,7 @@ void testWithPoolSize() throws IOException { executor.shutdown(); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .build() @@ -274,7 +273,7 @@ private void testWithInterceptors(int numChannels) throws Exception { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); InstantiatingGrpcChannelProvider channelProvider = InstantiatingGrpcChannelProvider.newBuilder() @@ -312,7 +311,7 @@ void testChannelConfigurator() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); // Invoke the provider InstantiatingGrpcChannelProvider.newBuilder() @@ -338,7 +337,7 @@ void testWithGCECredentials() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -424,7 +423,7 @@ void testWithNonGCECredentials() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -457,7 +456,7 @@ void testWithDirectPathDisabled() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -490,7 +489,7 @@ void testWithNoDirectPathFlagSet() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -515,7 +514,7 @@ void testWithIPv6Address() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -535,7 +534,7 @@ void testWithIPv6Address() throws IOException { void testWithPrimeChannel() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); // create channelProvider with different pool sizes to verify ChannelPrimer is called the // correct number of times for (int poolSize = 1; poolSize < 5; poolSize++) { @@ -669,7 +668,7 @@ private void createAndCloseTransportChannel(InstantiatingGrpcChannelProvider pro InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); InstantiatingGrpcChannelProvider provider = createChannelProviderBuilderForDirectPathLogTests() .setAttemptDirectPathXds() @@ -717,7 +716,7 @@ void testLogDirectPathMisconfigWrongCredential() throws Exception { InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPathXds() @@ -746,7 +745,7 @@ void testLogDirectPathMisconfigNotOnGCE() throws Exception { InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPathXds() @@ -780,7 +779,7 @@ public void canUseDirectPath_happyPath() throws IOException { InstantiatingGrpcChannelProvider.DIRECT_PATH_ENV_DISABLE_DIRECT_PATH)) .thenReturn("false"); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) @@ -809,7 +808,7 @@ public void canUseDirectPath_directPathEnvVarDisabled() throws IOException { .thenReturn("true"); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.mtlsEndpoint()).thenReturn(DEFAULT_MTLS_ENDPOINT); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) diff --git a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java index 3af6eb323d..aa66282831 100644 --- a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java +++ b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java @@ -197,7 +197,7 @@ private HttpJsonTransportChannel createChannel() throws IOException, GeneralSecu // the channel will use a default executor for the calls. ManagedHttpJsonChannel channel = ManagedHttpJsonChannel.newBuilder() - .setEndpoint(endpoint) + .setEndpoint(endpointContext.resolvedEndpoint()) .setExecutor(executor) .setHttpTransport(httpTransportToUse) .build(); diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java index 5aa3b2cb6e..da66cc5058 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java @@ -31,6 +31,7 @@ import com.google.api.core.BetaApi; import com.google.api.core.InternalExtensionOnly; +import com.google.api.core.ObsoleteApi; import com.google.auth.Credentials; import java.io.IOException; import java.util.Map; @@ -88,6 +89,7 @@ public interface TransportChannelProvider { TransportChannelProvider withHeaders(Map headers); /** True if the TransportProvider has no endpoint set. */ + @ObsoleteApi("Use endpointContext.resolvedEndpoint() instead") boolean needsEndpoint(); /** @@ -95,6 +97,7 @@ public interface TransportChannelProvider { * *

This method should only be called if {@link #needsEndpoint()} returns true. */ + @ObsoleteApi("Use endpointContext.resolvedEndpoint() instead") TransportChannelProvider withEndpoint(String endpoint); /** Sets the {@link EndpointContext} when constructing a new {@link TransportChannel}. */ From 4ee2ee91154b83def30ae44fce7424674f616f80 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 6 Nov 2024 14:13:43 -0800 Subject: [PATCH 34/51] fix remaining tests to mock endpointContext.resolvedEndpoint(). --- .../InstantiatingGrpcChannelProviderTest.java | 16 +++++++++++++++- .../httpjson/HttpJsonClientInterceptorTest.java | 3 +++ ...InstantiatingHttpJsonChannelProviderTest.java | 16 +++++++++++++++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index 7711e60d83..19bedd0bd1 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -377,22 +377,30 @@ void testDirectPathDisallowNullCredentials() throws IOException { @Test void testDirectPathWithGDUEndpoint() { + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); + InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setAttemptDirectPathXds() .setEndpoint(DEFAULT_ENDPOINT) + .setEndpointContext(endpointContext) .build(); assertThat(provider.canUseDirectPathWithUniverseDomain()).isTrue(); } @Test void testDirectPathWithNonGDUEndpoint() { + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn("test.random.com:443"); + InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setAttemptDirectPathXds() .setEndpoint("test.random.com:443") + .setEndpointContext(endpointContext) .build(); assertThat(provider.canUseDirectPathWithUniverseDomain()).isFalse(); } @@ -830,11 +838,14 @@ public void canUseDirectPath_directPathEnvVarDisabled() throws IOException { @Test public void canUseDirectPath_directPathEnvVarNotSet_attemptDirectPathIsTrue() { System.setProperty("os.name", "Linux"); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setCredentials(computeEngineCredentials) - .setEndpoint(DEFAULT_ENDPOINT); + .setEndpoint(DEFAULT_ENDPOINT) + .setEndpointContext(endpointContext); InstantiatingGrpcChannelProvider provider = new InstantiatingGrpcChannelProvider(builder, GCE_PRODUCTION_NAME_AFTER_2016); Truth.assertThat(provider.canUseDirectPath()).isTrue(); @@ -938,11 +949,14 @@ public void canUseDirectPath_nonGDUUniverseDomain() { InstantiatingGrpcChannelProvider.DIRECT_PATH_ENV_DISABLE_DIRECT_PATH)) .thenReturn("false"); String nonGDUEndpoint = "test.random.com:443"; + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(nonGDUEndpoint); InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setCredentials(computeEngineCredentials) .setEndpoint(nonGDUEndpoint) + .setEndpointContext(endpointContext) .setEnvProvider(envProvider); InstantiatingGrpcChannelProvider provider = new InstantiatingGrpcChannelProvider(builder, GCE_PRODUCTION_NAME_AFTER_2016); diff --git a/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonClientInterceptorTest.java b/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonClientInterceptorTest.java index 85146ceb07..269a0b9615 100644 --- a/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonClientInterceptorTest.java +++ b/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonClientInterceptorTest.java @@ -159,9 +159,12 @@ public static void destroy() { @BeforeEach void setUp() throws IOException { interceptor = new CapturingClientInterceptor(); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn("google.com:443"); channel = InstantiatingHttpJsonChannelProvider.newBuilder() .setEndpoint("google.com:443") + .setEndpointContext(endpointContext) .setExecutor(executorService) .setHttpTransport(MOCK_SERVICE) .setHeaderProvider(() -> Collections.singletonMap("header-key", "headerValue")) diff --git a/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProviderTest.java b/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProviderTest.java index 2e46157534..a779091fd6 100644 --- a/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProviderTest.java +++ b/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProviderTest.java @@ -32,6 +32,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; +import com.google.api.gax.rpc.EndpointContext; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.TransportChannelProvider; import com.google.api.gax.rpc.mtls.AbstractMtlsTransportChannelTest; @@ -56,8 +57,12 @@ void basicTest() throws IOException { ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1); executor.shutdown(); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); + TransportChannelProvider provider = InstantiatingHttpJsonChannelProvider.newBuilder().build(); + provider = provider.withEndpointContext(endpointContext); assertThat(provider.needsEndpoint()).isTrue(); provider = provider.withEndpoint(DEFAULT_ENDPOINT); assertThat(provider.needsEndpoint()).isFalse(); @@ -107,8 +112,13 @@ void basicTest() throws IOException { // if not provided by the TransportChannelProvider @Test void managedChannelUsesDefaultChannelExecutor() throws IOException { + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); InstantiatingHttpJsonChannelProvider instantiatingHttpJsonChannelProvider = - InstantiatingHttpJsonChannelProvider.newBuilder().setEndpoint(DEFAULT_ENDPOINT).build(); + InstantiatingHttpJsonChannelProvider.newBuilder() + .setEndpoint(DEFAULT_ENDPOINT) + .setEndpointContext(endpointContext) + .build(); instantiatingHttpJsonChannelProvider = (InstantiatingHttpJsonChannelProvider) instantiatingHttpJsonChannelProvider.withHeaders(DEFAULT_HEADER_MAP); @@ -132,9 +142,13 @@ void managedChannelUsesCustomExecutor() throws IOException { ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1); executor.shutdown(); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); + InstantiatingHttpJsonChannelProvider instantiatingHttpJsonChannelProvider = InstantiatingHttpJsonChannelProvider.newBuilder() .setEndpoint(DEFAULT_ENDPOINT) + .setEndpointContext(endpointContext) .setExecutor(executor) .build(); instantiatingHttpJsonChannelProvider = From 2f70bf80b7f870fb426a73b6caecd6ea473c25d8 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 6 Nov 2024 14:18:56 -0800 Subject: [PATCH 35/51] modify obsolete statement. --- .../java/com/google/api/gax/rpc/TransportChannelProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java index da66cc5058..d7d2067b32 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java @@ -89,7 +89,7 @@ public interface TransportChannelProvider { TransportChannelProvider withHeaders(Map headers); /** True if the TransportProvider has no endpoint set. */ - @ObsoleteApi("Use endpointContext.resolvedEndpoint() instead") + @ObsoleteApi("Endpoint should be configured set in the ClientSettings") boolean needsEndpoint(); /** @@ -97,7 +97,7 @@ public interface TransportChannelProvider { * *

This method should only be called if {@link #needsEndpoint()} returns true. */ - @ObsoleteApi("Use endpointContext.resolvedEndpoint() instead") + @ObsoleteApi("Endpoint should be configured set in the ClientSettings") TransportChannelProvider withEndpoint(String endpoint); /** Sets the {@link EndpointContext} when constructing a new {@link TransportChannel}. */ From c96c76092c69755007878ace8a44acc56e8a59ec Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Thu, 7 Nov 2024 06:09:47 -0800 Subject: [PATCH 36/51] revert usage of endpointContext.resolvedEndpoint(). --- .../InstantiatingGrpcChannelProvider.java | 13 +++--- .../InstantiatingGrpcChannelProviderTest.java | 45 ++++++++----------- .../InstantiatingHttpJsonChannelProvider.java | 2 +- .../HttpJsonClientInterceptorTest.java | 3 -- ...tantiatingHttpJsonChannelProviderTest.java | 16 +------ .../api/gax/rpc/TransportChannelProvider.java | 3 -- 6 files changed, 26 insertions(+), 56 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index efc81be98b..d33fef2d54 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -421,7 +421,7 @@ private static String getSystemProductName() { // Universe Domain configuration is currently only supported in the GDU @VisibleForTesting boolean canUseDirectPathWithUniverseDomain() { - return endpointContext.resolvedEndpoint().contains(Credentials.GOOGLE_DEFAULT_UNIVERSE); + return endpoint.contains(Credentials.GOOGLE_DEFAULT_UNIVERSE); } @VisibleForTesting @@ -542,13 +542,12 @@ private ManagedChannel createSingleChannel() throws IOException { GrpcMetadataHandlerInterceptor metadataHandlerInterceptor = new GrpcMetadataHandlerInterceptor(); - int colon = endpointContext.resolvedEndpoint().lastIndexOf(':'); + int colon = endpoint.lastIndexOf(':'); if (colon < 0) { - throw new IllegalStateException( - "invalid endpoint - should have been validated: " + endpointContext.resolvedEndpoint()); + throw new IllegalStateException("invalid endpoint - should have been validated: " + endpoint); } - int port = Integer.parseInt(endpointContext.resolvedEndpoint().substring(colon + 1)); - String serviceAddress = endpointContext.resolvedEndpoint().substring(0, colon); + int port = Integer.parseInt(endpoint.substring(colon + 1)); + String serviceAddress = endpoint.substring(0, colon); ManagedChannelBuilder builder; @@ -582,7 +581,7 @@ private ManagedChannel createSingleChannel() throws IOException { } if (channelCredentials != null) { // Create the channel using channel credentials created via DCA. - builder = Grpc.newChannelBuilder(endpointContext.resolvedEndpoint(), channelCredentials); + builder = Grpc.newChannelBuilder(endpoint, channelCredentials); } else { // Could not create channel credentials via DCA. In accordance with // https://google.aip.dev/auth/4115, if credentials not available through diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index 19bedd0bd1..025c15a06c 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -205,7 +205,7 @@ void testWithPoolSize() throws IOException { executor.shutdown(); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); + TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .build() @@ -273,7 +273,6 @@ private void testWithInterceptors(int numChannels) throws Exception { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); InstantiatingGrpcChannelProvider channelProvider = InstantiatingGrpcChannelProvider.newBuilder() @@ -311,7 +310,6 @@ void testChannelConfigurator() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); // Invoke the provider InstantiatingGrpcChannelProvider.newBuilder() @@ -337,7 +335,6 @@ void testWithGCECredentials() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -377,30 +374,28 @@ void testDirectPathDisallowNullCredentials() throws IOException { @Test void testDirectPathWithGDUEndpoint() { - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); + // EndpointContext endpointContext = Mockito.mock(EndpointContext.class); InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setAttemptDirectPathXds() .setEndpoint(DEFAULT_ENDPOINT) - .setEndpointContext(endpointContext) + // .setEndpointContext(endpointContext) .build(); assertThat(provider.canUseDirectPathWithUniverseDomain()).isTrue(); } @Test void testDirectPathWithNonGDUEndpoint() { - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn("test.random.com:443"); + // EndpointContext endpointContext = Mockito.mock(EndpointContext.class); InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setAttemptDirectPathXds() .setEndpoint("test.random.com:443") - .setEndpointContext(endpointContext) + // .setEndpointContext(endpointContext) .build(); assertThat(provider.canUseDirectPathWithUniverseDomain()).isFalse(); } @@ -431,7 +426,6 @@ void testWithNonGCECredentials() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -464,7 +458,6 @@ void testWithDirectPathDisabled() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -497,7 +490,6 @@ void testWithNoDirectPathFlagSet() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -522,7 +514,6 @@ void testWithIPv6Address() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() @@ -542,7 +533,7 @@ void testWithIPv6Address() throws IOException { void testWithPrimeChannel() throws IOException { EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); + // create channelProvider with different pool sizes to verify ChannelPrimer is called the // correct number of times for (int poolSize = 1; poolSize < 5; poolSize++) { @@ -676,7 +667,7 @@ private void createAndCloseTransportChannel(InstantiatingGrpcChannelProvider pro InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); + InstantiatingGrpcChannelProvider provider = createChannelProviderBuilderForDirectPathLogTests() .setAttemptDirectPathXds() @@ -724,7 +715,7 @@ void testLogDirectPathMisconfigWrongCredential() throws Exception { InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); + InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPathXds() @@ -753,7 +744,7 @@ void testLogDirectPathMisconfigNotOnGCE() throws Exception { InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); + InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPathXds() @@ -787,7 +778,7 @@ public void canUseDirectPath_happyPath() throws IOException { InstantiatingGrpcChannelProvider.DIRECT_PATH_ENV_DISABLE_DIRECT_PATH)) .thenReturn("false"); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); + InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) @@ -816,7 +807,7 @@ public void canUseDirectPath_directPathEnvVarDisabled() throws IOException { .thenReturn("true"); EndpointContext endpointContext = Mockito.mock(EndpointContext.class); Mockito.when(endpointContext.useS2A()).thenReturn(false); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); + InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) @@ -838,14 +829,14 @@ public void canUseDirectPath_directPathEnvVarDisabled() throws IOException { @Test public void canUseDirectPath_directPathEnvVarNotSet_attemptDirectPathIsTrue() { System.setProperty("os.name", "Linux"); - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); + // EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setCredentials(computeEngineCredentials) - .setEndpoint(DEFAULT_ENDPOINT) - .setEndpointContext(endpointContext); + .setEndpoint(DEFAULT_ENDPOINT); + // .setEndpointContext(endpointContext); InstantiatingGrpcChannelProvider provider = new InstantiatingGrpcChannelProvider(builder, GCE_PRODUCTION_NAME_AFTER_2016); Truth.assertThat(provider.canUseDirectPath()).isTrue(); @@ -949,14 +940,14 @@ public void canUseDirectPath_nonGDUUniverseDomain() { InstantiatingGrpcChannelProvider.DIRECT_PATH_ENV_DISABLE_DIRECT_PATH)) .thenReturn("false"); String nonGDUEndpoint = "test.random.com:443"; - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(nonGDUEndpoint); + // EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setCredentials(computeEngineCredentials) .setEndpoint(nonGDUEndpoint) - .setEndpointContext(endpointContext) + // .setEndpointContext(endpointContext) .setEnvProvider(envProvider); InstantiatingGrpcChannelProvider provider = new InstantiatingGrpcChannelProvider(builder, GCE_PRODUCTION_NAME_AFTER_2016); diff --git a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java index aa66282831..3af6eb323d 100644 --- a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java +++ b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java @@ -197,7 +197,7 @@ private HttpJsonTransportChannel createChannel() throws IOException, GeneralSecu // the channel will use a default executor for the calls. ManagedHttpJsonChannel channel = ManagedHttpJsonChannel.newBuilder() - .setEndpoint(endpointContext.resolvedEndpoint()) + .setEndpoint(endpoint) .setExecutor(executor) .setHttpTransport(httpTransportToUse) .build(); diff --git a/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonClientInterceptorTest.java b/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonClientInterceptorTest.java index 269a0b9615..85146ceb07 100644 --- a/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonClientInterceptorTest.java +++ b/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonClientInterceptorTest.java @@ -159,12 +159,9 @@ public static void destroy() { @BeforeEach void setUp() throws IOException { interceptor = new CapturingClientInterceptor(); - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn("google.com:443"); channel = InstantiatingHttpJsonChannelProvider.newBuilder() .setEndpoint("google.com:443") - .setEndpointContext(endpointContext) .setExecutor(executorService) .setHttpTransport(MOCK_SERVICE) .setHeaderProvider(() -> Collections.singletonMap("header-key", "headerValue")) diff --git a/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProviderTest.java b/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProviderTest.java index a779091fd6..2e46157534 100644 --- a/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProviderTest.java +++ b/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProviderTest.java @@ -32,7 +32,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import com.google.api.gax.rpc.EndpointContext; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.TransportChannelProvider; import com.google.api.gax.rpc.mtls.AbstractMtlsTransportChannelTest; @@ -57,12 +56,8 @@ void basicTest() throws IOException { ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1); executor.shutdown(); - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); - TransportChannelProvider provider = InstantiatingHttpJsonChannelProvider.newBuilder().build(); - provider = provider.withEndpointContext(endpointContext); assertThat(provider.needsEndpoint()).isTrue(); provider = provider.withEndpoint(DEFAULT_ENDPOINT); assertThat(provider.needsEndpoint()).isFalse(); @@ -112,13 +107,8 @@ void basicTest() throws IOException { // if not provided by the TransportChannelProvider @Test void managedChannelUsesDefaultChannelExecutor() throws IOException { - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); InstantiatingHttpJsonChannelProvider instantiatingHttpJsonChannelProvider = - InstantiatingHttpJsonChannelProvider.newBuilder() - .setEndpoint(DEFAULT_ENDPOINT) - .setEndpointContext(endpointContext) - .build(); + InstantiatingHttpJsonChannelProvider.newBuilder().setEndpoint(DEFAULT_ENDPOINT).build(); instantiatingHttpJsonChannelProvider = (InstantiatingHttpJsonChannelProvider) instantiatingHttpJsonChannelProvider.withHeaders(DEFAULT_HEADER_MAP); @@ -142,13 +132,9 @@ void managedChannelUsesCustomExecutor() throws IOException { ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1); executor.shutdown(); - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.resolvedEndpoint()).thenReturn(DEFAULT_ENDPOINT); - InstantiatingHttpJsonChannelProvider instantiatingHttpJsonChannelProvider = InstantiatingHttpJsonChannelProvider.newBuilder() .setEndpoint(DEFAULT_ENDPOINT) - .setEndpointContext(endpointContext) .setExecutor(executor) .build(); instantiatingHttpJsonChannelProvider = diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java index d7d2067b32..5aa3b2cb6e 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java @@ -31,7 +31,6 @@ import com.google.api.core.BetaApi; import com.google.api.core.InternalExtensionOnly; -import com.google.api.core.ObsoleteApi; import com.google.auth.Credentials; import java.io.IOException; import java.util.Map; @@ -89,7 +88,6 @@ public interface TransportChannelProvider { TransportChannelProvider withHeaders(Map headers); /** True if the TransportProvider has no endpoint set. */ - @ObsoleteApi("Endpoint should be configured set in the ClientSettings") boolean needsEndpoint(); /** @@ -97,7 +95,6 @@ public interface TransportChannelProvider { * *

This method should only be called if {@link #needsEndpoint()} returns true. */ - @ObsoleteApi("Endpoint should be configured set in the ClientSettings") TransportChannelProvider withEndpoint(String endpoint); /** Sets the {@link EndpointContext} when constructing a new {@link TransportChannel}. */ From 791ab2c6b570a3e9db0ca86f3998454c086d93f7 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Mon, 11 Nov 2024 13:49:43 -0800 Subject: [PATCH 37/51] don't propogate endpointContext. --- .../InstantiatingGrpcChannelProvider.java | 28 +++--- .../api/gax/grpc/GrpcLongRunningTest.java | 2 +- .../InstantiatingGrpcChannelProviderTest.java | 85 ++----------------- .../grpc/testing/LocalChannelProvider.java | 7 +- .../InstantiatingHttpJsonChannelProvider.java | 23 +++-- gax-java/gax/clirr-ignored-differences.xml | 2 +- .../com/google/api/gax/rpc/ClientContext.java | 2 +- .../google/api/gax/rpc/EndpointContext.java | 4 + .../rpc/FixedTransportChannelProvider.java | 6 +- .../api/gax/rpc/TransportChannelProvider.java | 4 +- .../google/api/gax/rpc/ClientContextTest.java | 2 +- 11 files changed, 49 insertions(+), 116 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index d33fef2d54..ef7bb41b17 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -37,7 +37,6 @@ import com.google.api.core.InternalApi; import com.google.api.core.ObsoleteApi; import com.google.api.gax.core.ExecutorProvider; -import com.google.api.gax.rpc.EndpointContext; import com.google.api.gax.rpc.FixedHeaderProvider; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.TransportChannel; @@ -122,7 +121,7 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP private final int processorCount; private final Executor executor; private final HeaderProvider headerProvider; - private final EndpointContext endpointContext; + private final boolean useS2A; private final String endpoint; // TODO: remove. envProvider currently provides DirectPath environment variable, and is only used // during initial rollout for DirectPath. This provider will be removed once the DirectPath @@ -152,7 +151,7 @@ private InstantiatingGrpcChannelProvider(Builder builder) { this.executor = builder.executor; this.headerProvider = builder.headerProvider; this.endpoint = builder.endpoint; - this.endpointContext = builder.endpointContext; + this.useS2A = builder.useS2A; this.mtlsProvider = builder.mtlsProvider; this.envProvider = builder.envProvider; this.interceptorProvider = builder.interceptorProvider; @@ -243,14 +242,14 @@ public TransportChannelProvider withEndpoint(String endpoint) { } /** - * Specify the {@link EndpointContext}. + * Specify whether or not to use S2A. * - * @param endpointContext - * @return A new {@link InstantiatingGrpcChannelProvider} with the endpointContext + * @param useS2A + * @return A new {@link InstantiatingGrpcChannelProvider} with useS2A set. */ @Override - public TransportChannelProvider withEndpointContext(EndpointContext endpointContext) { - return toBuilder().setEndpointContext(endpointContext).build(); + public TransportChannelProvider withUseS2A(boolean useS2A) { + return toBuilder().setUseS2A(useS2A).build(); } /** @deprecated Please modify pool settings via {@link #toBuilder()} */ @@ -586,12 +585,13 @@ private ManagedChannel createSingleChannel() throws IOException { // Could not create channel credentials via DCA. In accordance with // https://google.aip.dev/auth/4115, if credentials not available through // DCA, try mTLS with credentials held by the S2A (Secure Session Agent). - if (endpointContext.useS2A()) { + if (useS2A) { channelCredentials = createS2ASecuredChannelCredentials(); } if (channelCredentials != null) { // Create the channel using S2A-secured channel credentials. - builder = Grpc.newChannelBuilder(endpointContext.mtlsEndpoint(), channelCredentials); + // {@code endpoint} is set to mtlsEndpoint in {@link EndpointContext} when useS2A is true. + builder = Grpc.newChannelBuilder(endpoint, channelCredentials); } else { // Use default if we cannot initialize channel credentials via DCA or S2A. builder = ManagedChannelBuilder.forAddress(serviceAddress, port); @@ -743,7 +743,7 @@ public static final class Builder { private Executor executor; private HeaderProvider headerProvider; private String endpoint; - private EndpointContext endpointContext; + private boolean useS2A; private EnvironmentProvider envProvider; private MtlsProvider mtlsProvider = new MtlsProvider(); @Nullable private GrpcInterceptorProvider interceptorProvider; @@ -772,7 +772,7 @@ private Builder(InstantiatingGrpcChannelProvider provider) { this.executor = provider.executor; this.headerProvider = provider.headerProvider; this.endpoint = provider.endpoint; - this.endpointContext = provider.endpointContext; + this.useS2A = provider.useS2A; this.envProvider = provider.envProvider; this.interceptorProvider = provider.interceptorProvider; this.maxInboundMessageSize = provider.maxInboundMessageSize; @@ -841,8 +841,8 @@ public Builder setEndpoint(String endpoint) { return this; } - Builder setEndpointContext(EndpointContext endpointContext) { - this.endpointContext = endpointContext; + Builder setUseS2A(boolean useS2A) { + this.useS2A = useS2A; return this; } diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcLongRunningTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcLongRunningTest.java index fe2c2f7293..ac88e4acec 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcLongRunningTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcLongRunningTest.java @@ -101,7 +101,7 @@ void setUp() throws IOException { TransportChannel transportChannel = GrpcTransportChannel.newBuilder().setManagedChannel(channel).build(); when(operationsChannelProvider.getTransportChannel()).thenReturn(transportChannel); - when(operationsChannelProvider.withEndpointContext(Mockito.any(EndpointContext.class))) + when(operationsChannelProvider.withUseS2A(Mockito.any(boolean.class))) .thenReturn(operationsChannelProvider); clock = new FakeApiClock(0L); diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index 025c15a06c..c920937e6c 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -39,7 +39,6 @@ import com.google.api.core.ApiFunction; import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.Builder; -import com.google.api.gax.rpc.EndpointContext; import com.google.api.gax.rpc.FixedHeaderProvider; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.TransportChannel; @@ -203,16 +202,13 @@ void testCpuPoolSize() { void testWithPoolSize() throws IOException { ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1); executor.shutdown(); - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.useS2A()).thenReturn(false); TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .build() .withExecutor((Executor) executor) .withHeaders(Collections.emptyMap()) - .withEndpoint("localhost:8080") - .withEndpointContext(endpointContext); + .withEndpoint("localhost:8080"); assertThat(provider.acceptsPoolSize()).isTrue(); // Make sure we can create channels OK. @@ -271,13 +267,9 @@ void testWithInterceptorsAndMultipleChannels() throws Exception { private void testWithInterceptors(int numChannels) throws Exception { final GrpcInterceptorProvider interceptorProvider = Mockito.mock(GrpcInterceptorProvider.class); - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.useS2A()).thenReturn(false); - InstantiatingGrpcChannelProvider channelProvider = InstantiatingGrpcChannelProvider.newBuilder() .setEndpoint("localhost:8080") - .setEndpointContext(endpointContext) .setPoolSize(numChannels) .setHeaderProvider(Mockito.mock(HeaderProvider.class)) .setExecutor(Mockito.mock(Executor.class)) @@ -308,13 +300,9 @@ void testChannelConfigurator() throws IOException { Mockito.when(channelConfigurator.apply(channelBuilderCaptor.capture())) .thenReturn(swappedBuilder); - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.useS2A()).thenReturn(false); - // Invoke the provider InstantiatingGrpcChannelProvider.newBuilder() .setEndpoint("localhost:8080") - .setEndpointContext(endpointContext) .setHeaderProvider(Mockito.mock(HeaderProvider.class)) .setExecutor(Mockito.mock(Executor.class)) .setChannelConfigurator(channelConfigurator) @@ -333,17 +321,13 @@ void testWithGCECredentials() throws IOException { ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1); executor.shutdown(); - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.useS2A()).thenReturn(false); - TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .build() .withExecutor((Executor) executor) .withHeaders(Collections.emptyMap()) - .withEndpoint("localhost:8080") - .withEndpointContext(endpointContext); + .withEndpoint("localhost:8080"); assertThat(provider.needsCredentials()).isTrue(); if (InstantiatingGrpcChannelProvider.isOnComputeEngine()) { @@ -374,28 +358,22 @@ void testDirectPathDisallowNullCredentials() throws IOException { @Test void testDirectPathWithGDUEndpoint() { - // EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setAttemptDirectPathXds() .setEndpoint(DEFAULT_ENDPOINT) - // .setEndpointContext(endpointContext) .build(); assertThat(provider.canUseDirectPathWithUniverseDomain()).isTrue(); } @Test void testDirectPathWithNonGDUEndpoint() { - // EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setAttemptDirectPathXds() .setEndpoint("test.random.com:443") - // .setEndpointContext(endpointContext) .build(); assertThat(provider.canUseDirectPathWithUniverseDomain()).isFalse(); } @@ -424,9 +402,6 @@ void testWithNonGCECredentials() throws IOException { return channelBuilder; }; - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.useS2A()).thenReturn(false); - TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) @@ -434,8 +409,7 @@ void testWithNonGCECredentials() throws IOException { .build() .withExecutor((Executor) executor) .withHeaders(Collections.emptyMap()) - .withEndpoint("localhost:8080") - .withEndpointContext(endpointContext); + .withEndpoint("localhost:8080"); assertThat(provider.needsCredentials()).isTrue(); provider = provider.withCredentials(CloudShellCredentials.create(3000)); @@ -456,9 +430,6 @@ void testWithDirectPathDisabled() throws IOException { return channelBuilder; }; - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.useS2A()).thenReturn(false); - TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(false) @@ -466,8 +437,7 @@ void testWithDirectPathDisabled() throws IOException { .build() .withExecutor((Executor) executor) .withHeaders(Collections.emptyMap()) - .withEndpoint("localhost:8080") - .withEndpointContext(endpointContext); + .withEndpoint("localhost:8080"); assertThat(provider.needsCredentials()).isTrue(); provider = provider.withCredentials(ComputeEngineCredentials.create()); @@ -488,17 +458,13 @@ void testWithNoDirectPathFlagSet() throws IOException { return channelBuilder; }; - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.useS2A()).thenReturn(false); - TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setChannelConfigurator(channelConfigurator) .build() .withExecutor((Executor) executor) .withHeaders(Collections.emptyMap()) - .withEndpoint("localhost:8080") - .withEndpointContext(endpointContext); + .withEndpoint("localhost:8080"); assertThat(provider.needsCredentials()).isTrue(); provider = provider.withCredentials(ComputeEngineCredentials.create()); @@ -512,16 +478,12 @@ void testWithIPv6Address() throws IOException { ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1); executor.shutdown(); - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.useS2A()).thenReturn(false); - TransportChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .build() .withExecutor((Executor) executor) .withHeaders(Collections.emptyMap()) - .withEndpoint("[::1]:8080") - .withEndpointContext(endpointContext); + .withEndpoint("[::1]:8080"); assertThat(provider.needsEndpoint()).isFalse(); // Make sure we can create channels OK. @@ -531,9 +493,6 @@ void testWithIPv6Address() throws IOException { // Test that if ChannelPrimer is provided, it is called during creation @Test void testWithPrimeChannel() throws IOException { - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.useS2A()).thenReturn(false); - // create channelProvider with different pool sizes to verify ChannelPrimer is called the // correct number of times for (int poolSize = 1; poolSize < 5; poolSize++) { @@ -542,7 +501,6 @@ void testWithPrimeChannel() throws IOException { InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setEndpoint("localhost:8080") - .setEndpointContext(endpointContext) .setPoolSize(poolSize) .setHeaderProvider(Mockito.mock(HeaderProvider.class)) .setExecutor(Mockito.mock(Executor.class)) @@ -665,14 +623,8 @@ private void createAndCloseTransportChannel(InstantiatingGrpcChannelProvider pro throws Exception { FakeLogHandler logHandler = new FakeLogHandler(); InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.useS2A()).thenReturn(false); - InstantiatingGrpcChannelProvider provider = - createChannelProviderBuilderForDirectPathLogTests() - .setAttemptDirectPathXds() - .setEndpointContext(endpointContext) - .build(); + createChannelProviderBuilderForDirectPathLogTests().setAttemptDirectPathXds().build(); createAndCloseTransportChannel(provider); assertThat(logHandler.getAllMessages()) .contains( @@ -713,9 +665,6 @@ void testLogDirectPathMisconfig_shouldNotLogInTheBuilder() { void testLogDirectPathMisconfigWrongCredential() throws Exception { FakeLogHandler logHandler = new FakeLogHandler(); InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.useS2A()).thenReturn(false); - InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPathXds() @@ -723,7 +672,6 @@ void testLogDirectPathMisconfigWrongCredential() throws Exception { .setHeaderProvider(Mockito.mock(HeaderProvider.class)) .setExecutor(Mockito.mock(Executor.class)) .setEndpoint(DEFAULT_ENDPOINT) - .setEndpointContext(endpointContext) .build(); TransportChannel transportChannel = provider.getTransportChannel(); @@ -742,9 +690,6 @@ void testLogDirectPathMisconfigWrongCredential() throws Exception { void testLogDirectPathMisconfigNotOnGCE() throws Exception { FakeLogHandler logHandler = new FakeLogHandler(); InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.useS2A()).thenReturn(false); - InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPathXds() @@ -753,7 +698,6 @@ void testLogDirectPathMisconfigNotOnGCE() throws Exception { .setHeaderProvider(Mockito.mock(HeaderProvider.class)) .setExecutor(Mockito.mock(Executor.class)) .setEndpoint(DEFAULT_ENDPOINT) - .setEndpointContext(endpointContext) .build(); TransportChannel transportChannel = provider.getTransportChannel(); @@ -777,16 +721,13 @@ public void canUseDirectPath_happyPath() throws IOException { envProvider.getenv( InstantiatingGrpcChannelProvider.DIRECT_PATH_ENV_DISABLE_DIRECT_PATH)) .thenReturn("false"); - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setCredentials(computeEngineCredentials) .setEndpoint(DEFAULT_ENDPOINT) .setEnvProvider(envProvider) - .setHeaderProvider(Mockito.mock(HeaderProvider.class)) - .setEndpointContext(endpointContext); + .setHeaderProvider(Mockito.mock(HeaderProvider.class)); InstantiatingGrpcChannelProvider provider = new InstantiatingGrpcChannelProvider(builder, GCE_PRODUCTION_NAME_AFTER_2016); Truth.assertThat(provider.canUseDirectPath()).isTrue(); @@ -805,15 +746,11 @@ public void canUseDirectPath_directPathEnvVarDisabled() throws IOException { envProvider.getenv( InstantiatingGrpcChannelProvider.DIRECT_PATH_ENV_DISABLE_DIRECT_PATH)) .thenReturn("true"); - EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - Mockito.when(endpointContext.useS2A()).thenReturn(false); - InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setCredentials(computeEngineCredentials) .setEndpoint(DEFAULT_ENDPOINT) - .setEndpointContext(endpointContext) .setEnvProvider(envProvider) .setHeaderProvider(Mockito.mock(HeaderProvider.class)); InstantiatingGrpcChannelProvider provider = @@ -829,14 +766,11 @@ public void canUseDirectPath_directPathEnvVarDisabled() throws IOException { @Test public void canUseDirectPath_directPathEnvVarNotSet_attemptDirectPathIsTrue() { System.setProperty("os.name", "Linux"); - // EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setCredentials(computeEngineCredentials) .setEndpoint(DEFAULT_ENDPOINT); - // .setEndpointContext(endpointContext); InstantiatingGrpcChannelProvider provider = new InstantiatingGrpcChannelProvider(builder, GCE_PRODUCTION_NAME_AFTER_2016); Truth.assertThat(provider.canUseDirectPath()).isTrue(); @@ -940,14 +874,11 @@ public void canUseDirectPath_nonGDUUniverseDomain() { InstantiatingGrpcChannelProvider.DIRECT_PATH_ENV_DISABLE_DIRECT_PATH)) .thenReturn("false"); String nonGDUEndpoint = "test.random.com:443"; - // EndpointContext endpointContext = Mockito.mock(EndpointContext.class); - InstantiatingGrpcChannelProvider.Builder builder = InstantiatingGrpcChannelProvider.newBuilder() .setAttemptDirectPath(true) .setCredentials(computeEngineCredentials) .setEndpoint(nonGDUEndpoint) - // .setEndpointContext(endpointContext) .setEnvProvider(envProvider); InstantiatingGrpcChannelProvider provider = new InstantiatingGrpcChannelProvider(builder, GCE_PRODUCTION_NAME_AFTER_2016); diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java index dcaae0c706..a8f26e72fb 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java @@ -32,7 +32,6 @@ import com.google.api.core.BetaApi; import com.google.api.gax.grpc.GrpcHeaderInterceptor; import com.google.api.gax.grpc.GrpcTransportChannel; -import com.google.api.gax.rpc.EndpointContext; import com.google.api.gax.rpc.FixedHeaderProvider; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.TransportChannel; @@ -61,7 +60,7 @@ public class LocalChannelProvider implements TransportChannelProvider { private final List interceptors; private final String address; - private EndpointContext endpointContext; + private boolean useS2A; private volatile HeaderProvider headerProvider; @@ -109,8 +108,8 @@ public TransportChannelProvider withEndpoint(String endpoint) { } @Override - public TransportChannelProvider withEndpointContext(EndpointContext endpointContext) { - this.endpointContext = endpointContext; + public TransportChannelProvider withUseS2A(boolean useS2A) { + this.useS2A = useS2A; return this; } diff --git a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java index 3af6eb323d..c74a0a57fa 100644 --- a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java +++ b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java @@ -33,7 +33,6 @@ import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.core.InternalExtensionOnly; import com.google.api.gax.core.ExecutorProvider; -import com.google.api.gax.rpc.EndpointContext; import com.google.api.gax.rpc.FixedHeaderProvider; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.TransportChannelProvider; @@ -66,7 +65,7 @@ public final class InstantiatingHttpJsonChannelProvider implements TransportChan private final HeaderProvider headerProvider; private final HttpJsonInterceptorProvider interceptorProvider; private final String endpoint; - private final EndpointContext endpointContext; + private final boolean useS2A; private final HttpTransport httpTransport; private final MtlsProvider mtlsProvider; @@ -75,14 +74,14 @@ private InstantiatingHttpJsonChannelProvider( HeaderProvider headerProvider, HttpJsonInterceptorProvider interceptorProvider, String endpoint, - EndpointContext endpointContext, + boolean useS2A, HttpTransport httpTransport, MtlsProvider mtlsProvider) { this.executor = executor; this.headerProvider = headerProvider; this.interceptorProvider = interceptorProvider; this.endpoint = endpoint; - this.endpointContext = endpointContext; + this.useS2A = useS2A; this.httpTransport = httpTransport; this.mtlsProvider = mtlsProvider; } @@ -129,8 +128,8 @@ public TransportChannelProvider withEndpoint(String endpoint) { } @Override - public TransportChannelProvider withEndpointContext(EndpointContext endpointContext) { - return toBuilder().setEndpointContext(endpointContext).build(); + public TransportChannelProvider withUseS2A(boolean useS2A) { + return toBuilder().setUseS2A(useS2A).build(); } /** @deprecated REST transport channel doesn't support channel pooling */ @@ -240,7 +239,7 @@ public static final class Builder { private HeaderProvider headerProvider; private HttpJsonInterceptorProvider interceptorProvider; private String endpoint; - private EndpointContext endpointContext; + private boolean useS2A; private HttpTransport httpTransport; private MtlsProvider mtlsProvider = new MtlsProvider(); @@ -250,7 +249,7 @@ private Builder(InstantiatingHttpJsonChannelProvider provider) { this.executor = provider.executor; this.headerProvider = provider.headerProvider; this.endpoint = provider.endpoint; - this.endpointContext = provider.endpointContext; + this.useS2A = provider.useS2A; this.httpTransport = provider.httpTransport; this.mtlsProvider = provider.mtlsProvider; this.interceptorProvider = provider.interceptorProvider; @@ -305,9 +304,9 @@ public Builder setEndpoint(String endpoint) { return this; } - /** Sets the {@link EndpointContext} */ - public Builder setEndpointContext(EndpointContext endpointContext) { - this.endpointContext = endpointContext; + /** Sets whether to use S2A */ + public Builder setUseS2A(boolean useS2A) { + this.useS2A = useS2A; return this; } @@ -333,7 +332,7 @@ public InstantiatingHttpJsonChannelProvider build() { headerProvider, interceptorProvider, endpoint, - endpointContext, + useS2A, httpTransport, mtlsProvider); } diff --git a/gax-java/gax/clirr-ignored-differences.xml b/gax-java/gax/clirr-ignored-differences.xml index 67ab069abd..6e3b3953ac 100644 --- a/gax-java/gax/clirr-ignored-differences.xml +++ b/gax-java/gax/clirr-ignored-differences.xml @@ -116,6 +116,6 @@ 7012 com/google/api/gax/rpc/TransportChannelProvider - * withEndpointContext(*) + * withUseS2A(*) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java index 7c50c7a255..8e7c9a3090 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java @@ -222,7 +222,7 @@ public static ClientContext create(StubSettings settings) throws IOException { if (transportChannelProvider.needsEndpoint()) { transportChannelProvider = transportChannelProvider.withEndpoint(endpoint); } - transportChannelProvider = transportChannelProvider.withEndpointContext(endpointContext); + transportChannelProvider = transportChannelProvider.withUseS2A(endpointContext.useS2A()); TransportChannel transportChannel = transportChannelProvider.getTransportChannel(); ApiCallContext defaultCallContext = diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java index 483618ae14..883f4170d1 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java @@ -270,6 +270,10 @@ private String determineUniverseDomain() { /** Determines the fully resolved endpoint and universe domain values */ private String determineEndpoint() throws IOException { + if (shouldUseS2A()) { + return mtlsEndpoint(); + } + MtlsProvider mtlsProvider = mtlsProvider() == null ? new MtlsProvider() : mtlsProvider(); // TransportChannelProvider's endpoint will override the ClientSettings' endpoint String customEndpoint = diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java index caec3d7b08..e68798ad9c 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java @@ -42,7 +42,7 @@ public class FixedTransportChannelProvider implements TransportChannelProvider { private final TransportChannel transportChannel; - private EndpointContext endpointContext; + private boolean useS2A; private FixedTransportChannelProvider(TransportChannel transportChannel) { this.transportChannel = Preconditions.checkNotNull(transportChannel); @@ -91,8 +91,8 @@ public TransportChannelProvider withEndpoint(String endpoint) { } @Override - public TransportChannelProvider withEndpointContext(EndpointContext endpointContext) { - this.endpointContext = endpointContext; + public TransportChannelProvider withUseS2A(boolean useS2A) { + this.useS2A = useS2A; return this; } diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java index 5aa3b2cb6e..30ed63f245 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java @@ -97,8 +97,8 @@ public interface TransportChannelProvider { */ TransportChannelProvider withEndpoint(String endpoint); - /** Sets the {@link EndpointContext} when constructing a new {@link TransportChannel}. */ - TransportChannelProvider withEndpointContext(EndpointContext endpointContext); + /** Sets whether to use S2A when constructing a new {@link TransportChannel}. */ + TransportChannelProvider withUseS2A(boolean useS2A); /** * Reports whether this provider allows pool size customization. diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java index 48d1a342c5..facc93ed86 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java @@ -196,7 +196,7 @@ public TransportChannelProvider withEndpoint(String endpoint) { } @Override - public TransportChannelProvider withEndpointContext(EndpointContext endpointContext) { + public TransportChannelProvider withUseS2A(boolean useS2A) { return new FakeTransportProvider( this.transport, this.executor, From a4ee6c5496bb0f6b9452b6e188b4ffa952e57ab3 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Mon, 11 Nov 2024 14:02:58 -0800 Subject: [PATCH 38/51] log as warning. --- .../google/api/gax/grpc/InstantiatingGrpcChannelProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index ef7bb41b17..0500fd8865 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -526,7 +526,7 @@ ChannelCredentials createS2ASecuredChannelCredentials() { } catch (IOException ignore) { // Fallback to plaintext-to-S2A connection. LOG.log( - Level.INFO, + Level.WARNING, "Cannot establish an mTLS connection to S2A due to error creating MTLS to MDS TlsChannelCredentials credentials, falling back to plaintext connection to S2A: " + ignore.getMessage()); return createPlaintextToS2AChannelCredentials(plaintextAddress); From 6eeccb27cce567a3856cde06ad8ba055b754daa4 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Mon, 11 Nov 2024 14:34:43 -0800 Subject: [PATCH 39/51] package private + comment on S2A env var. --- .../src/main/java/com/google/api/gax/rpc/EndpointContext.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java index 883f4170d1..88bfbfff32 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java @@ -66,7 +66,9 @@ public abstract class EndpointContext { "The configured universe domain (%s) does not match the universe domain found in the credentials (%s). If you haven't configured the universe domain explicitly, `googleapis.com` is the default."; public static final String UNABLE_TO_RETRIEVE_CREDENTIALS_ERROR_MESSAGE = "Unable to retrieve the Universe Domain from the Credentials."; - public static final String S2A_ENV_ENABLE_USE_S2A = "EXPERIMENTAL_GOOGLE_API_USE_S2A"; + // This environment variable is a temporary measure. It will be removed when the feature is + // non-experimental. + static final String S2A_ENV_ENABLE_USE_S2A = "EXPERIMENTAL_GOOGLE_API_USE_S2A"; public static EndpointContext getDefaultInstance() { return INSTANCE; From 03eb991dc7ddc77d7ab4aaf77a0a3e85c649b496 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 12 Nov 2024 09:07:51 -0800 Subject: [PATCH 40/51] package private useS2A. --- .../src/main/java/com/google/api/gax/rpc/EndpointContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java index 88bfbfff32..0148c07a01 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java @@ -104,7 +104,7 @@ public static EndpointContext getDefaultInstance() { @Nullable public abstract String transportChannelProviderEndpoint(); - public abstract boolean useS2A(); + abstract boolean useS2A(); @Nullable abstract EnvironmentProvider envProvider(); From 91175ef017d1acf1ddd00cf3af2ad64037583fdd Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 12 Nov 2024 09:35:55 -0800 Subject: [PATCH 41/51] check if files exist. --- .../InstantiatingGrpcChannelProvider.java | 60 +++++++++++-------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 0500fd8865..cb23ce2975 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -503,35 +503,45 @@ ChannelCredentials createS2ASecuredChannelCredentials() { // Currently, MTLS to MDS is only available on GCE. See: // https://cloud.google.com/compute/docs/metadata/overview#https-mds // Try to load MTLS-MDS creds. - InputStream trustBundle = null; - InputStream privateKey = null; - InputStream certChain = null; - try { - trustBundle = new FileInputStream(MTLS_MDS_ROOT); - privateKey = new FileInputStream(MTLS_MDS_CERT_CHAIN_AND_KEY); - certChain = new FileInputStream(MTLS_MDS_CERT_CHAIN_AND_KEY); - } catch (FileNotFoundException ignore) { - // Fallback to plaintext-to-S2A connection. - LOG.log( - Level.INFO, - "Cannot establish an mTLS connection to S2A due to error loading MTLS to MDS credentials, falling back to plaintext connection to S2A: " - + ignore.getMessage()); - return createPlaintextToS2AChannelCredentials(plaintextAddress); - } - ChannelCredentials mtlsToS2AChannelCredentials = null; - try { + File rootFile = new File(MTLS_MDS_ROOT); + File certKeyFile = new File(MTLS_MDS_CERT_CHAIN_AND_KEY); + if (!rootFile.isFile() || !certKeyFile.isFile()) { // Try to connect to S2A using mTLS. - mtlsToS2AChannelCredentials = - createMtlsToS2AChannelCredentials(trustBundle, privateKey, certChain); - } catch (IOException ignore) { - // Fallback to plaintext-to-S2A connection. + ChannelCredentials mtlsToS2AChannelCredentials = null; + InputStream trustBundle = null; + InputStream privateKey = null; + InputStream certChain = null; + try { + trustBundle = new FileInputStream(MTLS_MDS_ROOT); + privateKey = new FileInputStream(MTLS_MDS_CERT_CHAIN_AND_KEY); + certChain = new FileInputStream(MTLS_MDS_CERT_CHAIN_AND_KEY); + } catch (FileNotFoundException ignore) { + // Fallback to plaintext-to-S2A connection on error. + LOG.log( + Level.INFO, + "Cannot establish an mTLS connection to S2A due to error loading MTLS to MDS credentials, falling back to plaintext connection to S2A: " + + ignore.getMessage()); + return createPlaintextToS2AChannelCredentials(plaintextAddress); + } + try { + mtlsToS2AChannelCredentials = + createMtlsToS2AChannelCredentials(trustBundle, privateKey, certChain); + } catch (IOException ignore) { + // Fallback to plaintext-to-S2A connection on error. + LOG.log( + Level.WARNING, + "Cannot establish an mTLS connection to S2A due to error creating MTLS to MDS TlsChannelCredentials credentials, falling back to plaintext connection to S2A: " + + ignore.getMessage()); + return createPlaintextToS2AChannelCredentials(plaintextAddress); + } + return S2AChannelCredentials.newBuilder(mtlsAddress, mtlsToS2AChannelCredentials).build(); + } else { + // Fallback to plaintext-to-S2A connection if MTLS-MDS creds do not exist. LOG.log( - Level.WARNING, - "Cannot establish an mTLS connection to S2A due to error creating MTLS to MDS TlsChannelCredentials credentials, falling back to plaintext connection to S2A: " - + ignore.getMessage()); + Level.INFO, + "Cannot establish an mTLS connection to S2A MTLS to MDS credentials do not exist on filesystem, falling back to plaintext connection to S2A"); return createPlaintextToS2AChannelCredentials(plaintextAddress); } - return S2AChannelCredentials.newBuilder(mtlsAddress, mtlsToS2AChannelCredentials).build(); } private ManagedChannel createSingleChannel() throws IOException { From 04d47a01955c27f8d24c76f454c65fc4bdd0726c Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 12 Nov 2024 12:45:01 -0800 Subject: [PATCH 42/51] default unsupported exception. --- .../grpc/testing/LocalChannelProvider.java | 3 +-- .../InstantiatingHttpJsonChannelProvider.java | 21 ++----------------- .../rpc/FixedTransportChannelProvider.java | 5 ++--- .../api/gax/rpc/TransportChannelProvider.java | 4 +++- 4 files changed, 8 insertions(+), 25 deletions(-) diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java index a8f26e72fb..856a2850bb 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/testing/LocalChannelProvider.java @@ -60,7 +60,6 @@ public class LocalChannelProvider implements TransportChannelProvider { private final List interceptors; private final String address; - private boolean useS2A; private volatile HeaderProvider headerProvider; @@ -109,7 +108,7 @@ public TransportChannelProvider withEndpoint(String endpoint) { @Override public TransportChannelProvider withUseS2A(boolean useS2A) { - this.useS2A = useS2A; + // Overriden for technical reasons. This method is a no-op for LocalChannelProvider. return this; } diff --git a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java index c74a0a57fa..170b955c2a 100644 --- a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java +++ b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java @@ -65,7 +65,6 @@ public final class InstantiatingHttpJsonChannelProvider implements TransportChan private final HeaderProvider headerProvider; private final HttpJsonInterceptorProvider interceptorProvider; private final String endpoint; - private final boolean useS2A; private final HttpTransport httpTransport; private final MtlsProvider mtlsProvider; @@ -74,14 +73,12 @@ private InstantiatingHttpJsonChannelProvider( HeaderProvider headerProvider, HttpJsonInterceptorProvider interceptorProvider, String endpoint, - boolean useS2A, HttpTransport httpTransport, MtlsProvider mtlsProvider) { this.executor = executor; this.headerProvider = headerProvider; this.interceptorProvider = interceptorProvider; this.endpoint = endpoint; - this.useS2A = useS2A; this.httpTransport = httpTransport; this.mtlsProvider = mtlsProvider; } @@ -129,7 +126,7 @@ public TransportChannelProvider withEndpoint(String endpoint) { @Override public TransportChannelProvider withUseS2A(boolean useS2A) { - return toBuilder().setUseS2A(useS2A).build(); + return this; } /** @deprecated REST transport channel doesn't support channel pooling */ @@ -239,7 +236,6 @@ public static final class Builder { private HeaderProvider headerProvider; private HttpJsonInterceptorProvider interceptorProvider; private String endpoint; - private boolean useS2A; private HttpTransport httpTransport; private MtlsProvider mtlsProvider = new MtlsProvider(); @@ -249,7 +245,6 @@ private Builder(InstantiatingHttpJsonChannelProvider provider) { this.executor = provider.executor; this.headerProvider = provider.headerProvider; this.endpoint = provider.endpoint; - this.useS2A = provider.useS2A; this.httpTransport = provider.httpTransport; this.mtlsProvider = provider.mtlsProvider; this.interceptorProvider = provider.interceptorProvider; @@ -304,12 +299,6 @@ public Builder setEndpoint(String endpoint) { return this; } - /** Sets whether to use S2A */ - public Builder setUseS2A(boolean useS2A) { - this.useS2A = useS2A; - return this; - } - /** Sets the HTTP transport to be used. */ public Builder setHttpTransport(HttpTransport httpTransport) { this.httpTransport = httpTransport; @@ -328,13 +317,7 @@ Builder setMtlsProvider(MtlsProvider mtlsProvider) { public InstantiatingHttpJsonChannelProvider build() { return new InstantiatingHttpJsonChannelProvider( - executor, - headerProvider, - interceptorProvider, - endpoint, - useS2A, - httpTransport, - mtlsProvider); + executor, headerProvider, interceptorProvider, endpoint, httpTransport, mtlsProvider); } } } diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java index e68798ad9c..2f70c06b5f 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/FixedTransportChannelProvider.java @@ -42,7 +42,6 @@ public class FixedTransportChannelProvider implements TransportChannelProvider { private final TransportChannel transportChannel; - private boolean useS2A; private FixedTransportChannelProvider(TransportChannel transportChannel) { this.transportChannel = Preconditions.checkNotNull(transportChannel); @@ -91,8 +90,8 @@ public TransportChannelProvider withEndpoint(String endpoint) { } @Override - public TransportChannelProvider withUseS2A(boolean useS2A) { - this.useS2A = useS2A; + public TransportChannelProvider withUseS2A(boolean useS2A) throws UnsupportedOperationException { + // Overriden for technical reasons. This method is a no-op for FixedTransportChannelProvider. return this; } diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java index 30ed63f245..f58acffc54 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/TransportChannelProvider.java @@ -98,7 +98,9 @@ public interface TransportChannelProvider { TransportChannelProvider withEndpoint(String endpoint); /** Sets whether to use S2A when constructing a new {@link TransportChannel}. */ - TransportChannelProvider withUseS2A(boolean useS2A); + default TransportChannelProvider withUseS2A(boolean useS2A) { + throw new UnsupportedOperationException("S2A is not supported"); + } /** * Reports whether this provider allows pool size customization. From 7d7b2337938df982e9a22621397995eb1a888fbe Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 12 Nov 2024 12:54:57 -0800 Subject: [PATCH 43/51] log a warning. --- .../google/api/gax/grpc/InstantiatingGrpcChannelProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index cb23ce2975..4ae6a1371a 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -518,7 +518,7 @@ ChannelCredentials createS2ASecuredChannelCredentials() { } catch (FileNotFoundException ignore) { // Fallback to plaintext-to-S2A connection on error. LOG.log( - Level.INFO, + Level.WARNING, "Cannot establish an mTLS connection to S2A due to error loading MTLS to MDS credentials, falling back to plaintext connection to S2A: " + ignore.getMessage()); return createPlaintextToS2AChannelCredentials(plaintextAddress); From a42dcbdf3c2eed8518d14c09dabf737ca99f865b Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 12 Nov 2024 14:23:34 -0800 Subject: [PATCH 44/51] pass File to TlsChannelCredentials. --- .../InstantiatingGrpcChannelProvider.java | 22 ++----------------- .../InstantiatingGrpcChannelProviderTest.java | 21 +++++++++--------- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 4ae6a1371a..4f4ca33530 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -64,10 +64,7 @@ import io.grpc.auth.MoreCallCredentials; import io.grpc.s2a.S2AChannelCredentials; import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.security.KeyStore; @@ -452,7 +449,7 @@ ChannelCredentials createMtlsChannelCredentials() throws IOException, GeneralSec */ @VisibleForTesting ChannelCredentials createMtlsToS2AChannelCredentials( - InputStream trustBundle, InputStream privateKey, InputStream certChain) throws IOException { + File trustBundle, File privateKey, File certChain) throws IOException { if (trustBundle == null || privateKey == null || certChain == null) { return null; } @@ -508,24 +505,9 @@ ChannelCredentials createS2ASecuredChannelCredentials() { if (!rootFile.isFile() || !certKeyFile.isFile()) { // Try to connect to S2A using mTLS. ChannelCredentials mtlsToS2AChannelCredentials = null; - InputStream trustBundle = null; - InputStream privateKey = null; - InputStream certChain = null; - try { - trustBundle = new FileInputStream(MTLS_MDS_ROOT); - privateKey = new FileInputStream(MTLS_MDS_CERT_CHAIN_AND_KEY); - certChain = new FileInputStream(MTLS_MDS_CERT_CHAIN_AND_KEY); - } catch (FileNotFoundException ignore) { - // Fallback to plaintext-to-S2A connection on error. - LOG.log( - Level.WARNING, - "Cannot establish an mTLS connection to S2A due to error loading MTLS to MDS credentials, falling back to plaintext connection to S2A: " - + ignore.getMessage()); - return createPlaintextToS2AChannelCredentials(plaintextAddress); - } try { mtlsToS2AChannelCredentials = - createMtlsToS2AChannelCredentials(trustBundle, privateKey, certChain); + createMtlsToS2AChannelCredentials(rootFile, certKeyFile, certKeyFile); } catch (IOException ignore) { // Fallback to plaintext-to-S2A connection on error. LOG.log( diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index c920937e6c..dc3c9f9030 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -58,8 +58,8 @@ import io.grpc.ManagedChannelBuilder; import io.grpc.TlsChannelCredentials; import io.grpc.alts.ComputeEngineChannelBuilder; +import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.security.GeneralSecurityException; import java.time.Duration; import java.util.ArrayList; @@ -993,8 +993,8 @@ void createMtlsToS2AChannelCredentials_missingAllFiles_throws() throws IOExcepti void createMtlsToS2AChannelCredentials_missingRootFile_throws() throws IOException { InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder().build(); - InputStream privateKey = this.getClass().getClassLoader().getResourceAsStream("client_key.pem"); - InputStream certChain = this.getClass().getClassLoader().getResourceAsStream("client_cert.pem"); + File privateKey = new File("src/test/resources/client_key.pem"); + File certChain = new File("src/test/resources/client_cert.pem"); assertThat(provider.createMtlsToS2AChannelCredentials(null, privateKey, certChain)).isNull(); } @@ -1002,8 +1002,8 @@ void createMtlsToS2AChannelCredentials_missingRootFile_throws() throws IOExcepti void createMtlsToS2AChannelCredentials_missingKeyFile_throws() throws IOException { InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder().build(); - InputStream trustBundle = this.getClass().getClassLoader().getResourceAsStream("root_cert.pem"); - InputStream certChain = this.getClass().getClassLoader().getResourceAsStream("client_cert.pem"); + File trustBundle = new File("src/test/resources/root_cert.pem"); + File certChain = new File("src/test/resources/client_cert.pem"); assertThat(provider.createMtlsToS2AChannelCredentials(trustBundle, null, certChain)).isNull(); } @@ -1011,8 +1011,8 @@ void createMtlsToS2AChannelCredentials_missingKeyFile_throws() throws IOExceptio void createMtlsToS2AChannelCredentials_missingCertChainFile_throws() throws IOException { InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder().build(); - InputStream trustBundle = this.getClass().getClassLoader().getResourceAsStream("root_cert.pem"); - InputStream privateKey = this.getClass().getClassLoader().getResourceAsStream("client_key.pem"); + File trustBundle = new File("src/test/resources/root_cert.pem"); + File privateKey = new File("src/test/resources/client_key.pem"); assertThat(provider.createMtlsToS2AChannelCredentials(trustBundle, privateKey, null)).isNull(); } @@ -1020,10 +1020,9 @@ void createMtlsToS2AChannelCredentials_missingCertChainFile_throws() throws IOEx void createMtlsToS2AChannelCredentials_success() throws IOException { InstantiatingGrpcChannelProvider provider = InstantiatingGrpcChannelProvider.newBuilder().build(); - InputStream trustBundle = this.getClass().getClassLoader().getResourceAsStream("root_cert.pem"); - InputStream privateKey = this.getClass().getClassLoader().getResourceAsStream("client_key.pem"); - InputStream certChain = this.getClass().getClassLoader().getResourceAsStream("client_cert.pem"); - assertThat(trustBundle).isNotNull(); + File trustBundle = new File("src/test/resources/root_cert.pem"); + File privateKey = new File("src/test/resources/client_key.pem"); + File certChain = new File("src/test/resources/client_cert.pem"); assertEquals( provider.createMtlsToS2AChannelCredentials(trustBundle, privateKey, certChain).getClass(), TlsChannelCredentials.class); From 56551c66c4ddca18e7708bc51459906b8dd078c7 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 12 Nov 2024 14:44:52 -0800 Subject: [PATCH 45/51] test createPlaintextS2AChannelCredentials. --- .../grpc/InstantiatingGrpcChannelProviderTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index dc3c9f9030..f6c92de089 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -982,6 +982,20 @@ private FixedHeaderProvider getHeaderProviderWithApiKeyHeader() { return FixedHeaderProvider.create(header); } + @Test + void createPlaintextToS2AChannelCredentials_emptyPlaintextAddress_returnsNull() { + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder().build(); + assertThat(provider.createPlaintextToS2AChannelCredentials("")).isNull(); + } + + @Test + void createPlaintextToS2AChannelCredentials_success() { + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder().build(); + assertThat(provider.createPlaintextToS2AChannelCredentials("localhost:8080")).isNotNull(); + } + @Test void createMtlsToS2AChannelCredentials_missingAllFiles_throws() throws IOException { InstantiatingGrpcChannelProvider provider = From 1ff7a92b35eecd6af981f76d8b074b170822d094 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Tue, 12 Nov 2024 14:45:19 -0800 Subject: [PATCH 46/51] fix file checking logic. --- .../google/api/gax/grpc/InstantiatingGrpcChannelProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 4f4ca33530..2df5a604bd 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -502,7 +502,7 @@ ChannelCredentials createS2ASecuredChannelCredentials() { // Try to load MTLS-MDS creds. File rootFile = new File(MTLS_MDS_ROOT); File certKeyFile = new File(MTLS_MDS_CERT_CHAIN_AND_KEY); - if (!rootFile.isFile() || !certKeyFile.isFile()) { + if (rootFile.isFile() && certKeyFile.isFile()) { // Try to connect to S2A using mTLS. ChannelCredentials mtlsToS2AChannelCredentials = null; try { From 2958fb485c03bbbea93df3ac34607d5265cf5c48 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 13 Nov 2024 08:43:30 -0800 Subject: [PATCH 47/51] document mtls mds. --- .../api/gax/grpc/InstantiatingGrpcChannelProvider.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 2df5a604bd..33f9160e28 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -104,10 +104,12 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP static final String DIRECT_PATH_ENV_ENABLE_XDS = "GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS"; // The public portion of the mTLS MDS root certificate is stored for performing - // cert verification when establishing an mTLS connection with the MDS. + // cert verification when establishing an mTLS connection with the MDS. See + // https://cloud.google.com/compute/docs/metadata/overview#https-mds-root-certs private static final String MTLS_MDS_ROOT = "/run/google-mds-mtls/root.crt"; // The mTLS MDS credentials are formatted as the concatenation of a PEM-encoded certificate chain - // followed by a PEM-encoded private key. + // followed by a PEM-encoded private key. See + // https://cloud.google.com/compute/docs/metadata/overview#https-mds-client-certs private static final String MTLS_MDS_CERT_CHAIN_AND_KEY = "/run/google-mds-mtls/client.key"; static final long DIRECT_PATH_KEEP_ALIVE_TIME_SECONDS = 3600; From c9a7edd268003058264b9dc4b079aad5d01582c5 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 13 Nov 2024 08:47:24 -0800 Subject: [PATCH 48/51] rename mtls mds vars to be clear these are filepaths. --- .../api/gax/grpc/InstantiatingGrpcChannelProvider.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 33f9160e28..68df8d947b 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -106,11 +106,11 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP // The public portion of the mTLS MDS root certificate is stored for performing // cert verification when establishing an mTLS connection with the MDS. See // https://cloud.google.com/compute/docs/metadata/overview#https-mds-root-certs - private static final String MTLS_MDS_ROOT = "/run/google-mds-mtls/root.crt"; + private static final String MTLS_MDS_ROOT_PATH = "/run/google-mds-mtls/root.crt"; // The mTLS MDS credentials are formatted as the concatenation of a PEM-encoded certificate chain // followed by a PEM-encoded private key. See // https://cloud.google.com/compute/docs/metadata/overview#https-mds-client-certs - private static final String MTLS_MDS_CERT_CHAIN_AND_KEY = "/run/google-mds-mtls/client.key"; + private static final String MTLS_MDS_CERT_CHAIN_AND_KEY_PATH = "/run/google-mds-mtls/client.key"; static final long DIRECT_PATH_KEEP_ALIVE_TIME_SECONDS = 3600; static final long DIRECT_PATH_KEEP_ALIVE_TIMEOUT_SECONDS = 20; @@ -502,8 +502,8 @@ ChannelCredentials createS2ASecuredChannelCredentials() { // Currently, MTLS to MDS is only available on GCE. See: // https://cloud.google.com/compute/docs/metadata/overview#https-mds // Try to load MTLS-MDS creds. - File rootFile = new File(MTLS_MDS_ROOT); - File certKeyFile = new File(MTLS_MDS_CERT_CHAIN_AND_KEY); + File rootFile = new File(MTLS_MDS_ROOT_PATH); + File certKeyFile = new File(MTLS_MDS_CERT_CHAIN_AND_KEY_PATH); if (rootFile.isFile() && certKeyFile.isFile()) { // Try to connect to S2A using mTLS. ChannelCredentials mtlsToS2AChannelCredentials = null; From 8bf770d81d2a98a48eef7fe45fb860fd42f2fe3c Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 13 Nov 2024 10:02:27 -0800 Subject: [PATCH 49/51] bump auth dep and add some tests for createS2ASecuredChannelCredentials. --- gapic-generator-java-pom-parent/pom.xml | 2 +- .../InstantiatingGrpcChannelProvider.java | 24 ++++++-- .../InstantiatingGrpcChannelProviderTest.java | 56 +++++++++++++++++++ 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/gapic-generator-java-pom-parent/pom.xml b/gapic-generator-java-pom-parent/pom.xml index 4560e43dc8..cbf713fe68 100644 --- a/gapic-generator-java-pom-parent/pom.xml +++ b/gapic-generator-java-pom-parent/pom.xml @@ -27,7 +27,7 @@ consistent across modules in this repository --> 1.3.2 1.68.1 - 1.29.1-SNAPSHOT + 1.30.0 1.45.0 2.11.0 33.3.1-jre diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 68df8d947b..8cad9f0383 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -46,7 +46,8 @@ import com.google.auth.ApiKeyCredentials; import com.google.auth.Credentials; import com.google.auth.oauth2.ComputeEngineCredentials; -import com.google.auth.oauth2.S2A; +import com.google.auth.oauth2.SecureSessionAgent; +import com.google.auth.oauth2.SecureSessionAgentConfig; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.base.Strings; @@ -140,6 +141,7 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP @Nullable private final Boolean allowNonDefaultServiceAccount; @VisibleForTesting final ImmutableMap directPathServiceConfig; @Nullable private final MtlsProvider mtlsProvider; + @Nullable private final SecureSessionAgent s2aConfigProvider; @VisibleForTesting final Map headersWithDuplicatesRemoved = new HashMap<>(); @Nullable @@ -152,6 +154,7 @@ private InstantiatingGrpcChannelProvider(Builder builder) { this.endpoint = builder.endpoint; this.useS2A = builder.useS2A; this.mtlsProvider = builder.mtlsProvider; + this.s2aConfigProvider = builder.s2aConfigProvider; this.envProvider = builder.envProvider; this.interceptorProvider = builder.interceptorProvider; this.maxInboundMessageSize = builder.maxInboundMessageSize; @@ -492,11 +495,14 @@ ChannelCredentials createPlaintextToS2AChannelCredentials(String plaintextAddres * mtlsEndpoint. */ ChannelCredentials createS2ASecuredChannelCredentials() { - S2A s2aUtils = S2A.newBuilder().build(); - String plaintextAddress = s2aUtils.getPlaintextS2AAddress(); - String mtlsAddress = s2aUtils.getMtlsS2AAddress(); + SecureSessionAgentConfig config = s2aConfigProvider.getConfig(); + String plaintextAddress = config.getPlaintextAddress(); + String mtlsAddress = config.getMtlsAddress(); if (Strings.isNullOrEmpty(mtlsAddress)) { // Fallback to plaintext connection to S2A. + LOG.log( + Level.INFO, + "Cannot establish an mTLS connection to S2A because autoconfig endpoint did not return a mtls address to reach S2A."); return createPlaintextToS2AChannelCredentials(plaintextAddress); } // Currently, MTLS to MDS is only available on GCE. See: @@ -523,7 +529,7 @@ ChannelCredentials createS2ASecuredChannelCredentials() { // Fallback to plaintext-to-S2A connection if MTLS-MDS creds do not exist. LOG.log( Level.INFO, - "Cannot establish an mTLS connection to S2A MTLS to MDS credentials do not exist on filesystem, falling back to plaintext connection to S2A"); + "Cannot establish an mTLS connection to S2A because MTLS to MDS credentials do not exist on filesystem, falling back to plaintext connection to S2A"); return createPlaintextToS2AChannelCredentials(plaintextAddress); } } @@ -739,6 +745,7 @@ public static final class Builder { private String endpoint; private boolean useS2A; private EnvironmentProvider envProvider; + private SecureSessionAgent s2aConfigProvider = SecureSessionAgent.create(); private MtlsProvider mtlsProvider = new MtlsProvider(); @Nullable private GrpcInterceptorProvider interceptorProvider; @Nullable private Integer maxInboundMessageSize; @@ -783,6 +790,7 @@ private Builder(InstantiatingGrpcChannelProvider provider) { this.allowNonDefaultServiceAccount = provider.allowNonDefaultServiceAccount; this.directPathServiceConfig = provider.directPathServiceConfig; this.mtlsProvider = provider.mtlsProvider; + this.s2aConfigProvider = provider.s2aConfigProvider; } /** @@ -846,6 +854,12 @@ Builder setMtlsProvider(MtlsProvider mtlsProvider) { return this; } + @VisibleForTesting + Builder setS2AConfigProvider(SecureSessionAgent s2aConfigProvider) { + this.s2aConfigProvider = s2aConfigProvider; + return this; + } + /** * Sets the GrpcInterceptorProvider for this TransportChannelProvider. * diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index f6c92de089..049c34dd96 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -51,6 +51,8 @@ import com.google.auth.http.AuthHttpConstants; import com.google.auth.oauth2.CloudShellCredentials; import com.google.auth.oauth2.ComputeEngineCredentials; +import com.google.auth.oauth2.SecureSessionAgent; +import com.google.auth.oauth2.SecureSessionAgentConfig; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.truth.Truth; @@ -1042,6 +1044,60 @@ void createMtlsToS2AChannelCredentials_success() throws IOException { TlsChannelCredentials.class); } + @Test + void createS2ASecuredChannelCredentials_bothS2AAddressesNull_returnsNull() { + SecureSessionAgent s2aConfigProvider = Mockito.mock(SecureSessionAgent.class); + SecureSessionAgentConfig config = SecureSessionAgentConfig.createBuilder().build(); + Mockito.when(s2aConfigProvider.getConfig()).thenReturn(config); + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder() + .setS2AConfigProvider(s2aConfigProvider) + .build(); + assertThat(provider.createS2ASecuredChannelCredentials()).isNull(); + } + + @Test + void + createS2ASecuredChannelCredentials_mtlsS2AAddressNull_returnsPlaintextToS2AS2AChannelCredentials() { + SecureSessionAgent s2aConfigProvider = Mockito.mock(SecureSessionAgent.class); + SecureSessionAgentConfig config = + SecureSessionAgentConfig.createBuilder().setPlaintextAddress("localhost:8080").build(); + Mockito.when(s2aConfigProvider.getConfig()).thenReturn(config); + FakeLogHandler logHandler = new FakeLogHandler(); + InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder() + .setS2AConfigProvider(s2aConfigProvider) + .build(); + assertThat(provider.createS2ASecuredChannelCredentials()).isNotNull(); + assertThat(logHandler.getAllMessages()) + .contains( + "Cannot establish an mTLS connection to S2A because autoconfig endpoint did not return a mtls address to reach S2A."); + InstantiatingGrpcChannelProvider.LOG.removeHandler(logHandler); + } + + @Test + void createS2ASecuredChannelCredentials_returnsPlaintextToS2AS2AChannelCredentials() { + SecureSessionAgent s2aConfigProvider = Mockito.mock(SecureSessionAgent.class); + SecureSessionAgentConfig config = + SecureSessionAgentConfig.createBuilder() + .setMtlsAddress("localhost:8080") + .setPlaintextAddress("localhost:8080") + .build(); + Mockito.when(s2aConfigProvider.getConfig()).thenReturn(config); + FakeLogHandler logHandler = new FakeLogHandler(); + InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler); + InstantiatingGrpcChannelProvider provider = + InstantiatingGrpcChannelProvider.newBuilder() + .setS2AConfigProvider(s2aConfigProvider) + .build(); + assertThat(provider.createS2ASecuredChannelCredentials()).isNotNull(); + assertThat(logHandler.getAllMessages()) + .contains( + "Cannot establish an mTLS connection to S2A because MTLS to MDS credentials do not exist on filesystem, falling back to plaintext connection to S2A"); + InstantiatingGrpcChannelProvider.LOG.removeHandler(logHandler); + } + private static class FakeLogHandler extends Handler { List records = new ArrayList<>(); From 924a4e4ad1ea129057e1076396336c03b11ad93a Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 13 Nov 2024 15:04:02 -0800 Subject: [PATCH 50/51] fix BUILD. --- gax-java/gax-grpc/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gax-java/gax-grpc/BUILD.bazel b/gax-java/gax-grpc/BUILD.bazel index 69db44c7a4..99e4aba500 100644 --- a/gax-java/gax-grpc/BUILD.bazel +++ b/gax-java/gax-grpc/BUILD.bazel @@ -28,7 +28,7 @@ _COMPILE_DEPS = [ "@io_grpc_grpc_netty_shaded//jar", "@io_grpc_grpc_grpclb//jar", "@io_grpc_grpc_java//alts:alts", - "@io_grpc_grpc_java//s2a:s2a", + "@io_grpc_grpc_java//s2a:s2av2_credentials", "@io_netty_netty_tcnative_boringssl_static//jar", "@javax_annotation_javax_annotation_api//jar", "//gax:gax", From ca5be85292114cc08270f6dce45b32c3f040158a Mon Sep 17 00:00:00 2001 From: blakeli Date: Thu, 14 Nov 2024 01:42:40 -0500 Subject: [PATCH 51/51] fix: Do not build s2a frpm grpc's Bazel target. --- WORKSPACE | 1 - gax-java/dependencies.properties | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index acc53e9842..1cea3cc3ae 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -65,7 +65,6 @@ maven_install( "com.google.api:gapic-generator-java:" + _gapic_generator_java_version, ] + PROTOBUF_MAVEN_ARTIFACTS + IO_GRPC_GRPC_JAVA_ARTIFACTS, fail_on_missing_checksum = False, - override_targets = IO_GRPC_GRPC_JAVA_OVERRIDE_TARGETS, repositories = [ "m2Local", "https://repo.maven.apache.org/maven2/", diff --git a/gax-java/dependencies.properties b/gax-java/dependencies.properties index 27509afd5c..2d24ad9746 100644 --- a/gax-java/dependencies.properties +++ b/gax-java/dependencies.properties @@ -37,7 +37,7 @@ version.io_grpc=1.68.1 # 2) Replace all characters which are neither alphabetic nor digits with the underscore ('_') character maven.com_google_api_grpc_proto_google_common_protos=com.google.api.grpc:proto-google-common-protos:2.46.0 maven.com_google_api_grpc_grpc_google_common_protos=com.google.api.grpc:grpc-google-common-protos:2.46.0 -maven.com_google_auth_google_auth_library_oauth2_http=com.google.auth:google-auth-library-oauth2-http:1.29.0 +maven.com_google_auth_google_auth_library_oauth2_http=com.google.auth:google-auth-library-oauth2-http:1.30.0 maven.com_google_auth_google_auth_library_credentials=com.google.auth:google-auth-library-credentials:1.30.0 maven.io_opentelemetry_opentelemetry_api=io.opentelemetry:opentelemetry-api:1.42.1 maven.io_opencensus_opencensus_api=io.opencensus:opencensus-api:0.31.1