Skip to content

Commit cca8963

Browse files
feat: allow setting channel and credential providers in DatastoreOptions (#1299)
* feat: allow setting channel and credential providers in DatastoreOptions * add additional validation and test * mark new fields as transient * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * update test * review feedback * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * review feedback * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
1 parent 71f510d commit cca8963

File tree

4 files changed

+143
-17
lines changed

4 files changed

+143
-17
lines changed

google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919
import static com.google.cloud.datastore.Validator.validateNamespace;
2020

21+
import com.google.api.gax.core.CredentialsProvider;
22+
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
23+
import com.google.api.gax.rpc.TransportChannelProvider;
2124
import com.google.cloud.ServiceDefaults;
2225
import com.google.cloud.ServiceOptions;
2326
import com.google.cloud.ServiceRpc;
@@ -46,6 +49,9 @@ public class DatastoreOptions extends ServiceOptions<Datastore, DatastoreOptions
4649
public static final String PROJECT_ID_ENV_VAR = "DATASTORE_PROJECT_ID";
4750
public static final String LOCAL_HOST_ENV_VAR = "DATASTORE_EMULATOR_HOST";
4851

52+
private transient TransportChannelProvider channelProvider = null;
53+
private transient CredentialsProvider credentialsProvider = null;
54+
4955
private final String namespace;
5056
private final String databaseId;
5157

@@ -69,6 +75,10 @@ public ServiceRpc create(DatastoreOptions options) {
6975
if (options.getTransportOptions() instanceof GrpcTransportOptions) {
7076
return new GrpcDatastoreRpc(options);
7177
} else if (options.getTransportOptions() instanceof HttpTransportOptions) {
78+
// todo see if we can remove this check
79+
if (DatastoreUtils.isEmulator(options)) {
80+
throw new IllegalArgumentException("Only GRPC channels are allowed for emulator.");
81+
}
7282
return new HttpDatastoreRpc(options);
7383
} else {
7484
throw new IllegalArgumentException(
@@ -84,20 +94,46 @@ public static class Builder extends ServiceOptions.Builder<Datastore, DatastoreO
8494

8595
private String namespace;
8696
private String databaseId;
97+
private TransportChannelProvider channelProvider = null;
98+
private CredentialsProvider credentialsProvider = null;
8799

88100
private Builder() {}
89101

90102
private Builder(DatastoreOptions options) {
91103
super(options);
92-
namespace = options.namespace;
93-
databaseId = options.databaseId;
104+
this.namespace = options.namespace;
105+
this.databaseId = options.databaseId;
106+
this.channelProvider = validateChannelProvider(options.channelProvider);
107+
this.credentialsProvider = options.credentialsProvider;
94108
}
95109

96110
@Override
97111
public Builder setTransportOptions(TransportOptions transportOptions) {
98112
return super.setTransportOptions(transportOptions);
99113
}
100114

115+
/**
116+
* Sets the {@link TransportChannelProvider} to use with this Datastore client.
117+
*
118+
* @param channelProvider A InstantiatingGrpcChannelProvider object that defines the transport
119+
* provider for this client.
120+
*/
121+
public Builder setChannelProvider(TransportChannelProvider channelProvider) {
122+
this.channelProvider = validateChannelProvider(channelProvider);
123+
return this;
124+
}
125+
126+
/**
127+
* Sets the {@link CredentialsProvider} to use with this Datastore client.
128+
*
129+
* @param credentialsProvider A CredentialsProvider object that defines the credential provider
130+
* for this client.
131+
*/
132+
public Builder setCredentialsProvider(CredentialsProvider credentialsProvider) {
133+
this.credentialsProvider = credentialsProvider;
134+
return this;
135+
}
136+
101137
@Override
102138
public DatastoreOptions build() {
103139
return new DatastoreOptions(this);
@@ -115,10 +151,45 @@ public Builder setDatabaseId(String databaseId) {
115151
}
116152
}
117153

154+
private static TransportChannelProvider validateChannelProvider(
155+
TransportChannelProvider channelProvider) {
156+
if (!(channelProvider instanceof InstantiatingGrpcChannelProvider)) {
157+
throw new IllegalArgumentException(
158+
"Only GRPC channels are allowed for " + API_SHORT_NAME + ".");
159+
}
160+
return channelProvider;
161+
}
162+
118163
private DatastoreOptions(Builder builder) {
119164
super(DatastoreFactory.class, DatastoreRpcFactory.class, builder, new DatastoreDefaults());
120165
namespace = MoreObjects.firstNonNull(builder.namespace, defaultNamespace());
121166
databaseId = MoreObjects.firstNonNull(builder.databaseId, DEFAULT_DATABASE_ID);
167+
168+
// todo see if we can update this
169+
if (getTransportOptions() instanceof HttpTransportOptions
170+
&& (builder.channelProvider != null || builder.credentialsProvider != null)) {
171+
throw new IllegalArgumentException(
172+
"Only gRPC transport allows setting of channel provider or credentials provider");
173+
} else if (getTransportOptions() instanceof GrpcTransportOptions) {
174+
this.channelProvider =
175+
builder.channelProvider != null
176+
? builder.channelProvider
177+
: GrpcTransportOptions.setUpChannelProvider(
178+
DatastoreSettings.defaultGrpcTransportProviderBuilder(), this);
179+
180+
this.credentialsProvider =
181+
builder.credentialsProvider != null
182+
? builder.credentialsProvider
183+
: GrpcTransportOptions.setUpCredentialsProvider(this);
184+
}
185+
}
186+
187+
public CredentialsProvider getCredentialsProvider() {
188+
return credentialsProvider;
189+
}
190+
191+
public TransportChannelProvider getTransportChannelProvider() {
192+
return channelProvider;
122193
}
123194

124195
@Override
@@ -134,6 +205,7 @@ protected String getDefaultProject() {
134205
}
135206

136207
private static class DatastoreDefaults implements ServiceDefaults<Datastore, DatastoreOptions> {
208+
private final TransportOptions TRANSPORT_OPTIONS = getDefaultTransportOptionsBuilder().build();
137209

138210
@Override
139211
public DatastoreFactory getDefaultServiceFactory() {
@@ -147,7 +219,11 @@ public DatastoreRpcFactory getDefaultRpcFactory() {
147219

148220
@Override
149221
public TransportOptions getDefaultTransportOptions() {
150-
return getDefaultGrpcTransportOptions();
222+
return TRANSPORT_OPTIONS;
223+
}
224+
225+
public static GrpcTransportOptions.Builder getDefaultTransportOptionsBuilder() {
226+
return GrpcTransportOptions.newBuilder();
151227
}
152228
}
153229

google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreUtils.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,19 @@
1717
package com.google.cloud.datastore;
1818

1919
import com.google.api.core.InternalApi;
20+
import com.google.cloud.NoCredentials;
2021
import com.google.common.base.Strings;
2122
import java.net.InetAddress;
2223
import java.net.URL;
2324

2425
@InternalApi
2526
public class DatastoreUtils {
2627

28+
public static boolean isEmulator(DatastoreOptions datastoreOptions) {
29+
return isLocalHost(datastoreOptions.getHost())
30+
|| NoCredentials.getInstance().equals(datastoreOptions.getCredentials());
31+
}
32+
2733
public static boolean isLocalHost(String host) {
2834
if (Strings.isNullOrEmpty(host)) {
2935
return false;

google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package com.google.cloud.datastore.spi.v1;
1818

19-
import static com.google.cloud.datastore.DatastoreUtils.isLocalHost;
19+
import static com.google.cloud.datastore.DatastoreUtils.isEmulator;
2020
import static com.google.cloud.datastore.DatastoreUtils.removeScheme;
2121
import static com.google.cloud.datastore.spi.v1.RpcUtils.retrySettingSetter;
2222
import static java.util.concurrent.TimeUnit.SECONDS;
@@ -30,14 +30,12 @@
3030
import com.google.api.gax.rpc.HeaderProvider;
3131
import com.google.api.gax.rpc.NoHeaderProvider;
3232
import com.google.api.gax.rpc.TransportChannel;
33-
import com.google.cloud.NoCredentials;
3433
import com.google.cloud.ServiceOptions;
3534
import com.google.cloud.datastore.DatastoreException;
3635
import com.google.cloud.datastore.DatastoreOptions;
3736
import com.google.cloud.datastore.v1.DatastoreSettings;
3837
import com.google.cloud.datastore.v1.stub.DatastoreStubSettings;
3938
import com.google.cloud.datastore.v1.stub.GrpcDatastoreStub;
40-
import com.google.cloud.grpc.GrpcTransportOptions;
4139
import com.google.common.base.Strings;
4240
import com.google.datastore.v1.AllocateIdsRequest;
4341
import com.google.datastore.v1.AllocateIdsResponse;
@@ -69,7 +67,6 @@ public class GrpcDatastoreRpc implements DatastoreRpc {
6967
private boolean closed;
7068

7169
public GrpcDatastoreRpc(DatastoreOptions datastoreOptions) throws IOException {
72-
7370
try {
7471
clientContext =
7572
isEmulator(datastoreOptions)
@@ -146,11 +143,6 @@ public boolean isClosed() {
146143
return closed && datastoreStub.isShutdown();
147144
}
148145

149-
private boolean isEmulator(DatastoreOptions datastoreOptions) {
150-
return isLocalHost(datastoreOptions.getHost())
151-
|| NoCredentials.getInstance().equals(datastoreOptions.getCredentials());
152-
}
153-
154146
private ClientContext getClientContextForEmulator(DatastoreOptions datastoreOptions)
155147
throws IOException {
156148
ManagedChannel managedChannel =
@@ -177,11 +169,8 @@ private ClientContext getClientContext(DatastoreOptions datastoreOptions) throws
177169

178170
DatastoreSettingsBuilder settingsBuilder =
179171
new DatastoreSettingsBuilder(DatastoreSettings.newBuilder().build());
180-
settingsBuilder.setCredentialsProvider(
181-
GrpcTransportOptions.setUpCredentialsProvider(datastoreOptions));
182-
settingsBuilder.setTransportChannelProvider(
183-
GrpcTransportOptions.setUpChannelProvider(
184-
DatastoreSettings.defaultGrpcTransportProviderBuilder(), datastoreOptions));
172+
settingsBuilder.setCredentialsProvider(datastoreOptions.getCredentialsProvider());
173+
settingsBuilder.setTransportChannelProvider(datastoreOptions.getTransportChannelProvider());
185174
settingsBuilder.setInternalHeaderProvider(internalHeaderProvider);
186175
settingsBuilder.setHeaderProvider(
187176
datastoreOptions.getMergedHeaderProvider(new NoHeaderProvider()));

google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreOptionsTest.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,17 @@
2222
import static org.junit.Assert.assertSame;
2323
import static org.junit.Assert.assertTrue;
2424

25+
import com.google.api.gax.core.NoCredentialsProvider;
26+
import com.google.api.gax.grpc.ChannelPoolSettings;
27+
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
28+
import com.google.cloud.NoCredentials;
2529
import com.google.cloud.datastore.spi.DatastoreRpcFactory;
2630
import com.google.cloud.datastore.spi.v1.DatastoreRpc;
31+
import com.google.cloud.datastore.v1.DatastoreSettings;
2732
import com.google.cloud.grpc.GrpcTransportOptions;
2833
import com.google.cloud.http.HttpTransportOptions;
2934
import org.easymock.EasyMock;
35+
import org.junit.Assert;
3036
import org.junit.Before;
3137
import org.junit.Test;
3238

@@ -48,7 +54,9 @@ public void setUp() {
4854
.setServiceRpcFactory(datastoreRpcFactory)
4955
.setProjectId(PROJECT_ID)
5056
.setDatabaseId(DATABASE_ID)
57+
.setCredentials(NoCredentials.getInstance())
5158
.setHost("http://localhost:" + PORT);
59+
5260
EasyMock.expect(datastoreRpcFactory.create(EasyMock.anyObject(DatastoreOptions.class)))
5361
.andReturn(datastoreRpc)
5462
.anyTimes();
@@ -81,6 +89,51 @@ public void testDatastore() {
8189
assertSame(datastoreRpc, options.build().getRpc());
8290
}
8391

92+
@Test
93+
public void testCustomChannelAndCredentials() {
94+
NoCredentialsProvider noCredentialsProvider = NoCredentialsProvider.create();
95+
InstantiatingGrpcChannelProvider channelProvider =
96+
DatastoreSettings.defaultGrpcTransportProviderBuilder()
97+
.setChannelPoolSettings(
98+
ChannelPoolSettings.builder()
99+
.setInitialChannelCount(10)
100+
.setMaxChannelCount(20)
101+
.build())
102+
.build();
103+
DatastoreOptions datastoreOptions =
104+
DatastoreOptions.newBuilder()
105+
.setServiceRpcFactory(datastoreRpcFactory)
106+
.setProjectId(PROJECT_ID)
107+
.setDatabaseId(DATABASE_ID)
108+
.setChannelProvider(channelProvider)
109+
.setCredentialsProvider(noCredentialsProvider)
110+
.setHost("http://localhost:" + PORT)
111+
.build();
112+
assertEquals(datastoreOptions.getTransportChannelProvider(), channelProvider);
113+
assertEquals(datastoreOptions.getCredentialsProvider(), noCredentialsProvider);
114+
}
115+
116+
@Test
117+
public void testInvalidConfigForHttp() {
118+
DatastoreOptions.Builder options =
119+
DatastoreOptions.newBuilder()
120+
.setServiceRpcFactory(datastoreRpcFactory)
121+
.setProjectId(PROJECT_ID)
122+
.setDatabaseId(DATABASE_ID)
123+
.setTransportOptions(HttpTransportOptions.newBuilder().build())
124+
.setChannelProvider(
125+
DatastoreSettings.defaultGrpcTransportProviderBuilder()
126+
.setChannelPoolSettings(
127+
ChannelPoolSettings.builder()
128+
.setInitialChannelCount(10)
129+
.setMaxChannelCount(20)
130+
.build())
131+
.build())
132+
.setCredentialsProvider(NoCredentialsProvider.create())
133+
.setHost("http://localhost:" + PORT);
134+
Assert.assertThrows(IllegalArgumentException.class, options::build);
135+
}
136+
84137
@Test
85138
public void testTransport() {
86139
// default grpc transport
@@ -93,6 +146,8 @@ public void testTransport() {
93146
.setProjectId(PROJECT_ID)
94147
.build();
95148
assertThat(httpDatastoreOptions.getTransportOptions()).isInstanceOf(HttpTransportOptions.class);
149+
assertThat(httpDatastoreOptions.getCredentialsProvider()).isNull();
150+
assertThat(httpDatastoreOptions.getTransportChannelProvider()).isNull();
96151

97152
// custom grpc transport
98153
DatastoreOptions grpcDatastoreOptions =

0 commit comments

Comments
 (0)