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 88bfd91601..e22ffa098a 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 @@ -129,6 +129,7 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP private final HeaderProvider headerProvider; private final boolean useS2A; 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. @@ -179,6 +180,7 @@ private InstantiatingGrpcChannelProvider(Builder builder) { this.headerProvider = builder.headerProvider; this.useS2A = builder.useS2A; this.endpoint = builder.endpoint; + this.mtlsEndpoint = builder.mtlsEndpoint; this.allowedHardBoundTokenTypes = builder.allowedHardBoundTokenTypes; this.mtlsProvider = builder.mtlsProvider; this.s2aConfigProvider = builder.s2aConfigProvider; @@ -258,6 +260,12 @@ public boolean needsEndpoint() { return endpoint == null; } + @InternalApi("This public method is used by Gax to help configure the MTLS endpoint for S2A") + @Override + public boolean needsMtlsEndpoint() { + return mtlsEndpoint == null; + } + /** * Specify the endpoint the channel should connect to. * @@ -272,6 +280,22 @@ public TransportChannelProvider withEndpoint(String endpoint) { return toBuilder().setEndpoint(endpoint).build(); } + /** + * Specify the mTLS endpoint the channel should connect to when using S2A. + * + *
The value of {@code mtlsEndpoint} must be of the form {@code host:port}.
+ *
+ * @param mtlsEndpoint The mtTLS endpoint to connect to
+ * @return A new {@link InstantiatingGrpcChannelProvider} with the specified mTLS endpoint
+ * configured
+ */
+ @InternalApi("This public method is used by Gax to help configure the MTLS endpoint for S2A")
+ @Override
+ public TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) {
+ validateEndpoint(mtlsEndpoint);
+ return toBuilder().setMtlsEndpoint(mtlsEndpoint).build();
+ }
+
/**
* Specify whether or not to use S2A.
*
@@ -666,7 +690,9 @@ private ManagedChannel createSingleChannel() throws IOException {
channelCredentials =
CompositeChannelCredentials.create(channelCredentials, mtlsS2ACallCredentials);
}
- builder = Grpc.newChannelBuilder(endpoint, channelCredentials);
+ // Connect to the MTLS endpoint when using S2A because S2A is used to perform an MTLS
+ // handshake.
+ builder = Grpc.newChannelBuilder(mtlsEndpoint, channelCredentials);
} else {
// Use default if we cannot initialize channel credentials via DCA or S2A.
builder = ManagedChannelBuilder.forAddress(serviceAddress, port);
@@ -819,6 +845,7 @@ public static final class Builder {
private Executor executor;
private HeaderProvider headerProvider;
private String endpoint;
+ private String mtlsEndpoint;
private boolean useS2A;
private EnvironmentProvider envProvider;
private SecureSessionAgent s2aConfigProvider = SecureSessionAgent.create();
@@ -926,6 +953,14 @@ public Builder setEndpoint(String endpoint) {
return this;
}
+ /** Sets the mTLS Endpoint used to reach the service, eg "localhost:8080". */
+ @InternalApi("This public method is used by Gax to help configure the MTLS endpoint for S2A")
+ public Builder setMtlsEndpoint(String mtlsEndpoint) {
+ validateEndpoint(mtlsEndpoint);
+ this.mtlsEndpoint = mtlsEndpoint;
+ return this;
+ }
+
Builder setUseS2A(boolean useS2A) {
this.useS2A = useS2A;
return this;
diff --git a/gax-java/gax/clirr-ignored-differences.xml b/gax-java/gax/clirr-ignored-differences.xml
index ee2e254c96..4e0a8816c1 100644
--- a/gax-java/gax/clirr-ignored-differences.xml
+++ b/gax-java/gax/clirr-ignored-differences.xml
@@ -118,4 +118,14 @@
This method should only be called if {@link #needsMtlsEndpoint()} returns true. + */ + default TransportChannelProvider withMtlsEndpoint(String mtlsEndpoint) { + return this; + } + /** Sets whether to use S2A when constructing a new {@link TransportChannel}. */ @BetaApi( "The S2A feature is not stable yet and may change in the future. https://github.com/grpc/grpc-java/issues/11533.") 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 94f013f9ba..dd1d383801 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 @@ -374,7 +374,7 @@ void endpointContextBuild_multipleUniverseDomainConfigurations_clientSettingsHas } @Test - void endpointContextBuild_shouldUseS2A_mtlsEndpoint() throws IOException { + void endpointContextBuild_shouldUseS2A_tlsEndpoint() throws IOException { EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class); Mockito.when(envProvider.getenv(EndpointContext.S2A_ENV_ENABLE_USE_S2A)).thenReturn("true"); defaultEndpointContextBuilder = @@ -385,7 +385,7 @@ void endpointContextBuild_shouldUseS2A_mtlsEndpoint() throws IOException { .setUsingGDCH(false); EndpointContext endpointContext = defaultEndpointContextBuilder.build(); Truth.assertThat(defaultEndpointContextBuilder.shouldUseS2A()).isTrue(); - Truth.assertThat(endpointContext.resolvedEndpoint()).isEqualTo(DEFAULT_MTLS_ENDPOINT); + Truth.assertThat(endpointContext.resolvedEndpoint()).isEqualTo(DEFAULT_ENDPOINT); } @Test