Skip to content

Commit 24fb234

Browse files
authored
feat(Datastore): Swap the default transport from HttpJson to gRPC (#12977)
1 parent 2cecd0c commit 24fb234

9 files changed

Lines changed: 114 additions & 75 deletions

File tree

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

Lines changed: 64 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import static com.google.cloud.datastore.Validator.validateNamespace;
2020

2121
import com.google.api.core.BetaApi;
22-
import com.google.api.core.ObsoleteApi;
2322
import com.google.api.gax.grpc.ChannelPoolSettings;
2423
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
2524
import com.google.api.gax.rpc.TransportChannelProvider;
@@ -35,18 +34,21 @@
3534
import com.google.cloud.grpc.GrpcTransportOptions;
3635
import com.google.cloud.http.HttpTransportOptions;
3736
import com.google.common.base.MoreObjects;
37+
import com.google.common.base.Preconditions;
3838
import com.google.common.collect.ImmutableSet;
3939
import java.io.IOException;
4040
import java.lang.reflect.Method;
4141
import java.util.Objects;
4242
import java.util.Set;
43+
import java.util.logging.Logger;
4344
import javax.annotation.Nonnull;
4445
import javax.annotation.Nullable;
4546

4647
public class DatastoreOptions extends ServiceOptions<Datastore, DatastoreOptions> {
4748

4849
private static final long serialVersionUID = -1018382430058137336L;
4950
private static final String API_SHORT_NAME = "Datastore";
51+
private static final Logger logger = Logger.getLogger(DatastoreOptions.class.getName());
5052
private static final String DATASTORE_SCOPE = "https://www.googleapis.com/auth/datastore";
5153
private static final Set<String> SCOPES = ImmutableSet.of(DATASTORE_SCOPE);
5254
private static final String DEFAULT_DATABASE_ID = "";
@@ -72,9 +74,7 @@ public class DatastoreOptions extends ServiceOptions<Datastore, DatastoreOptions
7274
/**
7375
* @deprecated This constant is obsolete and will be removed in a future version.
7476
*/
75-
@ObsoleteApi("This constant is obsolete and will be removed in a future version.")
76-
@Deprecated
77-
public static final int MAX_CHANNEL_COUNT = 10;
77+
@Deprecated public static final int MAX_CHANNEL_COUNT = 10;
7878

7979
private transient TransportChannelProvider channelProvider = null;
8080

@@ -129,7 +129,10 @@ public static class Builder extends ServiceOptions.Builder<Datastore, DatastoreO
129129
private String databaseId;
130130
private TransportChannelProvider channelProvider = null;
131131
private String host;
132-
private TransportOptions transportOptions;
132+
133+
@Nonnull
134+
private TransportOptions transportOptions =
135+
new DatastoreDefaults().getDefaultTransportOptions();
133136

134137
@Nullable private DatastoreOpenTelemetryOptions openTelemetryOptions = null;
135138

@@ -141,25 +144,51 @@ private Builder(DatastoreOptions options) {
141144
this.databaseId = options.databaseId;
142145
this.openTelemetryOptions = options.openTelemetryOptions;
143146
this.channelProvider = validateChannelProvider(options.channelProvider);
147+
this.host = options.getHost();
148+
this.transportOptions = options.getTransportOptions();
149+
}
150+
151+
private TransportChannelProvider validateChannelProvider(
152+
TransportChannelProvider channelProvider) {
153+
Preconditions.checkNotNull(channelProvider, "TransportChannelProvider cannot be null");
154+
if (!(channelProvider instanceof InstantiatingGrpcChannelProvider)) {
155+
throw new IllegalArgumentException(
156+
"Only GRPC channels are allowed for " + API_SHORT_NAME + ".");
157+
}
158+
return channelProvider;
144159
}
145160

161+
/**
162+
* Sets the transport options.
163+
*
164+
* @param transportOptions the transport options to set, must be {@link HttpTransportOptions} or
165+
* {@link GrpcTransportOptions}
166+
* @return the builder
167+
* @throws IllegalArgumentException if the transport options are not supported
168+
*/
146169
@Override
147-
public Builder setTransportOptions(TransportOptions transportOptions) {
148-
if (!(transportOptions instanceof HttpTransportOptions)) {
170+
public Builder setTransportOptions(@Nonnull TransportOptions transportOptions) {
171+
Preconditions.checkNotNull(transportOptions, "TransportOptions cannot be null");
172+
if (!(transportOptions instanceof HttpTransportOptions)
173+
&& !(transportOptions instanceof GrpcTransportOptions)) {
149174
throw new IllegalArgumentException(
150-
"Only http transport is allowed for " + API_SHORT_NAME + ".");
175+
"Only http and grpc transport are allowed for " + API_SHORT_NAME + ".");
151176
}
152177
this.transportOptions = transportOptions;
153178
return super.setTransportOptions(transportOptions);
154179
}
155180

156181
/**
157-
* Sets the transport to gRPC. Note this functionality is experimental and subject to change.
182+
* This method deprecated. Prefer to use {@link #setTransportOptions(TransportOptions)} instead.
183+
* When using the transport-neutral variant, you may need to cast to TransportOptions when using
184+
* a GrpcTransportOptions class, otherwise it will default to the deprecated method.
185+
*
186+
* <p>Sets the transport to gRPC. Note this functionality is experimental and subject to change.
158187
*/
188+
@Deprecated
159189
@BetaApi
160190
public Builder setTransportOptions(GrpcTransportOptions transportOptions) {
161-
this.transportOptions = transportOptions;
162-
return super.setTransportOptions(transportOptions);
191+
return setTransportOptions((TransportOptions) transportOptions);
163192
}
164193

165194
@Override
@@ -185,10 +214,28 @@ public Builder setChannelProvider(TransportChannelProvider channelProvider) {
185214
return this;
186215
}
187216

217+
/**
218+
* Builds the {@link DatastoreOptions} instance.
219+
*
220+
* <p>If the host is not explicitly set, it defaults to the transport-specific default host:
221+
*
222+
* <ul>
223+
* <li>gRPC: {@code datastore.googleapis.com:443}
224+
* <li>HTTP: {@code https://datastore.googleapis.com}
225+
* </ul>
226+
*
227+
* @return the {@link DatastoreOptions} instance
228+
*/
188229
@Override
189230
public DatastoreOptions build() {
190-
if (this.host == null && this.transportOptions instanceof GrpcTransportOptions) {
191-
this.setHost(DatastoreSettings.getDefaultEndpoint());
231+
if (this.host == null) {
232+
// Use whatever host value the user passes in, otherwise use the transport specific default
233+
// host values
234+
if (this.transportOptions instanceof GrpcTransportOptions) {
235+
this.setHost(DatastoreSettings.getDefaultEndpoint());
236+
} else if (this.transportOptions instanceof HttpTransportOptions) {
237+
this.setHost(com.google.datastore.v1.client.DatastoreFactory.DEFAULT_HOST);
238+
}
192239
}
193240
return new DatastoreOptions(this);
194241
}
@@ -218,15 +265,6 @@ public Builder setOpenTelemetryOptions(
218265
}
219266
}
220267

221-
private static TransportChannelProvider validateChannelProvider(
222-
TransportChannelProvider channelProvider) {
223-
if (channelProvider != null && !(channelProvider instanceof InstantiatingGrpcChannelProvider)) {
224-
throw new IllegalArgumentException(
225-
"Only GRPC channels are allowed for " + API_SHORT_NAME + ".");
226-
}
227-
return channelProvider;
228-
}
229-
230268
private DatastoreOptions(Builder builder) {
231269
super(DatastoreFactory.class, DatastoreRpcFactory.class, builder, new DatastoreDefaults());
232270

@@ -239,9 +277,9 @@ private DatastoreOptions(Builder builder) {
239277
namespace = MoreObjects.firstNonNull(builder.namespace, defaultNamespace());
240278
databaseId = MoreObjects.firstNonNull(builder.databaseId, DEFAULT_DATABASE_ID);
241279

280+
// ChannelProvider is used by GAX but HttpJson does not use it so we safely ignore it.
242281
if (getTransportOptions() instanceof HttpTransportOptions && builder.channelProvider != null) {
243-
throw new IllegalArgumentException(
244-
"Only gRPC transport allows setting of channel provider or credentials provider");
282+
logger.warning("Channel provider is ignored for HttpJson transport.");
245283
} else if (getTransportOptions() instanceof GrpcTransportOptions) {
246284
if (builder.channelProvider == null) {
247285
// Set the default gRPC connection pool to be configured with a minimum of 1 channel.
@@ -310,8 +348,8 @@ public TransportOptions getDefaultTransportOptions() {
310348
return TRANSPORT_OPTIONS;
311349
}
312350

313-
public static HttpTransportOptions.Builder getDefaultTransportOptionsBuilder() {
314-
return HttpTransportOptions.newBuilder();
351+
public static GrpcTransportOptions.Builder getDefaultTransportOptionsBuilder() {
352+
return GrpcTransportOptions.newBuilder();
315353
}
316354
}
317355

java-datastore/google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.google.api.core.InternalApi;
2323
import com.google.cloud.NoCredentials;
2424
import com.google.cloud.ServiceOptions;
25+
import com.google.cloud.TransportOptions;
2526
import com.google.cloud.datastore.DatastoreOptions;
2627
import com.google.cloud.grpc.GrpcTransportOptions;
2728
import com.google.cloud.testing.BaseEmulatorHelper;
@@ -242,11 +243,14 @@ public DatastoreOptions getOptions(String namespace) {
242243
}
243244

244245
/**
245-
* Returns a {@link DatastoreOptions} instance that sets the host to use the Datastore emulator on
246-
* localhost. The transportOptions is set to {@code grpcTransportOptions}.
246+
* Prefer to set the TransportOptions via the Options Builder.
247+
*
248+
* <p>Returns a {@link DatastoreOptions} instance that sets the host to use the Datastore emulator
249+
* on localhost. The transportOptions is set to {@code grpcTransportOptions}.
247250
*/
251+
@Deprecated
248252
public DatastoreOptions getGrpcTransportOptions(GrpcTransportOptions grpcTransportOptions) {
249-
return optionsBuilder.setTransportOptions(grpcTransportOptions).build();
253+
return optionsBuilder.setTransportOptions((TransportOptions) grpcTransportOptions).build();
250254
}
251255

252256
public DatastoreOptions.Builder setNamespace(String namespace) {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.google.api.gax.rpc.StatusCode;
2222
import com.google.cloud.NoCredentials;
2323
import com.google.cloud.ServiceOptions;
24+
import com.google.cloud.TransportOptions;
2425
import com.google.cloud.datastore.spi.DatastoreRpcFactory;
2526
import com.google.cloud.datastore.spi.v1.DatastoreRpc;
2627
import com.google.cloud.datastore.telemetry.DatastoreMetricsRecorder;
@@ -115,7 +116,7 @@ public void setUp() {
115116
.build());
116117

117118
if (TelemetryConstants.Transport.GRPC.equals(transport)) {
118-
builder.setTransportOptions(GrpcTransportOptions.newBuilder().build());
119+
builder.setTransportOptions((TransportOptions) GrpcTransportOptions.newBuilder().build());
119120
} else {
120121
builder.setTransportOptions(HttpTransportOptions.newBuilder().build());
121122
}

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

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@
2727
import com.google.api.gax.grpc.ChannelPoolSettings;
2828
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
2929
import com.google.cloud.NoCredentials;
30+
import com.google.cloud.TransportOptions;
3031
import com.google.cloud.datastore.spi.DatastoreRpcFactory;
3132
import com.google.cloud.datastore.spi.v1.DatastoreRpc;
3233
import com.google.cloud.datastore.v1.DatastoreSettings;
3334
import com.google.cloud.grpc.GrpcTransportOptions;
3435
import com.google.cloud.http.HttpTransportOptions;
3536
import com.google.datastore.v1.client.DatastoreFactory;
3637
import org.easymock.EasyMock;
37-
import org.junit.Assert;
3838
import org.junit.Before;
3939
import org.junit.Test;
4040

@@ -217,7 +217,7 @@ public void testGrpcDefaultChannelConfigurations() {
217217
.setServiceRpcFactory(datastoreRpcFactory)
218218
.setProjectId(PROJECT_ID)
219219
.setDatabaseId(DATABASE_ID)
220-
.setTransportOptions(GrpcTransportOptions.newBuilder().build())
220+
.setTransportOptions((TransportOptions) GrpcTransportOptions.newBuilder().build())
221221
.setCredentials(NoCredentials.getInstance())
222222
.setHost("http://localhost:" + PORT)
223223
.build();
@@ -250,7 +250,7 @@ public void testCustomChannelAndCredentials() {
250250
.setServiceRpcFactory(datastoreRpcFactory)
251251
.setProjectId(PROJECT_ID)
252252
.setDatabaseId(DATABASE_ID)
253-
.setTransportOptions(GrpcTransportOptions.newBuilder().build())
253+
.setTransportOptions((TransportOptions) GrpcTransportOptions.newBuilder().build())
254254
.setChannelProvider(channelProvider)
255255
.setCredentials(NoCredentials.getInstance())
256256
.setHost("http://localhost:" + PORT)
@@ -259,35 +259,23 @@ public void testCustomChannelAndCredentials() {
259259
}
260260

261261
@Test
262-
public void testInvalidConfigForHttp() {
263-
DatastoreOptions.Builder options =
262+
public void testTransport() {
263+
// default grpc transport
264+
assertThat(options.build().getTransportOptions()).isInstanceOf(GrpcTransportOptions.class);
265+
266+
// custom http transport
267+
DatastoreOptions httpTransportOptions =
264268
DatastoreOptions.newBuilder()
265-
.setServiceRpcFactory(datastoreRpcFactory)
266-
.setProjectId(PROJECT_ID)
267-
.setDatabaseId(DATABASE_ID)
268269
.setTransportOptions(HttpTransportOptions.newBuilder().build())
269-
.setChannelProvider(
270-
DatastoreSettings.defaultGrpcTransportProviderBuilder()
271-
.setChannelPoolSettings(
272-
ChannelPoolSettings.builder()
273-
.setInitialChannelCount(10)
274-
.setMaxChannelCount(20)
275-
.build())
276-
.build())
270+
.setProjectId(PROJECT_ID)
277271
.setCredentials(NoCredentials.getInstance())
278-
.setHost("http://localhost:" + PORT);
279-
Assert.assertThrows(IllegalArgumentException.class, options::build);
280-
}
281-
282-
@Test
283-
public void testTransport() {
284-
// default http transport
285-
assertThat(options.build().getTransportOptions()).isInstanceOf(HttpTransportOptions.class);
272+
.build();
273+
assertThat(httpTransportOptions.getTransportOptions()).isInstanceOf(HttpTransportOptions.class);
286274

287275
// custom grpc transport
288276
DatastoreOptions grpcTransportOptions =
289277
DatastoreOptions.newBuilder()
290-
.setTransportOptions(GrpcTransportOptions.newBuilder().build())
278+
.setTransportOptions((TransportOptions) GrpcTransportOptions.newBuilder().build())
291279
.setProjectId(PROJECT_ID)
292280
.setCredentials(NoCredentials.getInstance())
293281
.build();
@@ -300,7 +288,7 @@ public void testTransport() {
300288
public void testHostWithGrpcAndHttp() {
301289
DatastoreOptions grpcTransportOptions =
302290
DatastoreOptions.newBuilder()
303-
.setTransportOptions(GrpcTransportOptions.newBuilder().build())
291+
.setTransportOptions((TransportOptions) GrpcTransportOptions.newBuilder().build())
304292
.setProjectId(PROJECT_ID)
305293
.setCredentials(NoCredentials.getInstance())
306294
.build();
@@ -310,22 +298,31 @@ public void testHostWithGrpcAndHttp() {
310298
String customHost = "http://localhost:" + PORT;
311299
DatastoreOptions grpcTransportOptionsCustomHost =
312300
DatastoreOptions.newBuilder()
313-
.setTransportOptions(GrpcTransportOptions.newBuilder().build())
301+
.setTransportOptions((TransportOptions) GrpcTransportOptions.newBuilder().build())
314302
.setHost(customHost)
315303
.setProjectId(PROJECT_ID)
316304
.setCredentials(NoCredentials.getInstance())
317305
.build();
318306
assertThat(grpcTransportOptionsCustomHost.getHost()).isEqualTo(customHost);
319307

308+
DatastoreOptions defaultTransportOptions =
309+
DatastoreOptions.newBuilder()
310+
.setProjectId(PROJECT_ID)
311+
.setCredentials(NoCredentials.getInstance())
312+
.build();
313+
assertThat(defaultTransportOptions.getHost()).isEqualTo(DatastoreSettings.getDefaultEndpoint());
314+
320315
DatastoreOptions httpTransportOptions =
321316
DatastoreOptions.newBuilder()
317+
.setTransportOptions(HttpTransportOptions.newBuilder().build())
322318
.setProjectId(PROJECT_ID)
323319
.setCredentials(NoCredentials.getInstance())
324320
.build();
325321
assertThat(httpTransportOptions.getHost()).isEqualTo(DatastoreFactory.DEFAULT_HOST);
326322

327323
DatastoreOptions httpTransportOptionsCustomHost =
328324
DatastoreOptions.newBuilder()
325+
.setTransportOptions(HttpTransportOptions.newBuilder().build())
329326
.setHost(customHost)
330327
.setProjectId(PROJECT_ID)
331328
.setCredentials(NoCredentials.getInstance())

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

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

1919
import com.google.cloud.datastore.testing.LocalDatastoreHelper;
20-
import com.google.cloud.grpc.GrpcTransportOptions;
2120
import com.google.common.truth.Truth;
2221
import java.io.IOException;
2322
import java.time.Duration;
@@ -32,8 +31,7 @@ public class DatastoreTestGrpc extends AbstractDatastoreTest {
3231

3332
private static final LocalDatastoreHelper helper = LocalDatastoreHelper.create(1.0, 9090);
3433

35-
private static DatastoreOptions options =
36-
helper.getGrpcTransportOptions(GrpcTransportOptions.newBuilder().build());
34+
private static DatastoreOptions options = helper.getOptions();
3735
private static Datastore datastore = options.getService();
3836

3937
public DatastoreTestGrpc(DatastoreOptions options, Datastore datastore) {
@@ -48,7 +46,7 @@ public static Iterable<Object[]> data() {
4846
@BeforeClass
4947
public static void beforeClass() throws IOException, InterruptedException {
5048
helper.start();
51-
options = helper.getGrpcTransportOptions(GrpcTransportOptions.newBuilder().build());
49+
options = helper.getOptions();
5250
datastore = options.getService();
5351
}
5452

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
package com.google.cloud.datastore;
1818

1919
import com.google.cloud.datastore.testing.LocalDatastoreHelper;
20-
import com.google.cloud.grpc.GrpcTransportOptions;
20+
import com.google.cloud.http.HttpTransportOptions;
2121
import java.io.IOException;
2222
import java.time.Duration;
2323
import java.util.Arrays;
@@ -46,7 +46,10 @@ public static Iterable<Object[]> data() {
4646
@BeforeClass
4747
public static void beforeClass() throws IOException, InterruptedException {
4848
helper.start();
49-
options = helper.getGrpcTransportOptions(GrpcTransportOptions.newBuilder().build());
49+
options =
50+
helper.getOptions().toBuilder()
51+
.setTransportOptions(HttpTransportOptions.newBuilder().build())
52+
.build();
5053
datastore = options.getService();
5154
}
5255

0 commit comments

Comments
 (0)