Skip to content
This repository was archived by the owner on Sep 26, 2023. It is now read-only.

Commit 71d7e35

Browse files
Merge 57f206f into 73da2af
2 parents 73da2af + 57f206f commit 71d7e35

18 files changed

Lines changed: 998 additions & 12 deletions

File tree

build.gradle

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ buildscript {
66
maven {
77
url 'https://plugins.gradle.org/m2/'
88
}
9+
maven {
10+
url 'https://oss.sonatype.org/content/repositories/snapshots/'
11+
}
912
mavenCentral()
1013
jcenter()
1114
}
@@ -58,6 +61,9 @@ if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')
5861
allprojects {
5962
repositories {
6063
mavenCentral() // for google-java-format's dependency
64+
maven {
65+
url 'https://oss.sonatype.org/content/repositories/snapshots/'
66+
}
6167
}
6268

6369
// Formatting tasks
@@ -140,6 +146,9 @@ subprojects {
140146
repositories {
141147
mavenLocal()
142148
mavenCentral()
149+
maven {
150+
url 'https://oss.sonatype.org/content/repositories/snapshots/'
151+
}
143152
}
144153

145154
configurations {

dependencies.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ version.gax_httpjson=0.79.1-SNAPSHOT
2525
# with the sources.
2626
version.com_google_protobuf=3.15.2
2727
version.google_java_format=1.1
28-
version.io_grpc=1.36.0
28+
version.io_grpc=1.37.0-SNAPSHOT
2929

3030
# Maven artifacts.
3131
# Note, the actual name of each property matters (bazel build scripts depend on it).

gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.google.api.gax.rpc.HeaderProvider;
3939
import com.google.api.gax.rpc.TransportChannel;
4040
import com.google.api.gax.rpc.TransportChannelProvider;
41+
import com.google.api.gax.rpc.mtls.MtlsProvider;
4142
import com.google.auth.Credentials;
4243
import com.google.auth.oauth2.ComputeEngineCredentials;
4344
import com.google.common.annotations.VisibleForTesting;
@@ -46,16 +47,22 @@
4647
import com.google.common.collect.ImmutableList;
4748
import com.google.common.collect.ImmutableMap;
4849
import com.google.common.io.CharStreams;
50+
import io.grpc.ChannelCredentials;
51+
import io.grpc.Grpc;
4952
import io.grpc.ManagedChannel;
5053
import io.grpc.ManagedChannelBuilder;
54+
import io.grpc.TlsChannelCredentials;
5155
import io.grpc.alts.ComputeEngineChannelBuilder;
5256
import java.io.IOException;
5357
import java.io.InputStreamReader;
58+
import java.security.GeneralSecurityException;
59+
import java.security.KeyStore;
5460
import java.util.Map;
5561
import java.util.concurrent.Executor;
5662
import java.util.concurrent.ScheduledExecutorService;
5763
import java.util.concurrent.TimeUnit;
5864
import javax.annotation.Nullable;
65+
import javax.net.ssl.KeyManagerFactory;
5966
import org.threeten.bp.Duration;
6067

6168
/**
@@ -96,6 +103,7 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP
96103
@Nullable private final ChannelPrimer channelPrimer;
97104
@Nullable private final Boolean attemptDirectPath;
98105
@VisibleForTesting final ImmutableMap<String, ?> directPathServiceConfig;
106+
@Nullable private final MtlsProvider mtlsProvider;
99107

100108
@Nullable
101109
private final ApiFunction<ManagedChannelBuilder, ManagedChannelBuilder> channelConfigurator;
@@ -105,6 +113,7 @@ private InstantiatingGrpcChannelProvider(Builder builder) {
105113
this.executor = builder.executor;
106114
this.headerProvider = builder.headerProvider;
107115
this.endpoint = builder.endpoint;
116+
this.mtlsProvider = builder.mtlsProvider;
108117
this.envProvider = builder.envProvider;
109118
this.interceptorProvider = builder.interceptorProvider;
110119
this.maxInboundMessageSize = builder.maxInboundMessageSize;
@@ -264,6 +273,24 @@ static boolean isOnComputeEngine() {
264273
return false;
265274
}
266275

276+
@VisibleForTesting
277+
ChannelCredentials createMtlsChannelCredentials() throws IOException {
278+
if (mtlsProvider.useMtlsClientCertificate()) {
279+
try {
280+
KeyStore mtlsKeyStore = mtlsProvider.getKeyStore();
281+
if (mtlsKeyStore != null) {
282+
KeyManagerFactory factory =
283+
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
284+
factory.init(mtlsKeyStore, new char[] {});
285+
return TlsChannelCredentials.newBuilder().keyManager(factory.getKeyManagers()).build();
286+
}
287+
} catch (GeneralSecurityException e) {
288+
throw new IOException(e.toString());
289+
}
290+
}
291+
return null;
292+
}
293+
267294
private ManagedChannel createSingleChannel() throws IOException {
268295
GrpcHeaderInterceptor headerInterceptor =
269296
new GrpcHeaderInterceptor(headerProvider.getHeaders());
@@ -290,7 +317,12 @@ && isOnComputeEngine()) {
290317
builder.keepAliveTimeout(DIRECT_PATH_KEEP_ALIVE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
291318
builder.defaultServiceConfig(directPathServiceConfig);
292319
} else {
293-
builder = ManagedChannelBuilder.forAddress(serviceAddress, port);
320+
ChannelCredentials mTlsChannelCredentials = createMtlsChannelCredentials();
321+
if (mTlsChannelCredentials != null) {
322+
builder = Grpc.newChannelBuilder(endpoint, mTlsChannelCredentials);
323+
} else {
324+
builder = ManagedChannelBuilder.forAddress(serviceAddress, port);
325+
}
294326
}
295327
builder =
296328
builder
@@ -376,6 +408,7 @@ public static final class Builder {
376408
private HeaderProvider headerProvider;
377409
private String endpoint;
378410
private EnvironmentProvider envProvider;
411+
private MtlsProvider mtlsProvider = new MtlsProvider();
379412
@Nullable private GrpcInterceptorProvider interceptorProvider;
380413
@Nullable private Integer maxInboundMessageSize;
381414
@Nullable private Integer maxInboundMetadataSize;
@@ -412,6 +445,7 @@ private Builder(InstantiatingGrpcChannelProvider provider) {
412445
this.channelPrimer = provider.channelPrimer;
413446
this.attemptDirectPath = provider.attemptDirectPath;
414447
this.directPathServiceConfig = provider.directPathServiceConfig;
448+
this.mtlsProvider = provider.mtlsProvider;
415449
}
416450

417451
/** Sets the number of available CPUs, used internally for testing. */
@@ -458,6 +492,12 @@ public Builder setEndpoint(String endpoint) {
458492
return this;
459493
}
460494

495+
@VisibleForTesting
496+
Builder setMtlsProvider(MtlsProvider mtlsProvider) {
497+
this.mtlsProvider = mtlsProvider;
498+
return this;
499+
}
500+
461501
/**
462502
* Sets the GrpcInterceptorProvider for this TransportChannelProvider.
463503
*

gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.Builder;
3939
import com.google.api.gax.rpc.HeaderProvider;
4040
import com.google.api.gax.rpc.TransportChannelProvider;
41+
import com.google.api.gax.rpc.mtls.AbstractMtlsTransportChannelTest;
42+
import com.google.api.gax.rpc.mtls.MtlsProvider;
4143
import com.google.auth.oauth2.CloudShellCredentials;
4244
import com.google.auth.oauth2.ComputeEngineCredentials;
4345
import com.google.common.collect.ImmutableList;
@@ -63,8 +65,7 @@
6365
import org.threeten.bp.Duration;
6466

6567
@RunWith(JUnit4.class)
66-
public class InstantiatingGrpcChannelProviderTest {
67-
68+
public class InstantiatingGrpcChannelProviderTest extends AbstractMtlsTransportChannelTest {
6869
@Test
6970
public void testEndpoint() {
7071
String endpoint = "localhost:8080";
@@ -499,4 +500,15 @@ public void testWithCustomDirectPathServiceConfig() {
499500
ImmutableMap<String, ?> defaultServiceConfig = provider.directPathServiceConfig;
500501
assertThat(defaultServiceConfig).isEqualTo(passedServiceConfig);
501502
}
503+
504+
@Override
505+
protected Object getMtlsObjectFromTransportChannel(MtlsProvider provider) throws IOException {
506+
return InstantiatingGrpcChannelProvider.newBuilder()
507+
.setEndpoint("localhost:8080")
508+
.setMtlsProvider(provider)
509+
.setHeaderProvider(Mockito.mock(HeaderProvider.class))
510+
.setExecutor(Mockito.mock(Executor.class))
511+
.build()
512+
.createMtlsChannelCredentials();
513+
}
502514
}

gax-grpc/src/test/java/com/google/api/gax/grpc/SettingsTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import com.google.api.gax.rpc.StubSettings;
5151
import com.google.api.gax.rpc.TransportChannelProvider;
5252
import com.google.api.gax.rpc.UnaryCallSettings;
53+
import com.google.api.gax.rpc.mtls.MtlsProvider;
5354
import com.google.auth.Credentials;
5455
import com.google.common.collect.ImmutableList;
5556
import com.google.common.collect.ImmutableMap;
@@ -83,6 +84,7 @@ private static class FakeStubSettings extends StubSettings<FakeStubSettings> {
8384
public static final int DEFAULT_SERVICE_PORT = 443;
8485
public static final String DEFAULT_SERVICE_ENDPOINT =
8586
DEFAULT_SERVICE_ADDRESS + ':' + DEFAULT_SERVICE_PORT;
87+
public static final MtlsProvider DEFAULT_MTLS_PROVIDER = new MtlsProvider();
8688
public static final ImmutableList<String> DEFAULT_SERVICE_SCOPES =
8789
ImmutableList.<String>builder()
8890
.add("https://www.googleapis.com/auth/pubsub")
@@ -148,7 +150,9 @@ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuild
148150

149151
/** Returns a builder for the default TransportChannelProvider for this service. */
150152
public static InstantiatingGrpcChannelProvider.Builder defaultGrpcChannelProviderBuilder() {
151-
return InstantiatingGrpcChannelProvider.newBuilder().setEndpoint(DEFAULT_SERVICE_ENDPOINT);
153+
return InstantiatingGrpcChannelProvider.newBuilder()
154+
.setEndpoint(DEFAULT_SERVICE_ENDPOINT)
155+
.setMtlsProvider(DEFAULT_MTLS_PROVIDER);
152156
}
153157

154158
public static ApiClientHeaderProvider.Builder defaultGoogleServiceHeaderProviderBuilder() {

gax-httpjson/src/main/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProvider.java

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,21 @@
3030
package com.google.api.gax.httpjson;
3131

3232
import com.google.api.client.http.HttpTransport;
33+
import com.google.api.client.http.javanet.NetHttpTransport;
3334
import com.google.api.core.BetaApi;
3435
import com.google.api.core.InternalExtensionOnly;
3536
import com.google.api.gax.core.ExecutorProvider;
3637
import com.google.api.gax.rpc.FixedHeaderProvider;
3738
import com.google.api.gax.rpc.HeaderProvider;
3839
import com.google.api.gax.rpc.TransportChannel;
3940
import com.google.api.gax.rpc.TransportChannelProvider;
41+
import com.google.api.gax.rpc.mtls.MtlsProvider;
4042
import com.google.auth.Credentials;
43+
import com.google.common.annotations.VisibleForTesting;
4144
import com.google.common.collect.Lists;
4245
import java.io.IOException;
46+
import java.security.GeneralSecurityException;
47+
import java.security.KeyStore;
4348
import java.util.List;
4449
import java.util.Map;
4550
import java.util.concurrent.Executor;
@@ -64,24 +69,28 @@ public final class InstantiatingHttpJsonChannelProvider implements TransportChan
6469
private final HeaderProvider headerProvider;
6570
private final String endpoint;
6671
private final HttpTransport httpTransport;
72+
private final MtlsProvider mtlsProvider;
6773

6874
private InstantiatingHttpJsonChannelProvider(
6975
Executor executor, HeaderProvider headerProvider, String endpoint) {
7076
this.executor = executor;
7177
this.headerProvider = headerProvider;
7278
this.endpoint = endpoint;
7379
this.httpTransport = null;
80+
this.mtlsProvider = new MtlsProvider();
7481
}
7582

7683
private InstantiatingHttpJsonChannelProvider(
7784
Executor executor,
7885
HeaderProvider headerProvider,
7986
String endpoint,
80-
HttpTransport httpTransport) {
87+
HttpTransport httpTransport,
88+
MtlsProvider mtlsProvider) {
8189
this.executor = executor;
8290
this.headerProvider = headerProvider;
8391
this.endpoint = endpoint;
8492
this.httpTransport = httpTransport;
93+
this.mtlsProvider = mtlsProvider;
8594
}
8695

8796
@Override
@@ -160,6 +169,20 @@ public TransportChannelProvider withCredentials(Credentials credentials) {
160169
"InstantiatingHttpJsonChannelProvider doesn't need credentials");
161170
}
162171

172+
HttpTransport createHttpTransport() throws IOException {
173+
if (mtlsProvider.useMtlsClientCertificate()) {
174+
try {
175+
KeyStore mtlsKeyStore = mtlsProvider.getKeyStore();
176+
if (mtlsKeyStore != null) {
177+
return new NetHttpTransport.Builder().trustCertificates(null, mtlsKeyStore, "").build();
178+
}
179+
} catch (GeneralSecurityException e) {
180+
throw new IOException(e.toString());
181+
}
182+
}
183+
return null;
184+
}
185+
163186
private TransportChannel createChannel() throws IOException {
164187
Map<String, String> headers = headerProvider.getHeaders();
165188

@@ -168,12 +191,17 @@ private TransportChannel createChannel() throws IOException {
168191
headerEnhancers.add(HttpJsonHeaderEnhancers.create(header.getKey(), header.getValue()));
169192
}
170193

194+
HttpTransport httpTransportToUse = httpTransport;
195+
if (httpTransportToUse == null) {
196+
httpTransportToUse = createHttpTransport();
197+
}
198+
171199
ManagedHttpJsonChannel channel =
172200
ManagedHttpJsonChannel.newBuilder()
173201
.setEndpoint(endpoint)
174202
.setHeaderEnhancers(headerEnhancers)
175203
.setExecutor(executor)
176-
.setHttpTransport(httpTransport)
204+
.setHttpTransport(httpTransportToUse)
177205
.build();
178206

179207
return HttpJsonTransportChannel.newBuilder().setManagedChannel(channel).build();
@@ -202,6 +230,7 @@ public static final class Builder {
202230
private HeaderProvider headerProvider;
203231
private String endpoint;
204232
private HttpTransport httpTransport;
233+
private MtlsProvider mtlsProvider = new MtlsProvider();
205234

206235
private Builder() {}
207236

@@ -210,6 +239,7 @@ private Builder(InstantiatingHttpJsonChannelProvider provider) {
210239
this.headerProvider = provider.headerProvider;
211240
this.endpoint = provider.endpoint;
212241
this.httpTransport = provider.httpTransport;
242+
this.mtlsProvider = provider.mtlsProvider;
213243
}
214244

215245
/**
@@ -259,9 +289,15 @@ public String getEndpoint() {
259289
return endpoint;
260290
}
261291

292+
@VisibleForTesting
293+
Builder setMtlsProvider(MtlsProvider mtlsProvider) {
294+
this.mtlsProvider = mtlsProvider;
295+
return this;
296+
}
297+
262298
public InstantiatingHttpJsonChannelProvider build() {
263299
return new InstantiatingHttpJsonChannelProvider(
264-
executor, headerProvider, endpoint, httpTransport);
300+
executor, headerProvider, endpoint, httpTransport, mtlsProvider);
265301
}
266302
}
267303
}

gax-httpjson/src/test/java/com/google/api/gax/httpjson/InstantiatingHttpJsonChannelProviderTest.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@
3232
import static com.google.common.truth.Truth.assertThat;
3333
import static org.junit.Assert.assertEquals;
3434

35+
import com.google.api.gax.rpc.HeaderProvider;
3536
import com.google.api.gax.rpc.TransportChannelProvider;
37+
import com.google.api.gax.rpc.mtls.AbstractMtlsTransportChannelTest;
38+
import com.google.api.gax.rpc.mtls.MtlsProvider;
3639
import java.io.IOException;
3740
import java.util.Collections;
3841
import java.util.concurrent.Executor;
@@ -41,9 +44,10 @@
4144
import org.junit.Test;
4245
import org.junit.runner.RunWith;
4346
import org.junit.runners.JUnit4;
47+
import org.mockito.Mockito;
4448

4549
@RunWith(JUnit4.class)
46-
public class InstantiatingHttpJsonChannelProviderTest {
50+
public class InstantiatingHttpJsonChannelProviderTest extends AbstractMtlsTransportChannelTest {
4751

4852
@Test
4953
public void basicTest() throws IOException {
@@ -94,4 +98,15 @@ public void basicTest() throws IOException {
9498
// Make sure we can create channels OK.
9599
provider.getTransportChannel().shutdownNow();
96100
}
101+
102+
@Override
103+
protected Object getMtlsObjectFromTransportChannel(MtlsProvider provider) throws IOException {
104+
return InstantiatingHttpJsonChannelProvider.newBuilder()
105+
.setEndpoint("localhost:8080")
106+
.setMtlsProvider(provider)
107+
.setHeaderProvider(Mockito.mock(HeaderProvider.class))
108+
.setExecutor(Mockito.mock(Executor.class))
109+
.build()
110+
.createHttpTransport();
111+
}
97112
}

gax/BUILD.bazel

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ java_library(
5151
srcs = glob(["src/test/java/**/*.java"]),
5252
javacopts = _JAVA_COPTS,
5353
plugins = ["//:auto_value_plugin"],
54+
resources = glob([
55+
"src/test/resources/com/google/api/gax/rpc/mtls/mtls_context_aware_metadata.json",
56+
"src/test/resources/com/google/api/gax/rpc/mtls/mtlsCertAndKey.pem",
57+
]),
5458
visibility = ["//visibility:public"],
5559
deps = [":gax"] + _COMPILE_DEPS + _TEST_COMPILE_DEPS,
5660
)

0 commit comments

Comments
 (0)