From 0f79a32c0d969425e5342da086f29adcb0c03d6c Mon Sep 17 00:00:00 2001 From: Prateek Date: Thu, 16 Nov 2023 21:34:31 +0530 Subject: [PATCH 01/42] chore: Importing auto-generated code from googleapis-gen (#1235) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Script to setup generated code from googleapis-gen * fixing script and gitignore * adding generated code * add maven config for new grpc module * fixing script * owlbot config to fetch grpc and gapic modules for V1 * fix lint * Revert "add maven config for new grpc module" This reverts commit 7769d8083a84f3ae9255c51c3ecb01fbfdd49320. * Reapply "add maven config for new grpc module" This reverts commit 759475d121afa772f66f549958e8b092cf3c5f0a. * remove unused dependency * fix library version * fix library version * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * removing exclusion of grpc-google-cloud-datastore-v1 module from repo metadata * 🦉 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 --- .github/.OwlBot.yaml | 6 +- .gitignore | 2 +- .repo-metadata.json | 4 +- google-cloud-datastore-bom/pom.xml | 5 + google-cloud-datastore/pom.xml | 4 + .../cloud/datastore/v1/DatastoreClient.java | 947 +++++++ .../cloud/datastore/v1/DatastoreSettings.java | 294 +++ .../cloud/datastore/v1/gapic_metadata.json | 42 + .../cloud/datastore/v1/package-info.java | 49 + .../datastore/v1/stub/DatastoreStub.java | 84 + .../v1/stub/DatastoreStubSettings.java | 518 ++++ .../v1/stub/GrpcDatastoreCallableFactory.java | 113 + .../datastore/v1/stub/GrpcDatastoreStub.java | 429 ++++ .../HttpJsonDatastoreCallableFactory.java | 105 + .../v1/stub/HttpJsonDatastoreStub.java | 678 +++++ .../reflect-config.json | 2198 +++++++++++++++++ .../v1/DatastoreClientHttpJsonTest.java | 538 ++++ .../datastore/v1/DatastoreClientTest.java | 514 ++++ .../cloud/datastore/v1/MockDatastore.java | 59 + .../cloud/datastore/v1/MockDatastoreImpl.java | 241 ++ grpc-google-cloud-datastore-v1/pom.xml | 81 + .../google/datastore/v1/DatastoreGrpc.java | 1194 +++++++++ pom.xml | 6 + pull-gapic-grpc.sh | 42 + versions.txt | 1 + 25 files changed, 8149 insertions(+), 5 deletions(-) create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/DatastoreClient.java create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/DatastoreSettings.java create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/gapic_metadata.json create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/package-info.java create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/DatastoreStub.java create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/DatastoreStubSettings.java create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/GrpcDatastoreCallableFactory.java create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/GrpcDatastoreStub.java create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/HttpJsonDatastoreCallableFactory.java create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/HttpJsonDatastoreStub.java create mode 100644 google-cloud-datastore/src/main/resources/META-INF/native-image/com.google.cloud.datastore.v1/reflect-config.json create mode 100644 google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/DatastoreClientHttpJsonTest.java create mode 100644 google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/DatastoreClientTest.java create mode 100644 google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/MockDatastore.java create mode 100644 google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/MockDatastoreImpl.java create mode 100644 grpc-google-cloud-datastore-v1/pom.xml create mode 100644 grpc-google-cloud-datastore-v1/src/main/java/com/google/datastore/v1/DatastoreGrpc.java create mode 100644 pull-gapic-grpc.sh diff --git a/.github/.OwlBot.yaml b/.github/.OwlBot.yaml index d89045599..76eece042 100644 --- a/.github/.OwlBot.yaml +++ b/.github/.OwlBot.yaml @@ -25,8 +25,12 @@ deep-copy-regex: dest: "/owl-bot-staging/$1/proto-google-cloud-datastore-$1/src" - source: "/google/datastore/admin/(v.*)/.*-java/proto-google-.*/src" dest: "/owl-bot-staging/$1/proto-google-cloud-datastore-admin-$1/src" +- source: "/google/datastore/(v.*)/.*-java/grpc-google-.*/src" + dest: "/owl-bot-staging/$1/grpc-google-cloud-datastore-$1/src" - source: "/google/datastore/admin/(v.*)/.*-java/grpc-google-.*/src" dest: "/owl-bot-staging/$1/grpc-google-cloud-datastore-admin-$1/src" # Admin & Data APIs share the same wrapper library. +- source: "/google/datastore/(v.*)/.*-java/gapic-google-.*/src" + dest: "/owl-bot-staging/$1/google-cloud-datastore/src" - source: "/google/datastore/admin/(v.*)/.*-java/gapic-google-.*/src" - dest: "/owl-bot-staging/$1/google-cloud-datastore/src" \ No newline at end of file + dest: "/owl-bot-staging/$1/google-cloud-datastore/src" diff --git a/.gitignore b/.gitignore index 6f5e4424d..241f84417 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ target/ *.iml __pycache__/ -.flattened-pom.xml \ No newline at end of file +.flattened-pom.xml diff --git a/.repo-metadata.json b/.repo-metadata.json index 1d382e4ed..d5f4a9450 100644 --- a/.repo-metadata.json +++ b/.repo-metadata.json @@ -13,7 +13,5 @@ "api_id": "datastore.googleapis.com", "library_type": "GAPIC_COMBO", "api_description": "is a fully managed, schemaless database for\nstoring non-relational data. Cloud Datastore automatically scales with\nyour users and supports ACID transactions, high availability of reads and\nwrites, strong consistency for reads and ancestor queries, and eventual\nconsistency for all other queries.", - "excluded_dependencies": "grpc-google-cloud-datastore-v1", - "extra_versioned_modules": "datastore-v1-proto-client", - "excluded_poms": "grpc-google-cloud-datastore-v1" + "extra_versioned_modules": "datastore-v1-proto-client" } diff --git a/google-cloud-datastore-bom/pom.xml b/google-cloud-datastore-bom/pom.xml index e6ead0506..2105a8caa 100644 --- a/google-cloud-datastore-bom/pom.xml +++ b/google-cloud-datastore-bom/pom.xml @@ -59,6 +59,11 @@ grpc-google-cloud-datastore-admin-v1 2.17.6-SNAPSHOT + + com.google.api.grpc + grpc-google-cloud-datastore-v1 + 2.17.6-SNAPSHOT + com.google.api.grpc proto-google-cloud-datastore-v1 diff --git a/google-cloud-datastore/pom.xml b/google-cloud-datastore/pom.xml index 9c16ae06b..fc1e45ef1 100644 --- a/google-cloud-datastore/pom.xml +++ b/google-cloud-datastore/pom.xml @@ -18,6 +18,10 @@ google-cloud-datastore + + com.google.api.grpc + grpc-google-cloud-datastore-v1 + com.google.api.grpc grpc-google-cloud-datastore-admin-v1 diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/DatastoreClient.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/DatastoreClient.java new file mode 100644 index 000000000..ad988b32d --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/DatastoreClient.java @@ -0,0 +1,947 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.v1; + +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.datastore.v1.stub.DatastoreStub; +import com.google.cloud.datastore.v1.stub.DatastoreStubSettings; +import com.google.datastore.v1.AllocateIdsRequest; +import com.google.datastore.v1.AllocateIdsResponse; +import com.google.datastore.v1.BeginTransactionRequest; +import com.google.datastore.v1.BeginTransactionResponse; +import com.google.datastore.v1.CommitRequest; +import com.google.datastore.v1.CommitResponse; +import com.google.datastore.v1.Key; +import com.google.datastore.v1.LookupRequest; +import com.google.datastore.v1.LookupResponse; +import com.google.datastore.v1.Mutation; +import com.google.datastore.v1.ReadOptions; +import com.google.datastore.v1.ReserveIdsRequest; +import com.google.datastore.v1.ReserveIdsResponse; +import com.google.datastore.v1.RollbackRequest; +import com.google.datastore.v1.RollbackResponse; +import com.google.datastore.v1.RunAggregationQueryRequest; +import com.google.datastore.v1.RunAggregationQueryResponse; +import com.google.datastore.v1.RunQueryRequest; +import com.google.datastore.v1.RunQueryResponse; +import com.google.protobuf.ByteString; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Service Description: Each RPC normalizes the partition IDs of the keys in its input entities, and + * always returns entities with keys with normalized partition IDs. This applies to all keys and + * entities, including those in values, except keys with both an empty path and an empty or unset + * partition ID. Normalization of input keys sets the project ID (if not already set) to the project + * ID from the request. + * + *

This class provides the ability to make remote calls to the backing service through method + * calls that map to API methods. Sample code to get started: + * + *

{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+ *   String projectId = "projectId-894832108";
+ *   ReadOptions readOptions = ReadOptions.newBuilder().build();
+ *   List keys = new ArrayList<>();
+ *   LookupResponse response = datastoreClient.lookup(projectId, readOptions, keys);
+ * }
+ * }
+ * + *

Note: close() needs to be called on the DatastoreClient object to clean up resources such as + * threads. In the example above, try-with-resources is used, which automatically calls close(). + * + *

The surface of this class includes several types of Java methods for each of the API's + * methods: + * + *

    + *
  1. A "flattened" method. With this type of method, the fields of the request type have been + * converted into function parameters. It may be the case that not all fields are available as + * parameters, and not every API method will have a flattened method entry point. + *
  2. A "request object" method. This type of method only takes one parameter, a request object, + * which must be constructed before the call. Not every API method will have a request object + * method. + *
  3. A "callable" method. This type of method takes no parameters and returns an immutable API + * callable object, which can be used to initiate calls to the service. + *
+ * + *

See the individual methods for example code. + * + *

Many parameters require resource names to be formatted in a particular way. To assist with + * these names, this class includes a format method for each type of name, and additionally a parse + * method to extract the individual identifiers contained within names that are returned. + * + *

This class can be customized by passing in a custom instance of DatastoreSettings to create(). + * For example: + * + *

To customize credentials: + * + *

{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * DatastoreSettings datastoreSettings =
+ *     DatastoreSettings.newBuilder()
+ *         .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials))
+ *         .build();
+ * DatastoreClient datastoreClient = DatastoreClient.create(datastoreSettings);
+ * }
+ * + *

To customize the endpoint: + * + *

{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * DatastoreSettings datastoreSettings =
+ *     DatastoreSettings.newBuilder().setEndpoint(myEndpoint).build();
+ * DatastoreClient datastoreClient = DatastoreClient.create(datastoreSettings);
+ * }
+ * + *

To use REST (HTTP1.1/JSON) transport (instead of gRPC) for sending and receiving requests over + * the wire: + * + *

{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * DatastoreSettings datastoreSettings = DatastoreSettings.newHttpJsonBuilder().build();
+ * DatastoreClient datastoreClient = DatastoreClient.create(datastoreSettings);
+ * }
+ * + *

Please refer to the GitHub repository's samples for more quickstart code snippets. + */ +@Generated("by gapic-generator-java") +public class DatastoreClient implements BackgroundResource { + private final DatastoreSettings settings; + private final DatastoreStub stub; + + /** Constructs an instance of DatastoreClient with default settings. */ + public static final DatastoreClient create() throws IOException { + return create(DatastoreSettings.newBuilder().build()); + } + + /** + * Constructs an instance of DatastoreClient, using the given settings. The channels are created + * based on the settings passed in, or defaults for any settings that are not set. + */ + public static final DatastoreClient create(DatastoreSettings settings) throws IOException { + return new DatastoreClient(settings); + } + + /** + * Constructs an instance of DatastoreClient, using the given stub for making calls. This is for + * advanced usage - prefer using create(DatastoreSettings). + */ + public static final DatastoreClient create(DatastoreStub stub) { + return new DatastoreClient(stub); + } + + /** + * Constructs an instance of DatastoreClient, using the given settings. This is protected so that + * it is easy to make a subclass, but otherwise, the static factory methods should be preferred. + */ + protected DatastoreClient(DatastoreSettings settings) throws IOException { + this.settings = settings; + this.stub = ((DatastoreStubSettings) settings.getStubSettings()).createStub(); + } + + protected DatastoreClient(DatastoreStub stub) { + this.settings = null; + this.stub = stub; + } + + public final DatastoreSettings getSettings() { + return settings; + } + + public DatastoreStub getStub() { + return stub; + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Looks up entities by key. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   String projectId = "projectId-894832108";
+   *   ReadOptions readOptions = ReadOptions.newBuilder().build();
+   *   List keys = new ArrayList<>();
+   *   LookupResponse response = datastoreClient.lookup(projectId, readOptions, keys);
+   * }
+   * }
+ * + * @param projectId Required. The ID of the project against which to make the request. + * @param readOptions The options for this lookup request. + * @param keys Required. Keys of entities to look up. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final LookupResponse lookup(String projectId, ReadOptions readOptions, List keys) { + LookupRequest request = + LookupRequest.newBuilder() + .setProjectId(projectId) + .setReadOptions(readOptions) + .addAllKeys(keys) + .build(); + return lookup(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Looks up entities by key. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   LookupRequest request =
+   *       LookupRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .setReadOptions(ReadOptions.newBuilder().build())
+   *           .addAllKeys(new ArrayList())
+   *           .build();
+   *   LookupResponse response = datastoreClient.lookup(request);
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final LookupResponse lookup(LookupRequest request) { + return lookupCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Looks up entities by key. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   LookupRequest request =
+   *       LookupRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .setReadOptions(ReadOptions.newBuilder().build())
+   *           .addAllKeys(new ArrayList())
+   *           .build();
+   *   ApiFuture future = datastoreClient.lookupCallable().futureCall(request);
+   *   // Do something.
+   *   LookupResponse response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable lookupCallable() { + return stub.lookupCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Queries for entities. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   RunQueryRequest request =
+   *       RunQueryRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .setPartitionId(PartitionId.newBuilder().build())
+   *           .setReadOptions(ReadOptions.newBuilder().build())
+   *           .build();
+   *   RunQueryResponse response = datastoreClient.runQuery(request);
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final RunQueryResponse runQuery(RunQueryRequest request) { + return runQueryCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Queries for entities. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   RunQueryRequest request =
+   *       RunQueryRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .setPartitionId(PartitionId.newBuilder().build())
+   *           .setReadOptions(ReadOptions.newBuilder().build())
+   *           .build();
+   *   ApiFuture future = datastoreClient.runQueryCallable().futureCall(request);
+   *   // Do something.
+   *   RunQueryResponse response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable runQueryCallable() { + return stub.runQueryCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Runs an aggregation query. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   RunAggregationQueryRequest request =
+   *       RunAggregationQueryRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .setPartitionId(PartitionId.newBuilder().build())
+   *           .setReadOptions(ReadOptions.newBuilder().build())
+   *           .build();
+   *   RunAggregationQueryResponse response = datastoreClient.runAggregationQuery(request);
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final RunAggregationQueryResponse runAggregationQuery(RunAggregationQueryRequest request) { + return runAggregationQueryCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Runs an aggregation query. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   RunAggregationQueryRequest request =
+   *       RunAggregationQueryRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .setPartitionId(PartitionId.newBuilder().build())
+   *           .setReadOptions(ReadOptions.newBuilder().build())
+   *           .build();
+   *   ApiFuture future =
+   *       datastoreClient.runAggregationQueryCallable().futureCall(request);
+   *   // Do something.
+   *   RunAggregationQueryResponse response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable + runAggregationQueryCallable() { + return stub.runAggregationQueryCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Begins a new transaction. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   String projectId = "projectId-894832108";
+   *   BeginTransactionResponse response = datastoreClient.beginTransaction(projectId);
+   * }
+   * }
+ * + * @param projectId Required. The ID of the project against which to make the request. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final BeginTransactionResponse beginTransaction(String projectId) { + BeginTransactionRequest request = + BeginTransactionRequest.newBuilder().setProjectId(projectId).build(); + return beginTransaction(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Begins a new transaction. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   BeginTransactionRequest request =
+   *       BeginTransactionRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .setTransactionOptions(TransactionOptions.newBuilder().build())
+   *           .build();
+   *   BeginTransactionResponse response = datastoreClient.beginTransaction(request);
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final BeginTransactionResponse beginTransaction(BeginTransactionRequest request) { + return beginTransactionCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Begins a new transaction. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   BeginTransactionRequest request =
+   *       BeginTransactionRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .setTransactionOptions(TransactionOptions.newBuilder().build())
+   *           .build();
+   *   ApiFuture future =
+   *       datastoreClient.beginTransactionCallable().futureCall(request);
+   *   // Do something.
+   *   BeginTransactionResponse response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable + beginTransactionCallable() { + return stub.beginTransactionCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Commits a transaction, optionally creating, deleting or modifying some entities. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   String projectId = "projectId-894832108";
+   *   CommitRequest.Mode mode = CommitRequest.Mode.forNumber(0);
+   *   List mutations = new ArrayList<>();
+   *   CommitResponse response = datastoreClient.commit(projectId, mode, mutations);
+   * }
+   * }
+ * + * @param projectId Required. The ID of the project against which to make the request. + * @param mode The type of commit to perform. Defaults to `TRANSACTIONAL`. + * @param mutations The mutations to perform. + *

When mode is `TRANSACTIONAL`, mutations affecting a single entity are applied in order. + * The following sequences of mutations affecting a single entity are not permitted in a + * single `Commit` request: + *

- `insert` followed by `insert` - `update` followed by `insert` - `upsert` followed by + * `insert` - `delete` followed by `update` + *

When mode is `NON_TRANSACTIONAL`, no two mutations may affect a single entity. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final CommitResponse commit( + String projectId, CommitRequest.Mode mode, List mutations) { + CommitRequest request = + CommitRequest.newBuilder() + .setProjectId(projectId) + .setMode(mode) + .addAllMutations(mutations) + .build(); + return commit(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Commits a transaction, optionally creating, deleting or modifying some entities. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   String projectId = "projectId-894832108";
+   *   CommitRequest.Mode mode = CommitRequest.Mode.forNumber(0);
+   *   ByteString transaction = ByteString.EMPTY;
+   *   List mutations = new ArrayList<>();
+   *   CommitResponse response = datastoreClient.commit(projectId, mode, transaction, mutations);
+   * }
+   * }
+ * + * @param projectId Required. The ID of the project against which to make the request. + * @param mode The type of commit to perform. Defaults to `TRANSACTIONAL`. + * @param transaction The identifier of the transaction associated with the commit. A transaction + * identifier is returned by a call to + * [Datastore.BeginTransaction][google.datastore.v1.Datastore.BeginTransaction]. + * @param mutations The mutations to perform. + *

When mode is `TRANSACTIONAL`, mutations affecting a single entity are applied in order. + * The following sequences of mutations affecting a single entity are not permitted in a + * single `Commit` request: + *

- `insert` followed by `insert` - `update` followed by `insert` - `upsert` followed by + * `insert` - `delete` followed by `update` + *

When mode is `NON_TRANSACTIONAL`, no two mutations may affect a single entity. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final CommitResponse commit( + String projectId, CommitRequest.Mode mode, ByteString transaction, List mutations) { + CommitRequest request = + CommitRequest.newBuilder() + .setProjectId(projectId) + .setMode(mode) + .setTransaction(transaction) + .addAllMutations(mutations) + .build(); + return commit(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Commits a transaction, optionally creating, deleting or modifying some entities. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   CommitRequest request =
+   *       CommitRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .addAllMutations(new ArrayList())
+   *           .build();
+   *   CommitResponse response = datastoreClient.commit(request);
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final CommitResponse commit(CommitRequest request) { + return commitCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Commits a transaction, optionally creating, deleting or modifying some entities. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   CommitRequest request =
+   *       CommitRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .addAllMutations(new ArrayList())
+   *           .build();
+   *   ApiFuture future = datastoreClient.commitCallable().futureCall(request);
+   *   // Do something.
+   *   CommitResponse response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable commitCallable() { + return stub.commitCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Rolls back a transaction. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   String projectId = "projectId-894832108";
+   *   ByteString transaction = ByteString.EMPTY;
+   *   RollbackResponse response = datastoreClient.rollback(projectId, transaction);
+   * }
+   * }
+ * + * @param projectId Required. The ID of the project against which to make the request. + * @param transaction Required. The transaction identifier, returned by a call to + * [Datastore.BeginTransaction][google.datastore.v1.Datastore.BeginTransaction]. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final RollbackResponse rollback(String projectId, ByteString transaction) { + RollbackRequest request = + RollbackRequest.newBuilder().setProjectId(projectId).setTransaction(transaction).build(); + return rollback(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Rolls back a transaction. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   RollbackRequest request =
+   *       RollbackRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .setTransaction(ByteString.EMPTY)
+   *           .build();
+   *   RollbackResponse response = datastoreClient.rollback(request);
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final RollbackResponse rollback(RollbackRequest request) { + return rollbackCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Rolls back a transaction. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   RollbackRequest request =
+   *       RollbackRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .setTransaction(ByteString.EMPTY)
+   *           .build();
+   *   ApiFuture future = datastoreClient.rollbackCallable().futureCall(request);
+   *   // Do something.
+   *   RollbackResponse response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable rollbackCallable() { + return stub.rollbackCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Allocates IDs for the given keys, which is useful for referencing an entity before it is + * inserted. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   String projectId = "projectId-894832108";
+   *   List keys = new ArrayList<>();
+   *   AllocateIdsResponse response = datastoreClient.allocateIds(projectId, keys);
+   * }
+   * }
+ * + * @param projectId Required. The ID of the project against which to make the request. + * @param keys Required. A list of keys with incomplete key paths for which to allocate IDs. No + * key may be reserved/read-only. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final AllocateIdsResponse allocateIds(String projectId, List keys) { + AllocateIdsRequest request = + AllocateIdsRequest.newBuilder().setProjectId(projectId).addAllKeys(keys).build(); + return allocateIds(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Allocates IDs for the given keys, which is useful for referencing an entity before it is + * inserted. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   AllocateIdsRequest request =
+   *       AllocateIdsRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .addAllKeys(new ArrayList())
+   *           .build();
+   *   AllocateIdsResponse response = datastoreClient.allocateIds(request);
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final AllocateIdsResponse allocateIds(AllocateIdsRequest request) { + return allocateIdsCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Allocates IDs for the given keys, which is useful for referencing an entity before it is + * inserted. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   AllocateIdsRequest request =
+   *       AllocateIdsRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .addAllKeys(new ArrayList())
+   *           .build();
+   *   ApiFuture future =
+   *       datastoreClient.allocateIdsCallable().futureCall(request);
+   *   // Do something.
+   *   AllocateIdsResponse response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable allocateIdsCallable() { + return stub.allocateIdsCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Prevents the supplied keys' IDs from being auto-allocated by Cloud Datastore. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   String projectId = "projectId-894832108";
+   *   List keys = new ArrayList<>();
+   *   ReserveIdsResponse response = datastoreClient.reserveIds(projectId, keys);
+   * }
+   * }
+ * + * @param projectId Required. The ID of the project against which to make the request. + * @param keys Required. A list of keys with complete key paths whose numeric IDs should not be + * auto-allocated. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final ReserveIdsResponse reserveIds(String projectId, List keys) { + ReserveIdsRequest request = + ReserveIdsRequest.newBuilder().setProjectId(projectId).addAllKeys(keys).build(); + return reserveIds(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Prevents the supplied keys' IDs from being auto-allocated by Cloud Datastore. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   ReserveIdsRequest request =
+   *       ReserveIdsRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .addAllKeys(new ArrayList())
+   *           .build();
+   *   ReserveIdsResponse response = datastoreClient.reserveIds(request);
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final ReserveIdsResponse reserveIds(ReserveIdsRequest request) { + return reserveIdsCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Prevents the supplied keys' IDs from being auto-allocated by Cloud Datastore. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+   *   ReserveIdsRequest request =
+   *       ReserveIdsRequest.newBuilder()
+   *           .setProjectId("projectId-894832108")
+   *           .setDatabaseId("databaseId1688905718")
+   *           .addAllKeys(new ArrayList())
+   *           .build();
+   *   ApiFuture future =
+   *       datastoreClient.reserveIdsCallable().futureCall(request);
+   *   // Do something.
+   *   ReserveIdsResponse response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable reserveIdsCallable() { + return stub.reserveIdsCallable(); + } + + @Override + public final void close() { + stub.close(); + } + + @Override + public void shutdown() { + stub.shutdown(); + } + + @Override + public boolean isShutdown() { + return stub.isShutdown(); + } + + @Override + public boolean isTerminated() { + return stub.isTerminated(); + } + + @Override + public void shutdownNow() { + stub.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return stub.awaitTermination(duration, unit); + } +} diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/DatastoreSettings.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/DatastoreSettings.java new file mode 100644 index 000000000..22feacdce --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/DatastoreSettings.java @@ -0,0 +1,294 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.v1; + +import com.google.api.core.ApiFunction; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.GoogleCredentialsProvider; +import com.google.api.gax.core.InstantiatingExecutorProvider; +import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ClientSettings; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.cloud.datastore.v1.stub.DatastoreStubSettings; +import com.google.datastore.v1.AllocateIdsRequest; +import com.google.datastore.v1.AllocateIdsResponse; +import com.google.datastore.v1.BeginTransactionRequest; +import com.google.datastore.v1.BeginTransactionResponse; +import com.google.datastore.v1.CommitRequest; +import com.google.datastore.v1.CommitResponse; +import com.google.datastore.v1.LookupRequest; +import com.google.datastore.v1.LookupResponse; +import com.google.datastore.v1.ReserveIdsRequest; +import com.google.datastore.v1.ReserveIdsResponse; +import com.google.datastore.v1.RollbackRequest; +import com.google.datastore.v1.RollbackResponse; +import com.google.datastore.v1.RunAggregationQueryRequest; +import com.google.datastore.v1.RunAggregationQueryResponse; +import com.google.datastore.v1.RunQueryRequest; +import com.google.datastore.v1.RunQueryResponse; +import java.io.IOException; +import java.util.List; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Settings class to configure an instance of {@link DatastoreClient}. + * + *

The default instance has everything set to sensible defaults: + * + *

    + *
  • The default service address (datastore.googleapis.com) and default port (443) are used. + *
  • Credentials are acquired automatically through Application Default Credentials. + *
  • Retries are configured for idempotent methods but not for non-idempotent methods. + *
+ * + *

The builder of this class is recursive, so contained classes are themselves builders. When + * build() is called, the tree of builders is called to create the complete settings object. + * + *

For example, to set the total timeout of lookup to 30 seconds: + * + *

{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * DatastoreSettings.Builder datastoreSettingsBuilder = DatastoreSettings.newBuilder();
+ * datastoreSettingsBuilder
+ *     .lookupSettings()
+ *     .setRetrySettings(
+ *         datastoreSettingsBuilder
+ *             .lookupSettings()
+ *             .getRetrySettings()
+ *             .toBuilder()
+ *             .setTotalTimeout(Duration.ofSeconds(30))
+ *             .build());
+ * DatastoreSettings datastoreSettings = datastoreSettingsBuilder.build();
+ * }
+ */ +@Generated("by gapic-generator-java") +public class DatastoreSettings extends ClientSettings { + + /** Returns the object with the settings used for calls to lookup. */ + public UnaryCallSettings lookupSettings() { + return ((DatastoreStubSettings) getStubSettings()).lookupSettings(); + } + + /** Returns the object with the settings used for calls to runQuery. */ + public UnaryCallSettings runQuerySettings() { + return ((DatastoreStubSettings) getStubSettings()).runQuerySettings(); + } + + /** Returns the object with the settings used for calls to runAggregationQuery. */ + public UnaryCallSettings + runAggregationQuerySettings() { + return ((DatastoreStubSettings) getStubSettings()).runAggregationQuerySettings(); + } + + /** Returns the object with the settings used for calls to beginTransaction. */ + public UnaryCallSettings + beginTransactionSettings() { + return ((DatastoreStubSettings) getStubSettings()).beginTransactionSettings(); + } + + /** Returns the object with the settings used for calls to commit. */ + public UnaryCallSettings commitSettings() { + return ((DatastoreStubSettings) getStubSettings()).commitSettings(); + } + + /** Returns the object with the settings used for calls to rollback. */ + public UnaryCallSettings rollbackSettings() { + return ((DatastoreStubSettings) getStubSettings()).rollbackSettings(); + } + + /** Returns the object with the settings used for calls to allocateIds. */ + public UnaryCallSettings allocateIdsSettings() { + return ((DatastoreStubSettings) getStubSettings()).allocateIdsSettings(); + } + + /** Returns the object with the settings used for calls to reserveIds. */ + public UnaryCallSettings reserveIdsSettings() { + return ((DatastoreStubSettings) getStubSettings()).reserveIdsSettings(); + } + + public static final DatastoreSettings create(DatastoreStubSettings stub) throws IOException { + return new DatastoreSettings.Builder(stub.toBuilder()).build(); + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return DatastoreStubSettings.defaultExecutorProviderBuilder(); + } + + /** Returns the default service endpoint. */ + public static String getDefaultEndpoint() { + return DatastoreStubSettings.getDefaultEndpoint(); + } + + /** Returns the default service scopes. */ + public static List getDefaultServiceScopes() { + return DatastoreStubSettings.getDefaultServiceScopes(); + } + + /** Returns a builder for the default credentials for this service. */ + public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { + return DatastoreStubSettings.defaultCredentialsProviderBuilder(); + } + + /** Returns a builder for the default gRPC ChannelProvider for this service. */ + public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() { + return DatastoreStubSettings.defaultGrpcTransportProviderBuilder(); + } + + /** Returns a builder for the default REST ChannelProvider for this service. */ + @BetaApi + public static InstantiatingHttpJsonChannelProvider.Builder + defaultHttpJsonTransportProviderBuilder() { + return DatastoreStubSettings.defaultHttpJsonTransportProviderBuilder(); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return DatastoreStubSettings.defaultTransportChannelProvider(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return DatastoreStubSettings.defaultApiClientHeaderProviderBuilder(); + } + + /** Returns a new gRPC builder for this class. */ + public static Builder newBuilder() { + return Builder.createDefault(); + } + + /** Returns a new REST builder for this class. */ + @BetaApi + public static Builder newHttpJsonBuilder() { + return Builder.createHttpJsonDefault(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder(ClientContext clientContext) { + return new Builder(clientContext); + } + + /** Returns a builder containing all the values of this settings class. */ + public Builder toBuilder() { + return new Builder(this); + } + + protected DatastoreSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + } + + /** Builder for DatastoreSettings. */ + public static class Builder extends ClientSettings.Builder { + + protected Builder() throws IOException { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(DatastoreStubSettings.newBuilder(clientContext)); + } + + protected Builder(DatastoreSettings settings) { + super(settings.getStubSettings().toBuilder()); + } + + protected Builder(DatastoreStubSettings.Builder stubSettings) { + super(stubSettings); + } + + private static Builder createDefault() { + return new Builder(DatastoreStubSettings.newBuilder()); + } + + @BetaApi + private static Builder createHttpJsonDefault() { + return new Builder(DatastoreStubSettings.newHttpJsonBuilder()); + } + + public DatastoreStubSettings.Builder getStubSettingsBuilder() { + return ((DatastoreStubSettings.Builder) getStubSettings()); + } + + /** + * Applies the given settings updater function to all of the unary API methods in this service. + * + *

Note: This method does not support applying settings to streaming methods. + */ + public Builder applyToAllUnaryMethods( + ApiFunction, Void> settingsUpdater) { + super.applyToAllUnaryMethods( + getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); + return this; + } + + /** Returns the builder for the settings used for calls to lookup. */ + public UnaryCallSettings.Builder lookupSettings() { + return getStubSettingsBuilder().lookupSettings(); + } + + /** Returns the builder for the settings used for calls to runQuery. */ + public UnaryCallSettings.Builder runQuerySettings() { + return getStubSettingsBuilder().runQuerySettings(); + } + + /** Returns the builder for the settings used for calls to runAggregationQuery. */ + public UnaryCallSettings.Builder + runAggregationQuerySettings() { + return getStubSettingsBuilder().runAggregationQuerySettings(); + } + + /** Returns the builder for the settings used for calls to beginTransaction. */ + public UnaryCallSettings.Builder + beginTransactionSettings() { + return getStubSettingsBuilder().beginTransactionSettings(); + } + + /** Returns the builder for the settings used for calls to commit. */ + public UnaryCallSettings.Builder commitSettings() { + return getStubSettingsBuilder().commitSettings(); + } + + /** Returns the builder for the settings used for calls to rollback. */ + public UnaryCallSettings.Builder rollbackSettings() { + return getStubSettingsBuilder().rollbackSettings(); + } + + /** Returns the builder for the settings used for calls to allocateIds. */ + public UnaryCallSettings.Builder + allocateIdsSettings() { + return getStubSettingsBuilder().allocateIdsSettings(); + } + + /** Returns the builder for the settings used for calls to reserveIds. */ + public UnaryCallSettings.Builder reserveIdsSettings() { + return getStubSettingsBuilder().reserveIdsSettings(); + } + + @Override + public DatastoreSettings build() throws IOException { + return new DatastoreSettings(this); + } + } +} diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/gapic_metadata.json b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/gapic_metadata.json new file mode 100644 index 000000000..02196d36e --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/gapic_metadata.json @@ -0,0 +1,42 @@ +{ + "schema": "1.0", + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "java", + "protoPackage": "google.datastore.v1", + "libraryPackage": "com.google.cloud.datastore.v1", + "services": { + "Datastore": { + "clients": { + "grpc": { + "libraryClient": "DatastoreClient", + "rpcs": { + "AllocateIds": { + "methods": ["allocateIds", "allocateIds", "allocateIdsCallable"] + }, + "BeginTransaction": { + "methods": ["beginTransaction", "beginTransaction", "beginTransactionCallable"] + }, + "Commit": { + "methods": ["commit", "commit", "commit", "commitCallable"] + }, + "Lookup": { + "methods": ["lookup", "lookup", "lookupCallable"] + }, + "ReserveIds": { + "methods": ["reserveIds", "reserveIds", "reserveIdsCallable"] + }, + "Rollback": { + "methods": ["rollback", "rollback", "rollbackCallable"] + }, + "RunAggregationQuery": { + "methods": ["runAggregationQuery", "runAggregationQueryCallable"] + }, + "RunQuery": { + "methods": ["runQuery", "runQueryCallable"] + } + } + } + } + } + } +} \ No newline at end of file diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/package-info.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/package-info.java new file mode 100644 index 000000000..2227971ca --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/package-info.java @@ -0,0 +1,49 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * A client to Cloud Datastore API + * + *

The interfaces provided are listed below, along with usage samples. + * + *

======================= DatastoreClient ======================= + * + *

Service Description: Each RPC normalizes the partition IDs of the keys in its input entities, + * and always returns entities with keys with normalized partition IDs. This applies to all keys and + * entities, including those in values, except keys with both an empty path and an empty or unset + * partition ID. Normalization of input keys sets the project ID (if not already set) to the project + * ID from the request. + * + *

Sample for DatastoreClient: + * + *

{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (DatastoreClient datastoreClient = DatastoreClient.create()) {
+ *   String projectId = "projectId-894832108";
+ *   ReadOptions readOptions = ReadOptions.newBuilder().build();
+ *   List keys = new ArrayList<>();
+ *   LookupResponse response = datastoreClient.lookup(projectId, readOptions, keys);
+ * }
+ * }
+ */ +@Generated("by gapic-generator-java") +package com.google.cloud.datastore.v1; + +import javax.annotation.Generated; diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/DatastoreStub.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/DatastoreStub.java new file mode 100644 index 000000000..3b2b170bd --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/DatastoreStub.java @@ -0,0 +1,84 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.v1.stub; + +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.datastore.v1.AllocateIdsRequest; +import com.google.datastore.v1.AllocateIdsResponse; +import com.google.datastore.v1.BeginTransactionRequest; +import com.google.datastore.v1.BeginTransactionResponse; +import com.google.datastore.v1.CommitRequest; +import com.google.datastore.v1.CommitResponse; +import com.google.datastore.v1.LookupRequest; +import com.google.datastore.v1.LookupResponse; +import com.google.datastore.v1.ReserveIdsRequest; +import com.google.datastore.v1.ReserveIdsResponse; +import com.google.datastore.v1.RollbackRequest; +import com.google.datastore.v1.RollbackResponse; +import com.google.datastore.v1.RunAggregationQueryRequest; +import com.google.datastore.v1.RunAggregationQueryResponse; +import com.google.datastore.v1.RunQueryRequest; +import com.google.datastore.v1.RunQueryResponse; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Base stub class for the Datastore service API. + * + *

This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +public abstract class DatastoreStub implements BackgroundResource { + + public UnaryCallable lookupCallable() { + throw new UnsupportedOperationException("Not implemented: lookupCallable()"); + } + + public UnaryCallable runQueryCallable() { + throw new UnsupportedOperationException("Not implemented: runQueryCallable()"); + } + + public UnaryCallable + runAggregationQueryCallable() { + throw new UnsupportedOperationException("Not implemented: runAggregationQueryCallable()"); + } + + public UnaryCallable + beginTransactionCallable() { + throw new UnsupportedOperationException("Not implemented: beginTransactionCallable()"); + } + + public UnaryCallable commitCallable() { + throw new UnsupportedOperationException("Not implemented: commitCallable()"); + } + + public UnaryCallable rollbackCallable() { + throw new UnsupportedOperationException("Not implemented: rollbackCallable()"); + } + + public UnaryCallable allocateIdsCallable() { + throw new UnsupportedOperationException("Not implemented: allocateIdsCallable()"); + } + + public UnaryCallable reserveIdsCallable() { + throw new UnsupportedOperationException("Not implemented: reserveIdsCallable()"); + } + + @Override + public abstract void close(); +} diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/DatastoreStubSettings.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/DatastoreStubSettings.java new file mode 100644 index 000000000..bfc622726 --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/DatastoreStubSettings.java @@ -0,0 +1,518 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.v1.stub; + +import com.google.api.core.ApiFunction; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.GaxProperties; +import com.google.api.gax.core.GoogleCredentialsProvider; +import com.google.api.gax.core.InstantiatingExecutorProvider; +import com.google.api.gax.grpc.GaxGrpcProperties; +import com.google.api.gax.grpc.GrpcTransportChannel; +import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.api.gax.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.httpjson.HttpJsonTransportChannel; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.StatusCode; +import com.google.api.gax.rpc.StubSettings; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.datastore.v1.AllocateIdsRequest; +import com.google.datastore.v1.AllocateIdsResponse; +import com.google.datastore.v1.BeginTransactionRequest; +import com.google.datastore.v1.BeginTransactionResponse; +import com.google.datastore.v1.CommitRequest; +import com.google.datastore.v1.CommitResponse; +import com.google.datastore.v1.LookupRequest; +import com.google.datastore.v1.LookupResponse; +import com.google.datastore.v1.ReserveIdsRequest; +import com.google.datastore.v1.ReserveIdsResponse; +import com.google.datastore.v1.RollbackRequest; +import com.google.datastore.v1.RollbackResponse; +import com.google.datastore.v1.RunAggregationQueryRequest; +import com.google.datastore.v1.RunAggregationQueryResponse; +import com.google.datastore.v1.RunQueryRequest; +import com.google.datastore.v1.RunQueryResponse; +import java.io.IOException; +import java.util.List; +import javax.annotation.Generated; +import org.threeten.bp.Duration; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Settings class to configure an instance of {@link DatastoreStub}. + * + *

The default instance has everything set to sensible defaults: + * + *

    + *
  • The default service address (datastore.googleapis.com) and default port (443) are used. + *
  • Credentials are acquired automatically through Application Default Credentials. + *
  • Retries are configured for idempotent methods but not for non-idempotent methods. + *
+ * + *

The builder of this class is recursive, so contained classes are themselves builders. When + * build() is called, the tree of builders is called to create the complete settings object. + * + *

For example, to set the total timeout of lookup to 30 seconds: + * + *

{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * DatastoreStubSettings.Builder datastoreSettingsBuilder = DatastoreStubSettings.newBuilder();
+ * datastoreSettingsBuilder
+ *     .lookupSettings()
+ *     .setRetrySettings(
+ *         datastoreSettingsBuilder
+ *             .lookupSettings()
+ *             .getRetrySettings()
+ *             .toBuilder()
+ *             .setTotalTimeout(Duration.ofSeconds(30))
+ *             .build());
+ * DatastoreStubSettings datastoreSettings = datastoreSettingsBuilder.build();
+ * }
+ */ +@Generated("by gapic-generator-java") +public class DatastoreStubSettings extends StubSettings { + /** The default scopes of the service. */ + private static final ImmutableList DEFAULT_SERVICE_SCOPES = + ImmutableList.builder() + .add("https://www.googleapis.com/auth/cloud-platform") + .add("https://www.googleapis.com/auth/datastore") + .build(); + + private final UnaryCallSettings lookupSettings; + private final UnaryCallSettings runQuerySettings; + private final UnaryCallSettings + runAggregationQuerySettings; + private final UnaryCallSettings + beginTransactionSettings; + private final UnaryCallSettings commitSettings; + private final UnaryCallSettings rollbackSettings; + private final UnaryCallSettings allocateIdsSettings; + private final UnaryCallSettings reserveIdsSettings; + + /** Returns the object with the settings used for calls to lookup. */ + public UnaryCallSettings lookupSettings() { + return lookupSettings; + } + + /** Returns the object with the settings used for calls to runQuery. */ + public UnaryCallSettings runQuerySettings() { + return runQuerySettings; + } + + /** Returns the object with the settings used for calls to runAggregationQuery. */ + public UnaryCallSettings + runAggregationQuerySettings() { + return runAggregationQuerySettings; + } + + /** Returns the object with the settings used for calls to beginTransaction. */ + public UnaryCallSettings + beginTransactionSettings() { + return beginTransactionSettings; + } + + /** Returns the object with the settings used for calls to commit. */ + public UnaryCallSettings commitSettings() { + return commitSettings; + } + + /** Returns the object with the settings used for calls to rollback. */ + public UnaryCallSettings rollbackSettings() { + return rollbackSettings; + } + + /** Returns the object with the settings used for calls to allocateIds. */ + public UnaryCallSettings allocateIdsSettings() { + return allocateIdsSettings; + } + + /** Returns the object with the settings used for calls to reserveIds. */ + public UnaryCallSettings reserveIdsSettings() { + return reserveIdsSettings; + } + + public DatastoreStub createStub() throws IOException { + if (getTransportChannelProvider() + .getTransportName() + .equals(GrpcTransportChannel.getGrpcTransportName())) { + return GrpcDatastoreStub.create(this); + } + if (getTransportChannelProvider() + .getTransportName() + .equals(HttpJsonTransportChannel.getHttpJsonTransportName())) { + return HttpJsonDatastoreStub.create(this); + } + throw new UnsupportedOperationException( + String.format( + "Transport not supported: %s", getTransportChannelProvider().getTransportName())); + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return InstantiatingExecutorProvider.newBuilder(); + } + + /** Returns the default service endpoint. */ + public static String getDefaultEndpoint() { + return "datastore.googleapis.com:443"; + } + + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "datastore.mtls.googleapis.com:443"; + } + + /** Returns the default service scopes. */ + public static List getDefaultServiceScopes() { + return DEFAULT_SERVICE_SCOPES; + } + + /** Returns a builder for the default credentials for this service. */ + public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); + } + + /** Returns a builder for the default gRPC ChannelProvider for this service. */ + public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() { + return InstantiatingGrpcChannelProvider.newBuilder() + .setMaxInboundMessageSize(Integer.MAX_VALUE); + } + + /** Returns a builder for the default REST ChannelProvider for this service. */ + @BetaApi + public static InstantiatingHttpJsonChannelProvider.Builder + defaultHttpJsonTransportProviderBuilder() { + return InstantiatingHttpJsonChannelProvider.newBuilder(); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return defaultGrpcTransportProviderBuilder().build(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultGrpcApiClientHeaderProviderBuilder() { + return ApiClientHeaderProvider.newBuilder() + .setGeneratedLibToken("gapic", GaxProperties.getLibraryVersion(DatastoreStubSettings.class)) + .setTransportToken( + GaxGrpcProperties.getGrpcTokenName(), GaxGrpcProperties.getGrpcVersion()); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultHttpJsonApiClientHeaderProviderBuilder() { + return ApiClientHeaderProvider.newBuilder() + .setGeneratedLibToken("gapic", GaxProperties.getLibraryVersion(DatastoreStubSettings.class)) + .setTransportToken( + GaxHttpJsonProperties.getHttpJsonTokenName(), + GaxHttpJsonProperties.getHttpJsonVersion()); + } + + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return DatastoreStubSettings.defaultGrpcApiClientHeaderProviderBuilder(); + } + + /** Returns a new gRPC builder for this class. */ + public static Builder newBuilder() { + return Builder.createDefault(); + } + + /** Returns a new REST builder for this class. */ + public static Builder newHttpJsonBuilder() { + return Builder.createHttpJsonDefault(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder(ClientContext clientContext) { + return new Builder(clientContext); + } + + /** Returns a builder containing all the values of this settings class. */ + public Builder toBuilder() { + return new Builder(this); + } + + protected DatastoreStubSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + + lookupSettings = settingsBuilder.lookupSettings().build(); + runQuerySettings = settingsBuilder.runQuerySettings().build(); + runAggregationQuerySettings = settingsBuilder.runAggregationQuerySettings().build(); + beginTransactionSettings = settingsBuilder.beginTransactionSettings().build(); + commitSettings = settingsBuilder.commitSettings().build(); + rollbackSettings = settingsBuilder.rollbackSettings().build(); + allocateIdsSettings = settingsBuilder.allocateIdsSettings().build(); + reserveIdsSettings = settingsBuilder.reserveIdsSettings().build(); + } + + /** Builder for DatastoreStubSettings. */ + public static class Builder extends StubSettings.Builder { + private final ImmutableList> unaryMethodSettingsBuilders; + private final UnaryCallSettings.Builder lookupSettings; + private final UnaryCallSettings.Builder runQuerySettings; + private final UnaryCallSettings.Builder + runAggregationQuerySettings; + private final UnaryCallSettings.Builder + beginTransactionSettings; + private final UnaryCallSettings.Builder commitSettings; + private final UnaryCallSettings.Builder rollbackSettings; + private final UnaryCallSettings.Builder + allocateIdsSettings; + private final UnaryCallSettings.Builder + reserveIdsSettings; + private static final ImmutableMap> + RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = + ImmutableMap.builder(); + definitions.put( + "retry_policy_0_codes", + ImmutableSet.copyOf( + Lists.newArrayList( + StatusCode.Code.UNAVAILABLE, StatusCode.Code.DEADLINE_EXCEEDED))); + definitions.put( + "no_retry_1_codes", ImmutableSet.copyOf(Lists.newArrayList())); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetrySettings settings = null; + settings = + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.ofMillis(100L)) + .setRetryDelayMultiplier(1.3) + .setMaxRetryDelay(Duration.ofMillis(60000L)) + .setInitialRpcTimeout(Duration.ofMillis(60000L)) + .setRpcTimeoutMultiplier(1.0) + .setMaxRpcTimeout(Duration.ofMillis(60000L)) + .setTotalTimeout(Duration.ofMillis(60000L)) + .build(); + definitions.put("retry_policy_0_params", settings); + settings = + RetrySettings.newBuilder() + .setInitialRpcTimeout(Duration.ofMillis(60000L)) + .setRpcTimeoutMultiplier(1.0) + .setMaxRpcTimeout(Duration.ofMillis(60000L)) + .setTotalTimeout(Duration.ofMillis(60000L)) + .build(); + definitions.put("no_retry_1_params", settings); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + protected Builder() { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(clientContext); + + lookupSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + runQuerySettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + runAggregationQuerySettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + beginTransactionSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + commitSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + rollbackSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + allocateIdsSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + reserveIdsSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + + unaryMethodSettingsBuilders = + ImmutableList.>of( + lookupSettings, + runQuerySettings, + runAggregationQuerySettings, + beginTransactionSettings, + commitSettings, + rollbackSettings, + allocateIdsSettings, + reserveIdsSettings); + initDefaults(this); + } + + protected Builder(DatastoreStubSettings settings) { + super(settings); + + lookupSettings = settings.lookupSettings.toBuilder(); + runQuerySettings = settings.runQuerySettings.toBuilder(); + runAggregationQuerySettings = settings.runAggregationQuerySettings.toBuilder(); + beginTransactionSettings = settings.beginTransactionSettings.toBuilder(); + commitSettings = settings.commitSettings.toBuilder(); + rollbackSettings = settings.rollbackSettings.toBuilder(); + allocateIdsSettings = settings.allocateIdsSettings.toBuilder(); + reserveIdsSettings = settings.reserveIdsSettings.toBuilder(); + + unaryMethodSettingsBuilders = + ImmutableList.>of( + lookupSettings, + runQuerySettings, + runAggregationQuerySettings, + beginTransactionSettings, + commitSettings, + rollbackSettings, + allocateIdsSettings, + reserveIdsSettings); + } + + private static Builder createDefault() { + Builder builder = new Builder(((ClientContext) null)); + + builder.setTransportChannelProvider(defaultTransportChannelProvider()); + builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); + builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); + builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); + + return initDefaults(builder); + } + + private static Builder createHttpJsonDefault() { + Builder builder = new Builder(((ClientContext) null)); + + builder.setTransportChannelProvider(defaultHttpJsonTransportProviderBuilder().build()); + builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); + builder.setInternalHeaderProvider(defaultHttpJsonApiClientHeaderProviderBuilder().build()); + builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); + + return initDefaults(builder); + } + + private static Builder initDefaults(Builder builder) { + builder + .lookupSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + builder + .runQuerySettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + builder + .runAggregationQuerySettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + builder + .beginTransactionSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_1_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_1_params")); + + builder + .commitSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_1_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_1_params")); + + builder + .rollbackSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_1_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_1_params")); + + builder + .allocateIdsSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_1_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_1_params")); + + builder + .reserveIdsSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + return builder; + } + + /** + * Applies the given settings updater function to all of the unary API methods in this service. + * + *

Note: This method does not support applying settings to streaming methods. + */ + public Builder applyToAllUnaryMethods( + ApiFunction, Void> settingsUpdater) { + super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); + return this; + } + + public ImmutableList> unaryMethodSettingsBuilders() { + return unaryMethodSettingsBuilders; + } + + /** Returns the builder for the settings used for calls to lookup. */ + public UnaryCallSettings.Builder lookupSettings() { + return lookupSettings; + } + + /** Returns the builder for the settings used for calls to runQuery. */ + public UnaryCallSettings.Builder runQuerySettings() { + return runQuerySettings; + } + + /** Returns the builder for the settings used for calls to runAggregationQuery. */ + public UnaryCallSettings.Builder + runAggregationQuerySettings() { + return runAggregationQuerySettings; + } + + /** Returns the builder for the settings used for calls to beginTransaction. */ + public UnaryCallSettings.Builder + beginTransactionSettings() { + return beginTransactionSettings; + } + + /** Returns the builder for the settings used for calls to commit. */ + public UnaryCallSettings.Builder commitSettings() { + return commitSettings; + } + + /** Returns the builder for the settings used for calls to rollback. */ + public UnaryCallSettings.Builder rollbackSettings() { + return rollbackSettings; + } + + /** Returns the builder for the settings used for calls to allocateIds. */ + public UnaryCallSettings.Builder + allocateIdsSettings() { + return allocateIdsSettings; + } + + /** Returns the builder for the settings used for calls to reserveIds. */ + public UnaryCallSettings.Builder reserveIdsSettings() { + return reserveIdsSettings; + } + + @Override + public DatastoreStubSettings build() throws IOException { + return new DatastoreStubSettings(this); + } + } +} diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/GrpcDatastoreCallableFactory.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/GrpcDatastoreCallableFactory.java new file mode 100644 index 000000000..4e640ead2 --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/GrpcDatastoreCallableFactory.java @@ -0,0 +1,113 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.v1.stub; + +import com.google.api.gax.grpc.GrpcCallSettings; +import com.google.api.gax.grpc.GrpcCallableFactory; +import com.google.api.gax.grpc.GrpcStubCallableFactory; +import com.google.api.gax.rpc.BatchingCallSettings; +import com.google.api.gax.rpc.BidiStreamingCallable; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ClientStreamingCallable; +import com.google.api.gax.rpc.OperationCallSettings; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.StreamingCallSettings; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; +import com.google.longrunning.stub.OperationsStub; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * gRPC callable factory implementation for the Datastore service API. + * + *

This class is for advanced usage. + */ +@Generated("by gapic-generator-java") +public class GrpcDatastoreCallableFactory implements GrpcStubCallableFactory { + + @Override + public UnaryCallable createUnaryCallable( + GrpcCallSettings grpcCallSettings, + UnaryCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createUnaryCallable(grpcCallSettings, callSettings, clientContext); + } + + @Override + public + UnaryCallable createPagedCallable( + GrpcCallSettings grpcCallSettings, + PagedCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createPagedCallable(grpcCallSettings, callSettings, clientContext); + } + + @Override + public UnaryCallable createBatchingCallable( + GrpcCallSettings grpcCallSettings, + BatchingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createBatchingCallable( + grpcCallSettings, callSettings, clientContext); + } + + @Override + public + OperationCallable createOperationCallable( + GrpcCallSettings grpcCallSettings, + OperationCallSettings callSettings, + ClientContext clientContext, + OperationsStub operationsStub) { + return GrpcCallableFactory.createOperationCallable( + grpcCallSettings, callSettings, clientContext, operationsStub); + } + + @Override + public + BidiStreamingCallable createBidiStreamingCallable( + GrpcCallSettings grpcCallSettings, + StreamingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createBidiStreamingCallable( + grpcCallSettings, callSettings, clientContext); + } + + @Override + public + ServerStreamingCallable createServerStreamingCallable( + GrpcCallSettings grpcCallSettings, + ServerStreamingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createServerStreamingCallable( + grpcCallSettings, callSettings, clientContext); + } + + @Override + public + ClientStreamingCallable createClientStreamingCallable( + GrpcCallSettings grpcCallSettings, + StreamingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createClientStreamingCallable( + grpcCallSettings, callSettings, clientContext); + } +} diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/GrpcDatastoreStub.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/GrpcDatastoreStub.java new file mode 100644 index 000000000..f68e8996b --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/GrpcDatastoreStub.java @@ -0,0 +1,429 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.v1.stub; + +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.core.BackgroundResourceAggregation; +import com.google.api.gax.grpc.GrpcCallSettings; +import com.google.api.gax.grpc.GrpcStubCallableFactory; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.RequestParamsBuilder; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.api.pathtemplate.PathTemplate; +import com.google.datastore.v1.AllocateIdsRequest; +import com.google.datastore.v1.AllocateIdsResponse; +import com.google.datastore.v1.BeginTransactionRequest; +import com.google.datastore.v1.BeginTransactionResponse; +import com.google.datastore.v1.CommitRequest; +import com.google.datastore.v1.CommitResponse; +import com.google.datastore.v1.LookupRequest; +import com.google.datastore.v1.LookupResponse; +import com.google.datastore.v1.ReserveIdsRequest; +import com.google.datastore.v1.ReserveIdsResponse; +import com.google.datastore.v1.RollbackRequest; +import com.google.datastore.v1.RollbackResponse; +import com.google.datastore.v1.RunAggregationQueryRequest; +import com.google.datastore.v1.RunAggregationQueryResponse; +import com.google.datastore.v1.RunQueryRequest; +import com.google.datastore.v1.RunQueryResponse; +import com.google.longrunning.stub.GrpcOperationsStub; +import io.grpc.MethodDescriptor; +import io.grpc.protobuf.ProtoUtils; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * gRPC stub implementation for the Datastore service API. + * + *

This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +public class GrpcDatastoreStub extends DatastoreStub { + private static final MethodDescriptor lookupMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.datastore.v1.Datastore/Lookup") + .setRequestMarshaller(ProtoUtils.marshaller(LookupRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(LookupResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + runQueryMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.datastore.v1.Datastore/RunQuery") + .setRequestMarshaller(ProtoUtils.marshaller(RunQueryRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(RunQueryResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + runAggregationQueryMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.datastore.v1.Datastore/RunAggregationQuery") + .setRequestMarshaller( + ProtoUtils.marshaller(RunAggregationQueryRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(RunAggregationQueryResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + beginTransactionMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.datastore.v1.Datastore/BeginTransaction") + .setRequestMarshaller( + ProtoUtils.marshaller(BeginTransactionRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(BeginTransactionResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor commitMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.datastore.v1.Datastore/Commit") + .setRequestMarshaller(ProtoUtils.marshaller(CommitRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(CommitResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + rollbackMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.datastore.v1.Datastore/Rollback") + .setRequestMarshaller(ProtoUtils.marshaller(RollbackRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(RollbackResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + allocateIdsMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.datastore.v1.Datastore/AllocateIds") + .setRequestMarshaller(ProtoUtils.marshaller(AllocateIdsRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(AllocateIdsResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + reserveIdsMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.datastore.v1.Datastore/ReserveIds") + .setRequestMarshaller(ProtoUtils.marshaller(ReserveIdsRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(ReserveIdsResponse.getDefaultInstance())) + .build(); + + private final UnaryCallable lookupCallable; + private final UnaryCallable runQueryCallable; + private final UnaryCallable + runAggregationQueryCallable; + private final UnaryCallable + beginTransactionCallable; + private final UnaryCallable commitCallable; + private final UnaryCallable rollbackCallable; + private final UnaryCallable allocateIdsCallable; + private final UnaryCallable reserveIdsCallable; + + private final BackgroundResource backgroundResources; + private final GrpcOperationsStub operationsStub; + private final GrpcStubCallableFactory callableFactory; + + private static final PathTemplate LOOKUP_0_PATH_TEMPLATE = PathTemplate.create("{project_id=**}"); + private static final PathTemplate LOOKUP_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + private static final PathTemplate RUN_QUERY_0_PATH_TEMPLATE = + PathTemplate.create("{project_id=**}"); + private static final PathTemplate RUN_QUERY_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + private static final PathTemplate RUN_AGGREGATION_QUERY_0_PATH_TEMPLATE = + PathTemplate.create("{project_id=**}"); + private static final PathTemplate RUN_AGGREGATION_QUERY_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + private static final PathTemplate BEGIN_TRANSACTION_0_PATH_TEMPLATE = + PathTemplate.create("{project_id=**}"); + private static final PathTemplate BEGIN_TRANSACTION_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + private static final PathTemplate COMMIT_0_PATH_TEMPLATE = PathTemplate.create("{project_id=**}"); + private static final PathTemplate COMMIT_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + private static final PathTemplate ROLLBACK_0_PATH_TEMPLATE = + PathTemplate.create("{project_id=**}"); + private static final PathTemplate ROLLBACK_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + private static final PathTemplate ALLOCATE_IDS_0_PATH_TEMPLATE = + PathTemplate.create("{project_id=**}"); + private static final PathTemplate ALLOCATE_IDS_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + private static final PathTemplate RESERVE_IDS_0_PATH_TEMPLATE = + PathTemplate.create("{project_id=**}"); + private static final PathTemplate RESERVE_IDS_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + + public static final GrpcDatastoreStub create(DatastoreStubSettings settings) throws IOException { + return new GrpcDatastoreStub(settings, ClientContext.create(settings)); + } + + public static final GrpcDatastoreStub create(ClientContext clientContext) throws IOException { + return new GrpcDatastoreStub(DatastoreStubSettings.newBuilder().build(), clientContext); + } + + public static final GrpcDatastoreStub create( + ClientContext clientContext, GrpcStubCallableFactory callableFactory) throws IOException { + return new GrpcDatastoreStub( + DatastoreStubSettings.newBuilder().build(), clientContext, callableFactory); + } + + /** + * Constructs an instance of GrpcDatastoreStub, using the given settings. This is protected so + * that it is easy to make a subclass, but otherwise, the static factory methods should be + * preferred. + */ + protected GrpcDatastoreStub(DatastoreStubSettings settings, ClientContext clientContext) + throws IOException { + this(settings, clientContext, new GrpcDatastoreCallableFactory()); + } + + /** + * Constructs an instance of GrpcDatastoreStub, using the given settings. This is protected so + * that it is easy to make a subclass, but otherwise, the static factory methods should be + * preferred. + */ + protected GrpcDatastoreStub( + DatastoreStubSettings settings, + ClientContext clientContext, + GrpcStubCallableFactory callableFactory) + throws IOException { + this.callableFactory = callableFactory; + this.operationsStub = GrpcOperationsStub.create(clientContext, callableFactory); + + GrpcCallSettings lookupTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(lookupMethodDescriptor) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add(request.getProjectId(), "project_id", LOOKUP_0_PATH_TEMPLATE); + builder.add(request.getDatabaseId(), "database_id", LOOKUP_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + GrpcCallSettings runQueryTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(runQueryMethodDescriptor) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add(request.getProjectId(), "project_id", RUN_QUERY_0_PATH_TEMPLATE); + builder.add(request.getDatabaseId(), "database_id", RUN_QUERY_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + GrpcCallSettings + runAggregationQueryTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(runAggregationQueryMethodDescriptor) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add( + request.getProjectId(), + "project_id", + RUN_AGGREGATION_QUERY_0_PATH_TEMPLATE); + builder.add( + request.getDatabaseId(), + "database_id", + RUN_AGGREGATION_QUERY_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + GrpcCallSettings + beginTransactionTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(beginTransactionMethodDescriptor) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add( + request.getProjectId(), "project_id", BEGIN_TRANSACTION_0_PATH_TEMPLATE); + builder.add( + request.getDatabaseId(), + "database_id", + BEGIN_TRANSACTION_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + GrpcCallSettings commitTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(commitMethodDescriptor) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add(request.getProjectId(), "project_id", COMMIT_0_PATH_TEMPLATE); + builder.add(request.getDatabaseId(), "database_id", COMMIT_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + GrpcCallSettings rollbackTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(rollbackMethodDescriptor) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add(request.getProjectId(), "project_id", ROLLBACK_0_PATH_TEMPLATE); + builder.add(request.getDatabaseId(), "database_id", ROLLBACK_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + GrpcCallSettings allocateIdsTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(allocateIdsMethodDescriptor) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add(request.getProjectId(), "project_id", ALLOCATE_IDS_0_PATH_TEMPLATE); + builder.add(request.getDatabaseId(), "database_id", ALLOCATE_IDS_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + GrpcCallSettings reserveIdsTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(reserveIdsMethodDescriptor) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add(request.getProjectId(), "project_id", RESERVE_IDS_0_PATH_TEMPLATE); + builder.add(request.getDatabaseId(), "database_id", RESERVE_IDS_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + + this.lookupCallable = + callableFactory.createUnaryCallable( + lookupTransportSettings, settings.lookupSettings(), clientContext); + this.runQueryCallable = + callableFactory.createUnaryCallable( + runQueryTransportSettings, settings.runQuerySettings(), clientContext); + this.runAggregationQueryCallable = + callableFactory.createUnaryCallable( + runAggregationQueryTransportSettings, + settings.runAggregationQuerySettings(), + clientContext); + this.beginTransactionCallable = + callableFactory.createUnaryCallable( + beginTransactionTransportSettings, settings.beginTransactionSettings(), clientContext); + this.commitCallable = + callableFactory.createUnaryCallable( + commitTransportSettings, settings.commitSettings(), clientContext); + this.rollbackCallable = + callableFactory.createUnaryCallable( + rollbackTransportSettings, settings.rollbackSettings(), clientContext); + this.allocateIdsCallable = + callableFactory.createUnaryCallable( + allocateIdsTransportSettings, settings.allocateIdsSettings(), clientContext); + this.reserveIdsCallable = + callableFactory.createUnaryCallable( + reserveIdsTransportSettings, settings.reserveIdsSettings(), clientContext); + + this.backgroundResources = + new BackgroundResourceAggregation(clientContext.getBackgroundResources()); + } + + public GrpcOperationsStub getOperationsStub() { + return operationsStub; + } + + @Override + public UnaryCallable lookupCallable() { + return lookupCallable; + } + + @Override + public UnaryCallable runQueryCallable() { + return runQueryCallable; + } + + @Override + public UnaryCallable + runAggregationQueryCallable() { + return runAggregationQueryCallable; + } + + @Override + public UnaryCallable + beginTransactionCallable() { + return beginTransactionCallable; + } + + @Override + public UnaryCallable commitCallable() { + return commitCallable; + } + + @Override + public UnaryCallable rollbackCallable() { + return rollbackCallable; + } + + @Override + public UnaryCallable allocateIdsCallable() { + return allocateIdsCallable; + } + + @Override + public UnaryCallable reserveIdsCallable() { + return reserveIdsCallable; + } + + @Override + public final void close() { + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } + } + + @Override + public void shutdown() { + backgroundResources.shutdown(); + } + + @Override + public boolean isShutdown() { + return backgroundResources.isShutdown(); + } + + @Override + public boolean isTerminated() { + return backgroundResources.isTerminated(); + } + + @Override + public void shutdownNow() { + backgroundResources.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return backgroundResources.awaitTermination(duration, unit); + } +} diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/HttpJsonDatastoreCallableFactory.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/HttpJsonDatastoreCallableFactory.java new file mode 100644 index 000000000..8639433a7 --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/HttpJsonDatastoreCallableFactory.java @@ -0,0 +1,105 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.v1.stub; + +import com.google.api.core.BetaApi; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.httpjson.longrunning.stub.OperationsStub; +import com.google.api.gax.rpc.BatchingCallSettings; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.OperationCallSettings; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * REST callable factory implementation for the Datastore service API. + * + *

This class is for advanced usage. + */ +@Generated("by gapic-generator-java") +@BetaApi +public class HttpJsonDatastoreCallableFactory + implements HttpJsonStubCallableFactory { + + @Override + public UnaryCallable createUnaryCallable( + HttpJsonCallSettings httpJsonCallSettings, + UnaryCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createUnaryCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @Override + public + UnaryCallable createPagedCallable( + HttpJsonCallSettings httpJsonCallSettings, + PagedCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createPagedCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @Override + public UnaryCallable createBatchingCallable( + HttpJsonCallSettings httpJsonCallSettings, + BatchingCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createBatchingCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @BetaApi( + "The surface for long-running operations is not stable yet and may change in the future.") + @Override + public + OperationCallable createOperationCallable( + HttpJsonCallSettings httpJsonCallSettings, + OperationCallSettings callSettings, + ClientContext clientContext, + OperationsStub operationsStub) { + UnaryCallable innerCallable = + HttpJsonCallableFactory.createBaseUnaryCallable( + httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); + HttpJsonOperationSnapshotCallable initialCallable = + new HttpJsonOperationSnapshotCallable( + innerCallable, + httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); + return HttpJsonCallableFactory.createOperationCallable( + callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); + } + + @Override + public + ServerStreamingCallable createServerStreamingCallable( + HttpJsonCallSettings httpJsonCallSettings, + ServerStreamingCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createServerStreamingCallable( + httpJsonCallSettings, callSettings, clientContext); + } +} diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/HttpJsonDatastoreStub.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/HttpJsonDatastoreStub.java new file mode 100644 index 000000000..c0f1c7766 --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/v1/stub/HttpJsonDatastoreStub.java @@ -0,0 +1,678 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.v1.stub; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.core.BackgroundResourceAggregation; +import com.google.api.gax.httpjson.ApiMethodDescriptor; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.httpjson.ProtoMessageRequestFormatter; +import com.google.api.gax.httpjson.ProtoMessageResponseParser; +import com.google.api.gax.httpjson.ProtoRestSerializer; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.RequestParamsBuilder; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.api.pathtemplate.PathTemplate; +import com.google.datastore.v1.AllocateIdsRequest; +import com.google.datastore.v1.AllocateIdsResponse; +import com.google.datastore.v1.BeginTransactionRequest; +import com.google.datastore.v1.BeginTransactionResponse; +import com.google.datastore.v1.CommitRequest; +import com.google.datastore.v1.CommitResponse; +import com.google.datastore.v1.LookupRequest; +import com.google.datastore.v1.LookupResponse; +import com.google.datastore.v1.ReserveIdsRequest; +import com.google.datastore.v1.ReserveIdsResponse; +import com.google.datastore.v1.RollbackRequest; +import com.google.datastore.v1.RollbackResponse; +import com.google.datastore.v1.RunAggregationQueryRequest; +import com.google.datastore.v1.RunAggregationQueryResponse; +import com.google.datastore.v1.RunQueryRequest; +import com.google.datastore.v1.RunQueryResponse; +import com.google.protobuf.TypeRegistry; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * REST stub implementation for the Datastore service API. + * + *

This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +@BetaApi +public class HttpJsonDatastoreStub extends DatastoreStub { + private static final TypeRegistry typeRegistry = TypeRegistry.newBuilder().build(); + + private static final ApiMethodDescriptor lookupMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.datastore.v1.Datastore/Lookup") + .setHttpMethod("POST") + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/projects/{projectId}:lookup", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "projectId", request.getProjectId()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "$alt", "json;enum-encoding=int"); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create() + .toBody("*", request.toBuilder().clearProjectId().build(), true)) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(LookupResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor + runQueryMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.datastore.v1.Datastore/RunQuery") + .setHttpMethod("POST") + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/projects/{projectId}:runQuery", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "projectId", request.getProjectId()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "$alt", "json;enum-encoding=int"); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create() + .toBody("*", request.toBuilder().clearProjectId().build(), true)) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(RunQueryResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor + runAggregationQueryMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.datastore.v1.Datastore/RunAggregationQuery") + .setHttpMethod("POST") + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/projects/{projectId}:runAggregationQuery", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "projectId", request.getProjectId()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "$alt", "json;enum-encoding=int"); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create() + .toBody("*", request.toBuilder().clearProjectId().build(), true)) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(RunAggregationQueryResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor + beginTransactionMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.datastore.v1.Datastore/BeginTransaction") + .setHttpMethod("POST") + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/projects/{projectId}:beginTransaction", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "projectId", request.getProjectId()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "$alt", "json;enum-encoding=int"); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create() + .toBody("*", request.toBuilder().clearProjectId().build(), true)) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(BeginTransactionResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor commitMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.datastore.v1.Datastore/Commit") + .setHttpMethod("POST") + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/projects/{projectId}:commit", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "projectId", request.getProjectId()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "$alt", "json;enum-encoding=int"); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create() + .toBody("*", request.toBuilder().clearProjectId().build(), true)) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(CommitResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor + rollbackMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.datastore.v1.Datastore/Rollback") + .setHttpMethod("POST") + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/projects/{projectId}:rollback", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "projectId", request.getProjectId()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "$alt", "json;enum-encoding=int"); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create() + .toBody("*", request.toBuilder().clearProjectId().build(), true)) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(RollbackResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor + allocateIdsMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.datastore.v1.Datastore/AllocateIds") + .setHttpMethod("POST") + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/projects/{projectId}:allocateIds", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "projectId", request.getProjectId()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "$alt", "json;enum-encoding=int"); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create() + .toBody("*", request.toBuilder().clearProjectId().build(), true)) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(AllocateIdsResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor + reserveIdsMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.datastore.v1.Datastore/ReserveIds") + .setHttpMethod("POST") + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1/projects/{projectId}:reserveIds", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "projectId", request.getProjectId()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "$alt", "json;enum-encoding=int"); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create() + .toBody("*", request.toBuilder().clearProjectId().build(), true)) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(ReserveIdsResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private final UnaryCallable lookupCallable; + private final UnaryCallable runQueryCallable; + private final UnaryCallable + runAggregationQueryCallable; + private final UnaryCallable + beginTransactionCallable; + private final UnaryCallable commitCallable; + private final UnaryCallable rollbackCallable; + private final UnaryCallable allocateIdsCallable; + private final UnaryCallable reserveIdsCallable; + + private final BackgroundResource backgroundResources; + private final HttpJsonStubCallableFactory callableFactory; + + private static final PathTemplate LOOKUP_0_PATH_TEMPLATE = PathTemplate.create("{project_id=**}"); + private static final PathTemplate LOOKUP_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + private static final PathTemplate RUN_QUERY_0_PATH_TEMPLATE = + PathTemplate.create("{project_id=**}"); + private static final PathTemplate RUN_QUERY_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + private static final PathTemplate RUN_AGGREGATION_QUERY_0_PATH_TEMPLATE = + PathTemplate.create("{project_id=**}"); + private static final PathTemplate RUN_AGGREGATION_QUERY_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + private static final PathTemplate BEGIN_TRANSACTION_0_PATH_TEMPLATE = + PathTemplate.create("{project_id=**}"); + private static final PathTemplate BEGIN_TRANSACTION_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + private static final PathTemplate COMMIT_0_PATH_TEMPLATE = PathTemplate.create("{project_id=**}"); + private static final PathTemplate COMMIT_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + private static final PathTemplate ROLLBACK_0_PATH_TEMPLATE = + PathTemplate.create("{project_id=**}"); + private static final PathTemplate ROLLBACK_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + private static final PathTemplate ALLOCATE_IDS_0_PATH_TEMPLATE = + PathTemplate.create("{project_id=**}"); + private static final PathTemplate ALLOCATE_IDS_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + private static final PathTemplate RESERVE_IDS_0_PATH_TEMPLATE = + PathTemplate.create("{project_id=**}"); + private static final PathTemplate RESERVE_IDS_1_PATH_TEMPLATE = + PathTemplate.create("{database_id=**}"); + + public static final HttpJsonDatastoreStub create(DatastoreStubSettings settings) + throws IOException { + return new HttpJsonDatastoreStub(settings, ClientContext.create(settings)); + } + + public static final HttpJsonDatastoreStub create(ClientContext clientContext) throws IOException { + return new HttpJsonDatastoreStub( + DatastoreStubSettings.newHttpJsonBuilder().build(), clientContext); + } + + public static final HttpJsonDatastoreStub create( + ClientContext clientContext, HttpJsonStubCallableFactory callableFactory) throws IOException { + return new HttpJsonDatastoreStub( + DatastoreStubSettings.newHttpJsonBuilder().build(), clientContext, callableFactory); + } + + /** + * Constructs an instance of HttpJsonDatastoreStub, using the given settings. This is protected so + * that it is easy to make a subclass, but otherwise, the static factory methods should be + * preferred. + */ + protected HttpJsonDatastoreStub(DatastoreStubSettings settings, ClientContext clientContext) + throws IOException { + this(settings, clientContext, new HttpJsonDatastoreCallableFactory()); + } + + /** + * Constructs an instance of HttpJsonDatastoreStub, using the given settings. This is protected so + * that it is easy to make a subclass, but otherwise, the static factory methods should be + * preferred. + */ + protected HttpJsonDatastoreStub( + DatastoreStubSettings settings, + ClientContext clientContext, + HttpJsonStubCallableFactory callableFactory) + throws IOException { + this.callableFactory = callableFactory; + + HttpJsonCallSettings lookupTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(lookupMethodDescriptor) + .setTypeRegistry(typeRegistry) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add(request.getProjectId(), "project_id", LOOKUP_0_PATH_TEMPLATE); + builder.add(request.getDatabaseId(), "database_id", LOOKUP_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + HttpJsonCallSettings runQueryTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(runQueryMethodDescriptor) + .setTypeRegistry(typeRegistry) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add(request.getProjectId(), "project_id", RUN_QUERY_0_PATH_TEMPLATE); + builder.add(request.getDatabaseId(), "database_id", RUN_QUERY_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + HttpJsonCallSettings + runAggregationQueryTransportSettings = + HttpJsonCallSettings + .newBuilder() + .setMethodDescriptor(runAggregationQueryMethodDescriptor) + .setTypeRegistry(typeRegistry) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add( + request.getProjectId(), + "project_id", + RUN_AGGREGATION_QUERY_0_PATH_TEMPLATE); + builder.add( + request.getDatabaseId(), + "database_id", + RUN_AGGREGATION_QUERY_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + HttpJsonCallSettings + beginTransactionTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(beginTransactionMethodDescriptor) + .setTypeRegistry(typeRegistry) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add( + request.getProjectId(), "project_id", BEGIN_TRANSACTION_0_PATH_TEMPLATE); + builder.add( + request.getDatabaseId(), + "database_id", + BEGIN_TRANSACTION_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + HttpJsonCallSettings commitTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(commitMethodDescriptor) + .setTypeRegistry(typeRegistry) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add(request.getProjectId(), "project_id", COMMIT_0_PATH_TEMPLATE); + builder.add(request.getDatabaseId(), "database_id", COMMIT_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + HttpJsonCallSettings rollbackTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(rollbackMethodDescriptor) + .setTypeRegistry(typeRegistry) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add(request.getProjectId(), "project_id", ROLLBACK_0_PATH_TEMPLATE); + builder.add(request.getDatabaseId(), "database_id", ROLLBACK_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + HttpJsonCallSettings allocateIdsTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(allocateIdsMethodDescriptor) + .setTypeRegistry(typeRegistry) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add(request.getProjectId(), "project_id", ALLOCATE_IDS_0_PATH_TEMPLATE); + builder.add(request.getDatabaseId(), "database_id", ALLOCATE_IDS_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + HttpJsonCallSettings reserveIdsTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(reserveIdsMethodDescriptor) + .setTypeRegistry(typeRegistry) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add(request.getProjectId(), "project_id", RESERVE_IDS_0_PATH_TEMPLATE); + builder.add(request.getDatabaseId(), "database_id", RESERVE_IDS_1_PATH_TEMPLATE); + return builder.build(); + }) + .build(); + + this.lookupCallable = + callableFactory.createUnaryCallable( + lookupTransportSettings, settings.lookupSettings(), clientContext); + this.runQueryCallable = + callableFactory.createUnaryCallable( + runQueryTransportSettings, settings.runQuerySettings(), clientContext); + this.runAggregationQueryCallable = + callableFactory.createUnaryCallable( + runAggregationQueryTransportSettings, + settings.runAggregationQuerySettings(), + clientContext); + this.beginTransactionCallable = + callableFactory.createUnaryCallable( + beginTransactionTransportSettings, settings.beginTransactionSettings(), clientContext); + this.commitCallable = + callableFactory.createUnaryCallable( + commitTransportSettings, settings.commitSettings(), clientContext); + this.rollbackCallable = + callableFactory.createUnaryCallable( + rollbackTransportSettings, settings.rollbackSettings(), clientContext); + this.allocateIdsCallable = + callableFactory.createUnaryCallable( + allocateIdsTransportSettings, settings.allocateIdsSettings(), clientContext); + this.reserveIdsCallable = + callableFactory.createUnaryCallable( + reserveIdsTransportSettings, settings.reserveIdsSettings(), clientContext); + + this.backgroundResources = + new BackgroundResourceAggregation(clientContext.getBackgroundResources()); + } + + @InternalApi + public static List getMethodDescriptors() { + List methodDescriptors = new ArrayList<>(); + methodDescriptors.add(lookupMethodDescriptor); + methodDescriptors.add(runQueryMethodDescriptor); + methodDescriptors.add(runAggregationQueryMethodDescriptor); + methodDescriptors.add(beginTransactionMethodDescriptor); + methodDescriptors.add(commitMethodDescriptor); + methodDescriptors.add(rollbackMethodDescriptor); + methodDescriptors.add(allocateIdsMethodDescriptor); + methodDescriptors.add(reserveIdsMethodDescriptor); + return methodDescriptors; + } + + @Override + public UnaryCallable lookupCallable() { + return lookupCallable; + } + + @Override + public UnaryCallable runQueryCallable() { + return runQueryCallable; + } + + @Override + public UnaryCallable + runAggregationQueryCallable() { + return runAggregationQueryCallable; + } + + @Override + public UnaryCallable + beginTransactionCallable() { + return beginTransactionCallable; + } + + @Override + public UnaryCallable commitCallable() { + return commitCallable; + } + + @Override + public UnaryCallable rollbackCallable() { + return rollbackCallable; + } + + @Override + public UnaryCallable allocateIdsCallable() { + return allocateIdsCallable; + } + + @Override + public UnaryCallable reserveIdsCallable() { + return reserveIdsCallable; + } + + @Override + public final void close() { + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } + } + + @Override + public void shutdown() { + backgroundResources.shutdown(); + } + + @Override + public boolean isShutdown() { + return backgroundResources.isShutdown(); + } + + @Override + public boolean isTerminated() { + return backgroundResources.isTerminated(); + } + + @Override + public void shutdownNow() { + backgroundResources.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return backgroundResources.awaitTermination(duration, unit); + } +} diff --git a/google-cloud-datastore/src/main/resources/META-INF/native-image/com.google.cloud.datastore.v1/reflect-config.json b/google-cloud-datastore/src/main/resources/META-INF/native-image/com.google.cloud.datastore.v1/reflect-config.json new file mode 100644 index 000000000..b0a64366e --- /dev/null +++ b/google-cloud-datastore/src/main/resources/META-INF/native-image/com.google.cloud.datastore.v1/reflect-config.json @@ -0,0 +1,2198 @@ +[ + { + "name": "com.google.api.ClientLibraryDestination", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.ClientLibraryOrganization", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.ClientLibrarySettings", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.ClientLibrarySettings$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.CommonLanguageSettings", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.CommonLanguageSettings$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.CppSettings", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.CppSettings$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.CustomHttpPattern", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.CustomHttpPattern$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.DotnetSettings", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.DotnetSettings$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.FieldBehavior", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.GoSettings", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.GoSettings$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.Http", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.Http$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.HttpRule", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.HttpRule$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.JavaSettings", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.JavaSettings$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.LaunchStage", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.MethodSettings", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.MethodSettings$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.MethodSettings$LongRunning", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.MethodSettings$LongRunning$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.NodeSettings", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.NodeSettings$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.PhpSettings", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.PhpSettings$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.Publishing", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.Publishing$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.PythonSettings", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.PythonSettings$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.ResourceDescriptor", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.ResourceDescriptor$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.ResourceDescriptor$History", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.ResourceDescriptor$Style", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.ResourceReference", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.ResourceReference$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.RoutingParameter", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.RoutingParameter$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.RoutingRule", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.RoutingRule$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.RubySettings", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.api.RubySettings$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AggregationQuery", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AggregationQuery$Aggregation", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AggregationQuery$Aggregation$Avg", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AggregationQuery$Aggregation$Avg$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AggregationQuery$Aggregation$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AggregationQuery$Aggregation$Count", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AggregationQuery$Aggregation$Count$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AggregationQuery$Aggregation$Sum", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AggregationQuery$Aggregation$Sum$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AggregationQuery$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AggregationResult", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AggregationResult$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AggregationResultBatch", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AggregationResultBatch$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AllocateIdsRequest", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AllocateIdsRequest$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AllocateIdsResponse", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.AllocateIdsResponse$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.ArrayValue", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.ArrayValue$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.BeginTransactionRequest", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.BeginTransactionRequest$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.BeginTransactionResponse", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.BeginTransactionResponse$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.CommitRequest", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.CommitRequest$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.CommitRequest$Mode", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.CommitResponse", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.CommitResponse$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.CompositeFilter", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.CompositeFilter$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.CompositeFilter$Operator", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Entity", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Entity$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.EntityResult", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.EntityResult$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.EntityResult$ResultType", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Filter", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Filter$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.GqlQuery", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.GqlQuery$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.GqlQueryParameter", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.GqlQueryParameter$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Key", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Key$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Key$PathElement", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Key$PathElement$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.KindExpression", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.KindExpression$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.LookupRequest", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.LookupRequest$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.LookupResponse", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.LookupResponse$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Mutation", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Mutation$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.MutationResult", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.MutationResult$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.PartitionId", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.PartitionId$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Projection", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Projection$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.PropertyFilter", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.PropertyFilter$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.PropertyFilter$Operator", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.PropertyOrder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.PropertyOrder$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.PropertyOrder$Direction", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.PropertyReference", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.PropertyReference$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Query", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Query$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.QueryResultBatch", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.QueryResultBatch$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.QueryResultBatch$MoreResultsType", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.ReadOptions", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.ReadOptions$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.ReadOptions$ReadConsistency", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.ReserveIdsRequest", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.ReserveIdsRequest$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.ReserveIdsResponse", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.ReserveIdsResponse$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.RollbackRequest", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.RollbackRequest$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.RollbackResponse", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.RollbackResponse$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.RunAggregationQueryRequest", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.RunAggregationQueryRequest$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.RunAggregationQueryResponse", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.RunAggregationQueryResponse$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.RunQueryRequest", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.RunQueryRequest$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.RunQueryResponse", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.RunQueryResponse$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.TransactionOptions", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.TransactionOptions$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.TransactionOptions$ReadOnly", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.TransactionOptions$ReadOnly$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.TransactionOptions$ReadWrite", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.TransactionOptions$ReadWrite$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Value", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.datastore.v1.Value$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.BoolValue", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.BoolValue$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.BytesValue", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.BytesValue$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$DescriptorProto", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$DescriptorProto$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$DescriptorProto$ExtensionRange", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$DescriptorProto$ExtensionRange$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$DescriptorProto$ReservedRange", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$DescriptorProto$ReservedRange$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$EnumDescriptorProto", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$EnumDescriptorProto$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$EnumDescriptorProto$EnumReservedRange", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$EnumDescriptorProto$EnumReservedRange$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$EnumOptions", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$EnumOptions$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$EnumValueDescriptorProto", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$EnumValueDescriptorProto$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$EnumValueOptions", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$EnumValueOptions$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$ExtensionRangeOptions", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$ExtensionRangeOptions$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$ExtensionRangeOptions$Declaration", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$ExtensionRangeOptions$Declaration$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$ExtensionRangeOptions$VerificationState", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FieldDescriptorProto", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FieldDescriptorProto$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FieldDescriptorProto$Label", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FieldDescriptorProto$Type", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FieldOptions", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FieldOptions$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FieldOptions$CType", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FieldOptions$JSType", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FieldOptions$OptionRetention", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FieldOptions$OptionTargetType", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FileDescriptorProto", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FileDescriptorProto$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FileDescriptorSet", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FileDescriptorSet$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FileOptions", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FileOptions$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$FileOptions$OptimizeMode", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$GeneratedCodeInfo", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$GeneratedCodeInfo$Annotation", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$GeneratedCodeInfo$Annotation$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$GeneratedCodeInfo$Annotation$Semantic", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$GeneratedCodeInfo$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$MessageOptions", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$MessageOptions$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$MethodDescriptorProto", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$MethodDescriptorProto$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$MethodOptions", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$MethodOptions$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$MethodOptions$IdempotencyLevel", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$OneofDescriptorProto", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$OneofDescriptorProto$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$OneofOptions", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$OneofOptions$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$ServiceDescriptorProto", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$ServiceDescriptorProto$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$ServiceOptions", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$ServiceOptions$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$SourceCodeInfo", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$SourceCodeInfo$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$SourceCodeInfo$Location", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$SourceCodeInfo$Location$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$UninterpretedOption", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$UninterpretedOption$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$UninterpretedOption$NamePart", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DescriptorProtos$UninterpretedOption$NamePart$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DoubleValue", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.DoubleValue$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.Duration", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.Duration$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.FloatValue", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.FloatValue$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.Int32Value", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.Int32Value$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.Int64Value", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.Int64Value$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.ListValue", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.ListValue$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.NullValue", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.StringValue", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.StringValue$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.Struct", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.Struct$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.Timestamp", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.Timestamp$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.UInt32Value", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.UInt32Value$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.UInt64Value", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.UInt64Value$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.Value", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.protobuf.Value$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.type.LatLng", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.type.LatLng$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + } +] \ No newline at end of file diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/DatastoreClientHttpJsonTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/DatastoreClientHttpJsonTest.java new file mode 100644 index 000000000..fa3a2a4e9 --- /dev/null +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/DatastoreClientHttpJsonTest.java @@ -0,0 +1,538 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.v1; + +import com.google.api.gax.core.NoCredentialsProvider; +import com.google.api.gax.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.httpjson.testing.MockHttpService; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ApiExceptionFactory; +import com.google.api.gax.rpc.InvalidArgumentException; +import com.google.api.gax.rpc.StatusCode; +import com.google.api.gax.rpc.testing.FakeStatusCode; +import com.google.cloud.datastore.v1.stub.HttpJsonDatastoreStub; +import com.google.datastore.v1.AggregationQuery; +import com.google.datastore.v1.AggregationResultBatch; +import com.google.datastore.v1.AllocateIdsResponse; +import com.google.datastore.v1.BeginTransactionResponse; +import com.google.datastore.v1.CommitRequest; +import com.google.datastore.v1.CommitResponse; +import com.google.datastore.v1.EntityResult; +import com.google.datastore.v1.Key; +import com.google.datastore.v1.LookupResponse; +import com.google.datastore.v1.Mutation; +import com.google.datastore.v1.MutationResult; +import com.google.datastore.v1.PartitionId; +import com.google.datastore.v1.Query; +import com.google.datastore.v1.QueryResultBatch; +import com.google.datastore.v1.ReadOptions; +import com.google.datastore.v1.ReserveIdsResponse; +import com.google.datastore.v1.RollbackResponse; +import com.google.datastore.v1.RunAggregationQueryRequest; +import com.google.datastore.v1.RunAggregationQueryResponse; +import com.google.datastore.v1.RunQueryRequest; +import com.google.datastore.v1.RunQueryResponse; +import com.google.protobuf.ByteString; +import com.google.protobuf.Timestamp; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Generated; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +@Generated("by gapic-generator-java") +public class DatastoreClientHttpJsonTest { + private static MockHttpService mockService; + private static DatastoreClient client; + + @BeforeClass + public static void startStaticServer() throws IOException { + mockService = + new MockHttpService( + HttpJsonDatastoreStub.getMethodDescriptors(), DatastoreSettings.getDefaultEndpoint()); + DatastoreSettings settings = + DatastoreSettings.newHttpJsonBuilder() + .setTransportChannelProvider( + DatastoreSettings.defaultHttpJsonTransportProviderBuilder() + .setHttpTransport(mockService) + .build()) + .setCredentialsProvider(NoCredentialsProvider.create()) + .build(); + client = DatastoreClient.create(settings); + } + + @AfterClass + public static void stopServer() { + client.close(); + } + + @Before + public void setUp() {} + + @After + public void tearDown() throws Exception { + mockService.reset(); + } + + @Test + public void lookupTest() throws Exception { + LookupResponse expectedResponse = + LookupResponse.newBuilder() + .addAllFound(new ArrayList()) + .addAllMissing(new ArrayList()) + .addAllDeferred(new ArrayList()) + .setTransaction(ByteString.EMPTY) + .setReadTime(Timestamp.newBuilder().build()) + .build(); + mockService.addResponse(expectedResponse); + + String projectId = "projectId-1530"; + ReadOptions readOptions = ReadOptions.newBuilder().build(); + List keys = new ArrayList<>(); + + LookupResponse actualResponse = client.lookup(projectId, readOptions, keys); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void lookupExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String projectId = "projectId-1530"; + ReadOptions readOptions = ReadOptions.newBuilder().build(); + List keys = new ArrayList<>(); + client.lookup(projectId, readOptions, keys); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void runQueryTest() throws Exception { + RunQueryResponse expectedResponse = + RunQueryResponse.newBuilder() + .setBatch(QueryResultBatch.newBuilder().build()) + .setQuery(Query.newBuilder().build()) + .setTransaction(ByteString.EMPTY) + .build(); + mockService.addResponse(expectedResponse); + + RunQueryRequest request = + RunQueryRequest.newBuilder() + .setProjectId("projectId-1530") + .setDatabaseId("databaseId1688905718") + .setPartitionId(PartitionId.newBuilder().build()) + .setReadOptions(ReadOptions.newBuilder().build()) + .build(); + + RunQueryResponse actualResponse = client.runQuery(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void runQueryExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + RunQueryRequest request = + RunQueryRequest.newBuilder() + .setProjectId("projectId-1530") + .setDatabaseId("databaseId1688905718") + .setPartitionId(PartitionId.newBuilder().build()) + .setReadOptions(ReadOptions.newBuilder().build()) + .build(); + client.runQuery(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void runAggregationQueryTest() throws Exception { + RunAggregationQueryResponse expectedResponse = + RunAggregationQueryResponse.newBuilder() + .setBatch(AggregationResultBatch.newBuilder().build()) + .setQuery(AggregationQuery.newBuilder().build()) + .setTransaction(ByteString.EMPTY) + .build(); + mockService.addResponse(expectedResponse); + + RunAggregationQueryRequest request = + RunAggregationQueryRequest.newBuilder() + .setProjectId("projectId-1530") + .setDatabaseId("databaseId1688905718") + .setPartitionId(PartitionId.newBuilder().build()) + .setReadOptions(ReadOptions.newBuilder().build()) + .build(); + + RunAggregationQueryResponse actualResponse = client.runAggregationQuery(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void runAggregationQueryExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + RunAggregationQueryRequest request = + RunAggregationQueryRequest.newBuilder() + .setProjectId("projectId-1530") + .setDatabaseId("databaseId1688905718") + .setPartitionId(PartitionId.newBuilder().build()) + .setReadOptions(ReadOptions.newBuilder().build()) + .build(); + client.runAggregationQuery(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void beginTransactionTest() throws Exception { + BeginTransactionResponse expectedResponse = + BeginTransactionResponse.newBuilder().setTransaction(ByteString.EMPTY).build(); + mockService.addResponse(expectedResponse); + + String projectId = "projectId-1530"; + + BeginTransactionResponse actualResponse = client.beginTransaction(projectId); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void beginTransactionExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String projectId = "projectId-1530"; + client.beginTransaction(projectId); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void commitTest() throws Exception { + CommitResponse expectedResponse = + CommitResponse.newBuilder() + .addAllMutationResults(new ArrayList()) + .setIndexUpdates(-1425228195) + .setCommitTime(Timestamp.newBuilder().build()) + .build(); + mockService.addResponse(expectedResponse); + + String projectId = "projectId-1530"; + CommitRequest.Mode mode = CommitRequest.Mode.forNumber(0); + List mutations = new ArrayList<>(); + + CommitResponse actualResponse = client.commit(projectId, mode, mutations); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void commitExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String projectId = "projectId-1530"; + CommitRequest.Mode mode = CommitRequest.Mode.forNumber(0); + List mutations = new ArrayList<>(); + client.commit(projectId, mode, mutations); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void commitTest2() throws Exception { + CommitResponse expectedResponse = + CommitResponse.newBuilder() + .addAllMutationResults(new ArrayList()) + .setIndexUpdates(-1425228195) + .setCommitTime(Timestamp.newBuilder().build()) + .build(); + mockService.addResponse(expectedResponse); + + String projectId = "projectId-1530"; + CommitRequest.Mode mode = CommitRequest.Mode.forNumber(0); + ByteString transaction = ByteString.EMPTY; + List mutations = new ArrayList<>(); + + CommitResponse actualResponse = client.commit(projectId, mode, transaction, mutations); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void commitExceptionTest2() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String projectId = "projectId-1530"; + CommitRequest.Mode mode = CommitRequest.Mode.forNumber(0); + ByteString transaction = ByteString.EMPTY; + List mutations = new ArrayList<>(); + client.commit(projectId, mode, transaction, mutations); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void rollbackTest() throws Exception { + RollbackResponse expectedResponse = RollbackResponse.newBuilder().build(); + mockService.addResponse(expectedResponse); + + String projectId = "projectId-1530"; + ByteString transaction = ByteString.EMPTY; + + RollbackResponse actualResponse = client.rollback(projectId, transaction); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void rollbackExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String projectId = "projectId-1530"; + ByteString transaction = ByteString.EMPTY; + client.rollback(projectId, transaction); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void allocateIdsTest() throws Exception { + AllocateIdsResponse expectedResponse = + AllocateIdsResponse.newBuilder().addAllKeys(new ArrayList()).build(); + mockService.addResponse(expectedResponse); + + String projectId = "projectId-1530"; + List keys = new ArrayList<>(); + + AllocateIdsResponse actualResponse = client.allocateIds(projectId, keys); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void allocateIdsExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String projectId = "projectId-1530"; + List keys = new ArrayList<>(); + client.allocateIds(projectId, keys); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void reserveIdsTest() throws Exception { + ReserveIdsResponse expectedResponse = ReserveIdsResponse.newBuilder().build(); + mockService.addResponse(expectedResponse); + + String projectId = "projectId-1530"; + List keys = new ArrayList<>(); + + ReserveIdsResponse actualResponse = client.reserveIds(projectId, keys); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void reserveIdsExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String projectId = "projectId-1530"; + List keys = new ArrayList<>(); + client.reserveIds(projectId, keys); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } +} diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/DatastoreClientTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/DatastoreClientTest.java new file mode 100644 index 000000000..663de9fb0 --- /dev/null +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/DatastoreClientTest.java @@ -0,0 +1,514 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.v1; + +import com.google.api.gax.core.NoCredentialsProvider; +import com.google.api.gax.grpc.GaxGrpcProperties; +import com.google.api.gax.grpc.testing.LocalChannelProvider; +import com.google.api.gax.grpc.testing.MockGrpcService; +import com.google.api.gax.grpc.testing.MockServiceHelper; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.InvalidArgumentException; +import com.google.datastore.v1.AggregationQuery; +import com.google.datastore.v1.AggregationResultBatch; +import com.google.datastore.v1.AllocateIdsRequest; +import com.google.datastore.v1.AllocateIdsResponse; +import com.google.datastore.v1.BeginTransactionRequest; +import com.google.datastore.v1.BeginTransactionResponse; +import com.google.datastore.v1.CommitRequest; +import com.google.datastore.v1.CommitResponse; +import com.google.datastore.v1.EntityResult; +import com.google.datastore.v1.Key; +import com.google.datastore.v1.LookupRequest; +import com.google.datastore.v1.LookupResponse; +import com.google.datastore.v1.Mutation; +import com.google.datastore.v1.MutationResult; +import com.google.datastore.v1.PartitionId; +import com.google.datastore.v1.Query; +import com.google.datastore.v1.QueryResultBatch; +import com.google.datastore.v1.ReadOptions; +import com.google.datastore.v1.ReserveIdsRequest; +import com.google.datastore.v1.ReserveIdsResponse; +import com.google.datastore.v1.RollbackRequest; +import com.google.datastore.v1.RollbackResponse; +import com.google.datastore.v1.RunAggregationQueryRequest; +import com.google.datastore.v1.RunAggregationQueryResponse; +import com.google.datastore.v1.RunQueryRequest; +import com.google.datastore.v1.RunQueryResponse; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.ByteString; +import com.google.protobuf.Timestamp; +import io.grpc.StatusRuntimeException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import javax.annotation.Generated; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +@Generated("by gapic-generator-java") +public class DatastoreClientTest { + private static MockDatastore mockDatastore; + private static MockServiceHelper mockServiceHelper; + private LocalChannelProvider channelProvider; + private DatastoreClient client; + + @BeforeClass + public static void startStaticServer() { + mockDatastore = new MockDatastore(); + mockServiceHelper = + new MockServiceHelper( + UUID.randomUUID().toString(), Arrays.asList(mockDatastore)); + mockServiceHelper.start(); + } + + @AfterClass + public static void stopServer() { + mockServiceHelper.stop(); + } + + @Before + public void setUp() throws IOException { + mockServiceHelper.reset(); + channelProvider = mockServiceHelper.createChannelProvider(); + DatastoreSettings settings = + DatastoreSettings.newBuilder() + .setTransportChannelProvider(channelProvider) + .setCredentialsProvider(NoCredentialsProvider.create()) + .build(); + client = DatastoreClient.create(settings); + } + + @After + public void tearDown() throws Exception { + client.close(); + } + + @Test + public void lookupTest() throws Exception { + LookupResponse expectedResponse = + LookupResponse.newBuilder() + .addAllFound(new ArrayList()) + .addAllMissing(new ArrayList()) + .addAllDeferred(new ArrayList()) + .setTransaction(ByteString.EMPTY) + .setReadTime(Timestamp.newBuilder().build()) + .build(); + mockDatastore.addResponse(expectedResponse); + + String projectId = "projectId-894832108"; + ReadOptions readOptions = ReadOptions.newBuilder().build(); + List keys = new ArrayList<>(); + + LookupResponse actualResponse = client.lookup(projectId, readOptions, keys); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockDatastore.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + LookupRequest actualRequest = ((LookupRequest) actualRequests.get(0)); + + Assert.assertEquals(projectId, actualRequest.getProjectId()); + Assert.assertEquals(readOptions, actualRequest.getReadOptions()); + Assert.assertEquals(keys, actualRequest.getKeysList()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void lookupExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockDatastore.addException(exception); + + try { + String projectId = "projectId-894832108"; + ReadOptions readOptions = ReadOptions.newBuilder().build(); + List keys = new ArrayList<>(); + client.lookup(projectId, readOptions, keys); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void runQueryTest() throws Exception { + RunQueryResponse expectedResponse = + RunQueryResponse.newBuilder() + .setBatch(QueryResultBatch.newBuilder().build()) + .setQuery(Query.newBuilder().build()) + .setTransaction(ByteString.EMPTY) + .build(); + mockDatastore.addResponse(expectedResponse); + + RunQueryRequest request = + RunQueryRequest.newBuilder() + .setProjectId("projectId-894832108") + .setDatabaseId("databaseId1688905718") + .setPartitionId(PartitionId.newBuilder().build()) + .setReadOptions(ReadOptions.newBuilder().build()) + .build(); + + RunQueryResponse actualResponse = client.runQuery(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockDatastore.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + RunQueryRequest actualRequest = ((RunQueryRequest) actualRequests.get(0)); + + Assert.assertEquals(request.getProjectId(), actualRequest.getProjectId()); + Assert.assertEquals(request.getDatabaseId(), actualRequest.getDatabaseId()); + Assert.assertEquals(request.getPartitionId(), actualRequest.getPartitionId()); + Assert.assertEquals(request.getReadOptions(), actualRequest.getReadOptions()); + Assert.assertEquals(request.getQuery(), actualRequest.getQuery()); + Assert.assertEquals(request.getGqlQuery(), actualRequest.getGqlQuery()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void runQueryExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockDatastore.addException(exception); + + try { + RunQueryRequest request = + RunQueryRequest.newBuilder() + .setProjectId("projectId-894832108") + .setDatabaseId("databaseId1688905718") + .setPartitionId(PartitionId.newBuilder().build()) + .setReadOptions(ReadOptions.newBuilder().build()) + .build(); + client.runQuery(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void runAggregationQueryTest() throws Exception { + RunAggregationQueryResponse expectedResponse = + RunAggregationQueryResponse.newBuilder() + .setBatch(AggregationResultBatch.newBuilder().build()) + .setQuery(AggregationQuery.newBuilder().build()) + .setTransaction(ByteString.EMPTY) + .build(); + mockDatastore.addResponse(expectedResponse); + + RunAggregationQueryRequest request = + RunAggregationQueryRequest.newBuilder() + .setProjectId("projectId-894832108") + .setDatabaseId("databaseId1688905718") + .setPartitionId(PartitionId.newBuilder().build()) + .setReadOptions(ReadOptions.newBuilder().build()) + .build(); + + RunAggregationQueryResponse actualResponse = client.runAggregationQuery(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockDatastore.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + RunAggregationQueryRequest actualRequest = ((RunAggregationQueryRequest) actualRequests.get(0)); + + Assert.assertEquals(request.getProjectId(), actualRequest.getProjectId()); + Assert.assertEquals(request.getDatabaseId(), actualRequest.getDatabaseId()); + Assert.assertEquals(request.getPartitionId(), actualRequest.getPartitionId()); + Assert.assertEquals(request.getReadOptions(), actualRequest.getReadOptions()); + Assert.assertEquals(request.getAggregationQuery(), actualRequest.getAggregationQuery()); + Assert.assertEquals(request.getGqlQuery(), actualRequest.getGqlQuery()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void runAggregationQueryExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockDatastore.addException(exception); + + try { + RunAggregationQueryRequest request = + RunAggregationQueryRequest.newBuilder() + .setProjectId("projectId-894832108") + .setDatabaseId("databaseId1688905718") + .setPartitionId(PartitionId.newBuilder().build()) + .setReadOptions(ReadOptions.newBuilder().build()) + .build(); + client.runAggregationQuery(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void beginTransactionTest() throws Exception { + BeginTransactionResponse expectedResponse = + BeginTransactionResponse.newBuilder().setTransaction(ByteString.EMPTY).build(); + mockDatastore.addResponse(expectedResponse); + + String projectId = "projectId-894832108"; + + BeginTransactionResponse actualResponse = client.beginTransaction(projectId); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockDatastore.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + BeginTransactionRequest actualRequest = ((BeginTransactionRequest) actualRequests.get(0)); + + Assert.assertEquals(projectId, actualRequest.getProjectId()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void beginTransactionExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockDatastore.addException(exception); + + try { + String projectId = "projectId-894832108"; + client.beginTransaction(projectId); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void commitTest() throws Exception { + CommitResponse expectedResponse = + CommitResponse.newBuilder() + .addAllMutationResults(new ArrayList()) + .setIndexUpdates(-1425228195) + .setCommitTime(Timestamp.newBuilder().build()) + .build(); + mockDatastore.addResponse(expectedResponse); + + String projectId = "projectId-894832108"; + CommitRequest.Mode mode = CommitRequest.Mode.forNumber(0); + List mutations = new ArrayList<>(); + + CommitResponse actualResponse = client.commit(projectId, mode, mutations); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockDatastore.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + CommitRequest actualRequest = ((CommitRequest) actualRequests.get(0)); + + Assert.assertEquals(projectId, actualRequest.getProjectId()); + Assert.assertEquals(mode, actualRequest.getMode()); + Assert.assertEquals(mutations, actualRequest.getMutationsList()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void commitExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockDatastore.addException(exception); + + try { + String projectId = "projectId-894832108"; + CommitRequest.Mode mode = CommitRequest.Mode.forNumber(0); + List mutations = new ArrayList<>(); + client.commit(projectId, mode, mutations); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void commitTest2() throws Exception { + CommitResponse expectedResponse = + CommitResponse.newBuilder() + .addAllMutationResults(new ArrayList()) + .setIndexUpdates(-1425228195) + .setCommitTime(Timestamp.newBuilder().build()) + .build(); + mockDatastore.addResponse(expectedResponse); + + String projectId = "projectId-894832108"; + CommitRequest.Mode mode = CommitRequest.Mode.forNumber(0); + ByteString transaction = ByteString.EMPTY; + List mutations = new ArrayList<>(); + + CommitResponse actualResponse = client.commit(projectId, mode, transaction, mutations); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockDatastore.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + CommitRequest actualRequest = ((CommitRequest) actualRequests.get(0)); + + Assert.assertEquals(projectId, actualRequest.getProjectId()); + Assert.assertEquals(mode, actualRequest.getMode()); + Assert.assertEquals(transaction, actualRequest.getTransaction()); + Assert.assertEquals(mutations, actualRequest.getMutationsList()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void commitExceptionTest2() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockDatastore.addException(exception); + + try { + String projectId = "projectId-894832108"; + CommitRequest.Mode mode = CommitRequest.Mode.forNumber(0); + ByteString transaction = ByteString.EMPTY; + List mutations = new ArrayList<>(); + client.commit(projectId, mode, transaction, mutations); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void rollbackTest() throws Exception { + RollbackResponse expectedResponse = RollbackResponse.newBuilder().build(); + mockDatastore.addResponse(expectedResponse); + + String projectId = "projectId-894832108"; + ByteString transaction = ByteString.EMPTY; + + RollbackResponse actualResponse = client.rollback(projectId, transaction); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockDatastore.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + RollbackRequest actualRequest = ((RollbackRequest) actualRequests.get(0)); + + Assert.assertEquals(projectId, actualRequest.getProjectId()); + Assert.assertEquals(transaction, actualRequest.getTransaction()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void rollbackExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockDatastore.addException(exception); + + try { + String projectId = "projectId-894832108"; + ByteString transaction = ByteString.EMPTY; + client.rollback(projectId, transaction); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void allocateIdsTest() throws Exception { + AllocateIdsResponse expectedResponse = + AllocateIdsResponse.newBuilder().addAllKeys(new ArrayList()).build(); + mockDatastore.addResponse(expectedResponse); + + String projectId = "projectId-894832108"; + List keys = new ArrayList<>(); + + AllocateIdsResponse actualResponse = client.allocateIds(projectId, keys); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockDatastore.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + AllocateIdsRequest actualRequest = ((AllocateIdsRequest) actualRequests.get(0)); + + Assert.assertEquals(projectId, actualRequest.getProjectId()); + Assert.assertEquals(keys, actualRequest.getKeysList()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void allocateIdsExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockDatastore.addException(exception); + + try { + String projectId = "projectId-894832108"; + List keys = new ArrayList<>(); + client.allocateIds(projectId, keys); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void reserveIdsTest() throws Exception { + ReserveIdsResponse expectedResponse = ReserveIdsResponse.newBuilder().build(); + mockDatastore.addResponse(expectedResponse); + + String projectId = "projectId-894832108"; + List keys = new ArrayList<>(); + + ReserveIdsResponse actualResponse = client.reserveIds(projectId, keys); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockDatastore.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + ReserveIdsRequest actualRequest = ((ReserveIdsRequest) actualRequests.get(0)); + + Assert.assertEquals(projectId, actualRequest.getProjectId()); + Assert.assertEquals(keys, actualRequest.getKeysList()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void reserveIdsExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockDatastore.addException(exception); + + try { + String projectId = "projectId-894832108"; + List keys = new ArrayList<>(); + client.reserveIds(projectId, keys); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } +} diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/MockDatastore.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/MockDatastore.java new file mode 100644 index 000000000..d2295784c --- /dev/null +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/MockDatastore.java @@ -0,0 +1,59 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.v1; + +import com.google.api.core.BetaApi; +import com.google.api.gax.grpc.testing.MockGrpcService; +import com.google.protobuf.AbstractMessage; +import io.grpc.ServerServiceDefinition; +import java.util.List; +import javax.annotation.Generated; + +@BetaApi +@Generated("by gapic-generator-java") +public class MockDatastore implements MockGrpcService { + private final MockDatastoreImpl serviceImpl; + + public MockDatastore() { + serviceImpl = new MockDatastoreImpl(); + } + + @Override + public List getRequests() { + return serviceImpl.getRequests(); + } + + @Override + public void addResponse(AbstractMessage response) { + serviceImpl.addResponse(response); + } + + @Override + public void addException(Exception exception) { + serviceImpl.addException(exception); + } + + @Override + public ServerServiceDefinition getServiceDefinition() { + return serviceImpl.bindService(); + } + + @Override + public void reset() { + serviceImpl.reset(); + } +} diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/MockDatastoreImpl.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/MockDatastoreImpl.java new file mode 100644 index 000000000..3b3d8b937 --- /dev/null +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/v1/MockDatastoreImpl.java @@ -0,0 +1,241 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.v1; + +import com.google.api.core.BetaApi; +import com.google.datastore.v1.AllocateIdsRequest; +import com.google.datastore.v1.AllocateIdsResponse; +import com.google.datastore.v1.BeginTransactionRequest; +import com.google.datastore.v1.BeginTransactionResponse; +import com.google.datastore.v1.CommitRequest; +import com.google.datastore.v1.CommitResponse; +import com.google.datastore.v1.DatastoreGrpc.DatastoreImplBase; +import com.google.datastore.v1.LookupRequest; +import com.google.datastore.v1.LookupResponse; +import com.google.datastore.v1.ReserveIdsRequest; +import com.google.datastore.v1.ReserveIdsResponse; +import com.google.datastore.v1.RollbackRequest; +import com.google.datastore.v1.RollbackResponse; +import com.google.datastore.v1.RunAggregationQueryRequest; +import com.google.datastore.v1.RunAggregationQueryResponse; +import com.google.datastore.v1.RunQueryRequest; +import com.google.datastore.v1.RunQueryResponse; +import com.google.protobuf.AbstractMessage; +import io.grpc.stub.StreamObserver; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import javax.annotation.Generated; + +@BetaApi +@Generated("by gapic-generator-java") +public class MockDatastoreImpl extends DatastoreImplBase { + private List requests; + private Queue responses; + + public MockDatastoreImpl() { + requests = new ArrayList<>(); + responses = new LinkedList<>(); + } + + public List getRequests() { + return requests; + } + + public void addResponse(AbstractMessage response) { + responses.add(response); + } + + public void setResponses(List responses) { + this.responses = new LinkedList(responses); + } + + public void addException(Exception exception) { + responses.add(exception); + } + + public void reset() { + requests = new ArrayList<>(); + responses = new LinkedList<>(); + } + + @Override + public void lookup(LookupRequest request, StreamObserver responseObserver) { + Object response = responses.poll(); + if (response instanceof LookupResponse) { + requests.add(request); + responseObserver.onNext(((LookupResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method Lookup, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + LookupResponse.class.getName(), + Exception.class.getName()))); + } + } + + @Override + public void runQuery(RunQueryRequest request, StreamObserver responseObserver) { + Object response = responses.poll(); + if (response instanceof RunQueryResponse) { + requests.add(request); + responseObserver.onNext(((RunQueryResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method RunQuery, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + RunQueryResponse.class.getName(), + Exception.class.getName()))); + } + } + + @Override + public void runAggregationQuery( + RunAggregationQueryRequest request, + StreamObserver responseObserver) { + Object response = responses.poll(); + if (response instanceof RunAggregationQueryResponse) { + requests.add(request); + responseObserver.onNext(((RunAggregationQueryResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method RunAggregationQuery, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + RunAggregationQueryResponse.class.getName(), + Exception.class.getName()))); + } + } + + @Override + public void beginTransaction( + BeginTransactionRequest request, StreamObserver responseObserver) { + Object response = responses.poll(); + if (response instanceof BeginTransactionResponse) { + requests.add(request); + responseObserver.onNext(((BeginTransactionResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method BeginTransaction, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + BeginTransactionResponse.class.getName(), + Exception.class.getName()))); + } + } + + @Override + public void commit(CommitRequest request, StreamObserver responseObserver) { + Object response = responses.poll(); + if (response instanceof CommitResponse) { + requests.add(request); + responseObserver.onNext(((CommitResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method Commit, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + CommitResponse.class.getName(), + Exception.class.getName()))); + } + } + + @Override + public void rollback(RollbackRequest request, StreamObserver responseObserver) { + Object response = responses.poll(); + if (response instanceof RollbackResponse) { + requests.add(request); + responseObserver.onNext(((RollbackResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method Rollback, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + RollbackResponse.class.getName(), + Exception.class.getName()))); + } + } + + @Override + public void allocateIds( + AllocateIdsRequest request, StreamObserver responseObserver) { + Object response = responses.poll(); + if (response instanceof AllocateIdsResponse) { + requests.add(request); + responseObserver.onNext(((AllocateIdsResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method AllocateIds, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + AllocateIdsResponse.class.getName(), + Exception.class.getName()))); + } + } + + @Override + public void reserveIds( + ReserveIdsRequest request, StreamObserver responseObserver) { + Object response = responses.poll(); + if (response instanceof ReserveIdsResponse) { + requests.add(request); + responseObserver.onNext(((ReserveIdsResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method ReserveIds, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + ReserveIdsResponse.class.getName(), + Exception.class.getName()))); + } + } +} diff --git a/grpc-google-cloud-datastore-v1/pom.xml b/grpc-google-cloud-datastore-v1/pom.xml new file mode 100644 index 000000000..003dd8432 --- /dev/null +++ b/grpc-google-cloud-datastore-v1/pom.xml @@ -0,0 +1,81 @@ + + 4.0.0 + com.google.api.grpc + grpc-google-cloud-datastore-v1 + 2.17.6-SNAPSHOT + grpc-google-cloud-datastore-v1 + GRPC library for google-cloud-datastore + + com.google.cloud + google-cloud-datastore-parent + 2.17.6-SNAPSHOT + + + + io.grpc + grpc-api + + + io.grpc + grpc-stub + + + io.grpc + grpc-protobuf + + + com.google.protobuf + protobuf-java + + + com.google.api.grpc + proto-google-cloud-datastore-v1 + + + com.google.guava + guava + + + + + + java9 + + [9,) + + + + javax.annotation + javax.annotation-api + + + + + + + + + org.codehaus.mojo + flatten-maven-plugin + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + true + + + + + org.codehaus.mojo + clirr-maven-plugin + + true + + + + + \ No newline at end of file diff --git a/grpc-google-cloud-datastore-v1/src/main/java/com/google/datastore/v1/DatastoreGrpc.java b/grpc-google-cloud-datastore-v1/src/main/java/com/google/datastore/v1/DatastoreGrpc.java new file mode 100644 index 000000000..b3dc940b7 --- /dev/null +++ b/grpc-google-cloud-datastore-v1/src/main/java/com/google/datastore/v1/DatastoreGrpc.java @@ -0,0 +1,1194 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.datastore.v1; + +import static io.grpc.MethodDescriptor.generateFullMethodName; + +/** + * + * + *
+ * Each RPC normalizes the partition IDs of the keys in its input entities,
+ * and always returns entities with keys with normalized partition IDs.
+ * This applies to all keys and entities, including those in values, except keys
+ * with both an empty path and an empty or unset partition ID. Normalization of
+ * input keys sets the project ID (if not already set) to the project ID from
+ * the request.
+ * 
+ */ +@javax.annotation.Generated( + value = "by gRPC proto compiler", + comments = "Source: google/datastore/v1/datastore.proto") +@io.grpc.stub.annotations.GrpcGenerated +public final class DatastoreGrpc { + + private DatastoreGrpc() {} + + public static final java.lang.String SERVICE_NAME = "google.datastore.v1.Datastore"; + + // Static method descriptors that strictly reflect the proto. + private static volatile io.grpc.MethodDescriptor< + com.google.datastore.v1.LookupRequest, com.google.datastore.v1.LookupResponse> + getLookupMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "Lookup", + requestType = com.google.datastore.v1.LookupRequest.class, + responseType = com.google.datastore.v1.LookupResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor< + com.google.datastore.v1.LookupRequest, com.google.datastore.v1.LookupResponse> + getLookupMethod() { + io.grpc.MethodDescriptor< + com.google.datastore.v1.LookupRequest, com.google.datastore.v1.LookupResponse> + getLookupMethod; + if ((getLookupMethod = DatastoreGrpc.getLookupMethod) == null) { + synchronized (DatastoreGrpc.class) { + if ((getLookupMethod = DatastoreGrpc.getLookupMethod) == null) { + DatastoreGrpc.getLookupMethod = + getLookupMethod = + io.grpc.MethodDescriptor + . + newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Lookup")) + .setSampledToLocalTracing(true) + .setRequestMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.LookupRequest.getDefaultInstance())) + .setResponseMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.LookupResponse.getDefaultInstance())) + .setSchemaDescriptor(new DatastoreMethodDescriptorSupplier("Lookup")) + .build(); + } + } + } + return getLookupMethod; + } + + private static volatile io.grpc.MethodDescriptor< + com.google.datastore.v1.RunQueryRequest, com.google.datastore.v1.RunQueryResponse> + getRunQueryMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "RunQuery", + requestType = com.google.datastore.v1.RunQueryRequest.class, + responseType = com.google.datastore.v1.RunQueryResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor< + com.google.datastore.v1.RunQueryRequest, com.google.datastore.v1.RunQueryResponse> + getRunQueryMethod() { + io.grpc.MethodDescriptor< + com.google.datastore.v1.RunQueryRequest, com.google.datastore.v1.RunQueryResponse> + getRunQueryMethod; + if ((getRunQueryMethod = DatastoreGrpc.getRunQueryMethod) == null) { + synchronized (DatastoreGrpc.class) { + if ((getRunQueryMethod = DatastoreGrpc.getRunQueryMethod) == null) { + DatastoreGrpc.getRunQueryMethod = + getRunQueryMethod = + io.grpc.MethodDescriptor + . + newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "RunQuery")) + .setSampledToLocalTracing(true) + .setRequestMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.RunQueryRequest.getDefaultInstance())) + .setResponseMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.RunQueryResponse.getDefaultInstance())) + .setSchemaDescriptor(new DatastoreMethodDescriptorSupplier("RunQuery")) + .build(); + } + } + } + return getRunQueryMethod; + } + + private static volatile io.grpc.MethodDescriptor< + com.google.datastore.v1.RunAggregationQueryRequest, + com.google.datastore.v1.RunAggregationQueryResponse> + getRunAggregationQueryMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "RunAggregationQuery", + requestType = com.google.datastore.v1.RunAggregationQueryRequest.class, + responseType = com.google.datastore.v1.RunAggregationQueryResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor< + com.google.datastore.v1.RunAggregationQueryRequest, + com.google.datastore.v1.RunAggregationQueryResponse> + getRunAggregationQueryMethod() { + io.grpc.MethodDescriptor< + com.google.datastore.v1.RunAggregationQueryRequest, + com.google.datastore.v1.RunAggregationQueryResponse> + getRunAggregationQueryMethod; + if ((getRunAggregationQueryMethod = DatastoreGrpc.getRunAggregationQueryMethod) == null) { + synchronized (DatastoreGrpc.class) { + if ((getRunAggregationQueryMethod = DatastoreGrpc.getRunAggregationQueryMethod) == null) { + DatastoreGrpc.getRunAggregationQueryMethod = + getRunAggregationQueryMethod = + io.grpc.MethodDescriptor + . + newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName( + generateFullMethodName(SERVICE_NAME, "RunAggregationQuery")) + .setSampledToLocalTracing(true) + .setRequestMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.RunAggregationQueryRequest + .getDefaultInstance())) + .setResponseMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.RunAggregationQueryResponse + .getDefaultInstance())) + .setSchemaDescriptor( + new DatastoreMethodDescriptorSupplier("RunAggregationQuery")) + .build(); + } + } + } + return getRunAggregationQueryMethod; + } + + private static volatile io.grpc.MethodDescriptor< + com.google.datastore.v1.BeginTransactionRequest, + com.google.datastore.v1.BeginTransactionResponse> + getBeginTransactionMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "BeginTransaction", + requestType = com.google.datastore.v1.BeginTransactionRequest.class, + responseType = com.google.datastore.v1.BeginTransactionResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor< + com.google.datastore.v1.BeginTransactionRequest, + com.google.datastore.v1.BeginTransactionResponse> + getBeginTransactionMethod() { + io.grpc.MethodDescriptor< + com.google.datastore.v1.BeginTransactionRequest, + com.google.datastore.v1.BeginTransactionResponse> + getBeginTransactionMethod; + if ((getBeginTransactionMethod = DatastoreGrpc.getBeginTransactionMethod) == null) { + synchronized (DatastoreGrpc.class) { + if ((getBeginTransactionMethod = DatastoreGrpc.getBeginTransactionMethod) == null) { + DatastoreGrpc.getBeginTransactionMethod = + getBeginTransactionMethod = + io.grpc.MethodDescriptor + . + newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "BeginTransaction")) + .setSampledToLocalTracing(true) + .setRequestMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.BeginTransactionRequest.getDefaultInstance())) + .setResponseMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.BeginTransactionResponse + .getDefaultInstance())) + .setSchemaDescriptor( + new DatastoreMethodDescriptorSupplier("BeginTransaction")) + .build(); + } + } + } + return getBeginTransactionMethod; + } + + private static volatile io.grpc.MethodDescriptor< + com.google.datastore.v1.CommitRequest, com.google.datastore.v1.CommitResponse> + getCommitMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "Commit", + requestType = com.google.datastore.v1.CommitRequest.class, + responseType = com.google.datastore.v1.CommitResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor< + com.google.datastore.v1.CommitRequest, com.google.datastore.v1.CommitResponse> + getCommitMethod() { + io.grpc.MethodDescriptor< + com.google.datastore.v1.CommitRequest, com.google.datastore.v1.CommitResponse> + getCommitMethod; + if ((getCommitMethod = DatastoreGrpc.getCommitMethod) == null) { + synchronized (DatastoreGrpc.class) { + if ((getCommitMethod = DatastoreGrpc.getCommitMethod) == null) { + DatastoreGrpc.getCommitMethod = + getCommitMethod = + io.grpc.MethodDescriptor + . + newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Commit")) + .setSampledToLocalTracing(true) + .setRequestMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.CommitRequest.getDefaultInstance())) + .setResponseMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.CommitResponse.getDefaultInstance())) + .setSchemaDescriptor(new DatastoreMethodDescriptorSupplier("Commit")) + .build(); + } + } + } + return getCommitMethod; + } + + private static volatile io.grpc.MethodDescriptor< + com.google.datastore.v1.RollbackRequest, com.google.datastore.v1.RollbackResponse> + getRollbackMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "Rollback", + requestType = com.google.datastore.v1.RollbackRequest.class, + responseType = com.google.datastore.v1.RollbackResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor< + com.google.datastore.v1.RollbackRequest, com.google.datastore.v1.RollbackResponse> + getRollbackMethod() { + io.grpc.MethodDescriptor< + com.google.datastore.v1.RollbackRequest, com.google.datastore.v1.RollbackResponse> + getRollbackMethod; + if ((getRollbackMethod = DatastoreGrpc.getRollbackMethod) == null) { + synchronized (DatastoreGrpc.class) { + if ((getRollbackMethod = DatastoreGrpc.getRollbackMethod) == null) { + DatastoreGrpc.getRollbackMethod = + getRollbackMethod = + io.grpc.MethodDescriptor + . + newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Rollback")) + .setSampledToLocalTracing(true) + .setRequestMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.RollbackRequest.getDefaultInstance())) + .setResponseMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.RollbackResponse.getDefaultInstance())) + .setSchemaDescriptor(new DatastoreMethodDescriptorSupplier("Rollback")) + .build(); + } + } + } + return getRollbackMethod; + } + + private static volatile io.grpc.MethodDescriptor< + com.google.datastore.v1.AllocateIdsRequest, com.google.datastore.v1.AllocateIdsResponse> + getAllocateIdsMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "AllocateIds", + requestType = com.google.datastore.v1.AllocateIdsRequest.class, + responseType = com.google.datastore.v1.AllocateIdsResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor< + com.google.datastore.v1.AllocateIdsRequest, com.google.datastore.v1.AllocateIdsResponse> + getAllocateIdsMethod() { + io.grpc.MethodDescriptor< + com.google.datastore.v1.AllocateIdsRequest, com.google.datastore.v1.AllocateIdsResponse> + getAllocateIdsMethod; + if ((getAllocateIdsMethod = DatastoreGrpc.getAllocateIdsMethod) == null) { + synchronized (DatastoreGrpc.class) { + if ((getAllocateIdsMethod = DatastoreGrpc.getAllocateIdsMethod) == null) { + DatastoreGrpc.getAllocateIdsMethod = + getAllocateIdsMethod = + io.grpc.MethodDescriptor + . + newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "AllocateIds")) + .setSampledToLocalTracing(true) + .setRequestMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.AllocateIdsRequest.getDefaultInstance())) + .setResponseMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.AllocateIdsResponse.getDefaultInstance())) + .setSchemaDescriptor(new DatastoreMethodDescriptorSupplier("AllocateIds")) + .build(); + } + } + } + return getAllocateIdsMethod; + } + + private static volatile io.grpc.MethodDescriptor< + com.google.datastore.v1.ReserveIdsRequest, com.google.datastore.v1.ReserveIdsResponse> + getReserveIdsMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "ReserveIds", + requestType = com.google.datastore.v1.ReserveIdsRequest.class, + responseType = com.google.datastore.v1.ReserveIdsResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor< + com.google.datastore.v1.ReserveIdsRequest, com.google.datastore.v1.ReserveIdsResponse> + getReserveIdsMethod() { + io.grpc.MethodDescriptor< + com.google.datastore.v1.ReserveIdsRequest, com.google.datastore.v1.ReserveIdsResponse> + getReserveIdsMethod; + if ((getReserveIdsMethod = DatastoreGrpc.getReserveIdsMethod) == null) { + synchronized (DatastoreGrpc.class) { + if ((getReserveIdsMethod = DatastoreGrpc.getReserveIdsMethod) == null) { + DatastoreGrpc.getReserveIdsMethod = + getReserveIdsMethod = + io.grpc.MethodDescriptor + . + newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "ReserveIds")) + .setSampledToLocalTracing(true) + .setRequestMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.ReserveIdsRequest.getDefaultInstance())) + .setResponseMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.datastore.v1.ReserveIdsResponse.getDefaultInstance())) + .setSchemaDescriptor(new DatastoreMethodDescriptorSupplier("ReserveIds")) + .build(); + } + } + } + return getReserveIdsMethod; + } + + /** Creates a new async stub that supports all call types for the service */ + public static DatastoreStub newStub(io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public DatastoreStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DatastoreStub(channel, callOptions); + } + }; + return DatastoreStub.newStub(factory, channel); + } + + /** + * Creates a new blocking-style stub that supports unary and streaming output calls on the service + */ + public static DatastoreBlockingStub newBlockingStub(io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public DatastoreBlockingStub newStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DatastoreBlockingStub(channel, callOptions); + } + }; + return DatastoreBlockingStub.newStub(factory, channel); + } + + /** Creates a new ListenableFuture-style stub that supports unary calls on the service */ + public static DatastoreFutureStub newFutureStub(io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public DatastoreFutureStub newStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DatastoreFutureStub(channel, callOptions); + } + }; + return DatastoreFutureStub.newStub(factory, channel); + } + + /** + * + * + *
+   * Each RPC normalizes the partition IDs of the keys in its input entities,
+   * and always returns entities with keys with normalized partition IDs.
+   * This applies to all keys and entities, including those in values, except keys
+   * with both an empty path and an empty or unset partition ID. Normalization of
+   * input keys sets the project ID (if not already set) to the project ID from
+   * the request.
+   * 
+ */ + public interface AsyncService { + + /** + * + * + *
+     * Looks up entities by key.
+     * 
+ */ + default void lookup( + com.google.datastore.v1.LookupRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getLookupMethod(), responseObserver); + } + + /** + * + * + *
+     * Queries for entities.
+     * 
+ */ + default void runQuery( + com.google.datastore.v1.RunQueryRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getRunQueryMethod(), responseObserver); + } + + /** + * + * + *
+     * Runs an aggregation query.
+     * 
+ */ + default void runAggregationQuery( + com.google.datastore.v1.RunAggregationQueryRequest request, + io.grpc.stub.StreamObserver + responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall( + getRunAggregationQueryMethod(), responseObserver); + } + + /** + * + * + *
+     * Begins a new transaction.
+     * 
+ */ + default void beginTransaction( + com.google.datastore.v1.BeginTransactionRequest request, + io.grpc.stub.StreamObserver + responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall( + getBeginTransactionMethod(), responseObserver); + } + + /** + * + * + *
+     * Commits a transaction, optionally creating, deleting or modifying some
+     * entities.
+     * 
+ */ + default void commit( + com.google.datastore.v1.CommitRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getCommitMethod(), responseObserver); + } + + /** + * + * + *
+     * Rolls back a transaction.
+     * 
+ */ + default void rollback( + com.google.datastore.v1.RollbackRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getRollbackMethod(), responseObserver); + } + + /** + * + * + *
+     * Allocates IDs for the given keys, which is useful for referencing an entity
+     * before it is inserted.
+     * 
+ */ + default void allocateIds( + com.google.datastore.v1.AllocateIdsRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall( + getAllocateIdsMethod(), responseObserver); + } + + /** + * + * + *
+     * Prevents the supplied keys' IDs from being auto-allocated by Cloud
+     * Datastore.
+     * 
+ */ + default void reserveIds( + com.google.datastore.v1.ReserveIdsRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getReserveIdsMethod(), responseObserver); + } + } + + /** + * Base class for the server implementation of the service Datastore. + * + *
+   * Each RPC normalizes the partition IDs of the keys in its input entities,
+   * and always returns entities with keys with normalized partition IDs.
+   * This applies to all keys and entities, including those in values, except keys
+   * with both an empty path and an empty or unset partition ID. Normalization of
+   * input keys sets the project ID (if not already set) to the project ID from
+   * the request.
+   * 
+ */ + public abstract static class DatastoreImplBase implements io.grpc.BindableService, AsyncService { + + @java.lang.Override + public final io.grpc.ServerServiceDefinition bindService() { + return DatastoreGrpc.bindService(this); + } + } + + /** + * A stub to allow clients to do asynchronous rpc calls to service Datastore. + * + *
+   * Each RPC normalizes the partition IDs of the keys in its input entities,
+   * and always returns entities with keys with normalized partition IDs.
+   * This applies to all keys and entities, including those in values, except keys
+   * with both an empty path and an empty or unset partition ID. Normalization of
+   * input keys sets the project ID (if not already set) to the project ID from
+   * the request.
+   * 
+ */ + public static final class DatastoreStub extends io.grpc.stub.AbstractAsyncStub { + private DatastoreStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected DatastoreStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DatastoreStub(channel, callOptions); + } + + /** + * + * + *
+     * Looks up entities by key.
+     * 
+ */ + public void lookup( + com.google.datastore.v1.LookupRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getLookupMethod(), getCallOptions()), request, responseObserver); + } + + /** + * + * + *
+     * Queries for entities.
+     * 
+ */ + public void runQuery( + com.google.datastore.v1.RunQueryRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getRunQueryMethod(), getCallOptions()), request, responseObserver); + } + + /** + * + * + *
+     * Runs an aggregation query.
+     * 
+ */ + public void runAggregationQuery( + com.google.datastore.v1.RunAggregationQueryRequest request, + io.grpc.stub.StreamObserver + responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getRunAggregationQueryMethod(), getCallOptions()), + request, + responseObserver); + } + + /** + * + * + *
+     * Begins a new transaction.
+     * 
+ */ + public void beginTransaction( + com.google.datastore.v1.BeginTransactionRequest request, + io.grpc.stub.StreamObserver + responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getBeginTransactionMethod(), getCallOptions()), + request, + responseObserver); + } + + /** + * + * + *
+     * Commits a transaction, optionally creating, deleting or modifying some
+     * entities.
+     * 
+ */ + public void commit( + com.google.datastore.v1.CommitRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getCommitMethod(), getCallOptions()), request, responseObserver); + } + + /** + * + * + *
+     * Rolls back a transaction.
+     * 
+ */ + public void rollback( + com.google.datastore.v1.RollbackRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getRollbackMethod(), getCallOptions()), request, responseObserver); + } + + /** + * + * + *
+     * Allocates IDs for the given keys, which is useful for referencing an entity
+     * before it is inserted.
+     * 
+ */ + public void allocateIds( + com.google.datastore.v1.AllocateIdsRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getAllocateIdsMethod(), getCallOptions()), + request, + responseObserver); + } + + /** + * + * + *
+     * Prevents the supplied keys' IDs from being auto-allocated by Cloud
+     * Datastore.
+     * 
+ */ + public void reserveIds( + com.google.datastore.v1.ReserveIdsRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getReserveIdsMethod(), getCallOptions()), request, responseObserver); + } + } + + /** + * A stub to allow clients to do synchronous rpc calls to service Datastore. + * + *
+   * Each RPC normalizes the partition IDs of the keys in its input entities,
+   * and always returns entities with keys with normalized partition IDs.
+   * This applies to all keys and entities, including those in values, except keys
+   * with both an empty path and an empty or unset partition ID. Normalization of
+   * input keys sets the project ID (if not already set) to the project ID from
+   * the request.
+   * 
+ */ + public static final class DatastoreBlockingStub + extends io.grpc.stub.AbstractBlockingStub { + private DatastoreBlockingStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected DatastoreBlockingStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DatastoreBlockingStub(channel, callOptions); + } + + /** + * + * + *
+     * Looks up entities by key.
+     * 
+ */ + public com.google.datastore.v1.LookupResponse lookup( + com.google.datastore.v1.LookupRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getLookupMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Queries for entities.
+     * 
+ */ + public com.google.datastore.v1.RunQueryResponse runQuery( + com.google.datastore.v1.RunQueryRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getRunQueryMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Runs an aggregation query.
+     * 
+ */ + public com.google.datastore.v1.RunAggregationQueryResponse runAggregationQuery( + com.google.datastore.v1.RunAggregationQueryRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getRunAggregationQueryMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Begins a new transaction.
+     * 
+ */ + public com.google.datastore.v1.BeginTransactionResponse beginTransaction( + com.google.datastore.v1.BeginTransactionRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getBeginTransactionMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Commits a transaction, optionally creating, deleting or modifying some
+     * entities.
+     * 
+ */ + public com.google.datastore.v1.CommitResponse commit( + com.google.datastore.v1.CommitRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getCommitMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Rolls back a transaction.
+     * 
+ */ + public com.google.datastore.v1.RollbackResponse rollback( + com.google.datastore.v1.RollbackRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getRollbackMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Allocates IDs for the given keys, which is useful for referencing an entity
+     * before it is inserted.
+     * 
+ */ + public com.google.datastore.v1.AllocateIdsResponse allocateIds( + com.google.datastore.v1.AllocateIdsRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getAllocateIdsMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Prevents the supplied keys' IDs from being auto-allocated by Cloud
+     * Datastore.
+     * 
+ */ + public com.google.datastore.v1.ReserveIdsResponse reserveIds( + com.google.datastore.v1.ReserveIdsRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getReserveIdsMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service Datastore. + * + *
+   * Each RPC normalizes the partition IDs of the keys in its input entities,
+   * and always returns entities with keys with normalized partition IDs.
+   * This applies to all keys and entities, including those in values, except keys
+   * with both an empty path and an empty or unset partition ID. Normalization of
+   * input keys sets the project ID (if not already set) to the project ID from
+   * the request.
+   * 
+ */ + public static final class DatastoreFutureStub + extends io.grpc.stub.AbstractFutureStub { + private DatastoreFutureStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected DatastoreFutureStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DatastoreFutureStub(channel, callOptions); + } + + /** + * + * + *
+     * Looks up entities by key.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture< + com.google.datastore.v1.LookupResponse> + lookup(com.google.datastore.v1.LookupRequest request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getLookupMethod(), getCallOptions()), request); + } + + /** + * + * + *
+     * Queries for entities.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture< + com.google.datastore.v1.RunQueryResponse> + runQuery(com.google.datastore.v1.RunQueryRequest request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getRunQueryMethod(), getCallOptions()), request); + } + + /** + * + * + *
+     * Runs an aggregation query.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture< + com.google.datastore.v1.RunAggregationQueryResponse> + runAggregationQuery(com.google.datastore.v1.RunAggregationQueryRequest request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getRunAggregationQueryMethod(), getCallOptions()), request); + } + + /** + * + * + *
+     * Begins a new transaction.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture< + com.google.datastore.v1.BeginTransactionResponse> + beginTransaction(com.google.datastore.v1.BeginTransactionRequest request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getBeginTransactionMethod(), getCallOptions()), request); + } + + /** + * + * + *
+     * Commits a transaction, optionally creating, deleting or modifying some
+     * entities.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture< + com.google.datastore.v1.CommitResponse> + commit(com.google.datastore.v1.CommitRequest request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getCommitMethod(), getCallOptions()), request); + } + + /** + * + * + *
+     * Rolls back a transaction.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture< + com.google.datastore.v1.RollbackResponse> + rollback(com.google.datastore.v1.RollbackRequest request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getRollbackMethod(), getCallOptions()), request); + } + + /** + * + * + *
+     * Allocates IDs for the given keys, which is useful for referencing an entity
+     * before it is inserted.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture< + com.google.datastore.v1.AllocateIdsResponse> + allocateIds(com.google.datastore.v1.AllocateIdsRequest request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getAllocateIdsMethod(), getCallOptions()), request); + } + + /** + * + * + *
+     * Prevents the supplied keys' IDs from being auto-allocated by Cloud
+     * Datastore.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture< + com.google.datastore.v1.ReserveIdsResponse> + reserveIds(com.google.datastore.v1.ReserveIdsRequest request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getReserveIdsMethod(), getCallOptions()), request); + } + } + + private static final int METHODID_LOOKUP = 0; + private static final int METHODID_RUN_QUERY = 1; + private static final int METHODID_RUN_AGGREGATION_QUERY = 2; + private static final int METHODID_BEGIN_TRANSACTION = 3; + private static final int METHODID_COMMIT = 4; + private static final int METHODID_ROLLBACK = 5; + private static final int METHODID_ALLOCATE_IDS = 6; + private static final int METHODID_RESERVE_IDS = 7; + + private static final class MethodHandlers + implements io.grpc.stub.ServerCalls.UnaryMethod, + io.grpc.stub.ServerCalls.ServerStreamingMethod, + io.grpc.stub.ServerCalls.ClientStreamingMethod, + io.grpc.stub.ServerCalls.BidiStreamingMethod { + private final AsyncService serviceImpl; + private final int methodId; + + MethodHandlers(AsyncService serviceImpl, int methodId) { + this.serviceImpl = serviceImpl; + this.methodId = methodId; + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_LOOKUP: + serviceImpl.lookup( + (com.google.datastore.v1.LookupRequest) request, + (io.grpc.stub.StreamObserver) + responseObserver); + break; + case METHODID_RUN_QUERY: + serviceImpl.runQuery( + (com.google.datastore.v1.RunQueryRequest) request, + (io.grpc.stub.StreamObserver) + responseObserver); + break; + case METHODID_RUN_AGGREGATION_QUERY: + serviceImpl.runAggregationQuery( + (com.google.datastore.v1.RunAggregationQueryRequest) request, + (io.grpc.stub.StreamObserver) + responseObserver); + break; + case METHODID_BEGIN_TRANSACTION: + serviceImpl.beginTransaction( + (com.google.datastore.v1.BeginTransactionRequest) request, + (io.grpc.stub.StreamObserver) + responseObserver); + break; + case METHODID_COMMIT: + serviceImpl.commit( + (com.google.datastore.v1.CommitRequest) request, + (io.grpc.stub.StreamObserver) + responseObserver); + break; + case METHODID_ROLLBACK: + serviceImpl.rollback( + (com.google.datastore.v1.RollbackRequest) request, + (io.grpc.stub.StreamObserver) + responseObserver); + break; + case METHODID_ALLOCATE_IDS: + serviceImpl.allocateIds( + (com.google.datastore.v1.AllocateIdsRequest) request, + (io.grpc.stub.StreamObserver) + responseObserver); + break; + case METHODID_RESERVE_IDS: + serviceImpl.reserveIds( + (com.google.datastore.v1.ReserveIdsRequest) request, + (io.grpc.stub.StreamObserver) + responseObserver); + break; + default: + throw new AssertionError(); + } + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + default: + throw new AssertionError(); + } + } + } + + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getLookupMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + com.google.datastore.v1.LookupRequest, com.google.datastore.v1.LookupResponse>( + service, METHODID_LOOKUP))) + .addMethod( + getRunQueryMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + com.google.datastore.v1.RunQueryRequest, + com.google.datastore.v1.RunQueryResponse>(service, METHODID_RUN_QUERY))) + .addMethod( + getRunAggregationQueryMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + com.google.datastore.v1.RunAggregationQueryRequest, + com.google.datastore.v1.RunAggregationQueryResponse>( + service, METHODID_RUN_AGGREGATION_QUERY))) + .addMethod( + getBeginTransactionMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + com.google.datastore.v1.BeginTransactionRequest, + com.google.datastore.v1.BeginTransactionResponse>( + service, METHODID_BEGIN_TRANSACTION))) + .addMethod( + getCommitMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + com.google.datastore.v1.CommitRequest, com.google.datastore.v1.CommitResponse>( + service, METHODID_COMMIT))) + .addMethod( + getRollbackMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + com.google.datastore.v1.RollbackRequest, + com.google.datastore.v1.RollbackResponse>(service, METHODID_ROLLBACK))) + .addMethod( + getAllocateIdsMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + com.google.datastore.v1.AllocateIdsRequest, + com.google.datastore.v1.AllocateIdsResponse>(service, METHODID_ALLOCATE_IDS))) + .addMethod( + getReserveIdsMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + com.google.datastore.v1.ReserveIdsRequest, + com.google.datastore.v1.ReserveIdsResponse>(service, METHODID_RESERVE_IDS))) + .build(); + } + + private abstract static class DatastoreBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoFileDescriptorSupplier, + io.grpc.protobuf.ProtoServiceDescriptorSupplier { + DatastoreBaseDescriptorSupplier() {} + + @java.lang.Override + public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { + return com.google.datastore.v1.DatastoreProto.getDescriptor(); + } + + @java.lang.Override + public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() { + return getFileDescriptor().findServiceByName("Datastore"); + } + } + + private static final class DatastoreFileDescriptorSupplier + extends DatastoreBaseDescriptorSupplier { + DatastoreFileDescriptorSupplier() {} + } + + private static final class DatastoreMethodDescriptorSupplier + extends DatastoreBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { + private final java.lang.String methodName; + + DatastoreMethodDescriptorSupplier(java.lang.String methodName) { + this.methodName = methodName; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() { + return getServiceDescriptor().findMethodByName(methodName); + } + } + + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; + + public static io.grpc.ServiceDescriptor getServiceDescriptor() { + io.grpc.ServiceDescriptor result = serviceDescriptor; + if (result == null) { + synchronized (DatastoreGrpc.class) { + result = serviceDescriptor; + if (result == null) { + serviceDescriptor = + result = + io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) + .setSchemaDescriptor(new DatastoreFileDescriptorSupplier()) + .addMethod(getLookupMethod()) + .addMethod(getRunQueryMethod()) + .addMethod(getRunAggregationQueryMethod()) + .addMethod(getBeginTransactionMethod()) + .addMethod(getCommitMethod()) + .addMethod(getRollbackMethod()) + .addMethod(getAllocateIdsMethod()) + .addMethod(getReserveIdsMethod()) + .build(); + } + } + } + return result; + } +} diff --git a/pom.xml b/pom.xml index aa9951ac5..73ac365f7 100644 --- a/pom.xml +++ b/pom.xml @@ -176,6 +176,11 @@ proto-google-cloud-datastore-v1 0.108.6-SNAPSHOT + + com.google.api.grpc + grpc-google-cloud-datastore-v1 + 2.17.6-SNAPSHOT + com.google.cloud.datastore datastore-v1-proto-client @@ -267,6 +272,7 @@ google-cloud-datastore grpc-google-cloud-datastore-admin-v1 + grpc-google-cloud-datastore-v1 proto-google-cloud-datastore-v1 proto-google-cloud-datastore-admin-v1 datastore-v1-proto-client diff --git a/pull-gapic-grpc.sh b/pull-gapic-grpc.sh new file mode 100644 index 000000000..327d7676c --- /dev/null +++ b/pull-gapic-grpc.sh @@ -0,0 +1,42 @@ +# +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +GENERATED_CODE_DIR=$(pwd)/../googleapis-gen +DATASTORE_DIR=$(pwd) + +echo $GENERATED_CODE_DIR +if [ -d "$GENERATED_CODE_DIR" ]; then + echo "Pulling latest changes in ${GENERATED_CODE_DIR}" + pushd $GENERATED_CODE_DIR || exit + git pull + popd || exit +else + echo "Cloning googleapis-gen" + git clone --depth 1 git@github.com:googleapis/googleapis-gen.git $GENERATED_CODE_DIR +fi + +#Copying the required directories +mkdir -p "$DATASTORE_DIR/grpc-google-cloud-datastore-v1" +cp -r "$GENERATED_CODE_DIR/google/datastore/v1/google-cloud-datastore-v1-java/grpc-google-cloud-datastore-v1-java/." \ +"$DATASTORE_DIR/grpc-google-cloud-datastore-v1/." +cp -r "$GENERATED_CODE_DIR/google/datastore/v1/google-cloud-datastore-v1-java/gapic-google-cloud-datastore-v1-java/." \ +"$DATASTORE_DIR/google-cloud-datastore/." + +#Cleaning up unwanted files +rm grpc-google-cloud-datastore-v1/build.gradle +rm google-cloud-datastore/build.gradle + +echo "Success" diff --git a/versions.txt b/versions.txt index e31e9ef9d..474769910 100644 --- a/versions.txt +++ b/versions.txt @@ -7,3 +7,4 @@ proto-google-cloud-datastore-v1:0.108.5:0.108.6-SNAPSHOT datastore-v1-proto-client:2.17.5:2.17.6-SNAPSHOT proto-google-cloud-datastore-admin-v1:2.17.5:2.17.6-SNAPSHOT grpc-google-cloud-datastore-admin-v1:2.17.5:2.17.6-SNAPSHOT +grpc-google-cloud-datastore-v1:2.17.5:2.17.6-SNAPSHOT From a7c9beb4a00ac29a3ab252ebe362879660acd475 Mon Sep 17 00:00:00 2001 From: Prateek Date: Mon, 27 Nov 2023 22:25:55 +0530 Subject: [PATCH 02/42] refactor: Swap usage of HttpDatastoreRpc with GrpcDatastoreRpc (#1240) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Create basic structure of GrpcDatastoreRpc and using it in DatastoreOptions * applying unary settings to all the unary methods * Configuring header provider for GrpcDatastoreRpc * fixing emulator tests to be able to run successfully with grpc now * ignoring one more test which will be fixed in actionable error implementation * Making HttpDatastoreRpc completely unused * Making GrpcDatastoreRpc implement AutoCloseable * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * incorporating feedbacks * pinging emulator after each test for debugging * Revert "pinging emulator after each test for debugging" This reverts commit 60ee45d27412aab8140fc7065010633cf59a0ae8. * Reapply "pinging emulator after each test for debugging" This reverts commit d42e3b995fe56ded8c5f080a262e8ea02c00c9d9. * more debugging * Constant ping to avoid flaky behaviour of /shutdown endpoint * fixing test * checking if emulator is running before sending a shutdown command * fix lint * implement helper method for localhost * fix header lint * moving emulator health check to src/test * fix lint * adding no extra headers * minor cleanup * using mutlipleAttemptsRule in DatastoreTest * Revert "adding no extra headers" This reverts commit 9b43798422dc0627b1b2bc6dea8b9f4169682292. * using classRule --------- Co-authored-by: Owl Bot --- google-cloud-datastore/pom.xml | 4 + .../cloud/datastore/DatastoreOptions.java | 12 +- .../cloud/datastore/DatastoreUtils.java | 50 ++++ .../com/google/cloud/datastore/TraceUtil.java | 4 +- .../datastore/spi/v1/GrpcDatastoreRpc.java | 215 ++++++++++++++++++ .../google/cloud/datastore/DatastoreTest.java | 13 ++ .../cloud/datastore/DatastoreUtilsTest.java | 42 ++++ .../cloud/datastore/it/ITDatastoreTest.java | 3 + .../datastore/it/MultipleAttemptsRule.java | 2 +- 9 files changed, 339 insertions(+), 6 deletions(-) create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreUtils.java create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java create mode 100644 google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreUtilsTest.java diff --git a/google-cloud-datastore/pom.xml b/google-cloud-datastore/pom.xml index fc1e45ef1..59b4b30ed 100644 --- a/google-cloud-datastore/pom.xml +++ b/google-cloud-datastore/pom.xml @@ -30,6 +30,10 @@ com.google.cloud google-cloud-core-http + + com.google.cloud + google-cloud-core-grpc + com.google.api.grpc proto-google-cloud-datastore-v1 diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java index d4f3be3c2..1eb7f5105 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java @@ -25,10 +25,12 @@ import com.google.cloud.TransportOptions; import com.google.cloud.datastore.spi.DatastoreRpcFactory; import com.google.cloud.datastore.spi.v1.DatastoreRpc; -import com.google.cloud.datastore.spi.v1.HttpDatastoreRpc; +import com.google.cloud.datastore.spi.v1.GrpcDatastoreRpc; +import com.google.cloud.datastore.v1.DatastoreSettings; import com.google.cloud.http.HttpTransportOptions; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableSet; +import java.io.IOException; import java.lang.reflect.Method; import java.util.Objects; import java.util.Set; @@ -60,7 +62,11 @@ public static class DefaultDatastoreRpcFactory implements DatastoreRpcFactory { @Override public ServiceRpc create(DatastoreOptions options) { - return new HttpDatastoreRpc(options); + try { + return new GrpcDatastoreRpc(options); + } catch (IOException e) { + throw new RuntimeException(e); + } } } @@ -116,7 +122,7 @@ protected String getDefaultHost() { System.getProperty( com.google.datastore.v1.client.DatastoreHelper.LOCAL_HOST_ENV_VAR, System.getenv(com.google.datastore.v1.client.DatastoreHelper.LOCAL_HOST_ENV_VAR)); - return host != null ? host : com.google.datastore.v1.client.DatastoreFactory.DEFAULT_HOST; + return host != null ? host : DatastoreSettings.getDefaultEndpoint(); } @Override diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreUtils.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreUtils.java new file mode 100644 index 000000000..ae1c7e07d --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreUtils.java @@ -0,0 +1,50 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore; + +import com.google.api.core.InternalApi; +import com.google.common.base.Strings; +import java.net.InetAddress; +import java.net.URL; + +@InternalApi +public class DatastoreUtils { + + public static boolean isLocalHost(String host) { + if (Strings.isNullOrEmpty(host)) { + return false; + } + try { + String normalizedHost = "http://" + removeScheme(host); + InetAddress hostAddr = InetAddress.getByName(new URL(normalizedHost).getHost()); + return hostAddr.isAnyLocalAddress() || hostAddr.isLoopbackAddress(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static String removeScheme(String url) { + if (url != null) { + if (url.startsWith("https://")) { + return url.substring("https://".length()); + } else if (url.startsWith("http://")) { + return url.substring("http://".length()); + } + } + return url; + } +} diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/TraceUtil.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/TraceUtil.java index 57525d15d..876a871a2 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/TraceUtil.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/TraceUtil.java @@ -16,14 +16,14 @@ package com.google.cloud.datastore; -import com.google.cloud.datastore.spi.v1.HttpDatastoreRpc; +import com.google.cloud.datastore.spi.v1.DatastoreRpc; import io.opencensus.trace.EndSpanOptions; import io.opencensus.trace.Span; import io.opencensus.trace.Tracer; import io.opencensus.trace.Tracing; /** - * Helper class for tracing utility. It is used for instrumenting {@link HttpDatastoreRpc} with + * Helper class for tracing utility. It is used for instrumenting {@link DatastoreRpc} with * OpenCensus APIs. * *

TraceUtil instances are created by the {@link TraceUtil#getInstance()} method. diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java new file mode 100644 index 000000000..fe2b2f27b --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java @@ -0,0 +1,215 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.spi.v1; + +import static com.google.cloud.datastore.DatastoreUtils.isLocalHost; +import static com.google.cloud.datastore.DatastoreUtils.removeScheme; +import static java.util.concurrent.TimeUnit.SECONDS; + +import com.google.api.core.ApiFunction; +import com.google.api.core.InternalApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.core.GaxProperties; +import com.google.api.gax.grpc.GrpcCallContext; +import com.google.api.gax.grpc.GrpcTransportChannel; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.HeaderProvider; +import com.google.api.gax.rpc.NoHeaderProvider; +import com.google.api.gax.rpc.TransportChannel; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.cloud.NoCredentials; +import com.google.cloud.ServiceOptions; +import com.google.cloud.datastore.DatastoreException; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.v1.DatastoreSettings; +import com.google.cloud.datastore.v1.stub.DatastoreStubSettings; +import com.google.cloud.datastore.v1.stub.GrpcDatastoreStub; +import com.google.cloud.grpc.GrpcTransportOptions; +import com.google.common.base.Strings; +import com.google.datastore.v1.AllocateIdsRequest; +import com.google.datastore.v1.AllocateIdsResponse; +import com.google.datastore.v1.BeginTransactionRequest; +import com.google.datastore.v1.BeginTransactionResponse; +import com.google.datastore.v1.CommitRequest; +import com.google.datastore.v1.CommitResponse; +import com.google.datastore.v1.LookupRequest; +import com.google.datastore.v1.LookupResponse; +import com.google.datastore.v1.ReserveIdsRequest; +import com.google.datastore.v1.ReserveIdsResponse; +import com.google.datastore.v1.RollbackRequest; +import com.google.datastore.v1.RollbackResponse; +import com.google.datastore.v1.RunAggregationQueryRequest; +import com.google.datastore.v1.RunAggregationQueryResponse; +import com.google.datastore.v1.RunQueryRequest; +import com.google.datastore.v1.RunQueryResponse; +import io.grpc.CallOptions; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.io.IOException; +import java.util.Collections; + +@InternalApi +public class GrpcDatastoreRpc implements AutoCloseable, DatastoreRpc { + + private final GrpcDatastoreStub datastoreStub; + private final ClientContext clientContext; + private boolean closed; + + public GrpcDatastoreRpc(DatastoreOptions datastoreOptions) throws IOException { + + try { + clientContext = + isEmulator(datastoreOptions) + ? getClientContextForEmulator(datastoreOptions) + : getClientContext(datastoreOptions); + ApiFunction, Void> retrySettingsSetter = + builder -> { + builder.setRetrySettings(datastoreOptions.getRetrySettings()); + return null; + }; + DatastoreStubSettings datastoreStubSettings = + DatastoreStubSettings.newBuilder(clientContext) + .applyToAllUnaryMethods(retrySettingsSetter) + .build(); + datastoreStub = GrpcDatastoreStub.create(datastoreStubSettings); + } catch (IOException e) { + throw new IOException(e); + } + } + + @Override + public void close() throws Exception { + if (!closed) { + datastoreStub.close(); + for (BackgroundResource resource : clientContext.getBackgroundResources()) { + resource.close(); + } + closed = true; + } + for (BackgroundResource resource : clientContext.getBackgroundResources()) { + resource.awaitTermination(1, SECONDS); + } + } + + @Override + public AllocateIdsResponse allocateIds(AllocateIdsRequest request) { + return datastoreStub.allocateIdsCallable().call(request); + } + + @Override + public BeginTransactionResponse beginTransaction(BeginTransactionRequest request) + throws DatastoreException { + return datastoreStub.beginTransactionCallable().call(request); + } + + @Override + public CommitResponse commit(CommitRequest request) { + return datastoreStub.commitCallable().call(request); + } + + @Override + public LookupResponse lookup(LookupRequest request) { + return datastoreStub.lookupCallable().call(request); + } + + @Override + public ReserveIdsResponse reserveIds(ReserveIdsRequest request) { + return datastoreStub.reserveIdsCallable().call(request); + } + + @Override + public RollbackResponse rollback(RollbackRequest request) { + return datastoreStub.rollbackCallable().call(request); + } + + @Override + public RunQueryResponse runQuery(RunQueryRequest request) { + return datastoreStub.runQueryCallable().call(request); + } + + @Override + public RunAggregationQueryResponse runAggregationQuery(RunAggregationQueryRequest request) { + return datastoreStub.runAggregationQueryCallable().call(request); + } + + private boolean isEmulator(DatastoreOptions datastoreOptions) { + return isLocalHost(datastoreOptions.getHost()) + || NoCredentials.getInstance().equals(datastoreOptions.getCredentials()); + } + + private ClientContext getClientContextForEmulator(DatastoreOptions datastoreOptions) + throws IOException { + ManagedChannel managedChannel = + ManagedChannelBuilder.forTarget(removeScheme(datastoreOptions.getHost())) + .usePlaintext() + .build(); + TransportChannel transportChannel = GrpcTransportChannel.create(managedChannel); + return ClientContext.newBuilder() + .setCredentials(null) + .setTransportChannel(transportChannel) + .setDefaultCallContext(GrpcCallContext.of(managedChannel, CallOptions.DEFAULT)) + .setBackgroundResources(Collections.singletonList(transportChannel)) + .build(); + } + + private ClientContext getClientContext(DatastoreOptions datastoreOptions) throws IOException { + HeaderProvider internalHeaderProvider = + DatastoreSettings.defaultApiClientHeaderProviderBuilder() + .setClientLibToken( + ServiceOptions.getGoogApiClientLibName(), + GaxProperties.getLibraryVersion(datastoreOptions.getClass())) + .setResourceToken(getResourceToken(datastoreOptions)) + .build(); + + DatastoreSettingsBuilder settingsBuilder = + new DatastoreSettingsBuilder(DatastoreSettings.newBuilder().build()); + settingsBuilder.setCredentialsProvider( + GrpcTransportOptions.setUpCredentialsProvider(datastoreOptions)); + settingsBuilder.setTransportChannelProvider( + GrpcTransportOptions.setUpChannelProvider( + DatastoreSettings.defaultGrpcTransportProviderBuilder(), datastoreOptions)); + settingsBuilder.setInternalHeaderProvider(internalHeaderProvider); + settingsBuilder.setHeaderProvider( + datastoreOptions.getMergedHeaderProvider(new NoHeaderProvider())); + ClientContext clientContext = ClientContext.create(settingsBuilder.build()); + return clientContext; + } + + private String getResourceToken(DatastoreOptions datastoreOptions) { + StringBuilder builder = new StringBuilder("project_id="); + builder.append(datastoreOptions.getProjectId()); + if (!Strings.isNullOrEmpty(datastoreOptions.getDatabaseId())) { + builder.append("&database_id="); + builder.append(datastoreOptions.getDatabaseId()); + } + return builder.toString(); + } + + // This class is needed solely to get access to protected method setInternalHeaderProvider() + private static class DatastoreSettingsBuilder extends DatastoreSettings.Builder { + + private DatastoreSettingsBuilder(DatastoreSettings settings) { + super(settings); + } + + @Override + protected DatastoreSettings.Builder setInternalHeaderProvider( + HeaderProvider internalHeaderProvider) { + return super.setInternalHeaderProvider(internalHeaderProvider); + } + } +} diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java index cd768f986..b1b36569a 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java @@ -38,6 +38,7 @@ import com.google.cloud.datastore.Query.ResultType; import com.google.cloud.datastore.StructuredQuery.OrderBy; import com.google.cloud.datastore.StructuredQuery.PropertyFilter; +import com.google.cloud.datastore.it.MultipleAttemptsRule; import com.google.cloud.datastore.spi.DatastoreRpcFactory; import com.google.cloud.datastore.spi.v1.DatastoreRpc; import com.google.cloud.datastore.testing.LocalDatastoreHelper; @@ -84,6 +85,8 @@ import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -91,6 +94,10 @@ @RunWith(JUnit4.class) public class DatastoreTest { + private static final int NUMBER_OF_ATTEMPTS = 5; + + @ClassRule + public static MultipleAttemptsRule rr = new MultipleAttemptsRule(NUMBER_OF_ATTEMPTS, 10); private static LocalDatastoreHelper helper = LocalDatastoreHelper.create(1.0); private static final DatastoreOptions options = helper.getOptions(); @@ -231,6 +238,8 @@ public void testNewTransactionCommit() { verifyNotUsable(transaction); } + // TODO(gapic_upgrade): Remove the @ignore annotation + @Ignore("This should be fixed with actionable error implementation") @Test public void testTransactionWithRead() { Transaction transaction = datastore.newTransaction(); @@ -252,6 +261,8 @@ public void testTransactionWithRead() { } } + // TODO(gapic_upgrade): Remove the @ignore annotation + @Ignore("This should be fixed with actionable error implementation") @Test public void testTransactionWithQuery() { Query query = @@ -648,6 +659,7 @@ private List buildResponsesForQueryPagination() { List responses = new ArrayList<>(); RecordQuery query = Query.newKeyQueryBuilder().build(); RunQueryRequest.Builder requestPb = RunQueryRequest.newBuilder(); + requestPb.setProjectId(PROJECT_ID); query.populatePb(requestPb); QueryResultBatch queryResultBatchPb = RunQueryResponse.newBuilder() @@ -757,6 +769,7 @@ private List buildResponsesForQueryPaginationWithLimit() { List responses = new ArrayList<>(); RecordQuery query = Query.newEntityQueryBuilder().build(); RunQueryRequest.Builder requestPb = RunQueryRequest.newBuilder(); + requestPb.setProjectId(PROJECT_ID); query.populatePb(requestPb); QueryResultBatch queryResultBatchPb = RunQueryResponse.newBuilder() diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreUtilsTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreUtilsTest.java new file mode 100644 index 000000000..9a5855d30 --- /dev/null +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreUtilsTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore; + +import static com.google.cloud.datastore.DatastoreUtils.isLocalHost; +import static com.google.cloud.datastore.DatastoreUtils.removeScheme; +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; + +public class DatastoreUtilsTest { + + @Test + public void testIsLocalHost() { + assertThat(isLocalHost(null)).isFalse(); + assertThat(isLocalHost("")).isFalse(); + assertThat(isLocalHost("http://localhost:9090")).isTrue(); + assertThat(isLocalHost("https://localhost:9090")).isTrue(); + assertThat(isLocalHost("10.10.10.10:9090")).isFalse(); + } + + @Test + public void testRemoveScheme() { + assertThat(removeScheme("http://localhost:9090")).isEqualTo("localhost:9090"); + assertThat(removeScheme("https://localhost:9090")).isEqualTo("localhost:9090"); + assertThat(removeScheme("https://localhost:9090")).isEqualTo("localhost:9090"); + } +} diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java index 7c68ffe32..d1e7646d2 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java @@ -86,6 +86,7 @@ import org.junit.After; import org.junit.AfterClass; import org.junit.Before; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.Timeout; @@ -1391,6 +1392,8 @@ public Integer run(DatastoreReaderWriter transaction) { } } + // TODO(gapic_upgrade): Remove the @ignore annotation + @Ignore("This should be fixed with actionable error implementation") @Test public void testRunInTransactionReadWrite() { diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/MultipleAttemptsRule.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/MultipleAttemptsRule.java index 8472f3131..ce9a226a6 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/MultipleAttemptsRule.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/MultipleAttemptsRule.java @@ -37,7 +37,7 @@ public final class MultipleAttemptsRule implements TestRule { this(attemptCount, 1000L); } - MultipleAttemptsRule(int attemptCount, long initialBackoffMillis) { + public MultipleAttemptsRule(int attemptCount, long initialBackoffMillis) { checkState(attemptCount > 0, "attemptCount must be > 0"); checkState(initialBackoffMillis > 0, "initialBackoffMillis must be > 0"); this.initialBackoffMillis = initialBackoffMillis; From 7048bdd464988711c57958885a980b8d0dc1c054 Mon Sep 17 00:00:00 2001 From: Prateek Date: Tue, 28 Nov 2023 23:47:18 +0530 Subject: [PATCH 03/42] feat!: Actionable Error (#1244) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Create basic structure of GrpcDatastoreRpc and using it in DatastoreOptions * applying unary settings to all the unary methods * Configuring header provider for GrpcDatastoreRpc * fixing emulator tests to be able to run successfully with grpc now * ignoring one more test which will be fixed in actionable error implementation * Making HttpDatastoreRpc completely unused * Making GrpcDatastoreRpc implement AutoCloseable * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * incorporating feedbacks * pinging emulator after each test for debugging * Revert "pinging emulator after each test for debugging" This reverts commit 60ee45d27412aab8140fc7065010633cf59a0ae8. * Reapply "pinging emulator after each test for debugging" This reverts commit d42e3b995fe56ded8c5f080a262e8ea02c00c9d9. * more debugging * Constant ping to avoid flaky behaviour of /shutdown endpoint * fixing test * checking if emulator is running before sending a shutdown command * fix lint * implement helper method for localhost * fix header lint * moving emulator health check to src/test * fix lint * adding no extra headers * minor cleanup * Making DatastoreException extend BaseGrpcServiceException * Creating DatastoreException through ApiException and exposing methods to extract out domain, reason and metadata * Wrapping ApiException in DatastoreException before throwing it * adding clirr configuration * javadoc for getReason * deleting unused file * enabling tests which were ignore for actionable error implementation * added clirr comments * fix lint --------- Co-authored-by: Owl Bot --- .../clirr-ignored-differences.xml | 12 ++ .../cloud/datastore/DatastoreException.java | 92 ++++++++++++- .../datastore/spi/v1/GrpcDatastoreRpc.java | 3 +- .../datastore/DatastoreExceptionTest.java | 121 ++++++++++++++---- .../google/cloud/datastore/DatastoreTest.java | 10 +- .../cloud/datastore/it/ITDatastoreTest.java | 8 +- 6 files changed, 204 insertions(+), 42 deletions(-) diff --git a/google-cloud-datastore/clirr-ignored-differences.xml b/google-cloud-datastore/clirr-ignored-differences.xml index 018afb17e..62459c953 100644 --- a/google-cloud-datastore/clirr-ignored-differences.xml +++ b/google-cloud-datastore/clirr-ignored-differences.xml @@ -26,4 +26,16 @@ com.google.cloud.datastore.AggregationResults runAggregation(com.google.cloud.datastore.AggregationQuery) 7012 + + + com/google/cloud/datastore/DatastoreException + 5000 + com/google/cloud/grpc/BaseGrpcServiceException + + + + com/google/cloud/datastore/DatastoreException + 5001 + com/google/cloud/http/BaseHttpServiceException + diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java index 512d0a3dc..5d01c3b9d 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java @@ -16,11 +16,16 @@ package com.google.cloud.datastore; +import static com.google.cloud.BaseServiceException.isRetryable; + +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ErrorDetails; import com.google.cloud.BaseServiceException; import com.google.cloud.RetryHelper.RetryHelperException; -import com.google.cloud.http.BaseHttpServiceException; +import com.google.cloud.grpc.BaseGrpcServiceException; import com.google.common.collect.ImmutableSet; import java.io.IOException; +import java.util.Map; import java.util.Set; /** @@ -29,7 +34,7 @@ * @see Google Cloud * Datastore error codes */ -public final class DatastoreException extends BaseHttpServiceException { +public final class DatastoreException extends BaseGrpcServiceException { // see https://cloud.google.com/datastore/docs/concepts/errors#Error_Codes" private static final Set RETRYABLE_ERRORS = @@ -38,22 +43,96 @@ public final class DatastoreException extends BaseHttpServiceException { new Error(4, "DEADLINE_EXCEEDED", false), new Error(14, "UNAVAILABLE", true)); private static final long serialVersionUID = 2663750991205874435L; + private String reason; + private ApiException apiException; public DatastoreException(int code, String message, String reason) { this(code, message, reason, true, null); + this.reason = reason; } public DatastoreException(int code, String message, String reason, Throwable cause) { - super(code, message, reason, true, RETRYABLE_ERRORS, cause); + super(message, cause, code, isRetryable(code, reason, true, RETRYABLE_ERRORS)); + this.reason = reason; } public DatastoreException( int code, String message, String reason, boolean idempotent, Throwable cause) { - super(code, message, reason, idempotent, RETRYABLE_ERRORS, cause); + super(message, cause, code, isRetryable(code, reason, idempotent, RETRYABLE_ERRORS)); + this.reason = reason; } public DatastoreException(IOException exception) { - super(exception, true, RETRYABLE_ERRORS); + super(exception, true); + } + + public DatastoreException(ApiException apiException) { + super(apiException); + this.apiException = apiException; + } + + /** + * Checks the underlying reason of the exception and if it's {@link ApiException} then return the + * specific domain otherwise null. + * + * @see Domain + * @return the logical grouping to which the "reason" belongs. + */ + public String getDomain() { + if (this.apiException != null) { + return this.apiException.getDomain(); + } + return null; + } + + /** + * Checks the underlying reason of the exception and if it's {@link ApiException} then return a + * map of key-value pairs otherwise null. + * + * @see Metadata + * @return the map of additional structured details about an error. + */ + public Map getMetadata() { + if (this.apiException != null) { + return this.apiException.getMetadata(); + } + return null; + } + + /** + * Checks the underlying reason of the exception and if it's {@link ApiException} then return the + * ErrorDetails otherwise null. + * + * @see Status + * @see Error + * Details + * @return An object containing getters for structured objects from error_details.proto. + */ + public ErrorDetails getErrorDetails() { + if (this.apiException != null) { + return this.apiException.getErrorDetails(); + } + return null; + } + + /** + * Checks the underlying reason of the exception and if it's {@link ApiException} then return the + * reason otherwise null/custom reason. + * + * @see Reason + * @return the reason of an error. + */ + @Override + public String getReason() { + if (this.apiException != null) { + return this.apiException.getReason(); + } + return this.reason; } /** @@ -64,6 +143,9 @@ public DatastoreException(IOException exception) { */ static DatastoreException translateAndThrow(RetryHelperException ex) { BaseServiceException.translate(ex); + if (ex.getCause() instanceof ApiException) { + throw new DatastoreException((ApiException) ex.getCause()); + } throw new DatastoreException(UNKNOWN_CODE, ex.getMessage(), null, ex.getCause()); } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java index fe2b2f27b..b4c83da89 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java @@ -185,8 +185,7 @@ private ClientContext getClientContext(DatastoreOptions datastoreOptions) throws settingsBuilder.setInternalHeaderProvider(internalHeaderProvider); settingsBuilder.setHeaderProvider( datastoreOptions.getMergedHeaderProvider(new NoHeaderProvider())); - ClientContext clientContext = ClientContext.create(settingsBuilder.build()); - return clientContext; + return ClientContext.create(settingsBuilder.build()); } private String getResourceToken(DatastoreOptions datastoreOptions) { diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java index 12b99c966..33f5ebb9c 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java @@ -16,6 +16,9 @@ package com.google.cloud.datastore; +import static com.google.common.truth.Truth.assertThat; +import static com.google.rpc.Code.FAILED_PRECONDITION; +import static java.util.Collections.singletonMap; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; @@ -24,11 +27,20 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.api.gax.grpc.GrpcStatusCode; +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ApiExceptionFactory; +import com.google.api.gax.rpc.ErrorDetails; +import com.google.api.gax.rpc.StatusCode; import com.google.cloud.BaseServiceException; import com.google.cloud.RetryHelper; +import com.google.protobuf.Any; +import com.google.rpc.ErrorInfo; +import io.grpc.Status; import java.io.IOException; import java.net.SocketTimeoutException; import org.junit.Test; @@ -76,39 +88,78 @@ public void testDatastoreException() { assertEquals("message", exception.getMessage()); assertFalse(exception.isRetryable()); assertSame(cause, exception.getCause()); + + exception = new DatastoreException(2, "message", "INTERNAL", true, cause); + assertEquals(2, exception.getCode()); + assertEquals("INTERNAL", exception.getReason()); + assertEquals("message", exception.getMessage()); + assertFalse(exception.isRetryable()); + assertSame(cause, exception.getCause()); + + ApiException apiException = createApiException(); + exception = new DatastoreException(apiException); + assertEquals(400, exception.getCode()); + assertEquals("MISSING_INDEXES", exception.getReason()); + assertThat(exception.getMetadata()) + .isEqualTo(singletonMap("missing_indexes_url", "__some__url__")); + assertSame(apiException, exception.getCause()); + } + + @Test + public void testApiException() { + ApiException apiException = createApiException(); + DatastoreException datastoreException = new DatastoreException(apiException); + + assertThat(datastoreException.getReason()).isEqualTo("MISSING_INDEXES"); + assertThat(datastoreException.getDomain()).isEqualTo("datastore.googleapis.com"); + assertThat(datastoreException.getMetadata()) + .isEqualTo(singletonMap("missing_indexes_url", "__some__url__")); + assertThat(datastoreException.getErrorDetails()).isEqualTo(apiException.getErrorDetails()); } @Test public void testTranslateAndThrow() { Exception cause = new DatastoreException(14, "message", "UNAVAILABLE"); - RetryHelper.RetryHelperException exceptionMock = + final RetryHelper.RetryHelperException exceptionMock = createMock(RetryHelper.RetryHelperException.class); expect(exceptionMock.getCause()).andReturn(cause).times(2); replay(exceptionMock); - try { - DatastoreException.translateAndThrow(exceptionMock); - } catch (BaseServiceException ex) { - assertEquals(14, ex.getCode()); - assertEquals("message", ex.getMessage()); - assertTrue(ex.isRetryable()); - } finally { - verify(exceptionMock); - } + BaseServiceException ex = + assertThrows( + BaseServiceException.class, () -> DatastoreException.translateAndThrow(exceptionMock)); + assertEquals(14, ex.getCode()); + assertEquals("message", ex.getMessage()); + assertTrue(ex.isRetryable()); + verify(exceptionMock); + + cause = createApiException(); + final RetryHelper.RetryHelperException exceptionMock2 = + createMock(RetryHelper.RetryHelperException.class); + expect(exceptionMock2.getCause()).andReturn(cause).times(3); + replay(exceptionMock2); + DatastoreException ex2 = + assertThrows( + DatastoreException.class, () -> DatastoreException.translateAndThrow(exceptionMock2)); + assertThat(ex2.getReason()).isEqualTo("MISSING_INDEXES"); + assertThat(ex2.getDomain()).isEqualTo("datastore.googleapis.com"); + assertThat(ex2.getMetadata()).isEqualTo(singletonMap("missing_indexes_url", "__some__url__")); + assertThat(ex2.getErrorDetails()).isEqualTo(((ApiException) cause).getErrorDetails()); + verify(exceptionMock2); + cause = new IllegalArgumentException("message"); - exceptionMock = createMock(RetryHelper.RetryHelperException.class); - expect(exceptionMock.getMessage()).andReturn("message").times(1); - expect(exceptionMock.getCause()).andReturn(cause).times(2); - replay(exceptionMock); - try { - DatastoreException.translateAndThrow(exceptionMock); - } catch (BaseServiceException ex) { - assertEquals(DatastoreException.UNKNOWN_CODE, ex.getCode()); - assertEquals("message", ex.getMessage()); - assertFalse(ex.isRetryable()); - assertSame(cause, ex.getCause()); - } finally { - verify(exceptionMock); - } + final RetryHelper.RetryHelperException exceptionMock3 = + createMock(RetryHelper.RetryHelperException.class); + expect(exceptionMock3.getMessage()).andReturn("message").times(1); + expect(exceptionMock3.getCause()).andReturn(cause).times(3); + replay(exceptionMock3); + BaseServiceException ex3 = + assertThrows( + BaseServiceException.class, () -> DatastoreException.translateAndThrow(exceptionMock3)); + assertEquals(DatastoreException.UNKNOWN_CODE, ex3.getCode()); + assertEquals("message", ex3.getMessage()); + assertFalse(ex3.isRetryable()); + assertSame(cause, ex3.getCause()); + verify(exceptionMock3); } @Test @@ -121,4 +172,26 @@ public void testThrowInvalidRequest() { assertEquals("message a 1", ex.getMessage()); } } + + private ApiException createApiException() { + // Simulating google.rpc.Status with an ErrorInfo + ErrorInfo errorInfo = + ErrorInfo.newBuilder() + .setDomain("datastore.googleapis.com") + .setReason("MISSING_INDEXES") + .putMetadata("missing_indexes_url", "__some__url__") + .build(); + com.google.rpc.Status status = + com.google.rpc.Status.newBuilder() + .setCode(FAILED_PRECONDITION.getNumber()) + .setMessage("The query requires indexes.") + .addDetails(Any.pack(errorInfo)) + .build(); + + // Using Gax to convert to ApiException + StatusCode statusCode = GrpcStatusCode.of(Status.fromCodeValue(status.getCode()).getCode()); + ErrorDetails errorDetails = + ErrorDetails.builder().setRawErrorMessages(status.getDetailsList()).build(); + return ApiExceptionFactory.createException(null, statusCode, true, errorDetails); + } } diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java index b1b36569a..5f42e2aeb 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java @@ -16,6 +16,7 @@ package com.google.cloud.datastore; +import static com.google.api.gax.rpc.StatusCode.Code.ABORTED; import static com.google.cloud.datastore.ProtoTestData.intValue; import static com.google.cloud.datastore.TestUtils.matches; import static com.google.cloud.datastore.aggregation.Aggregation.count; @@ -86,7 +87,6 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -238,8 +238,6 @@ public void testNewTransactionCommit() { verifyNotUsable(transaction); } - // TODO(gapic_upgrade): Remove the @ignore annotation - @Ignore("This should be fixed with actionable error implementation") @Test public void testTransactionWithRead() { Transaction transaction = datastore.newTransaction(); @@ -257,12 +255,10 @@ public void testTransactionWithRead() { transaction.commit(); fail("Expecting a failure"); } catch (DatastoreException expected) { - assertEquals("ABORTED", expected.getReason()); + assertEquals(ABORTED.getHttpStatusCode(), expected.getCode()); } } - // TODO(gapic_upgrade): Remove the @ignore annotation - @Ignore("This should be fixed with actionable error implementation") @Test public void testTransactionWithQuery() { Query query = @@ -288,7 +284,7 @@ public void testTransactionWithQuery() { transaction.commit(); fail("Expecting a failure"); } catch (DatastoreException expected) { - assertEquals("ABORTED", expected.getReason()); + assertEquals(ABORTED.getHttpStatusCode(), expected.getCode()); } } diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java index d1e7646d2..1e931dfc4 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java @@ -16,6 +16,7 @@ package com.google.cloud.datastore.it; +import static com.google.api.gax.rpc.StatusCode.Code.INVALID_ARGUMENT; import static com.google.cloud.datastore.aggregation.Aggregation.count; import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.common.truth.Truth.assertThat; @@ -86,7 +87,6 @@ import org.junit.After; import org.junit.AfterClass; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.Timeout; @@ -1392,8 +1392,6 @@ public Integer run(DatastoreReaderWriter transaction) { } } - // TODO(gapic_upgrade): Remove the @ignore annotation - @Ignore("This should be fixed with actionable error implementation") @Test public void testRunInTransactionReadWrite() { @@ -1444,7 +1442,9 @@ public Integer run(DatastoreReaderWriter transaction) { datastore.runInTransaction(callable2, readOnlyOptions); fail("Expecting a failure"); } catch (DatastoreException expected) { - assertEquals(3, ((DatastoreException) expected.getCause()).getCode()); + assertEquals( + INVALID_ARGUMENT.getHttpStatusCode(), + ((DatastoreException) expected.getCause()).getCode()); } } From 74941d8a28e68f938e403c2f2bd2a72a9a1aa25b Mon Sep 17 00:00:00 2001 From: Prateek Date: Thu, 14 Dec 2023 12:57:03 +0530 Subject: [PATCH 04/42] feat!: Making Datastore implement Closeable (#1246) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Making Datastore closeable and fixing integration test * Closing datastore in datastore test * fix lint * fix clirr config * test to verify if datastore client is getting closed after invoking close() method * Using a consistent port and reinitializing Datastore instance in @BeforeClass method * trying to fix connection reset problem * upgrading datastore emulator to fix DatastoreTest * 🦉 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 --- README.md | 8 ++--- .../clirr-ignored-differences.xml | 21 +++++++++++ .../com/google/cloud/datastore/Datastore.java | 15 ++++++-- .../google/cloud/datastore/DatastoreImpl.java | 17 +++++++++ .../RetryAndTraceDatastoreRpcDecorator.java | 10 ++++++ .../cloud/datastore/spi/v1/DatastoreRpc.java | 8 ++++- .../datastore/spi/v1/GrpcDatastoreRpc.java | 7 +++- .../datastore/spi/v1/HttpDatastoreRpc.java | 10 ++++++ .../testing/LocalDatastoreHelper.java | 4 +-- .../google/cloud/datastore/DatastoreTest.java | 35 ++++++++++++------- .../it/ITDatastoreAggregationsTest.java | 6 ++++ .../datastore/it/ITDatastoreConceptsTest.java | 21 +++++++---- .../cloud/datastore/it/ITDatastoreTest.java | 4 ++- 13 files changed, 137 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 31a90d7fb..ff9613efd 100644 --- a/README.md +++ b/README.md @@ -50,20 +50,20 @@ If you are using Maven without the BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies: ```Groovy -implementation platform('com.google.cloud:libraries-bom:26.27.0') +implementation platform('com.google.cloud:libraries-bom:26.29.0') implementation 'com.google.cloud:google-cloud-datastore' ``` If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-datastore:2.17.5' +implementation 'com.google.cloud:google-cloud-datastore:2.17.6' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.17.5" +libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.17.6" ``` @@ -380,7 +380,7 @@ Java is a registered trademark of Oracle and/or its affiliates. [kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-datastore/java11.html [stability-image]: https://img.shields.io/badge/stability-stable-green [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-datastore.svg -[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-datastore/2.17.5 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-datastore/2.17.6 [authentication]: https://github.com/googleapis/google-cloud-java#authentication [auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes [predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles diff --git a/google-cloud-datastore/clirr-ignored-differences.xml b/google-cloud-datastore/clirr-ignored-differences.xml index 62459c953..f80562fba 100644 --- a/google-cloud-datastore/clirr-ignored-differences.xml +++ b/google-cloud-datastore/clirr-ignored-differences.xml @@ -38,4 +38,25 @@ 5001 com/google/cloud/http/BaseHttpServiceException + + com/google/cloud/datastore/Datastore + void close() + 7012 + + + com/google/cloud/datastore/spi/v1/DatastoreRpc + void close() + 7012 + + + com/google/cloud/datastore/Datastore + boolean isClosed() + 7012 + + + com/google/cloud/datastore/spi/v1/DatastoreRpc + boolean isClosed() + 7012 + + diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Datastore.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Datastore.java index d78bea9a2..1fb5fcedc 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Datastore.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Datastore.java @@ -22,7 +22,7 @@ import java.util.List; /** An interface for Google Cloud Datastore. */ -public interface Datastore extends Service, DatastoreReaderWriter { +public interface Datastore extends Service, DatastoreReaderWriter, AutoCloseable { /** * Returns a new Datastore transaction. @@ -49,9 +49,9 @@ public interface Datastore extends Service, DatastoreReaderWri * @param the type of the return value */ interface TransactionCallable { + T run(DatastoreReaderWriter readerWriter) throws Exception; } - /** * Invokes the callback's {@link Datastore.TransactionCallable#run} method with a {@link * DatastoreReaderWriter} that is associated with a new transaction. The transaction will be @@ -508,4 +508,15 @@ interface TransactionCallable { default AggregationResults runAggregation(AggregationQuery query, ReadOption... options) { throw new UnsupportedOperationException("Not implemented."); } + + /** + * Closes the gRPC channels associated with this instance and frees up their resources. This + * method blocks until all channels are closed. Once this method is called, this Datastore client + * is no longer usable. + */ + @Override + void close() throws Exception; + + /** Returns true if this background resource has been shut down. */ + boolean isClosed(); } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java index a1b337c05..55add1c9f 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java @@ -48,9 +48,12 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.Callable; +import java.util.logging.Level; +import java.util.logging.Logger; final class DatastoreImpl extends BaseService implements Datastore { + Logger logger = Logger.getLogger(Datastore.class.getName()); private final DatastoreRpc datastoreRpc; private final RetrySettings retrySettings; private static final ExceptionHandler TRANSACTION_EXCEPTION_HANDLER = @@ -90,6 +93,20 @@ public Transaction newTransaction() { return new TransactionImpl(this); } + @Override + public void close() throws Exception { + try { + datastoreRpc.close(); + } catch (Exception e) { + logger.log(Level.WARNING, "Failed to close channels", e); + } + } + + @Override + public boolean isClosed() { + return datastoreRpc.isClosed(); + } + static class ReadWriteTransactionCallable implements Callable { private final Datastore datastore; diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/RetryAndTraceDatastoreRpcDecorator.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/RetryAndTraceDatastoreRpcDecorator.java index c4a85caab..920fb440f 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/RetryAndTraceDatastoreRpcDecorator.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/RetryAndTraceDatastoreRpcDecorator.java @@ -109,6 +109,16 @@ public RunAggregationQueryResponse runAggregationQuery(RunAggregationQueryReques () -> datastoreRpc.runAggregationQuery(request), SPAN_NAME_RUN_AGGREGATION_QUERY); } + @Override + public void close() throws Exception { + datastoreRpc.close(); + } + + @Override + public boolean isClosed() { + return datastoreRpc.isClosed(); + } + public O invokeRpc(Callable block, String startSpan) { Span span = traceUtil.startSpan(startSpan); try (Scope scope = traceUtil.getTracer().withSpan(span)) { diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/DatastoreRpc.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/DatastoreRpc.java index 33b8e11ea..24b5b0166 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/DatastoreRpc.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/DatastoreRpc.java @@ -36,7 +36,7 @@ import com.google.datastore.v1.RunQueryResponse; /** Provides access to the remote Datastore service. */ -public interface DatastoreRpc extends ServiceRpc { +public interface DatastoreRpc extends ServiceRpc, AutoCloseable { /** * Sends an allocate IDs request. @@ -96,4 +96,10 @@ BeginTransactionResponse beginTransaction(BeginTransactionRequest request) default RunAggregationQueryResponse runAggregationQuery(RunAggregationQueryRequest request) { throw new UnsupportedOperationException("Not implemented."); } + + @Override + void close() throws Exception; + + /** Returns true if this background resource has been shut down. */ + boolean isClosed(); } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java index b4c83da89..542d16d31 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java @@ -63,7 +63,7 @@ import java.util.Collections; @InternalApi -public class GrpcDatastoreRpc implements AutoCloseable, DatastoreRpc { +public class GrpcDatastoreRpc implements DatastoreRpc { private final GrpcDatastoreStub datastoreStub; private final ClientContext clientContext; @@ -146,6 +146,11 @@ public RunAggregationQueryResponse runAggregationQuery(RunAggregationQueryReques return datastoreStub.runAggregationQueryCallable().call(request); } + @Override + public boolean isClosed() { + return closed && datastoreStub.isShutdown(); + } + private boolean isEmulator(DatastoreOptions datastoreOptions) { return isLocalHost(datastoreOptions.getHost()) || NoCredentials.getInstance().equals(datastoreOptions.getCredentials()); diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/HttpDatastoreRpc.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/HttpDatastoreRpc.java index fd3cdc658..66bb0497b 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/HttpDatastoreRpc.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/HttpDatastoreRpc.java @@ -211,4 +211,14 @@ public RunAggregationQueryResponse runAggregationQuery(RunAggregationQueryReques throw translate(ex); } } + + @Override + public void close() throws Exception { + throw new UnsupportedOperationException("close() is not supported"); + } + + @Override + public boolean isClosed() { + throw new UnsupportedOperationException("isClosed() is not supported"); + } } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java index 26b892186..927a6cf23 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java @@ -57,12 +57,12 @@ public class LocalDatastoreHelper extends BaseEmulatorHelper { private static final String GCLOUD_CMD_TEXT = "gcloud beta emulators datastore start"; private static final String GCLOUD_CMD_PORT_FLAG = "--host-port="; private static final String VERSION_PREFIX = "cloud-datastore-emulator "; - private static final String MIN_VERSION = "1.2.0"; + private static final String MIN_VERSION = "2.0.2"; // latest version compatible with java 8 // Downloadable emulator settings private static final String BIN_NAME = "cloud-datastore-emulator/cloud_datastore_emulator"; private static final String FILENAME = "cloud-datastore-emulator-" + MIN_VERSION + ".zip"; - private static final String MD5_CHECKSUM = "ec2237a0f0ac54964c6bd95e12c73720"; + private static final String MD5_CHECKSUM = "e0d1170519cf52e2e5f9f93892cdf70c"; private static final String BIN_CMD_PORT_FLAG = "--port="; private static final URL EMULATOR_URL; private static final String EMULATOR_URL_ENV_VAR = "DATASTORE_EMULATOR_URL"; diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java index 5f42e2aeb..84cbd4b73 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java @@ -31,6 +31,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -39,7 +40,6 @@ import com.google.cloud.datastore.Query.ResultType; import com.google.cloud.datastore.StructuredQuery.OrderBy; import com.google.cloud.datastore.StructuredQuery.PropertyFilter; -import com.google.cloud.datastore.it.MultipleAttemptsRule; import com.google.cloud.datastore.spi.DatastoreRpcFactory; import com.google.cloud.datastore.spi.v1.DatastoreRpc; import com.google.cloud.datastore.testing.LocalDatastoreHelper; @@ -79,14 +79,12 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.TimeoutException; import java.util.function.Predicate; import org.easymock.EasyMock; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -94,14 +92,9 @@ @RunWith(JUnit4.class) public class DatastoreTest { - private static final int NUMBER_OF_ATTEMPTS = 5; - - @ClassRule - public static MultipleAttemptsRule rr = new MultipleAttemptsRule(NUMBER_OF_ATTEMPTS, 10); - - private static LocalDatastoreHelper helper = LocalDatastoreHelper.create(1.0); - private static final DatastoreOptions options = helper.getOptions(); - private static final Datastore datastore = options.getService(); + private static final LocalDatastoreHelper helper = LocalDatastoreHelper.create(1.0, 9090); + private static DatastoreOptions options = helper.getOptions(); + private static Datastore datastore; private static final String PROJECT_ID = options.getProjectId(); private static final String KIND1 = "kind1"; private static final String KIND2 = "kind2"; @@ -177,6 +170,8 @@ public class DatastoreTest { @BeforeClass public static void beforeClass() throws IOException, InterruptedException { helper.start(); + options = helper.getOptions(); + datastore = options.getService(); } @Before @@ -197,7 +192,8 @@ public void setUp() { } @AfterClass - public static void afterClass() throws IOException, InterruptedException, TimeoutException { + public static void afterClass() throws Exception { + datastore.close(); helper.stop(Duration.ofMinutes(1)); } @@ -1386,6 +1382,21 @@ public void testDatabaseIdKeyFactory() { checkKeyProperties(incompleteKey); } + @Test + public void testDatastoreClose() throws Exception { + Datastore datastore = options.toBuilder().build().getService(); + Entity entity = datastore.get(KEY3); + assertNull(entity); + + datastore.close(); + assertTrue(datastore.isClosed()); + + assertThrows( + "io.grpc.StatusRuntimeException: UNAVAILABLE: Channel shutdown invoked", + DatastoreException.class, + () -> datastore.get(KEY3)); + } + private void checkKeyProperties(BaseKey key) { assertEquals(options.getDatabaseId(), key.getDatabaseId()); assertEquals(options.getProjectId(), key.getProjectId()); diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java index fd430095f..e04f5e55f 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java @@ -43,6 +43,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import org.junit.After; +import org.junit.AfterClass; import org.junit.Test; // TODO(jainsahab) Move all the aggregation related tests from ITDatastoreTest to this file @@ -63,6 +64,11 @@ public void tearDown() { DATASTORE.delete(keysToDelete); } + @AfterClass + public static void afterClass() throws Exception { + DATASTORE.close(); + } + Key key1 = DATASTORE.newKeyFactory().setKind(KIND).newKey(1); Key key2 = DATASTORE.newKeyFactory().setKind(KIND).newKey(2); Key key3 = DATASTORE.newKeyFactory().setKind(KIND).newKey(3); diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreConceptsTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreConceptsTest.java index b8ebd277a..f61db4f48 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreConceptsTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreConceptsTest.java @@ -67,7 +67,9 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; /* @@ -77,7 +79,7 @@ public class ITDatastoreConceptsTest { private static final RemoteDatastoreHelper HELPER = RemoteDatastoreHelper.create(); private static final DatastoreOptions OPTIONS = HELPER.getOptions(); private static final FullEntity TEST_FULL_ENTITY = FullEntity.newBuilder().build(); - private Datastore datastore; + private static Datastore datastore; private KeyFactory keyFactory; private Key taskKey; private Entity testEntity; @@ -87,13 +89,15 @@ public class ITDatastoreConceptsTest { private static final String TASK_CONCEPTS = "TaskConcepts"; - /** - * Initializes Datastore and cleans out any residual values. Also initializes global variables - * used for testing. - */ + /** Initializes Datastore for testing. */ + @BeforeClass + public static void beforeClass() throws Exception { + datastore = OPTIONS.getService(); + } + + /** Cleans out any residual values. Also initializes global variables used for testing. */ @Before public void setUp() { - datastore = OPTIONS.getService(); StructuredQuery query = Query.newKeyQueryBuilder().build(); QueryResults result = datastore.run(query); datastore.delete(Iterators.toArray(result, Key.class)); @@ -128,6 +132,11 @@ public void tearDown() { datastore.delete(taskKeysToDelete); } + @AfterClass + public static void afterClass() throws Exception { + datastore.close(); + } + private void assertValidKey(Key taskKey) { datastore.put(Entity.newBuilder(taskKey, TEST_FULL_ENTITY).build()); } diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java index 1e931dfc4..3f00fe2cf 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java @@ -144,8 +144,10 @@ public class ITDatastoreTest { @Rule public MultipleAttemptsRule multipleAttemptsRule = new MultipleAttemptsRule(3); @AfterClass - public static void afterClass() { + public static void afterClass() throws Exception { HELPER.deleteNamespace(); + DATASTORE_1.close(); + DATASTORE_2.close(); } public ITDatastoreTest( From 874829abe12624fbee1c8f2919b92f342bf39d73 Mon Sep 17 00:00:00 2001 From: Prateek Date: Mon, 18 Dec 2023 23:08:12 +0530 Subject: [PATCH 05/42] feat: enabling regapic by giving an option to user to use http (#1261) * feat: enabling regapic by giving an option to user to use http * enabling retry settings * fix lint * fix deps failure * fix deps failure * trying out ipv6 address resolution * Revert "trying out ipv6 address resolution" This reverts commit 1bf0e299b163df5ad7c510fdce6dc71d681801b5. * upgrading emulator * fix lint * downgrading to 2.0.2 to maintain java 8 compatibility * incorporating feedbacks * test retry settings while configuring DatastoreRpc instance * fix test * fix header * fix clirr check * fix lint * fix integration test * fix lint * incorporating feedback --- google-cloud-datastore/pom.xml | 4 - .../cloud/datastore/DatastoreOptions.java | 23 +- .../cloud/datastore/spi/v1/DatastoreRpc.java | 24 ++- .../datastore/spi/v1/GrpcDatastoreRpc.java | 25 +-- .../datastore/spi/v1/HttpDatastoreRpc.java | 199 ++++++------------ .../cloud/datastore/spi/v1/RpcUtils.java | 34 +++ .../cloud/datastore/DatastoreOptionsTest.java | 19 ++ .../google/cloud/datastore/DatastoreTest.java | 1 + .../cloud/datastore/spi/v1/RpcUtilsTest.java | 57 +++++ 9 files changed, 220 insertions(+), 166 deletions(-) create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/RpcUtils.java create mode 100644 google-cloud-datastore/src/test/java/com/google/cloud/datastore/spi/v1/RpcUtilsTest.java diff --git a/google-cloud-datastore/pom.xml b/google-cloud-datastore/pom.xml index 59b4b30ed..a4b0434eb 100644 --- a/google-cloud-datastore/pom.xml +++ b/google-cloud-datastore/pom.xml @@ -106,10 +106,6 @@ com.google.oauth-client google-oauth-client - - com.google.auth - google-auth-library-oauth2-http - io.opencensus opencensus-api diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java index 1eb7f5105..a166a45ae 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java @@ -17,6 +17,7 @@ package com.google.cloud.datastore; import static com.google.cloud.datastore.Validator.validateNamespace; +import static com.google.cloud.datastore.spi.v1.DatastoreRpc.Transport.GRPC; import com.google.api.core.BetaApi; import com.google.cloud.ServiceDefaults; @@ -25,9 +26,12 @@ import com.google.cloud.TransportOptions; import com.google.cloud.datastore.spi.DatastoreRpcFactory; import com.google.cloud.datastore.spi.v1.DatastoreRpc; +import com.google.cloud.datastore.spi.v1.DatastoreRpc.Transport; import com.google.cloud.datastore.spi.v1.GrpcDatastoreRpc; +import com.google.cloud.datastore.spi.v1.HttpDatastoreRpc; import com.google.cloud.datastore.v1.DatastoreSettings; import com.google.cloud.http.HttpTransportOptions; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableSet; import java.io.IOException; @@ -45,6 +49,7 @@ public class DatastoreOptions extends ServiceOptions, Void> retrySettingsSetter = - builder -> { - builder.setRetrySettings(datastoreOptions.getRetrySettings()); - return null; - }; + DatastoreStubSettings datastoreStubSettings = DatastoreStubSettings.newBuilder(clientContext) - .applyToAllUnaryMethods(retrySettingsSetter) + .applyToAllUnaryMethods(retrySettingSetter(datastoreOptions)) .build(); datastoreStub = GrpcDatastoreStub.create(datastoreStubSettings); } catch (IOException e) { @@ -202,18 +197,4 @@ private String getResourceToken(DatastoreOptions datastoreOptions) { } return builder.toString(); } - - // This class is needed solely to get access to protected method setInternalHeaderProvider() - private static class DatastoreSettingsBuilder extends DatastoreSettings.Builder { - - private DatastoreSettingsBuilder(DatastoreSettings settings) { - super(settings); - } - - @Override - protected DatastoreSettings.Builder setInternalHeaderProvider( - HeaderProvider internalHeaderProvider) { - return super.setInternalHeaderProvider(internalHeaderProvider); - } - } } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/HttpDatastoreRpc.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/HttpDatastoreRpc.java index 66bb0497b..f5a6ebb42 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/HttpDatastoreRpc.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/HttpDatastoreRpc.java @@ -16,14 +16,17 @@ package com.google.cloud.datastore.spi.v1; -import com.google.api.client.http.HttpRequest; -import com.google.api.client.http.HttpRequestInitializer; -import com.google.api.client.http.HttpTransport; -import com.google.cloud.datastore.DatastoreException; +import static com.google.cloud.datastore.DatastoreUtils.isLocalHost; +import static com.google.cloud.datastore.spi.v1.RpcUtils.retrySettingSetter; +import static java.util.concurrent.TimeUnit.SECONDS; + +import com.google.api.core.InternalApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.rpc.ClientContext; import com.google.cloud.datastore.DatastoreOptions; -import com.google.cloud.datastore.TraceUtil; -import com.google.cloud.http.CensusHttpModule; -import com.google.cloud.http.HttpTransportOptions; +import com.google.cloud.datastore.v1.DatastoreSettings; +import com.google.cloud.datastore.v1.stub.DatastoreStubSettings; +import com.google.cloud.datastore.v1.stub.HttpJsonDatastoreStub; import com.google.datastore.v1.AllocateIdsRequest; import com.google.datastore.v1.AllocateIdsResponse; import com.google.datastore.v1.BeginTransactionRequest; @@ -41,184 +44,104 @@ import com.google.datastore.v1.RunQueryRequest; import com.google.datastore.v1.RunQueryResponse; import java.io.IOException; -import java.net.InetAddress; -import java.net.URL; +@InternalApi public class HttpDatastoreRpc implements DatastoreRpc { - private final com.google.datastore.v1.client.Datastore client; - - public HttpDatastoreRpc(DatastoreOptions options) { - HttpTransportOptions httpTransportOptions = - (HttpTransportOptions) options.getTransportOptions(); - HttpTransport transport = httpTransportOptions.getHttpTransportFactory().create(); - com.google.datastore.v1.client.DatastoreOptions.Builder clientBuilder = - new com.google.datastore.v1.client.DatastoreOptions.Builder() - .projectId(options.getProjectId()) - .initializer(getHttpRequestInitializer(options, httpTransportOptions)) - .transport(transport); - String normalizedHost = options.getHost() != null ? options.getHost().toLowerCase() : ""; - if (isLocalHost(normalizedHost)) { - clientBuilder = clientBuilder.localHost(removeScheme(normalizedHost)); - } else if (!removeScheme(com.google.datastore.v1.client.DatastoreFactory.DEFAULT_HOST) - .equals(removeScheme(normalizedHost)) - && !normalizedHost.isEmpty()) { - String fullUrl = normalizedHost; - if (fullUrl.charAt(fullUrl.length() - 1) != '/') { - fullUrl = fullUrl + '/'; - } - fullUrl = - fullUrl - + com.google.datastore.v1.client.DatastoreFactory.VERSION - + "/projects/" - + options.getProjectId(); - clientBuilder = clientBuilder.projectId(null).projectEndpoint(fullUrl); - } - client = com.google.datastore.v1.client.DatastoreFactory.get().create(clientBuilder.build()); - } + private final ClientContext clientContext; + private final HttpJsonDatastoreStub datastoreStub; - private HttpRequestInitializer getHttpRequestInitializer( - final DatastoreOptions options, HttpTransportOptions httpTransportOptions) { - // Open Census initialization - CensusHttpModule censusHttpModule = - new CensusHttpModule(TraceUtil.getInstance().getTracer(), true); - final HttpRequestInitializer censusHttpModuleHttpRequestInitializer = - censusHttpModule.getHttpRequestInitializer( - httpTransportOptions.getHttpRequestInitializer(options)); - - final String applicationName = options.getApplicationName(); - return new HttpRequestInitializer() { - @Override - public void initialize(HttpRequest httpRequest) throws IOException { - censusHttpModuleHttpRequestInitializer.initialize(httpRequest); - httpRequest.getHeaders().setUserAgent(applicationName); - } - }; - } + private boolean closed; - private static boolean isLocalHost(String host) { - if (!host.isEmpty()) { - try { - String normalizedHost = "http://" + removeScheme(host); - InetAddress hostAddr = InetAddress.getByName(new URL(normalizedHost).getHost()); - return hostAddr.isAnyLocalAddress() || hostAddr.isLoopbackAddress(); - } catch (Exception e) { - // ignore - } - } - return false; - } + public HttpDatastoreRpc(DatastoreOptions datastoreOptions) throws IOException { + DatastoreSettings datastoreSettings = + new DatastoreSettingsBuilder(DatastoreSettings.newBuilder().build()) + .setInternalHeaderProvider( + DatastoreStubSettings.defaultHttpJsonApiClientHeaderProviderBuilder().build()) + .setTransportChannelProvider( + DatastoreStubSettings.defaultHttpJsonTransportProviderBuilder().build()) + .setEndpoint(getHost(datastoreOptions)) + .build(); - private static String removeScheme(String url) { - if (url != null) { - if (url.startsWith("https://")) { - return url.substring("https://".length()); - } else if (url.startsWith("http://")) { - return url.substring("http://".length()); - } - } - return url; - } + clientContext = ClientContext.create(datastoreSettings); - private static DatastoreException translate( - com.google.datastore.v1.client.DatastoreException exception) { - return translate(exception, true); - } + DatastoreStubSettings datastoreStubSettings = + DatastoreStubSettings.newBuilder(clientContext) + .applyToAllUnaryMethods(retrySettingSetter(datastoreOptions)) + .build(); - private static DatastoreException translate( - com.google.datastore.v1.client.DatastoreException exception, boolean idempotent) { - String reason = ""; - if (exception.getCode() != null) { - reason = exception.getCode().name(); - } - if (reason.isEmpty()) { - if (exception.getCause() instanceof IOException) { - return new DatastoreException((IOException) exception.getCause()); - } - } - return new DatastoreException( - exception.getCode().getNumber(), exception.getMessage(), reason, idempotent, exception); + datastoreStub = HttpJsonDatastoreStub.create(datastoreStubSettings); } @Override public AllocateIdsResponse allocateIds(AllocateIdsRequest request) { - try { - return client.allocateIds(request); - } catch (com.google.datastore.v1.client.DatastoreException ex) { - throw translate(ex); - } + return this.datastoreStub.allocateIdsCallable().call(request); } @Override public BeginTransactionResponse beginTransaction(BeginTransactionRequest request) { - try { - return client.beginTransaction(request); - } catch (com.google.datastore.v1.client.DatastoreException ex) { - throw translate(ex); - } + return this.datastoreStub.beginTransactionCallable().call(request); } @Override public CommitResponse commit(CommitRequest request) { - try { - return client.commit(request); - } catch (com.google.datastore.v1.client.DatastoreException ex) { - throw translate(ex, request.getMode() == CommitRequest.Mode.NON_TRANSACTIONAL); - } + return this.datastoreStub.commitCallable().call(request); } @Override public LookupResponse lookup(LookupRequest request) { - try { - return client.lookup(request); - } catch (com.google.datastore.v1.client.DatastoreException ex) { - throw translate(ex); - } + return this.datastoreStub.lookupCallable().call(request); } @Override public ReserveIdsResponse reserveIds(ReserveIdsRequest request) { - try { - return client.reserveIds(request); - } catch (com.google.datastore.v1.client.DatastoreException ex) { - throw translate(ex); - } + return this.datastoreStub.reserveIdsCallable().call(request); } @Override public RollbackResponse rollback(RollbackRequest request) { - try { - return client.rollback(request); - } catch (com.google.datastore.v1.client.DatastoreException ex) { - throw translate(ex); - } + return this.datastoreStub.rollbackCallable().call(request); } @Override public RunQueryResponse runQuery(RunQueryRequest request) { - try { - return client.runQuery(request); - } catch (com.google.datastore.v1.client.DatastoreException ex) { - throw translate(ex); - } + return this.datastoreStub.runQueryCallable().call(request); } @Override public RunAggregationQueryResponse runAggregationQuery(RunAggregationQueryRequest request) { - try { - return client.runAggregationQuery(request); - } catch (com.google.datastore.v1.client.DatastoreException ex) { - throw translate(ex); - } + return this.datastoreStub.runAggregationQueryCallable().call(request); } @Override public void close() throws Exception { - throw new UnsupportedOperationException("close() is not supported"); + if (!closed) { + datastoreStub.close(); + for (BackgroundResource resource : clientContext.getBackgroundResources()) { + resource.close(); + } + closed = true; + } + for (BackgroundResource resource : clientContext.getBackgroundResources()) { + resource.awaitTermination(1, SECONDS); + } } @Override public boolean isClosed() { - throw new UnsupportedOperationException("isClosed() is not supported"); + return closed && datastoreStub.isShutdown(); + } + + /** + * Prefixing it with http scheme when host is localhost, otherwise {@link + * com.google.api.gax.httpjson.HttpRequestRunnable#normalizeEndpoint(String)} will prefix it with + * https. + */ + private String getHost(DatastoreOptions options) { + String host = options.getHost(); + if (isLocalHost(host) && !host.contains("://")) { + return "http://" + host; + } + return host; } } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/RpcUtils.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/RpcUtils.java new file mode 100644 index 000000000..dee8d6920 --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/RpcUtils.java @@ -0,0 +1,34 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.spi.v1; + +import com.google.api.core.ApiFunction; +import com.google.api.core.InternalApi; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.cloud.datastore.DatastoreOptions; + +@InternalApi +public class RpcUtils { + @InternalApi + static ApiFunction, Void> retrySettingSetter( + DatastoreOptions datastoreOptions) { + return builder -> { + builder.setRetrySettings(datastoreOptions.getRetrySettings()); + return null; + }; + } +} diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreOptionsTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreOptionsTest.java index a545580e2..6444b1a2d 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreOptionsTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreOptionsTest.java @@ -16,6 +16,9 @@ package com.google.cloud.datastore; +import static com.google.cloud.datastore.spi.v1.DatastoreRpc.Transport.GRPC; +import static com.google.cloud.datastore.spi.v1.DatastoreRpc.Transport.HTTP; +import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; @@ -81,6 +84,22 @@ public void testDatastore() { assertSame(datastoreRpc, options.build().getRpc()); } + @Test + public void testTransport() { + // default grpc transport + assertThat(options.build().getTransport()).isEqualTo(GRPC); + + // custom http transport + DatastoreOptions httpDatastoreOptions = + DatastoreOptions.newBuilder().setTransport(HTTP).setProjectId(PROJECT_ID).build(); + assertThat(httpDatastoreOptions.getTransport()).isEqualTo(HTTP); + + // custom grpc transport + DatastoreOptions grpcDatastoreOptions = + DatastoreOptions.newBuilder().setTransport(GRPC).setProjectId(PROJECT_ID).build(); + assertThat(grpcDatastoreOptions.getTransport()).isEqualTo(GRPC); + } + @Test public void testToBuilder() { DatastoreOptions original = options.setNamespace("ns1").build(); diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java index 84cbd4b73..efde25e61 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java @@ -92,6 +92,7 @@ @RunWith(JUnit4.class) public class DatastoreTest { + private static final LocalDatastoreHelper helper = LocalDatastoreHelper.create(1.0, 9090); private static DatastoreOptions options = helper.getOptions(); private static Datastore datastore; diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/spi/v1/RpcUtilsTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/spi/v1/RpcUtilsTest.java new file mode 100644 index 000000000..76fd00580 --- /dev/null +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/spi/v1/RpcUtilsTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.spi.v1; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.cloud.datastore.DatastoreOptions; +import org.junit.Test; +import org.threeten.bp.Duration; + +public class RpcUtilsTest { + + @Test + public void testRetrySettingSetter() { + UnaryCallSettings.Builder builder = + UnaryCallSettings.newUnaryCallSettingsBuilder(); + + // datastoreOptions with default retry settings + DatastoreOptions datastoreOptions = + DatastoreOptions.newBuilder().setProjectId("project-id").build(); + RpcUtils.retrySettingSetter(datastoreOptions).apply(builder); + assertThat(builder.getRetrySettings()).isEqualTo(datastoreOptions.getRetrySettings()); + + // datastoreOptions with custom retry settings + RetrySettings customRetrySettings = + RetrySettings.newBuilder() + .setTotalTimeout(Duration.ofMinutes(2)) + .setInitialRpcTimeout(Duration.ofSeconds(5)) + .setMaxRpcTimeout(Duration.ofSeconds(10)) + .setRetryDelayMultiplier(1.5) + .setMaxAttempts(5) + .build(); + DatastoreOptions datastoreOptionsWithCustomRetrySettings = + DatastoreOptions.newBuilder() + .setProjectId("project-id") + .setRetrySettings(customRetrySettings) + .build(); + RpcUtils.retrySettingSetter(datastoreOptionsWithCustomRetrySettings).apply(builder); + assertThat(builder.getRetrySettings()).isEqualTo(customRetrySettings); + } +} From 780c9f40f1ae04d0ec919d203bf256e3cff8fcc1 Mon Sep 17 00:00:00 2001 From: Prateek Date: Fri, 29 Dec 2023 10:20:35 +0530 Subject: [PATCH 06/42] test: Creating multi db rule to run tests multiple times against different named databases. (#1270) * integrating aggregation integration test with multidb rule * integrating multidb rule with ITDatastoreTest * addressing feedbacks --- .../it/ITDatastoreAggregationsTest.java | 51 +-- .../cloud/datastore/it/ITDatastoreTest.java | 313 ++++++++---------- .../cloud/datastore/it/MultiDbRule.java | 92 +++++ 3 files changed, 251 insertions(+), 205 deletions(-) create mode 100644 google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/MultiDbRule.java diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java index e04f5e55f..555c309fa 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java @@ -26,7 +26,6 @@ import com.google.cloud.datastore.AggregationResult; import com.google.cloud.datastore.Datastore; import com.google.cloud.datastore.Datastore.TransactionCallable; -import com.google.cloud.datastore.DatastoreOptions; import com.google.cloud.datastore.Entity; import com.google.cloud.datastore.EntityQuery; import com.google.cloud.datastore.GqlQuery; @@ -34,7 +33,6 @@ import com.google.cloud.datastore.Query; import com.google.cloud.datastore.QueryResults; import com.google.cloud.datastore.Transaction; -import com.google.cloud.datastore.testing.RemoteDatastoreHelper; import com.google.common.collect.ImmutableList; import com.google.datastore.v1.TransactionOptions; import com.google.datastore.v1.TransactionOptions.ReadOnly; @@ -43,18 +41,24 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import org.junit.After; -import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Test; // TODO(jainsahab) Move all the aggregation related tests from ITDatastoreTest to this file public class ITDatastoreAggregationsTest { - private static final RemoteDatastoreHelper HELPER = RemoteDatastoreHelper.create(); - private static final DatastoreOptions OPTIONS = HELPER.getOptions(); - private static final Datastore DATASTORE = OPTIONS.getService(); + @ClassRule public static MultiDbRule multiDbRule = new MultiDbRule(); + + private static Datastore DATASTORE; private static final String KIND = "Marks"; + @BeforeClass + public static void beforeClass() throws Exception { + DATASTORE = multiDbRule.getDatastore(); + } + @After public void tearDown() { EntityQuery allEntitiesQuery = Query.newEntityQueryBuilder().build(); @@ -64,11 +68,6 @@ public void tearDown() { DATASTORE.delete(keysToDelete); } - @AfterClass - public static void afterClass() throws Exception { - DATASTORE.close(); - } - Key key1 = DATASTORE.newKeyFactory().setKind(KIND).newKey(1); Key key2 = DATASTORE.newKeyFactory().setKind(KIND).newKey(2); Key key3 = DATASTORE.newKeyFactory().setKind(KIND).newKey(3); @@ -89,7 +88,6 @@ public void testSumAggregation() { Query.newAggregationQueryBuilder() .over(baseQuery) .addAggregations(sum("marks").as("total_marks")) - .setNamespace(OPTIONS.getNamespace()) .build(); // sum of 2 entities @@ -108,11 +106,7 @@ public void testSumAggregationWithAutoGeneratedAlias() { EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(KIND).build(); AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder() - .over(baseQuery) - .addAggregations(sum("marks")) - .setNamespace(OPTIONS.getNamespace()) - .build(); + Query.newAggregationQueryBuilder().over(baseQuery).addAggregations(sum("marks")).build(); // sum of 2 entities assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("property_1")) @@ -133,11 +127,7 @@ public void testSumAggregationInGqlQuery() { "AGGREGATE SUM(marks) AS total_marks OVER (SELECT * FROM Marks)") .build(); - AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder() - .over(gqlQuery) - .setNamespace(OPTIONS.getNamespace()) - .build(); + AggregationQuery aggregationQuery = Query.newAggregationQueryBuilder().over(gqlQuery).build(); // sum of 2 entities assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("total_marks")) @@ -158,7 +148,6 @@ public void testSumAggregationWithResultOfDoubleType() { Query.newAggregationQueryBuilder() .over(baseQuery) .addAggregations(sum("cgpa").as("total_cgpa")) - .setNamespace(OPTIONS.getNamespace()) .build(); // sum of 2 entities @@ -180,7 +169,6 @@ public void testAvgAggregation() { Query.newAggregationQueryBuilder() .over(baseQuery) .addAggregations(avg("marks").as("avg_marks")) - .setNamespace(OPTIONS.getNamespace()) .build(); // avg of 2 entities @@ -199,11 +187,7 @@ public void testAvgAggregationWithAutoGeneratedAlias() { EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(KIND).build(); AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder() - .over(baseQuery) - .addAggregations(avg("marks")) - .setNamespace(OPTIONS.getNamespace()) - .build(); + Query.newAggregationQueryBuilder().over(baseQuery).addAggregations(avg("marks")).build(); // avg of 2 entities assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getDouble("property_1")) @@ -223,11 +207,7 @@ public void testAvgAggregationInGqlQuery() { Query.newGqlQueryBuilder("AGGREGATE AVG(marks) AS avg_marks OVER (SELECT * FROM Marks)") .build(); - AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder() - .over(gqlQuery) - .setNamespace(OPTIONS.getNamespace()) - .build(); + AggregationQuery aggregationQuery = Query.newAggregationQueryBuilder().over(gqlQuery).build(); // avg of 2 entities assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getDouble("avg_marks")) @@ -249,7 +229,6 @@ public void testSumAndAvgAggregationTogether() { .over(baseQuery) .addAggregations(sum("marks").as("total_marks")) .addAggregations(avg("marks").as("avg_marks")) - .setNamespace(OPTIONS.getNamespace()) .build(); // sum of 2 entities @@ -271,7 +250,6 @@ public void testTransactionShouldReturnAConsistentSnapshot() { .addAggregation(count().as("count")) .addAggregations(sum("marks").as("total_marks")) .addAggregations(avg("marks").as("avg_marks")) - .setNamespace(OPTIONS.getNamespace()) .build(); // original entity count is 2 @@ -332,7 +310,6 @@ public void testReadOnlyTransactionShouldNotLockTheDocuments() .addAggregation(count().as("count")) .addAggregations(sum("marks").as("total_marks")) .addAggregations(avg("marks").as("avg_marks")) - .setNamespace(OPTIONS.getNamespace()) .build(); TransactionOptions transactionOptions = diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java index 3f00fe2cf..778fb6535 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java @@ -67,13 +67,11 @@ import com.google.cloud.datastore.TimestampValue; import com.google.cloud.datastore.Transaction; import com.google.cloud.datastore.ValueType; -import com.google.cloud.datastore.testing.RemoteDatastoreHelper; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.datastore.v1.TransactionOptions; import com.google.datastore.v1.TransactionOptions.ReadOnly; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; @@ -85,28 +83,17 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import org.junit.After; -import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.rules.Timeout; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -@RunWith(Parameterized.class) public class ITDatastoreTest { - private static final RemoteDatastoreHelper HELPER = RemoteDatastoreHelper.create(); - private static final DatastoreOptions OPTIONS_1 = HELPER.getOptions(); - private static final Datastore DATASTORE_1 = OPTIONS_1.getService(); - - private static final String CUSTOM_DB_ID = "test-db"; - private static final RemoteDatastoreHelper HELPER2 = RemoteDatastoreHelper.create(CUSTOM_DB_ID); - private static final DatastoreOptions OPTIONS_2 = HELPER2.getOptions(); - private static final Datastore DATASTORE_2 = OPTIONS_2.getService(); - - private final DatastoreOptions options; - private final Datastore datastore; + private static DatastoreOptions DATASTORE_OPTIONS; + private static Datastore DATASTORE; private static String PROJECT_ID; private static String NAMESPACE; @@ -139,37 +126,30 @@ public class ITDatastoreTest { private static Entity ENTITY2; private static Entity ENTITY3; + @ClassRule public static MultiDbRule multiDbRule = new MultiDbRule(); + @Rule public Timeout globalTimeout = Timeout.seconds(100); @Rule public MultipleAttemptsRule multipleAttemptsRule = new MultipleAttemptsRule(3); - @AfterClass - public static void afterClass() throws Exception { - HELPER.deleteNamespace(); - DATASTORE_1.close(); - DATASTORE_2.close(); - } + @BeforeClass + public static void beforeClass() throws Exception { - public ITDatastoreTest( - DatastoreOptions options, - Datastore datastore, - // databaseType is unused as a variable, but used as a parameterized label when running tests - String databaseType) { - this.options = options; - this.datastore = datastore; + DATASTORE_OPTIONS = multiDbRule.getCurrentOptions(); + DATASTORE = multiDbRule.getDatastore(); - PROJECT_ID = this.options.getProjectId(); - NAMESPACE = this.options.getNamespace(); + PROJECT_ID = DATASTORE_OPTIONS.getProjectId(); + NAMESPACE = DATASTORE_OPTIONS.getNamespace(); ROOT_KEY = - Key.newBuilder(PROJECT_ID, "rootkey", "default", options.getDatabaseId()) + Key.newBuilder(PROJECT_ID, "rootkey", "default", DATASTORE_OPTIONS.getDatabaseId()) .setNamespace(NAMESPACE) .build(); INCOMPLETE_KEY1 = IncompleteKey.newBuilder(ROOT_KEY, KIND1).setNamespace(NAMESPACE).build(); IncompleteKey INCOMPLETE_KEY2 = IncompleteKey.newBuilder(PROJECT_ID, KIND2) - .setDatabaseId(options.getDatabaseId()) + .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) .setNamespace(NAMESPACE) .build(); @@ -198,7 +178,7 @@ public ITDatastoreTest( .setKey( IncompleteKey.newBuilder(PROJECT_ID, KIND3) .setNamespace(NAMESPACE) - .setDatabaseId(options.getDatabaseId()) + .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) .build()) .build(); ENTITY1 = @@ -231,36 +211,30 @@ public ITDatastoreTest( @Before public void setUp() { - datastore.put(ENTITY1, ENTITY2); + DATASTORE.put(ENTITY1, ENTITY2); } @After public void tearDown() { EntityQuery allEntitiesQuery = Query.newEntityQueryBuilder().build(); - QueryResults allEntities = datastore.run(allEntitiesQuery); + QueryResults allEntities = DATASTORE.run(allEntitiesQuery); Key[] keysToDelete = ImmutableList.copyOf(allEntities).stream().map(Entity::getKey).toArray(Key[]::new); - datastore.delete(keysToDelete); - } - - @Parameterized.Parameters(name = "database: {2}") - public static Iterable data() { - return Arrays.asList( - new Object[][] {{OPTIONS_1, DATASTORE_1, "default"}, {OPTIONS_2, DATASTORE_2, "test-db"}}); + DATASTORE.delete(keysToDelete); } private Iterator getStronglyConsistentResults(Query scQuery, Query query) throws InterruptedException { // scQuery is equivalent to query, but with an ancestor filter in it // this makes scQuery strongly consistent - QueryResults scResults = datastore.run(scQuery); + QueryResults scResults = DATASTORE.run(scQuery); List scResultsCopy = makeResultsCopy(scResults); Set scResultsSet = new HashSet<>(scResultsCopy); int maxAttempts = 20; while (maxAttempts > 0) { --maxAttempts; - QueryResults results = datastore.run(query); + QueryResults results = DATASTORE.run(query); List resultsCopy = makeResultsCopy(results); Set resultsSet = new HashSet<>(resultsCopy); if (scResultsSet.size() == resultsSet.size() && scResultsSet.containsAll(resultsSet)) { @@ -293,7 +267,7 @@ public void orQuery() { .setNull("null") .set("age", 19) .build(); - datastore.put(entity3); + DATASTORE.put(entity3); // age == 19 || age == 20 CompositeFilter orFilter = @@ -304,7 +278,7 @@ public void orQuery() { .setKind(KIND2) .setFilter(orFilter) .build(); - QueryResults results = datastore.run(simpleOrQuery); + QueryResults results = DATASTORE.run(simpleOrQuery); assertTrue(results.hasNext()); assertEquals(ENTITY2, results.next()); assertTrue(results.hasNext()); @@ -319,7 +293,7 @@ public void orQuery() { .setFilter(orFilter) .setLimit(1) .build(); - QueryResults results2 = datastore.run(simpleOrQueryLimit); + QueryResults results2 = DATASTORE.run(simpleOrQueryLimit); assertTrue(results2.hasNext()); assertEquals(ENTITY2, results2.next()); assertFalse(results2.hasNext()); @@ -337,7 +311,7 @@ public void orQuery() { .setKind(KIND2) .setFilter(compositeFilter) .build(); - QueryResults results3 = datastore.run(orQueryNested); + QueryResults results3 = DATASTORE.run(orQueryNested); assertTrue(results3.hasNext()); assertEquals(ENTITY2, results3.next()); assertFalse(results3.hasNext()); @@ -355,7 +329,7 @@ public void orQuery() { .setFilter(ancestorAndFilter) .setLimit(1) .build(); - QueryResults results4 = datastore.run(orQueryNested2); + QueryResults results4 = DATASTORE.run(orQueryNested2); assertTrue(results4.hasNext()); assertEquals(ENTITY2, results4.next()); assertFalse(results4.hasNext()); @@ -363,7 +337,7 @@ public void orQuery() { @Test public void testNewTransactionCommit() { - Transaction transaction = datastore.newTransaction(); + Transaction transaction = DATASTORE.newTransaction(); transaction.add(ENTITY3); Entity entity2 = Entity.newBuilder(ENTITY2).clear().setNull("bla").build(); transaction.update(entity2); @@ -371,7 +345,7 @@ public void testNewTransactionCommit() { transaction.commit(); assertFalse(transaction.isActive()); - List list = datastore.fetch(KEY1, KEY2, KEY3); + List list = DATASTORE.fetch(KEY1, KEY2, KEY3); assertNull(list.get(0)); assertEquals(entity2, list.get(1)); assertEquals(ENTITY3, list.get(2)); @@ -395,20 +369,20 @@ public void testNewTransactionCommit() { @Test public void testTransactionWithRead() throws Exception { StatementExecutor statementExecutor = new StatementExecutor(); - Transaction baseTransaction = datastore.newTransaction(); + Transaction baseTransaction = DATASTORE.newTransaction(); assertNull(baseTransaction.get(KEY3)); baseTransaction.add(ENTITY3); baseTransaction.commit(); - assertEquals(ENTITY3, datastore.get(KEY3)); + assertEquals(ENTITY3, DATASTORE.get(KEY3)); - Transaction transaction = datastore.newTransaction(); + Transaction transaction = DATASTORE.newTransaction(); statementExecutor.execute( Tuple.of("T1", () -> assertEquals(ENTITY3, transaction.get(KEY3))), // update entity3 during the transaction, will be blocked in case of pessimistic concurrency Tuple.of( "T2", () -> - datastore.put(Entity.newBuilder(ENTITY3).clear().set("from", "datastore").build())), + DATASTORE.put(Entity.newBuilder(ENTITY3).clear().set("from", "datastore").build())), Tuple.of( "T1", () -> @@ -436,16 +410,16 @@ public void testTransactionWithQuery() throws Exception { .setFilter(PropertyFilter.hasAncestor(KEY2)) .setNamespace(NAMESPACE) .build(); - Transaction baseTransaction = datastore.newTransaction(); + Transaction baseTransaction = DATASTORE.newTransaction(); QueryResults baseResults = baseTransaction.run(query); assertTrue(baseResults.hasNext()); assertEquals(ENTITY2, baseResults.next()); assertFalse(baseResults.hasNext()); baseTransaction.add(ENTITY3); baseTransaction.commit(); - assertEquals(ENTITY3, datastore.get(KEY3)); + assertEquals(ENTITY3, DATASTORE.get(KEY3)); - Transaction transaction = datastore.newTransaction(); + Transaction transaction = DATASTORE.newTransaction(); statementExecutor.execute( Tuple.of( "T1", @@ -457,7 +431,7 @@ public void testTransactionWithQuery() throws Exception { }), Tuple.of("T1", () -> transaction.delete(ENTITY3.getKey())), // update entity2 during the transaction, will be blocked in case of pessimistic concurrency - Tuple.of("T2", () -> datastore.put(Entity.newBuilder(ENTITY2).clear().build())), + Tuple.of("T2", () -> DATASTORE.put(Entity.newBuilder(ENTITY2).clear().build())), Tuple.of("T1", transaction::commit) // T1 will throw error in case of optimistic concurrency ); @@ -473,7 +447,7 @@ public void testTransactionWithQuery() throws Exception { @Test public void testNewTransactionRollback() { - Transaction transaction = datastore.newTransaction(); + Transaction transaction = DATASTORE.newTransaction(); transaction.add(ENTITY3); Entity entity2 = Entity.newBuilder(ENTITY2) @@ -493,7 +467,7 @@ public void testNewTransactionRollback() { assertEquals("FAILED_PRECONDITION", expected.getReason()); } - List list = datastore.fetch(KEY1, KEY2, KEY3); + List list = DATASTORE.fetch(KEY1, KEY2, KEY3); assertEquals(ENTITY1, list.get(0)); assertEquals(ENTITY2, list.get(1)); assertNull(list.get(2)); @@ -502,7 +476,7 @@ public void testNewTransactionRollback() { @Test public void testNewBatch() { - Batch batch = datastore.newBatch(); + Batch batch = DATASTORE.newBatch(); Entity entity1 = Entity.newBuilder(ENTITY1).clear().build(); Entity entity2 = Entity.newBuilder(ENTITY2).clear().setNull("bla").build(); Entity entity4 = Entity.newBuilder(KEY4).set("value", StringValue.of("value")).build(); @@ -525,7 +499,7 @@ public void testNewBatch() { Batch.Response response = batch.submit(); entities = - datastore.fetch(KEY1, KEY2, KEY3, entity4.getKey(), entity5.getKey(), entity6.getKey()); + DATASTORE.fetch(KEY1, KEY2, KEY3, entity4.getKey(), entity5.getKey(), entity6.getKey()); assertEquals(entity1, entities.get(0)); assertEquals(entity2, entities.get(1)); assertEquals(ENTITY3, entities.get(2)); @@ -535,7 +509,7 @@ public void testNewBatch() { assertEquals(6, entities.size()); List generatedKeys = response.getGeneratedKeys(); assertEquals(1, generatedKeys.size()); - assertEquals(PARTIAL_ENTITY3.getNames(), datastore.get(generatedKeys.get(0)).getNames()); + assertEquals(PARTIAL_ENTITY3.getNames(), DATASTORE.get(generatedKeys.get(0)).getNames()); assertEquals(PARTIAL_ENTITY3.getKey(), IncompleteKey.newBuilder(generatedKeys.get(0)).build()); try { @@ -545,12 +519,12 @@ public void testNewBatch() { assertEquals("FAILED_PRECONDITION", expected.getReason()); } - batch = datastore.newBatch(); + batch = DATASTORE.newBatch(); batch.delete(entity4.getKey(), entity5.getKey(), entity6.getKey()); batch.update(ENTITY1, ENTITY2, ENTITY3); batch.submit(); entities = - datastore.fetch(KEY1, KEY2, KEY3, entity4.getKey(), entity5.getKey(), entity6.getKey()); + DATASTORE.fetch(KEY1, KEY2, KEY3, entity4.getKey(), entity5.getKey(), entity6.getKey()); assertEquals(ENTITY1, entities.get(0)); assertEquals(ENTITY2, entities.get(1)); assertEquals(ENTITY3, entities.get(2)); @@ -579,7 +553,7 @@ public void testRunGqlQueryNoCasting() throws InterruptedException { assertEquals(ENTITY1, results1.next()); assertFalse(results1.hasNext()); - datastore.put(ENTITY3); + DATASTORE.put(ENTITY3); Query query2 = Query.newGqlQueryBuilder(ResultType.ENTITY, "select * from " + KIND2 + " order by __key__") .setNamespace(NAMESPACE) @@ -646,7 +620,7 @@ public void testRunGqlQueryNoCasting() throws InterruptedException { assertEquals(KEY1, projectionEntity.getKey()); assertTrue(projectionEntity.getNames().isEmpty()); assertFalse(keyProjectionResult.hasNext()); - datastore.delete(ENTITY3.getKey()); + DATASTORE.delete(ENTITY3.getKey()); } @Test @@ -669,7 +643,7 @@ public void testRunGqlQueryWithCasting() throws InterruptedException { Query query2 = Query.newGqlQueryBuilder("select * from " + KIND1).setNamespace(NAMESPACE).build(); - QueryResults results2 = datastore.run(query2); + QueryResults results2 = DATASTORE.run(query2); assertSame(Entity.class, results2.getResultClass()); @@ -824,11 +798,11 @@ public void testRunAggregationQueryInTransactionShouldReturnAConsistentSnapshot( .build(); // original entity count is 2 - assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) + assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) .isEqualTo(2L); // FIRST TRANSACTION - datastore.runInTransaction( + DATASTORE.runInTransaction( (TransactionCallable) inFirstTransaction -> { // creating a new entity @@ -842,16 +816,16 @@ public void testRunAggregationQueryInTransactionShouldReturnAConsistentSnapshot( .getLong("count")) .isEqualTo(2L); assertThat( - getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) + getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) .isEqualTo(2L); return null; }); // after first transaction is committed, count is updated to 3 now. - assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) + assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) .isEqualTo(3L); // SECOND TRANSACTION - datastore.runInTransaction( + DATASTORE.runInTransaction( (TransactionCallable) inSecondTransaction -> { // deleting ENTITY2 @@ -863,14 +837,14 @@ public void testRunAggregationQueryInTransactionShouldReturnAConsistentSnapshot( .getLong("count")) .isEqualTo(3L); assertThat( - getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) + getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) .isEqualTo(3L); return null; }); // after second transaction is committed, count is updated to 2 now. - assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) + assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) .isEqualTo(2L); - datastore.delete(newEntityKey); + DATASTORE.delete(newEntityKey); } @Test @@ -891,7 +865,7 @@ public void testRunAggregationQueryInAReadOnlyTransactionShouldNotLockTheCounted TransactionOptions transactionOptions = TransactionOptions.newBuilder().setReadOnly(ReadOnly.newBuilder().build()).build(); - Transaction readOnlyTransaction = datastore.newTransaction(transactionOptions); + Transaction readOnlyTransaction = DATASTORE.newTransaction(transactionOptions); // Executing query in transaction assertThat( @@ -907,7 +881,7 @@ public void testRunAggregationQueryInAReadOnlyTransactionShouldNotLockTheCounted .setKey(Key.newBuilder(KEY1, "newKind", "name-01").build()) .set("v_int", 10) .build(); - datastore.put(aNewEntity); + DATASTORE.put(aNewEntity); return null; }); @@ -918,7 +892,7 @@ public void testRunAggregationQueryInAReadOnlyTransactionShouldNotLockTheCounted readOnlyTransaction.commit(); executor.shutdownNow(); - assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) + assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) .isEqualTo(3L); } @@ -1051,7 +1025,7 @@ public void testInNotInNeqFilters() throws InterruptedException { .setKey(Key.newBuilder(INCOMPLETE_KEY1, "e2").build()) .set("v_int", 20) .build(); - datastore.put(e1, e2); + DATASTORE.put(e1, e2); Query queryIn = Query.newEntityQueryBuilder() @@ -1121,21 +1095,21 @@ public void testInNotInNeqFilters() throws InterruptedException { PropertyFilter.eq("v_int", 10000))) .build(); - QueryResults run = datastore.run(scQueryInEqOr); + QueryResults run = DATASTORE.run(scQueryInEqOr); assertTrue(run.hasNext()); assertEquals(e1, run.next()); assertFalse(run.hasNext()); - datastore.delete(e1.getKey()); - datastore.delete(e2.getKey()); + DATASTORE.delete(e1.getKey()); + DATASTORE.delete(e2.getKey()); } @Test public void testAllocateId() { - KeyFactory keyFactory = datastore.newKeyFactory().setKind(KIND1); + KeyFactory keyFactory = DATASTORE.newKeyFactory().setKind(KIND1); IncompleteKey pk1 = keyFactory.newKey(); - Key key1 = datastore.allocateId(pk1); + Key key1 = DATASTORE.allocateId(pk1); assertEquals(key1.getProjectId(), pk1.getProjectId()); assertEquals(key1.getNamespace(), pk1.getNamespace()); assertEquals(key1.getAncestors(), pk1.getAncestors()); @@ -1144,31 +1118,31 @@ public void testAllocateId() { assertFalse(key1.hasName()); assertEquals(Key.newBuilder(pk1, key1.getId()).build(), key1); - Key key2 = datastore.allocateId(pk1); + Key key2 = DATASTORE.allocateId(pk1); assertNotEquals(key1, key2); assertEquals(Key.newBuilder(pk1, key2.getId()).build(), key2); } @Test public void testReserveIds() { - KeyFactory keyFactory = datastore.newKeyFactory().setKind("MyKind"); + KeyFactory keyFactory = DATASTORE.newKeyFactory().setKind("MyKind"); Key key1 = keyFactory.newKey(10); Key key2 = keyFactory.newKey("name"); - List keyList = datastore.reserveIds(key1, key2); + List keyList = DATASTORE.reserveIds(key1, key2); assertEquals(2, keyList.size()); } @Test public void testAllocateIdArray() { - KeyFactory keyFactory = datastore.newKeyFactory().setKind(KIND1); + KeyFactory keyFactory = DATASTORE.newKeyFactory().setKind(KIND1); IncompleteKey incompleteKey1 = keyFactory.newKey(); IncompleteKey incompleteKey2 = keyFactory .setKind(KIND2) - .setDatabaseId(options.getDatabaseId()) + .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) .addAncestors(PathElement.of(KIND1, 10)) .newKey(); - List result = datastore.allocateId(incompleteKey1, incompleteKey2, incompleteKey1); + List result = DATASTORE.allocateId(incompleteKey1, incompleteKey2, incompleteKey1); assertEquals(3, result.size()); assertEquals(Key.newBuilder(incompleteKey1, result.get(0).getId()).build(), result.get(0)); assertEquals(Key.newBuilder(incompleteKey1, result.get(2).getId()).build(), result.get(2)); @@ -1177,10 +1151,10 @@ public void testAllocateIdArray() { @Test public void testGet() { - Entity entity = datastore.get(KEY3); + Entity entity = DATASTORE.get(KEY3); assertNull(entity); - entity = datastore.get(KEY1); + entity = DATASTORE.get(KEY1); assertEquals(ENTITY1, entity); StringValue value1 = entity.getValue("str"); assertEquals(STR_VALUE, value1); @@ -1203,36 +1177,36 @@ public void testGet() { @Test public void testGetWithReadTime() throws InterruptedException { Key key = - Key.newBuilder(PROJECT_ID, "new_kind", "name", options.getDatabaseId()) + Key.newBuilder(PROJECT_ID, "new_kind", "name", DATASTORE_OPTIONS.getDatabaseId()) .setNamespace(NAMESPACE) .build(); try { - datastore.put(Entity.newBuilder(key).set("str", "old_str_value").build()); + DATASTORE.put(Entity.newBuilder(key).set("str", "old_str_value").build()); Thread.sleep(1000); Timestamp now = Timestamp.now(); Thread.sleep(1000); - datastore.put(Entity.newBuilder(key).set("str", "new_str_value").build()); + DATASTORE.put(Entity.newBuilder(key).set("str", "new_str_value").build()); - Entity entity = datastore.get(key); + Entity entity = DATASTORE.get(key); StringValue value1 = entity.getValue("str"); assertEquals(StringValue.of("new_str_value"), value1); - entity = datastore.get(key, ReadOption.readTime(now)); + entity = DATASTORE.get(key, ReadOption.readTime(now)); value1 = entity.getValue("str"); assertEquals(StringValue.of("old_str_value"), value1); } finally { - datastore.delete(key); + DATASTORE.delete(key); } } @Test public void testGetArrayNoDeferredResults() { - datastore.put(ENTITY3); + DATASTORE.put(ENTITY3); Iterator result = - datastore.fetch(KEY1, Key.newBuilder(KEY1).setName("bla").build(), KEY2, KEY3).iterator(); + DATASTORE.fetch(KEY1, Key.newBuilder(KEY1).setName("bla").build(), KEY2, KEY3).iterator(); assertEquals(ENTITY1, result.next()); assertNull(result.next()); assertEquals(ENTITY2, result.next()); @@ -1257,93 +1231,93 @@ public void testGetArrayNoDeferredResults() { // expected - no such property } assertFalse(result.hasNext()); - datastore.delete(ENTITY3.getKey()); + DATASTORE.delete(ENTITY3.getKey()); } @Test public void testAddEntity() { - List keys = datastore.fetch(ENTITY1.getKey(), ENTITY3.getKey()); + List keys = DATASTORE.fetch(ENTITY1.getKey(), ENTITY3.getKey()); assertEquals(ENTITY1, keys.get(0)); assertNull(keys.get(1)); assertEquals(2, keys.size()); try { - datastore.add(ENTITY1); + DATASTORE.add(ENTITY1); fail("Expecting a failure"); } catch (DatastoreException expected) { // expected; } - List entities = datastore.add(ENTITY3, PARTIAL_ENTITY1, PARTIAL_ENTITY2); - assertEquals(ENTITY3, datastore.get(ENTITY3.getKey())); + List entities = DATASTORE.add(ENTITY3, PARTIAL_ENTITY1, PARTIAL_ENTITY2); + assertEquals(ENTITY3, DATASTORE.get(ENTITY3.getKey())); assertEquals(ENTITY3, entities.get(0)); assertEquals(PARTIAL_ENTITY1.getNames(), entities.get(1).getNames()); assertEquals(PARTIAL_ENTITY1.getKey().getAncestors(), entities.get(1).getKey().getAncestors()); - assertNotNull(datastore.get(entities.get(1).getKey())); + assertNotNull(DATASTORE.get(entities.get(1).getKey())); assertEquals(PARTIAL_ENTITY2.getNames(), entities.get(2).getNames()); assertEquals(PARTIAL_ENTITY2.getKey().getAncestors(), entities.get(2).getKey().getAncestors()); - assertNotNull(datastore.get(entities.get(2).getKey())); + assertNotNull(DATASTORE.get(entities.get(2).getKey())); for (Entity entity : entities) { - datastore.delete(entity.getKey()); + DATASTORE.delete(entity.getKey()); } } @Test public void testUpdate() { - List keys = datastore.fetch(ENTITY1.getKey(), ENTITY3.getKey()); + List keys = DATASTORE.fetch(ENTITY1.getKey(), ENTITY3.getKey()); assertEquals(ENTITY1, keys.get(0)); assertNull(keys.get(1)); assertEquals(2, keys.size()); try { - datastore.update(ENTITY3); + DATASTORE.update(ENTITY3); fail("Expecting a failure"); } catch (DatastoreException expected) { // expected; } - datastore.add(ENTITY3); - assertEquals(ENTITY3, datastore.get(ENTITY3.getKey())); + DATASTORE.add(ENTITY3); + assertEquals(ENTITY3, DATASTORE.get(ENTITY3.getKey())); Entity entity3 = Entity.newBuilder(ENTITY3).clear().set("bla", new NullValue()).build(); assertNotEquals(ENTITY3, entity3); - datastore.update(entity3); - assertEquals(entity3, datastore.get(ENTITY3.getKey())); - datastore.delete(ENTITY3.getKey()); + DATASTORE.update(entity3); + assertEquals(entity3, DATASTORE.get(ENTITY3.getKey())); + DATASTORE.delete(ENTITY3.getKey()); } @Test public void testPut() { Entity updatedEntity = Entity.newBuilder(ENTITY1).set("new_property", 42L).build(); - assertEquals(updatedEntity, datastore.put(updatedEntity)); - assertEquals(updatedEntity, datastore.get(updatedEntity.getKey())); + assertEquals(updatedEntity, DATASTORE.put(updatedEntity)); + assertEquals(updatedEntity, DATASTORE.get(updatedEntity.getKey())); Entity entity2 = Entity.newBuilder(ENTITY2).clear().set("bla", new NullValue()).build(); assertNotEquals(ENTITY2, entity2); - List entities = datastore.put(ENTITY1, entity2, ENTITY3, PARTIAL_ENTITY1); + List entities = DATASTORE.put(ENTITY1, entity2, ENTITY3, PARTIAL_ENTITY1); assertEquals(ENTITY1, entities.get(0)); assertEquals(entity2, entities.get(1)); assertEquals(ENTITY3, entities.get(2)); assertEquals(PARTIAL_ENTITY1.getNames(), entities.get(3).getNames()); assertEquals(PARTIAL_ENTITY1.getKey().getAncestors(), entities.get(3).getKey().getAncestors()); - assertEquals(ENTITY1, datastore.get(ENTITY1.getKey())); - assertEquals(entity2, datastore.get(entity2.getKey())); - assertEquals(ENTITY3, datastore.get(ENTITY3.getKey())); - Entity entity = datastore.get(entities.get(3).getKey()); + assertEquals(ENTITY1, DATASTORE.get(ENTITY1.getKey())); + assertEquals(entity2, DATASTORE.get(entity2.getKey())); + assertEquals(ENTITY3, DATASTORE.get(ENTITY3.getKey())); + Entity entity = DATASTORE.get(entities.get(3).getKey()); assertEquals(entities.get(3), entity); for (Entity entityToDelete : entities) { - datastore.delete(entityToDelete.getKey()); + DATASTORE.delete(entityToDelete.getKey()); } } @Test public void testDelete() { Iterator keys = - datastore.fetch(ENTITY1.getKey(), ENTITY2.getKey(), ENTITY3.getKey()).iterator(); + DATASTORE.fetch(ENTITY1.getKey(), ENTITY2.getKey(), ENTITY3.getKey()).iterator(); assertEquals(ENTITY1, keys.next()); assertEquals(ENTITY2, keys.next()); assertNull(keys.next()); assertFalse(keys.hasNext()); - datastore.delete(ENTITY1.getKey(), ENTITY2.getKey(), ENTITY3.getKey()); - keys = datastore.fetch(ENTITY1.getKey(), ENTITY2.getKey(), ENTITY3.getKey()).iterator(); + DATASTORE.delete(ENTITY1.getKey(), ENTITY2.getKey(), ENTITY3.getKey()); + keys = DATASTORE.fetch(ENTITY1.getKey(), ENTITY2.getKey(), ENTITY3.getKey()).iterator(); assertNull(keys.next()); assertNull(keys.next()); assertNull(keys.next()); @@ -1368,7 +1342,7 @@ public Integer run(DatastoreReaderWriter transaction) { } }; - int result = datastore.runInTransaction(callable1); + int result = DATASTORE.runInTransaction(callable1); assertEquals(result, 2); Datastore.TransactionCallable callable2 = @@ -1387,7 +1361,7 @@ public Integer run(DatastoreReaderWriter transaction) { }; try { - datastore.runInTransaction(callable2); + DATASTORE.runInTransaction(callable2); fail("Expecting a failure"); } catch (DatastoreException expected) { assertEquals(4, ((DatastoreException) expected.getCause()).getCode()); @@ -1415,7 +1389,7 @@ public Integer run(DatastoreReaderWriter transaction) { } }; - int result = datastore.runInTransaction(callable1); + int result = DATASTORE.runInTransaction(callable1); assertEquals(result, 2); final Entity entity2 = Entity.newBuilder(ENTITY2).clear().setNull("bla").build(); @@ -1441,7 +1415,7 @@ public Integer run(DatastoreReaderWriter transaction) { .build(); try { - datastore.runInTransaction(callable2, readOnlyOptions); + DATASTORE.runInTransaction(callable2, readOnlyOptions); fail("Expecting a failure"); } catch (DatastoreException expected) { assertEquals( @@ -1453,20 +1427,20 @@ public Integer run(DatastoreReaderWriter transaction) { @Test public void testSkippedResults() { Query query = Query.newKeyQueryBuilder().setOffset(Integer.MAX_VALUE).build(); - int numberOfEntities = datastore.run(query).getSkippedResults(); + int numberOfEntities = DATASTORE.run(query).getSkippedResults(); assertEquals(2, numberOfEntities); } @Test public void testSetLimit() { - datastore.put(ENTITY1); + DATASTORE.put(ENTITY1); Query keyQuery = Query.newKeyQueryBuilder().setLimit(1).build(); - QueryResults queryResults = datastore.run(keyQuery); + QueryResults queryResults = DATASTORE.run(keyQuery); assertTrue(queryResults.hasNext()); assertEquals(KEY1, queryResults.next()); Query query = Query.newEntityQueryBuilder().setLimit(0).build(); - QueryResults results = datastore.run(query); + QueryResults results = DATASTORE.run(query); assertFalse(results.hasNext()); } @@ -1477,7 +1451,7 @@ public void testGqlQueryWithNullBinding() { .setNamespace(NAMESPACE) .setNullBinding("name") .build(); - Iterator results = datastore.run(query); + Iterator results = DATASTORE.run(query); assertTrue(results.hasNext()); assertEquals(ENTITY1, results.next()); assertFalse(results.hasNext()); @@ -1487,27 +1461,30 @@ public void testGqlQueryWithNullBinding() { public void testQueryWithStartCursor() { Entity entity1 = Entity.newBuilder( - Key.newBuilder(PROJECT_ID, KIND1, "name-01", options.getDatabaseId()).build()) + Key.newBuilder(PROJECT_ID, KIND1, "name-01", DATASTORE_OPTIONS.getDatabaseId()) + .build()) .build(); Entity entity2 = Entity.newBuilder( - Key.newBuilder(PROJECT_ID, KIND1, "name-02", options.getDatabaseId()).build()) + Key.newBuilder(PROJECT_ID, KIND1, "name-02", DATASTORE_OPTIONS.getDatabaseId()) + .build()) .build(); Entity entity3 = Entity.newBuilder( - Key.newBuilder(PROJECT_ID, KIND1, "name-03", options.getDatabaseId()).build()) + Key.newBuilder(PROJECT_ID, KIND1, "name-03", DATASTORE_OPTIONS.getDatabaseId()) + .build()) .build(); - datastore.put(entity1, entity2, entity3); - QueryResults run1 = datastore.run(Query.newEntityQueryBuilder().setKind(KIND1).build()); + DATASTORE.put(entity1, entity2, entity3); + QueryResults run1 = DATASTORE.run(Query.newEntityQueryBuilder().setKind(KIND1).build()); run1.next(); Cursor cursor1 = run1.getCursorAfter(); assertNotNull(cursor1); QueryResults run2 = - datastore.run(Query.newEntityQueryBuilder().setKind(KIND1).setStartCursor(cursor1).build()); + DATASTORE.run(Query.newEntityQueryBuilder().setKind(KIND1).setStartCursor(cursor1).build()); Cursor cursor2 = run2.getCursorAfter(); assertNotNull(cursor2); assertEquals(cursor2, cursor1); - datastore.delete(entity1.getKey(), entity2.getKey(), entity3.getKey()); + DATASTORE.delete(entity1.getKey(), entity2.getKey(), entity3.getKey()); } @Test @@ -1515,35 +1492,35 @@ public void testQueryWithReadTime() throws InterruptedException { Entity entity1 = Entity.newBuilder( Key.newBuilder(PROJECT_ID, "new_kind", "name-01") - .setDatabaseId(options.getDatabaseId()) + .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) .setNamespace(NAMESPACE) .build()) .build(); Entity entity2 = Entity.newBuilder( Key.newBuilder(PROJECT_ID, "new_kind", "name-02") - .setDatabaseId(options.getDatabaseId()) + .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) .setNamespace(NAMESPACE) .build()) .build(); Entity entity3 = Entity.newBuilder( Key.newBuilder(PROJECT_ID, "new_kind", "name-03") - .setDatabaseId(options.getDatabaseId()) + .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) .setNamespace(NAMESPACE) .build()) .build(); - datastore.put(entity1, entity2); + DATASTORE.put(entity1, entity2); Thread.sleep(1000); Timestamp now = Timestamp.now(); Thread.sleep(1000); - datastore.put(entity3); + DATASTORE.put(entity3); try { Query query = Query.newEntityQueryBuilder().setKind("new_kind").build(); - QueryResults withoutReadTime = datastore.run(query); + QueryResults withoutReadTime = DATASTORE.run(query); assertTrue(withoutReadTime.hasNext()); assertEquals(entity1, withoutReadTime.next()); assertTrue(withoutReadTime.hasNext()); @@ -1552,14 +1529,14 @@ public void testQueryWithReadTime() throws InterruptedException { assertEquals(entity3, withoutReadTime.next()); assertFalse(withoutReadTime.hasNext()); - QueryResults withReadTime = datastore.run(query, ReadOption.readTime(now)); + QueryResults withReadTime = DATASTORE.run(query, ReadOption.readTime(now)); assertTrue(withReadTime.hasNext()); assertEquals(entity1, withReadTime.next()); assertTrue(withReadTime.hasNext()); assertEquals(entity2, withReadTime.next()); assertFalse(withReadTime.hasNext()); } finally { - datastore.delete(entity1.getKey(), entity2.getKey(), entity3.getKey()); + DATASTORE.delete(entity1.getKey(), entity2.getKey(), entity3.getKey()); } } @@ -1569,7 +1546,7 @@ private void testCountAggregationWith(Consumer configu AggregationQuery aggregationQuery = builder.build(); String alias = "total_count"; - Long countBeforeAdd = getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong(alias); + Long countBeforeAdd = getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong(alias); long expectedCount = countBeforeAdd + 1; Entity newEntity = @@ -1579,12 +1556,12 @@ private void testCountAggregationWith(Consumer configu .set("partial1", PARTIAL_ENTITY2) .set("partial2", ENTITY2) .build(); - datastore.put(newEntity); + DATASTORE.put(newEntity); - Long countAfterAdd = getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong(alias); + Long countAfterAdd = getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong(alias); assertThat(countAfterAdd).isEqualTo(expectedCount); - datastore.delete(newEntity.getKey()); + DATASTORE.delete(newEntity.getKey()); } private void testCountAggregationWithLimit( @@ -1597,7 +1574,7 @@ private void testCountAggregationWithLimit( withoutLimitConfigurer.accept(withoutLimitBuilder); Long currentCount = - getOnlyElement(datastore.runAggregation(withoutLimitBuilder.build())).getLong(alias); + getOnlyElement(DATASTORE.runAggregation(withoutLimitBuilder.build())).getLong(alias); long limit = currentCount - 1; AggregationQuery.Builder withLimitBuilder = @@ -1605,7 +1582,7 @@ private void testCountAggregationWithLimit( withLimitConfigurer.accept(withLimitBuilder, limit); Long countWithLimit = - getOnlyElement(datastore.runAggregation(withLimitBuilder.build())).getLong(alias); + getOnlyElement(DATASTORE.runAggregation(withLimitBuilder.build())).getLong(alias); assertThat(countWithLimit).isEqualTo(limit); } @@ -1614,7 +1591,7 @@ private void testCountAggregationReadTimeWith(Consumer Entity entity1 = Entity.newBuilder( Key.newBuilder(PROJECT_ID, "new_kind", "name-01") - .setDatabaseId(options.getDatabaseId()) + .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) .setNamespace(NAMESPACE) .build()) .set("name", "Tyrion Lannister") @@ -1622,7 +1599,7 @@ private void testCountAggregationReadTimeWith(Consumer Entity entity2 = Entity.newBuilder( Key.newBuilder(PROJECT_ID, "new_kind", "name-02") - .setDatabaseId(options.getDatabaseId()) + .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) .setNamespace(NAMESPACE) .build()) .set("name", "Jaime Lannister") @@ -1630,17 +1607,17 @@ private void testCountAggregationReadTimeWith(Consumer Entity entity3 = Entity.newBuilder( Key.newBuilder(PROJECT_ID, "new_kind", "name-03") - .setDatabaseId(options.getDatabaseId()) + .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) .setNamespace(NAMESPACE) .build()) .set("name", "Cersei Lannister") .build(); - datastore.put(entity1, entity2); + DATASTORE.put(entity1, entity2); Thread.sleep(1000); Timestamp now = Timestamp.now(); Thread.sleep(1000); - datastore.put(entity3); + DATASTORE.put(entity3); try { AggregationQuery.Builder builder = Query.newAggregationQueryBuilder().setNamespace(NAMESPACE); @@ -1648,15 +1625,15 @@ private void testCountAggregationReadTimeWith(Consumer AggregationQuery countAggregationQuery = builder.build(); Long latestCount = - getOnlyElement(datastore.runAggregation(countAggregationQuery)).getLong("total_count"); + getOnlyElement(DATASTORE.runAggregation(countAggregationQuery)).getLong("total_count"); assertThat(latestCount).isEqualTo(3L); Long oldCount = - getOnlyElement(datastore.runAggregation(countAggregationQuery, ReadOption.readTime(now))) + getOnlyElement(DATASTORE.runAggregation(countAggregationQuery, ReadOption.readTime(now))) .getLong("total_count"); assertThat(oldCount).isEqualTo(2L); } finally { - datastore.delete(entity1.getKey(), entity2.getKey(), entity3.getKey()); + DATASTORE.delete(entity1.getKey(), entity2.getKey(), entity3.getKey()); } } } diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/MultiDbRule.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/MultiDbRule.java new file mode 100644 index 000000000..099ca01ee --- /dev/null +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/MultiDbRule.java @@ -0,0 +1,92 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.datastore.it; + +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.testing.RemoteDatastoreHelper; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +public class MultiDbRule implements TestRule { + + private static final String CUSTOM_DB_ID = "test-db"; + private static final Logger logger = Logger.getLogger(MultiDbRule.class.getName()); + + private final RemoteDatastoreHelper HELPER_1; + private final DatastoreOptions OPTIONS_1; + private final Datastore DATASTORE_1; + private final RemoteDatastoreHelper HELPER_2; + private final DatastoreOptions OPTIONS_2; + private final Datastore DATASTORE_2; + + private Datastore currentDatastore; + private DatastoreOptions currentDatastoreOptions; + + public MultiDbRule() { + HELPER_1 = RemoteDatastoreHelper.create(); + OPTIONS_1 = HELPER_1.getOptions(); + + HELPER_2 = RemoteDatastoreHelper.create(CUSTOM_DB_ID); + OPTIONS_2 = HELPER_2.getOptions(); + + DATASTORE_1 = OPTIONS_1.getService(); + DATASTORE_2 = OPTIONS_2.getService(); + this.currentDatastore = DATASTORE_1; + this.currentDatastoreOptions = OPTIONS_1; + } + + @Override + public Statement apply(Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + try { + String testName = description.getDisplayName(); + // running with default Datastore + logger.log( + Level.INFO, "Running {0} with database {1}", new Object[] {testName, "default"}); + base.evaluate(); + + // running with test-db Datastore + logger.log( + Level.INFO, "Running {0} with database {1}", new Object[] {testName, CUSTOM_DB_ID}); + MultiDbRule.this.currentDatastore = DATASTORE_2; + MultiDbRule.this.currentDatastoreOptions = OPTIONS_2; + base.evaluate(); + + } finally { + HELPER_1.deleteNamespace(); + HELPER_2.deleteNamespace(); + DATASTORE_1.close(); + DATASTORE_2.close(); + } + } + }; + } + + public Datastore getDatastore() { + return this.currentDatastore; + } + + public DatastoreOptions getCurrentOptions() { + return this.currentDatastoreOptions; + } +} From 408bb217a02e9ee1c71729e2195801b8d94e74b9 Mon Sep 17 00:00:00 2001 From: kolea2 <45548808+kolea2@users.noreply.github.com> Date: Thu, 4 Jan 2024 13:38:15 -0500 Subject: [PATCH 07/42] feat: remove `@BetaApi` annotations from get/setDatabaseId methods (#1277) Cherry pick of #1272 --- .../src/main/java/com/google/cloud/datastore/BaseKey.java | 3 --- .../main/java/com/google/cloud/datastore/DatastoreOptions.java | 3 --- .../main/java/com/google/cloud/datastore/IncompleteKey.java | 2 -- .../src/main/java/com/google/cloud/datastore/Key.java | 3 --- .../src/main/java/com/google/cloud/datastore/KeyFactory.java | 2 -- .../google/cloud/datastore/testing/RemoteDatastoreHelper.java | 2 -- 6 files changed, 15 deletions(-) diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/BaseKey.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/BaseKey.java index 6a015e388..5547979d9 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/BaseKey.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/BaseKey.java @@ -20,7 +20,6 @@ import static com.google.cloud.datastore.Validator.validateNamespace; import static com.google.cloud.datastore.Validator.validateProjectId; -import com.google.api.core.BetaApi; import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -117,7 +116,6 @@ public B setNamespace(String namespace) { } /** Sets the database id of the key. */ - @BetaApi public B setDatabaseId(String databaseId) { this.databaseId = databaseId; return self(); @@ -148,7 +146,6 @@ public String getNamespace() { return namespace; } - @BetaApi public String getDatabaseId() { return databaseId; } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java index a166a45ae..37bbb0a01 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java @@ -19,7 +19,6 @@ import static com.google.cloud.datastore.Validator.validateNamespace; import static com.google.cloud.datastore.spi.v1.DatastoreRpc.Transport.GRPC; -import com.google.api.core.BetaApi; import com.google.cloud.ServiceDefaults; import com.google.cloud.ServiceOptions; import com.google.cloud.ServiceRpc; @@ -112,7 +111,6 @@ public Builder setNamespace(String namespace) { return this; } - @BetaApi public Builder setDatabaseId(String databaseId) { this.databaseId = databaseId; return this; @@ -176,7 +174,6 @@ public String getNamespace() { return namespace; } - @BetaApi public String getDatabaseId() { return this.databaseId; } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/IncompleteKey.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/IncompleteKey.java index c1f7118e5..db9973cb5 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/IncompleteKey.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/IncompleteKey.java @@ -16,7 +16,6 @@ package com.google.cloud.datastore; -import com.google.api.core.BetaApi; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import java.util.List; @@ -107,7 +106,6 @@ public static Builder newBuilder(String projectId, String kind) { return new Builder(projectId, kind); } - @BetaApi public static Builder newBuilderWithDatabaseId(String projectId, String kind, String databaseId) { return new Builder(projectId, kind, databaseId); } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Key.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Key.java index bfd9dd7d3..9e851d0cb 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Key.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Key.java @@ -18,7 +18,6 @@ import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.api.core.BetaApi; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.protobuf.TextFormat; @@ -180,7 +179,6 @@ public static Builder newBuilder(String projectId, String kind, String name) { return new Builder(projectId, kind, name); } - @BetaApi public static Builder newBuilder(String projectId, String kind, String name, String databaseId) { return new Builder(projectId, kind, name, databaseId); } @@ -189,7 +187,6 @@ public static Builder newBuilder(String projectId, String kind, long id) { return new Builder(projectId, kind, id); } - @BetaApi public static Builder newBuilder(String projectId, String kind, long id, String databaseId) { return new Builder(projectId, kind, id, databaseId); } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/KeyFactory.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/KeyFactory.java index f8c3c93f6..628a32353 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/KeyFactory.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/KeyFactory.java @@ -16,7 +16,6 @@ package com.google.cloud.datastore; -import com.google.api.core.BetaApi; import com.google.common.collect.ImmutableList; /** @@ -37,7 +36,6 @@ public KeyFactory(String projectId, String namespace) { this(projectId, namespace, ""); } - @BetaApi public KeyFactory(String projectId, String namespace, String databaseId) { super(projectId); setNamespace(namespace); diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/RemoteDatastoreHelper.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/RemoteDatastoreHelper.java index d8b5ad932..596ce96d8 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/RemoteDatastoreHelper.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/RemoteDatastoreHelper.java @@ -16,7 +16,6 @@ package com.google.cloud.datastore.testing; -import com.google.api.core.BetaApi; import com.google.api.core.InternalApi; import com.google.api.gax.retrying.RetrySettings; import com.google.cloud.datastore.Datastore; @@ -79,7 +78,6 @@ public static RemoteDatastoreHelper create() { } /** Creates a {@code RemoteStorageHelper} object. */ - @BetaApi public static RemoteDatastoreHelper create(String databaseId) { HttpTransportOptions transportOptions = DatastoreOptions.getDefaultHttpTransportOptions(); transportOptions = From f077c04061018c52a31cb84bfa3594be7d5ef9d4 Mon Sep 17 00:00:00 2001 From: kolea2 <45548808+kolea2@users.noreply.github.com> Date: Mon, 8 Jan 2024 09:26:42 -0500 Subject: [PATCH 08/42] feat!: mark interfaces as `@InternalExtensionOnly` (#1275) * feat!: mark interfaces as `@InternalExtensionOnly` * lint --- .../src/main/java/com/google/cloud/datastore/Batch.java | 2 ++ .../src/main/java/com/google/cloud/datastore/Datastore.java | 6 +++--- .../com/google/cloud/datastore/DatastoreBatchWriter.java | 2 ++ .../java/com/google/cloud/datastore/DatastoreFactory.java | 2 ++ .../java/com/google/cloud/datastore/DatastoreReader.java | 6 +++--- .../com/google/cloud/datastore/DatastoreReaderWriter.java | 3 +++ .../java/com/google/cloud/datastore/DatastoreWriter.java | 2 ++ .../main/java/com/google/cloud/datastore/QueryResults.java | 2 ++ .../java/com/google/cloud/datastore/StructuredQuery.java | 2 ++ .../main/java/com/google/cloud/datastore/Transaction.java | 2 ++ .../main/java/com/google/cloud/datastore/ValueBuilder.java | 2 ++ .../cloud/datastore/aggregation/AggregationBuilder.java | 3 +++ .../com/google/cloud/datastore/spi/DatastoreRpcFactory.java | 2 ++ .../com/google/cloud/datastore/spi/v1/DatastoreRpc.java | 6 +++--- 14 files changed, 33 insertions(+), 9 deletions(-) diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Batch.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Batch.java index eb4abd854..c9a01673d 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Batch.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Batch.java @@ -16,6 +16,7 @@ package com.google.cloud.datastore; +import com.google.api.core.InternalExtensionOnly; import java.util.List; import javax.annotation.concurrent.NotThreadSafe; @@ -42,6 +43,7 @@ * This class too should not be treated as a thread safe class. */ @NotThreadSafe +@InternalExtensionOnly public interface Batch extends DatastoreBatchWriter { interface Response { diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Datastore.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Datastore.java index 1fb5fcedc..fc368506e 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Datastore.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Datastore.java @@ -16,12 +16,14 @@ package com.google.cloud.datastore; +import com.google.api.core.InternalExtensionOnly; import com.google.cloud.Service; import com.google.datastore.v1.TransactionOptions; import java.util.Iterator; import java.util.List; /** An interface for Google Cloud Datastore. */ +@InternalExtensionOnly public interface Datastore extends Service, DatastoreReaderWriter, AutoCloseable { /** @@ -505,9 +507,7 @@ interface TransactionCallable { * @throws DatastoreException upon failure * @return {@link AggregationResults} */ - default AggregationResults runAggregation(AggregationQuery query, ReadOption... options) { - throw new UnsupportedOperationException("Not implemented."); - } + AggregationResults runAggregation(AggregationQuery query, ReadOption... options); /** * Closes the gRPC channels associated with this instance and frees up their resources. This diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreBatchWriter.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreBatchWriter.java index db4bd3179..28d2569b6 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreBatchWriter.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreBatchWriter.java @@ -16,6 +16,7 @@ package com.google.cloud.datastore; +import com.google.api.core.InternalExtensionOnly; import java.util.List; import javax.annotation.concurrent.NotThreadSafe; @@ -31,6 +32,7 @@ * This class too should not be treated as a thread safe class. */ @NotThreadSafe +@InternalExtensionOnly public interface DatastoreBatchWriter extends DatastoreWriter { /** diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreFactory.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreFactory.java index 1b443066d..54274e7bb 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreFactory.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreFactory.java @@ -16,7 +16,9 @@ package com.google.cloud.datastore; +import com.google.api.core.InternalExtensionOnly; import com.google.cloud.ServiceFactory; /** An interface for Datastore factories. */ +@InternalExtensionOnly public interface DatastoreFactory extends ServiceFactory {} diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreReader.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreReader.java index 2a3071f3c..e8e5d3b03 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreReader.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreReader.java @@ -16,10 +16,12 @@ package com.google.cloud.datastore; +import com.google.api.core.InternalExtensionOnly; import java.util.Iterator; import java.util.List; /** An interface to represent Google Cloud Datastore read operations. */ +@InternalExtensionOnly public interface DatastoreReader { /** @@ -59,7 +61,5 @@ public interface DatastoreReader { * * @throws DatastoreException upon failure */ - default AggregationResults runAggregation(AggregationQuery query) { - throw new UnsupportedOperationException("Not implemented."); - } + AggregationResults runAggregation(AggregationQuery query); } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreReaderWriter.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreReaderWriter.java index a51a5aa77..bc8700c70 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreReaderWriter.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreReaderWriter.java @@ -16,5 +16,8 @@ package com.google.cloud.datastore; +import com.google.api.core.InternalExtensionOnly; + /** An interface that combines both Google Cloud Datastore read and write operations. */ +@InternalExtensionOnly public interface DatastoreReaderWriter extends DatastoreReader, DatastoreWriter {} diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreWriter.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreWriter.java index 6c1d6fdbc..b414995e6 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreWriter.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreWriter.java @@ -16,9 +16,11 @@ package com.google.cloud.datastore; +import com.google.api.core.InternalExtensionOnly; import java.util.List; /** An interface to represent Google Cloud Datastore write operations. */ +@InternalExtensionOnly public interface DatastoreWriter { /** diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java index 3f73824dc..b42e33d1a 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java @@ -16,6 +16,7 @@ package com.google.cloud.datastore; +import com.google.api.core.InternalExtensionOnly; import com.google.datastore.v1.QueryResultBatch; import java.util.Iterator; @@ -28,6 +29,7 @@ * * @param the type of the results value. */ +@InternalExtensionOnly public interface QueryResults extends Iterator { /** Returns the actual class of the result's values. */ diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java index 30cd05759..5bde80ed6 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java @@ -27,6 +27,7 @@ import com.google.api.core.ApiFunction; import com.google.api.core.InternalApi; +import com.google.api.core.InternalExtensionOnly; import com.google.cloud.StringEnumType; import com.google.cloud.StringEnumValue; import com.google.cloud.Timestamp; @@ -700,6 +701,7 @@ public String toString() { * * @param the type of result the query returns. */ + @InternalExtensionOnly public interface Builder { /** Sets the namespace for the query. */ diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Transaction.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Transaction.java index 69c18d75c..f68c3889b 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Transaction.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Transaction.java @@ -16,6 +16,7 @@ package com.google.cloud.datastore; +import com.google.api.core.InternalExtensionOnly; import com.google.protobuf.ByteString; import java.util.Iterator; import java.util.List; @@ -61,6 +62,7 @@ * This class too should not be treated as a thread safe class. */ @NotThreadSafe +@InternalExtensionOnly public interface Transaction extends DatastoreBatchWriter, DatastoreReaderWriter { interface Response { diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/ValueBuilder.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/ValueBuilder.java index 3c60ef409..315728147 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/ValueBuilder.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/ValueBuilder.java @@ -16,6 +16,7 @@ package com.google.cloud.datastore; +import com.google.api.core.InternalExtensionOnly; import com.google.cloud.GcpLaunchStage; /** @@ -25,6 +26,7 @@ * @param

the value type. * @param the value type's associated builder. */ +@InternalExtensionOnly public interface ValueBuilder, B extends ValueBuilder> { ValueType getValueType(); diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/aggregation/AggregationBuilder.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/aggregation/AggregationBuilder.java index ce23edcf0..632f44393 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/aggregation/AggregationBuilder.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/aggregation/AggregationBuilder.java @@ -16,6 +16,8 @@ package com.google.cloud.datastore.aggregation; +import com.google.api.core.InternalExtensionOnly; + /** * An interface to represent the builders which build and customize {@link Aggregation} for {@link * com.google.cloud.datastore.AggregationQuery}. @@ -23,6 +25,7 @@ *

Used by {@link * com.google.cloud.datastore.AggregationQuery.Builder#addAggregation(AggregationBuilder)}. */ +@InternalExtensionOnly public interface AggregationBuilder { A build(); } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/DatastoreRpcFactory.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/DatastoreRpcFactory.java index 0b7f9094b..acb85a61d 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/DatastoreRpcFactory.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/DatastoreRpcFactory.java @@ -16,6 +16,7 @@ package com.google.cloud.datastore.spi; +import com.google.api.core.InternalExtensionOnly; import com.google.cloud.datastore.DatastoreOptions; import com.google.cloud.spi.ServiceRpcFactory; @@ -23,4 +24,5 @@ * An interface for Datastore RPC factory. Implementation will be loaded via {@link * java.util.ServiceLoader}. */ +@InternalExtensionOnly public interface DatastoreRpcFactory extends ServiceRpcFactory {} diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/DatastoreRpc.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/DatastoreRpc.java index 1f73429f8..3b163f6fd 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/DatastoreRpc.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/DatastoreRpc.java @@ -17,6 +17,7 @@ package com.google.cloud.datastore.spi.v1; import com.google.api.core.InternalApi; +import com.google.api.core.InternalExtensionOnly; import com.google.api.gax.rpc.HeaderProvider; import com.google.cloud.ServiceRpc; import com.google.cloud.datastore.DatastoreException; @@ -39,6 +40,7 @@ import com.google.datastore.v1.RunQueryResponse; /** Provides access to the remote Datastore service. */ +@InternalExtensionOnly public interface DatastoreRpc extends ServiceRpc, AutoCloseable { /** @@ -96,9 +98,7 @@ BeginTransactionResponse beginTransaction(BeginTransactionRequest request) * * @throws DatastoreException upon failure */ - default RunAggregationQueryResponse runAggregationQuery(RunAggregationQueryRequest request) { - throw new UnsupportedOperationException("Not implemented."); - } + RunAggregationQueryResponse runAggregationQuery(RunAggregationQueryRequest request); @Override void close() throws Exception; From 030f7fa690f23494b489e854958d67e879418855 Mon Sep 17 00:00:00 2001 From: kolea2 <45548808+kolea2@users.noreply.github.com> Date: Mon, 8 Jan 2024 11:59:22 -0500 Subject: [PATCH 09/42] refactor: rename internal class QueryAndReadOptions to QueryConfig (#1245) (#1283) (cherry picked from commit 41d43e852d07a9026ae5be2add860c1f6980c7d6) --- .../clirr-ignored-differences.xml | 29 +++++-------------- .../google/cloud/datastore/ReadOption.java | 14 ++++----- .../execution/AggregationQueryExecutor.java | 10 +++---- .../AggregationQueryRequestProtoPreparer.java | 11 ++++--- ...regationQueryRequestProtoPreparerTest.java | 12 ++++---- 5 files changed, 31 insertions(+), 45 deletions(-) diff --git a/google-cloud-datastore/clirr-ignored-differences.xml b/google-cloud-datastore/clirr-ignored-differences.xml index f80562fba..9972e93e5 100644 --- a/google-cloud-datastore/clirr-ignored-differences.xml +++ b/google-cloud-datastore/clirr-ignored-differences.xml @@ -1,30 +1,17 @@ + - com/google/cloud/datastore/Datastore - java.util.List reserveIds(com.google.cloud.datastore.Key[]) - 7012 - - - com/google/cloud/datastore/spi/v1/DatastoreRpc - com.google.datastore.v1.ReserveIdsResponse reserveIds(com.google.datastore.v1.ReserveIdsRequest) - 7012 + com/google/cloud/datastore/ReadOption$QueryAndReadOptions + * + 8001 - com/google/cloud/datastore/spi/v1/DatastoreRpc - com.google.datastore.v1.RunAggregationQueryResponse runAggregationQuery(com.google.datastore.v1.RunAggregationQueryRequest) - 7012 - - - com/google/cloud/datastore/Datastore - com.google.cloud.datastore.AggregationResults runAggregation(com.google.cloud.datastore.AggregationQuery, com.google.cloud.datastore.ReadOption[]) - 7012 - - - com/google/cloud/datastore/DatastoreReader - com.google.cloud.datastore.AggregationResults runAggregation(com.google.cloud.datastore.AggregationQuery) - 7012 + com/google/cloud/datastore/execution/request/AggregationQueryRequestProtoPreparer + *QueryAndReadOptions* + *QueryConfig* + 7005 diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/ReadOption.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/ReadOption.java index be5644da0..c249e45a6 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/ReadOption.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/ReadOption.java @@ -142,17 +142,17 @@ static Map, ReadOption> asImmutableMap(List> { + public static class QueryConfig> { Q query; List readOptions; - private QueryAndReadOptions(Q query, List readOptions) { + private QueryConfig(Q query, List readOptions) { this.query = query; this.readOptions = readOptions; } - private QueryAndReadOptions(Q query) { + private QueryConfig(Q query) { this.query = query; this.readOptions = Collections.emptyList(); } @@ -165,13 +165,13 @@ public List getReadOptions() { return readOptions; } - public static > QueryAndReadOptions create(Q query) { - return new QueryAndReadOptions<>(query); + public static > QueryConfig create(Q query) { + return new QueryConfig<>(query); } - public static > QueryAndReadOptions create( + public static > QueryConfig create( Q query, List readOptions) { - return new QueryAndReadOptions<>(query, readOptions); + return new QueryConfig<>(query, readOptions); } } } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/execution/AggregationQueryExecutor.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/execution/AggregationQueryExecutor.java index 14e425845..5a1fdd2c3 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/execution/AggregationQueryExecutor.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/execution/AggregationQueryExecutor.java @@ -20,7 +20,7 @@ import com.google.cloud.datastore.AggregationResults; import com.google.cloud.datastore.DatastoreOptions; import com.google.cloud.datastore.ReadOption; -import com.google.cloud.datastore.ReadOption.QueryAndReadOptions; +import com.google.cloud.datastore.ReadOption.QueryConfig; import com.google.cloud.datastore.execution.request.AggregationQueryRequestProtoPreparer; import com.google.cloud.datastore.execution.response.AggregationQueryResponseTransformer; import com.google.cloud.datastore.spi.v1.DatastoreRpc; @@ -57,10 +57,10 @@ public AggregationResults execute(AggregationQuery query, ReadOption... readOpti private RunAggregationQueryRequest getRunAggregationQueryRequest( AggregationQuery query, ReadOption... readOptions) { - QueryAndReadOptions queryAndReadOptions = + QueryConfig queryConfig = readOptions == null - ? QueryAndReadOptions.create(query) - : QueryAndReadOptions.create(query, Arrays.asList(readOptions)); - return this.protoPreparer.prepare(queryAndReadOptions); + ? QueryConfig.create(query) + : QueryConfig.create(query, Arrays.asList(readOptions)); + return this.protoPreparer.prepare(queryConfig); } } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/execution/request/AggregationQueryRequestProtoPreparer.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/execution/request/AggregationQueryRequestProtoPreparer.java index 5c4fb3e5f..475a47b58 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/execution/request/AggregationQueryRequestProtoPreparer.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/execution/request/AggregationQueryRequestProtoPreparer.java @@ -22,7 +22,7 @@ import com.google.cloud.datastore.DatastoreOptions; import com.google.cloud.datastore.GqlQueryProtoPreparer; import com.google.cloud.datastore.ReadOption; -import com.google.cloud.datastore.ReadOption.QueryAndReadOptions; +import com.google.cloud.datastore.ReadOption.QueryConfig; import com.google.cloud.datastore.ReadOptionProtoPreparer; import com.google.cloud.datastore.StructuredQueryProtoPreparer; import com.google.cloud.datastore.aggregation.Aggregation; @@ -37,7 +37,7 @@ @InternalApi public class AggregationQueryRequestProtoPreparer - implements ProtoPreparer, RunAggregationQueryRequest> { + implements ProtoPreparer, RunAggregationQueryRequest> { private final DatastoreOptions datastoreOptions; private final StructuredQueryProtoPreparer structuredQueryProtoPreparer; @@ -52,10 +52,9 @@ public AggregationQueryRequestProtoPreparer(DatastoreOptions datastoreOptions) { } @Override - public RunAggregationQueryRequest prepare( - QueryAndReadOptions aggregationQueryAndReadOptions) { - AggregationQuery aggregationQuery = aggregationQueryAndReadOptions.getQuery(); - List readOptions = aggregationQueryAndReadOptions.getReadOptions(); + public RunAggregationQueryRequest prepare(QueryConfig queryConfig) { + AggregationQuery aggregationQuery = queryConfig.getQuery(); + List readOptions = queryConfig.getReadOptions(); PartitionId partitionId = getPartitionId(aggregationQuery); RunAggregationQueryRequest.Builder aggregationQueryRequestBuilder = RunAggregationQueryRequest.newBuilder() diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/execution/request/AggregationQueryRequestProtoPreparerTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/execution/request/AggregationQueryRequestProtoPreparerTest.java index 5fbb35b6e..0f22828d9 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/execution/request/AggregationQueryRequestProtoPreparerTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/execution/request/AggregationQueryRequestProtoPreparerTest.java @@ -38,7 +38,7 @@ import com.google.cloud.datastore.GqlQuery; import com.google.cloud.datastore.Query; import com.google.cloud.datastore.ReadOption; -import com.google.cloud.datastore.ReadOption.QueryAndReadOptions; +import com.google.cloud.datastore.ReadOption.QueryConfig; import com.google.common.collect.ImmutableMap; import com.google.datastore.v1.RunAggregationQueryRequest; import java.util.HashMap; @@ -91,7 +91,7 @@ public class AggregationQueryRequestProtoPreparerTest { @Test public void shouldPrepareAggregationQueryRequestWithGivenStructuredQuery() { RunAggregationQueryRequest runAggregationQueryRequest = - protoPreparer.prepare(QueryAndReadOptions.create(AGGREGATION_OVER_STRUCTURED_QUERY)); + protoPreparer.prepare(QueryConfig.create(AGGREGATION_OVER_STRUCTURED_QUERY)); assertThat(runAggregationQueryRequest.getProjectId()).isEqualTo(PROJECT_ID); assertThat(runAggregationQueryRequest.getDatabaseId()).isEqualTo(DATABASE_ID); @@ -114,7 +114,7 @@ public void shouldPrepareAggregationQueryRequestWithGivenStructuredQuery() { @Test public void shouldPrepareAggregationQueryRequestWithGivenGqlQuery() { RunAggregationQueryRequest runAggregationQueryRequest = - protoPreparer.prepare(QueryAndReadOptions.create(AGGREGATION_OVER_GQL_QUERY)); + protoPreparer.prepare(QueryConfig.create(AGGREGATION_OVER_GQL_QUERY)); assertThat(runAggregationQueryRequest.getProjectId()).isEqualTo(PROJECT_ID); assertThat(runAggregationQueryRequest.getDatabaseId()).isEqualTo(DATABASE_ID); @@ -172,9 +172,9 @@ public void shouldPrepareAggregationQueryWithNamespaceFromDatastoreOptions() { Query.newAggregationQueryBuilder().over(COMPLETED_TASK_GQL_QUERY).build(); RunAggregationQueryRequest runAggregationQueryFromStructuredQuery = - protoPreparer.prepare(QueryAndReadOptions.create(structuredQueryWithoutNamespace)); + protoPreparer.prepare(QueryConfig.create(structuredQueryWithoutNamespace)); RunAggregationQueryRequest runAggregationQueryFromGqlQuery = - protoPreparer.prepare(QueryAndReadOptions.create(gqlQueryWithoutNamespace)); + protoPreparer.prepare(QueryConfig.create(gqlQueryWithoutNamespace)); assertThat(runAggregationQueryFromStructuredQuery.getPartitionId().getNamespaceId()) .isEqualTo(NAMESPACE); @@ -183,6 +183,6 @@ public void shouldPrepareAggregationQueryWithNamespaceFromDatastoreOptions() { } private RunAggregationQueryRequest prepareQuery(AggregationQuery query, ReadOption readOption) { - return protoPreparer.prepare(QueryAndReadOptions.create(query, singletonList(readOption))); + return protoPreparer.prepare(QueryConfig.create(query, singletonList(readOption))); } } From c3038bffff096a72575fcc0458e8634daf51e29c Mon Sep 17 00:00:00 2001 From: kolea2 <45548808+kolea2@users.noreply.github.com> Date: Tue, 9 Jan 2024 10:55:14 -0500 Subject: [PATCH 10/42] deps: remove dependency on datastore-v1-proto-client module in google-cloud-datastore (#1281) --- google-cloud-datastore/pom.xml | 4 ---- .../com/google/cloud/datastore/DatastoreOptions.java | 12 ++++-------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/google-cloud-datastore/pom.xml b/google-cloud-datastore/pom.xml index a4b0434eb..114e4d40d 100644 --- a/google-cloud-datastore/pom.xml +++ b/google-cloud-datastore/pom.xml @@ -42,10 +42,6 @@ com.google.api.grpc proto-google-cloud-datastore-admin-v1 - - com.google.cloud.datastore - datastore-v1-proto-client - io.grpc grpc-api diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java index 37bbb0a01..0a590cc2e 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java @@ -45,6 +45,8 @@ public class DatastoreOptions extends ServiceOptions SCOPES = ImmutableSet.of(DATASTORE_SCOPE); private static final String DEFAULT_DATABASE_ID = ""; + public static final String PROJECT_ID_ENV_VAR = "DATASTORE_PROJECT_ID"; + public static final String LOCAL_HOST_ENV_VAR = "DATASTORE_EMULATOR_HOST"; private final String namespace; private final String databaseId; @@ -131,19 +133,13 @@ private DatastoreOptions(Builder builder) { @Override protected String getDefaultHost() { - String host = - System.getProperty( - com.google.datastore.v1.client.DatastoreHelper.LOCAL_HOST_ENV_VAR, - System.getenv(com.google.datastore.v1.client.DatastoreHelper.LOCAL_HOST_ENV_VAR)); + String host = System.getProperty(LOCAL_HOST_ENV_VAR, System.getenv(LOCAL_HOST_ENV_VAR)); return host != null ? host : DatastoreSettings.getDefaultEndpoint(); } @Override protected String getDefaultProject() { - String projectId = - System.getProperty( - com.google.datastore.v1.client.DatastoreHelper.PROJECT_ID_ENV_VAR, - System.getenv(com.google.datastore.v1.client.DatastoreHelper.PROJECT_ID_ENV_VAR)); + String projectId = System.getProperty(PROJECT_ID_ENV_VAR, System.getenv(PROJECT_ID_ENV_VAR)); return projectId != null ? projectId : super.getDefaultProject(); } From 4ee028ef6b4c7df8da36394217032f74e3f18131 Mon Sep 17 00:00:00 2001 From: kolea2 <45548808+kolea2@users.noreply.github.com> Date: Tue, 16 Jan 2024 12:02:03 -0500 Subject: [PATCH 11/42] feat: use existing transport options API to set transport (#1276) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: use existing transport options API to set transport * lint * remove stale test * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * 🦉 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 --- README.md | 6 +-- .../cloud/datastore/DatastoreOptions.java | 40 +++++++------------ .../cloud/datastore/spi/v1/DatastoreRpc.java | 8 ---- .../testing/RemoteDatastoreHelper.java | 5 +-- .../cloud/datastore/DatastoreOptionsTest.java | 34 ++++++---------- 5 files changed, 32 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index ff9613efd..024f41511 100644 --- a/README.md +++ b/README.md @@ -57,13 +57,13 @@ implementation 'com.google.cloud:google-cloud-datastore' If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-datastore:2.17.6' +implementation 'com.google.cloud:google-cloud-datastore:2.18.0' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.17.6" +libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.18.0" ``` @@ -380,7 +380,7 @@ Java is a registered trademark of Oracle and/or its affiliates. [kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-datastore/java11.html [stability-image]: https://img.shields.io/badge/stability-stable-green [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-datastore.svg -[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-datastore/2.17.6 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-datastore/2.18.0 [authentication]: https://github.com/googleapis/google-cloud-java#authentication [auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes [predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java index 0a590cc2e..c94e9ff7a 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java @@ -17,7 +17,6 @@ package com.google.cloud.datastore; import static com.google.cloud.datastore.Validator.validateNamespace; -import static com.google.cloud.datastore.spi.v1.DatastoreRpc.Transport.GRPC; import com.google.cloud.ServiceDefaults; import com.google.cloud.ServiceOptions; @@ -25,12 +24,11 @@ import com.google.cloud.TransportOptions; import com.google.cloud.datastore.spi.DatastoreRpcFactory; import com.google.cloud.datastore.spi.v1.DatastoreRpc; -import com.google.cloud.datastore.spi.v1.DatastoreRpc.Transport; import com.google.cloud.datastore.spi.v1.GrpcDatastoreRpc; import com.google.cloud.datastore.spi.v1.HttpDatastoreRpc; import com.google.cloud.datastore.v1.DatastoreSettings; +import com.google.cloud.grpc.GrpcTransportOptions; import com.google.cloud.http.HttpTransportOptions; -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableSet; import java.io.IOException; @@ -50,7 +48,6 @@ public class DatastoreOptions extends ServiceOptions Date: Wed, 7 Feb 2024 17:10:19 +0000 Subject: [PATCH 12/42] deps: bump com.google.truth:truth from 1.1.5 to 1.4.0 (#1323) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [com.google.truth:truth](https://togithub.com/google/truth) from 1.1.5 to 1.4.0.

Release notes

Sourced from com.google.truth:truth's releases.

1.4.0

In this release, our assertions on Java 8 types continue to move from the Truth8 class to the main Truth class. This change should not break compatibility for any supported JDK or Android version, even users who test under old versions of Android without API desugaring. Additionally, we will never break binary compatibility, though some users will have to make changes to their source code in order for it to compile against newer versions.

This release is likely to lead to more build failures than 1.3.0 did. However, those failures should be straightforward to fix.

Example build failure

Foo.java:152: error: reference to assertThat is ambiguous
    assertThat(repo.findFileWithName("foo")).isNull();
    ^
  both method assertThat(@org.jspecify.nullness.Nullable Path) in Truth8 and method assertThat(@org.jspecify.nullness.Nullable Path) in Truth match

Simplest upgrade strategy (if you can update all your code atomically in the same commit as the Truth upgrade)

In the same commit:

  1. Upgrade Truth to 1.4.0.
  2. Replace import static com.google.common.truth.Truth8.assertThat; with import static com.google.common.truth.Truth.assertThat;.
    • If you use Kotlin, replace import com.google.common.truth.Truth8.assertThat with import com.google.common.truth.Truth.assertThat.
  3. Replace import com.google.common.truth.Truth8; with import com.google.common.truth.Truth;.
    • again, similarly for Kotlin if needed
  4. Optionally replace remaining references to Truth8 with references to Truth.
    • For example, replace Truth8.assertThat(optional).isPresent() with Truth.assertThat(optional).isPresent().

If you're feeling lucky, you can try this one-liner for the code updates:

git grep -l Truth8 | xargs perl -pi -e 's/import static com.google.common.truth.Truth8.assertThat;/import static com.google.common.truth.Truth.assertThat;/g; s/import com.google.common.truth.Truth8.assertThat/import com.google.common.truth.Truth.assertThat/g; s/import com.google.common.truth.Truth8/import com.google.common.truth.Truth/g; s/\bTruth8[.]/Truth./g;'

In most cases, that can be further simplified to:

git grep -l Truth8 | xargs perl -pi -e 's/\bTruth8\b/Truth/g;'

After that process, it is possible that you'll still see build errors from ambiguous usages of assertThat static imports. If so, you can find a workaround in the section about overload ambiguity in the release notes for 1.3.0. Alternatively, you can wait to upgrade until after a future Truth release, which will eliminate the ambiguity by changing the signatures of some Truth.assertThat overloads.

Incremental upgrade strategy

If you have a very large repo or you have other reasons to prefer to upgrade incrementally, you can use the approach that we used inside Google. Roughly, that approach was:

  1. Make the optional changes discussed in the release notes for 1.3.0.
  2. For any remaining calls to Truth8.assertThat, change them to avoid static import.
    • That is, replace assertThat(optional).isPresent() with Truth8.assertThat(optional).isPresent().
  3. Upgrade Truth to 1.4.0.
  4. Optionally replace references to Truth8 with references to Truth (including restoring static imports if desired), as discussed in section about the simple upgrade strategy above.

... (truncated)

Commits
  • 2e8e488 Set version number for truth-parent to 1.4.0.
  • 1f81827 Copy Truth8.assertThat overloads for Path and OptionalLong to the main ...
  • 9be8e77 Copy remaining Truth8.assertThat overloads to the main Truth class—except...
  • b02a658 Migrate most usages of Truth8.assertThat to equivalent usages of `Truth.ass...
  • 0999369 Automated Code Change
  • 7c65fc6 Make it possible to write expect.that(optionalInt).isPresent(), `assertWith...
  • 87b371d Bump styfle/cancel-workflow-action from 0.12.0 to 0.12.1
  • 93b4d93 Add @since tags for the first batch of Java-8-related APIs.
  • 78d27dd Remove stale suppressions.
  • 7be930d Bump actions/cache from 3.3.3 to 4.0.0
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.truth:truth&package-manager=maven&previous-version=1.1.5&new-version=1.4.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- datastore-v1-proto-client/pom.xml | 2 +- google-cloud-datastore/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/datastore-v1-proto-client/pom.xml b/datastore-v1-proto-client/pom.xml index ebde7c645..142798e94 100644 --- a/datastore-v1-proto-client/pom.xml +++ b/datastore-v1-proto-client/pom.xml @@ -98,7 +98,7 @@ com.google.truth truth - 1.1.5 + 1.4.0 test diff --git a/google-cloud-datastore/pom.xml b/google-cloud-datastore/pom.xml index 114e4d40d..d42315753 100644 --- a/google-cloud-datastore/pom.xml +++ b/google-cloud-datastore/pom.xml @@ -150,7 +150,7 @@ com.google.truth truth - 1.1.5 + 1.4.0 test From cdfbead2317308bdce7d2fd19455d4c5ade16e31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 18:50:18 +0000 Subject: [PATCH 13/42] deps: bump com.google.cloud:google-cloud-shared-config from 1.6.1 to 1.7.1 (#1324) Bumps [com.google.cloud:google-cloud-shared-config](https://togithub.com/googleapis/java-shared-config) from 1.6.1 to 1.7.1.
Release notes

Sourced from com.google.cloud:google-cloud-shared-config's releases.

v1.7.1

1.7.1 (2023-12-07)

Bug Fixes

  • Move release configs to native-image-shared-config (#725) (58ffb4e)

v1.7.0

1.7.0 (2023-12-04)

Features

  • Separate native-image-shared-config into its own module (#712) (567fecb)
Changelog

Sourced from com.google.cloud:google-cloud-shared-config's changelog.

1.7.1 (2023-12-07)

Bug Fixes

  • Move release configs to native-image-shared-config (#725) (58ffb4e)

1.7.0 (2023-12-04)

Features

  • Separate native-image-shared-config into its own module (#712) (567fecb)
Commits
  • f5f57c8 chore(main): release 1.7.1 (#727)
  • 9fcbe9e chore: update release-please.yml to include cloudbuild test yamls (#728)
  • c432bae chore(main): release 1.7.1-SNAPSHOT (#719)
  • 58ffb4e fix: move release configs to native-image-shared-config (#725)
  • 8d411bc ci: Update ci.yaml to introduce Java 21 unit testing (#1907) (#717)
  • 3382cee chore: add downstream check for native image tests in cloud build (#715)
  • b22a75a chore: update graalvm docker image for 1.7.0 release (#720)
  • 93824e5 chore(main): release 1.7.0 (#716)
  • 7435981 chore: remove docker validation check (#718)
  • 567fecb feat: separate native-image-shared-config into its own module (#712)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.cloud:google-cloud-shared-config&package-manager=maven&previous-version=1.6.1&new-version=1.7.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- google-cloud-datastore-bom/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/google-cloud-datastore-bom/pom.xml b/google-cloud-datastore-bom/pom.xml index 2105a8caa..8620ce3a6 100644 --- a/google-cloud-datastore-bom/pom.xml +++ b/google-cloud-datastore-bom/pom.xml @@ -8,7 +8,7 @@ com.google.cloud google-cloud-shared-config - 1.6.1 + 1.7.1 Google Cloud datastore BOM diff --git a/pom.xml b/pom.xml index 73ac365f7..c768873e5 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ com.google.cloud google-cloud-shared-config - 1.6.1 + 1.7.1 From 8b1d52ee56e25c50647600c109462a4691aa18fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 19:12:16 +0000 Subject: [PATCH 14/42] deps: bump com.google.cloud:google-cloud-shared-dependencies from 3.19.0 to 3.24.0 (#1325) Bumps com.google.cloud:google-cloud-shared-dependencies from 3.19.0 to 3.24.0. [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.cloud:google-cloud-shared-dependencies&package-manager=maven&previous-version=3.19.0&new-version=3.24.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- README.md | 8 ++++---- pom.xml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 024f41511..e4f708557 100644 --- a/README.md +++ b/README.md @@ -50,20 +50,20 @@ If you are using Maven without the BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies: ```Groovy -implementation platform('com.google.cloud:libraries-bom:26.29.0') +implementation platform('com.google.cloud:libraries-bom:26.31.0') implementation 'com.google.cloud:google-cloud-datastore' ``` If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-datastore:2.18.0' +implementation 'com.google.cloud:google-cloud-datastore:2.18.3' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.18.0" +libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.18.3" ``` @@ -380,7 +380,7 @@ Java is a registered trademark of Oracle and/or its affiliates. [kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-datastore/java11.html [stability-image]: https://img.shields.io/badge/stability-stable-green [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-datastore.svg -[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-datastore/2.18.0 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-datastore/2.18.3 [authentication]: https://github.com/googleapis/google-cloud-java#authentication [auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes [predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles diff --git a/pom.xml b/pom.xml index c768873e5..ebd6fab8c 100644 --- a/pom.xml +++ b/pom.xml @@ -151,7 +151,7 @@ com.google.cloud google-cloud-shared-dependencies - 3.19.0 + 3.24.0 pom import From 73db59830437dafc400bb3407487b71bca13d0ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 19:24:16 +0000 Subject: [PATCH 15/42] deps: bump org.apache.maven.plugins:maven-compiler-plugin from 3.11.0 to 3.12.1 (#1327) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://togithub.com/apache/maven-compiler-plugin) from 3.11.0 to 3.12.1.
Release notes

Sourced from org.apache.maven.plugins:maven-compiler-plugin's releases.

3.12.1

🐛 Bug Fixes

📦 Dependency updates

3.12.0

🚀 New features and improvements

🐛 Bug Fixes

📦 Dependency updates

👻 Maintenance

Commits
  • 736da68 [maven-release-plugin] prepare release maven-compiler-plugin-3.12.1
  • ef93f3d [MCOMPILER-568] Bump plexusCompilerVersion from 2.14.1 to 2.14.2 (#220)
  • eb7840c [MCOMPILER-567] - Fail to compile if the "generated-sources/annotations" does...
  • 2a7a73b [maven-release-plugin] prepare for next development iteration
  • c08b0fd [maven-release-plugin] prepare release maven-compiler-plugin-3.12.0
  • a1c5b13 [MCOMPILER-565] Allow project build by Maven 4
  • 4855773 Bump plexusCompilerVersion from 2.13.0 to 2.14.1
  • 1d05342 [MCOMPILER-562] Add property maven.compiler.outputDirectory to CompilerMojo (...
  • ea74978 [MCOMPILER-381] - Refactor incremental detection (#181)
  • fd37f09 [MCOMPILER-333] Cleanup generated source files (#214)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-compiler-plugin&package-manager=maven&previous-version=3.11.0&new-version=3.12.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ebd6fab8c..a9755b9be 100644 --- a/pom.xml +++ b/pom.xml @@ -237,7 +237,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + 3.12.1 UTF-8 true From 2b99ee28e77f562cde6924572ccfa2c8cda97207 Mon Sep 17 00:00:00 2001 From: kolea2 <45548808+kolea2@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:32:26 -0500 Subject: [PATCH 16/42] test(deps): upgrade errorprone to 2.24.0 (#1271) (#1329) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test(deps): upgrade errorprone to 2.24.0 (#1271) * deps: upgrade errorprone to 2.24.0 * 🦉 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 * 🦉 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 --- google-cloud-datastore/pom.xml | 7 +++++++ .../src/test/java/com/google/cloud/datastore/BlobTest.java | 4 +++- .../test/java/com/google/cloud/datastore/LatLngTest.java | 4 +++- pom.xml | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/google-cloud-datastore/pom.xml b/google-cloud-datastore/pom.xml index d42315753..3f13224de 100644 --- a/google-cloud-datastore/pom.xml +++ b/google-cloud-datastore/pom.xml @@ -118,6 +118,13 @@ test-jar test
+ + + com.google.guava + guava-testlib + 33.0.0-jre + test + com.google.api diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/BlobTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/BlobTest.java index 55d5f0319..391f6f765 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/BlobTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/BlobTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; +import com.google.common.testing.EqualsTester; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.nio.ByteBuffer; @@ -46,7 +47,8 @@ public void setUp() { @Test public void testEquals() { - assertEquals(blob1, blob1); + EqualsTester equalsTester = new EqualsTester(); + equalsTester.addEqualityGroup(blob1, blob1).testEquals(); assertEquals(blob1, Blob.copyFrom(bytes1)); assertNotEquals(blob1, blob2); } diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/LatLngTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/LatLngTest.java index e8076eba0..9363fc15a 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/LatLngTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/LatLngTest.java @@ -19,6 +19,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; +import com.google.common.testing.EqualsTester; import org.junit.Assert; import org.junit.Test; @@ -40,7 +41,8 @@ public void testLatLng() { @Test public void testEquals() { - assertEquals(gp1, gp1); + EqualsTester equalsTester = new EqualsTester(); + equalsTester.addEqualityGroup(gp1, gp1).testEquals(); assertNotEquals(gp1, gp2); } diff --git a/pom.xml b/pom.xml index a9755b9be..27bb3600d 100644 --- a/pom.xml +++ b/pom.xml @@ -143,7 +143,7 @@ github google-cloud-datastore-parent https://googleapis.dev/java/google-api-grpc/latest - 2.23.0 + 2.24.0 From 71f510dc2ec356f0b0dd20b90e869183577a3e20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 20:48:17 +0000 Subject: [PATCH 17/42] deps: bump com.google.errorprone:error_prone_core from 2.23.0 to 2.24.1 (#1326) Bumps [com.google.errorprone:error_prone_core](https://togithub.com/google/error-prone) from 2.23.0 to 2.24.1.
Release notes

Sourced from com.google.errorprone:error_prone_core's releases.

Error Prone 2.24.1

Changes:

Full Changelog: https://togithub.com/google/error-prone/compare/v2.24.0...v2.24.1

Error Prone 2.24.0

New checks:

Full Changelog: https://togithub.com/google/error-prone/compare/v2.23.0...v2.24.0

Commits
  • ecf7e10 Release Error Prone 2.24.1
  • 2bd7859 Add an assertion to try to help debug https://togithub.com/google/error-prone/i...
  • 58a9e80 Update a few checks (and a class of tests, with AbstractToString) to handle #...
  • fd21bc9 Reflow a comment that didn't appreciate being formatted in unknown commit
  • 63cf192 Update CanIgnoreReturnValueSuggester summary.
  • 5fa727a Actually test that hasExtraParameterForEnclosingInstance works.
  • 21c190a Document that javadoc shouldn't appear between annotations and the documented...
  • d272dfa Automated rollback of commit 654d1dbf1e6dd652cd6e8ca003643ddf02266ec2.
  • 654d1db Handle Joiner.on(...) in AbstractToString.
  • da7be27 Descend into VariableTrees when looking for variables to check.
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.errorprone:error_prone_core&package-manager=maven&previous-version=2.23.0&new-version=2.24.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 27bb3600d..c71e85d91 100644 --- a/pom.xml +++ b/pom.xml @@ -143,7 +143,7 @@ github google-cloud-datastore-parent https://googleapis.dev/java/google-api-grpc/latest - 2.24.0 + 2.24.1 From cca89631f5c69a26fbc78e4c4b3a8a2a6537a7e8 Mon Sep 17 00:00:00 2001 From: kolea2 <45548808+kolea2@users.noreply.github.com> Date: Thu, 8 Feb 2024 14:00:34 -0500 Subject: [PATCH 18/42] feat: allow setting channel and credential providers in DatastoreOptions (#1299) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 --- .../cloud/datastore/DatastoreOptions.java | 82 ++++++++++++++++++- .../cloud/datastore/DatastoreUtils.java | 6 ++ .../datastore/spi/v1/GrpcDatastoreRpc.java | 17 +--- .../cloud/datastore/DatastoreOptionsTest.java | 55 +++++++++++++ 4 files changed, 143 insertions(+), 17 deletions(-) diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java index c94e9ff7a..c852fdb7f 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java @@ -18,6 +18,9 @@ import static com.google.cloud.datastore.Validator.validateNamespace; +import com.google.api.gax.core.CredentialsProvider; +import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.api.gax.rpc.TransportChannelProvider; import com.google.cloud.ServiceDefaults; import com.google.cloud.ServiceOptions; import com.google.cloud.ServiceRpc; @@ -46,6 +49,9 @@ public class DatastoreOptions extends ServiceOptions { + private final TransportOptions TRANSPORT_OPTIONS = getDefaultTransportOptionsBuilder().build(); @Override public DatastoreFactory getDefaultServiceFactory() { @@ -147,7 +219,11 @@ public DatastoreRpcFactory getDefaultRpcFactory() { @Override public TransportOptions getDefaultTransportOptions() { - return getDefaultGrpcTransportOptions(); + return TRANSPORT_OPTIONS; + } + + public static GrpcTransportOptions.Builder getDefaultTransportOptionsBuilder() { + return GrpcTransportOptions.newBuilder(); } } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreUtils.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreUtils.java index ae1c7e07d..7ca92872f 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreUtils.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreUtils.java @@ -17,6 +17,7 @@ package com.google.cloud.datastore; import com.google.api.core.InternalApi; +import com.google.cloud.NoCredentials; import com.google.common.base.Strings; import java.net.InetAddress; import java.net.URL; @@ -24,6 +25,11 @@ @InternalApi public class DatastoreUtils { + public static boolean isEmulator(DatastoreOptions datastoreOptions) { + return isLocalHost(datastoreOptions.getHost()) + || NoCredentials.getInstance().equals(datastoreOptions.getCredentials()); + } + public static boolean isLocalHost(String host) { if (Strings.isNullOrEmpty(host)) { return false; diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java index ffcab0560..3d9aebc68 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java @@ -16,7 +16,7 @@ package com.google.cloud.datastore.spi.v1; -import static com.google.cloud.datastore.DatastoreUtils.isLocalHost; +import static com.google.cloud.datastore.DatastoreUtils.isEmulator; import static com.google.cloud.datastore.DatastoreUtils.removeScheme; import static com.google.cloud.datastore.spi.v1.RpcUtils.retrySettingSetter; import static java.util.concurrent.TimeUnit.SECONDS; @@ -30,14 +30,12 @@ import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.NoHeaderProvider; import com.google.api.gax.rpc.TransportChannel; -import com.google.cloud.NoCredentials; import com.google.cloud.ServiceOptions; import com.google.cloud.datastore.DatastoreException; import com.google.cloud.datastore.DatastoreOptions; import com.google.cloud.datastore.v1.DatastoreSettings; import com.google.cloud.datastore.v1.stub.DatastoreStubSettings; import com.google.cloud.datastore.v1.stub.GrpcDatastoreStub; -import com.google.cloud.grpc.GrpcTransportOptions; import com.google.common.base.Strings; import com.google.datastore.v1.AllocateIdsRequest; import com.google.datastore.v1.AllocateIdsResponse; @@ -69,7 +67,6 @@ public class GrpcDatastoreRpc implements DatastoreRpc { private boolean closed; public GrpcDatastoreRpc(DatastoreOptions datastoreOptions) throws IOException { - try { clientContext = isEmulator(datastoreOptions) @@ -146,11 +143,6 @@ public boolean isClosed() { return closed && datastoreStub.isShutdown(); } - private boolean isEmulator(DatastoreOptions datastoreOptions) { - return isLocalHost(datastoreOptions.getHost()) - || NoCredentials.getInstance().equals(datastoreOptions.getCredentials()); - } - private ClientContext getClientContextForEmulator(DatastoreOptions datastoreOptions) throws IOException { ManagedChannel managedChannel = @@ -177,11 +169,8 @@ private ClientContext getClientContext(DatastoreOptions datastoreOptions) throws DatastoreSettingsBuilder settingsBuilder = new DatastoreSettingsBuilder(DatastoreSettings.newBuilder().build()); - settingsBuilder.setCredentialsProvider( - GrpcTransportOptions.setUpCredentialsProvider(datastoreOptions)); - settingsBuilder.setTransportChannelProvider( - GrpcTransportOptions.setUpChannelProvider( - DatastoreSettings.defaultGrpcTransportProviderBuilder(), datastoreOptions)); + settingsBuilder.setCredentialsProvider(datastoreOptions.getCredentialsProvider()); + settingsBuilder.setTransportChannelProvider(datastoreOptions.getTransportChannelProvider()); settingsBuilder.setInternalHeaderProvider(internalHeaderProvider); settingsBuilder.setHeaderProvider( datastoreOptions.getMergedHeaderProvider(new NoHeaderProvider())); diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreOptionsTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreOptionsTest.java index 6281befe6..098ae3427 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreOptionsTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreOptionsTest.java @@ -22,11 +22,17 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import com.google.api.gax.core.NoCredentialsProvider; +import com.google.api.gax.grpc.ChannelPoolSettings; +import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.cloud.NoCredentials; import com.google.cloud.datastore.spi.DatastoreRpcFactory; import com.google.cloud.datastore.spi.v1.DatastoreRpc; +import com.google.cloud.datastore.v1.DatastoreSettings; import com.google.cloud.grpc.GrpcTransportOptions; import com.google.cloud.http.HttpTransportOptions; import org.easymock.EasyMock; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -48,7 +54,9 @@ public void setUp() { .setServiceRpcFactory(datastoreRpcFactory) .setProjectId(PROJECT_ID) .setDatabaseId(DATABASE_ID) + .setCredentials(NoCredentials.getInstance()) .setHost("http://localhost:" + PORT); + EasyMock.expect(datastoreRpcFactory.create(EasyMock.anyObject(DatastoreOptions.class))) .andReturn(datastoreRpc) .anyTimes(); @@ -81,6 +89,51 @@ public void testDatastore() { assertSame(datastoreRpc, options.build().getRpc()); } + @Test + public void testCustomChannelAndCredentials() { + NoCredentialsProvider noCredentialsProvider = NoCredentialsProvider.create(); + InstantiatingGrpcChannelProvider channelProvider = + DatastoreSettings.defaultGrpcTransportProviderBuilder() + .setChannelPoolSettings( + ChannelPoolSettings.builder() + .setInitialChannelCount(10) + .setMaxChannelCount(20) + .build()) + .build(); + DatastoreOptions datastoreOptions = + DatastoreOptions.newBuilder() + .setServiceRpcFactory(datastoreRpcFactory) + .setProjectId(PROJECT_ID) + .setDatabaseId(DATABASE_ID) + .setChannelProvider(channelProvider) + .setCredentialsProvider(noCredentialsProvider) + .setHost("http://localhost:" + PORT) + .build(); + assertEquals(datastoreOptions.getTransportChannelProvider(), channelProvider); + assertEquals(datastoreOptions.getCredentialsProvider(), noCredentialsProvider); + } + + @Test + public void testInvalidConfigForHttp() { + DatastoreOptions.Builder options = + DatastoreOptions.newBuilder() + .setServiceRpcFactory(datastoreRpcFactory) + .setProjectId(PROJECT_ID) + .setDatabaseId(DATABASE_ID) + .setTransportOptions(HttpTransportOptions.newBuilder().build()) + .setChannelProvider( + DatastoreSettings.defaultGrpcTransportProviderBuilder() + .setChannelPoolSettings( + ChannelPoolSettings.builder() + .setInitialChannelCount(10) + .setMaxChannelCount(20) + .build()) + .build()) + .setCredentialsProvider(NoCredentialsProvider.create()) + .setHost("http://localhost:" + PORT); + Assert.assertThrows(IllegalArgumentException.class, options::build); + } + @Test public void testTransport() { // default grpc transport @@ -93,6 +146,8 @@ public void testTransport() { .setProjectId(PROJECT_ID) .build(); assertThat(httpDatastoreOptions.getTransportOptions()).isInstanceOf(HttpTransportOptions.class); + assertThat(httpDatastoreOptions.getCredentialsProvider()).isNull(); + assertThat(httpDatastoreOptions.getTransportChannelProvider()).isNull(); // custom grpc transport DatastoreOptions grpcDatastoreOptions = From 8897a86c218390853032c8a6365ac813c926f530 Mon Sep 17 00:00:00 2001 From: kolea2 <45548808+kolea2@users.noreply.github.com> Date: Mon, 12 Feb 2024 15:48:36 -0500 Subject: [PATCH 19/42] chore: Update CODEOWNERS (#1297) (#1331) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: Update CODEOWNERS * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * chore: Update .repo-metadata.json * 🦉 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 --- .github/CODEOWNERS | 6 +++--- .repo-metadata.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 17fe1884d..95d4bc11b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -4,11 +4,11 @@ # For syntax help see: # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax -# The @googleapis/cloud-native-db-dpes @googleapis/api-datastore-sdk is the default owner for changes in this repo -* @googleapis/yoshi-java @googleapis/cloud-native-db-dpes @googleapis/api-datastore-sdk +# The @googleapis/cloud-native-db-dpes @googleapis/api-datastore-sdk @googleapis/api-firestore-partners is the default owner for changes in this repo +* @googleapis/yoshi-java @googleapis/cloud-native-db-dpes @googleapis/api-datastore-sdk @googleapis/api-firestore-partners # for handwritten libraries, keep codeowner_team in .repo-metadata.json as owner -**/*.java @googleapis/cloud-native-db-dpes @googleapis/api-datastore-sdk +**/*.java @googleapis/cloud-native-db-dpes @googleapis/api-datastore-sdk @googleapis/api-firestore-partners # The java-samples-reviewers team is the default owner for samples changes diff --git a/.repo-metadata.json b/.repo-metadata.json index d5f4a9450..deaa82272 100644 --- a/.repo-metadata.json +++ b/.repo-metadata.json @@ -9,7 +9,7 @@ "repo": "googleapis/java-datastore", "repo_short": "java-datastore", "distribution_name": "com.google.cloud:google-cloud-datastore", - "codeowner_team": "@googleapis/cloud-native-db-dpes @googleapis/api-datastore-sdk", + "codeowner_team": "@googleapis/cloud-native-db-dpes @googleapis/api-datastore-sdk @googleapis/api-firestore-partners", "api_id": "datastore.googleapis.com", "library_type": "GAPIC_COMBO", "api_description": "is a fully managed, schemaless database for\nstoring non-relational data. Cloud Datastore automatically scales with\nyour users and supports ACID transactions, high availability of reads and\nwrites, strong consistency for reads and ancestor queries, and eventual\nconsistency for all other queries.", From fcff21bd8b3edb18e6777dbae62b1392f1442378 Mon Sep 17 00:00:00 2001 From: kolea2 <45548808+kolea2@users.noreply.github.com> Date: Mon, 12 Feb 2024 15:49:00 -0500 Subject: [PATCH 20/42] chore: run owlbot (#1330) * chore: run owlbot * update owlbot lock --- .github/.OwlBot.lock.yaml | 6 +-- .github/workflows/ci.yaml | 2 +- .github/workflows/renovate_config_check.yaml | 25 ++++++++++ .kokoro/requirements.txt | 48 ++++++++++---------- renovate.json | 14 +++++- 5 files changed, 66 insertions(+), 29 deletions(-) create mode 100644 .github/workflows/renovate_config_check.yaml diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 208af3438..b9c5b09c7 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,5 +13,5 @@ # limitations under the License. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-java:latest - digest: sha256:fb7584f6adb3847ac480ed49a4bfe1463965026b2919a1be270e3174f3ce1191 -# created: 2023-10-26T23:22:21.357007231Z + digest: sha256:1fb09a3eb66af09221da69087fd1b4d075bc7c79e508d0708f5dc0f842069da2 +# created: 2024-02-05T19:43:08.106031548Z diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e27b2c575..ae66b1973 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -25,7 +25,7 @@ jobs: strategy: fail-fast: false matrix: - java: [11, 17] + java: [11, 17, 21] steps: - uses: actions/checkout@v3 - uses: actions/setup-java@v3 diff --git a/.github/workflows/renovate_config_check.yaml b/.github/workflows/renovate_config_check.yaml new file mode 100644 index 000000000..87d8eb2be --- /dev/null +++ b/.github/workflows/renovate_config_check.yaml @@ -0,0 +1,25 @@ +name: Renovate Bot Config Validation + +on: + pull_request: + paths: + - 'renovate.json' + +jobs: + renovate_bot_config_validation: + runs-on: ubuntu-22.04 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '20' + + - name: Install Renovate and Config Validator + run: | + npm install -g npm@latest + npm install --global renovate + renovate-config-validator diff --git a/.kokoro/requirements.txt b/.kokoro/requirements.txt index c5c11bbe7..445c5c1f0 100644 --- a/.kokoro/requirements.txt +++ b/.kokoro/requirements.txt @@ -170,30 +170,30 @@ colorlog==6.7.0 \ --hash=sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662 \ --hash=sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5 # via gcp-docuploader -cryptography==41.0.2 \ - --hash=sha256:01f1d9e537f9a15b037d5d9ee442b8c22e3ae11ce65ea1f3316a41c78756b711 \ - --hash=sha256:079347de771f9282fbfe0e0236c716686950c19dee1b76240ab09ce1624d76d7 \ - --hash=sha256:182be4171f9332b6741ee818ec27daff9fb00349f706629f5cbf417bd50e66fd \ - --hash=sha256:192255f539d7a89f2102d07d7375b1e0a81f7478925b3bc2e0549ebf739dae0e \ - --hash=sha256:2a034bf7d9ca894720f2ec1d8b7b5832d7e363571828037f9e0c4f18c1b58a58 \ - --hash=sha256:342f3767e25876751e14f8459ad85e77e660537ca0a066e10e75df9c9e9099f0 \ - --hash=sha256:439c3cc4c0d42fa999b83ded80a9a1fb54d53c58d6e59234cfe97f241e6c781d \ - --hash=sha256:49c3222bb8f8e800aead2e376cbef687bc9e3cb9b58b29a261210456a7783d83 \ - --hash=sha256:674b669d5daa64206c38e507808aae49904c988fa0a71c935e7006a3e1e83831 \ - --hash=sha256:7a9a3bced53b7f09da251685224d6a260c3cb291768f54954e28f03ef14e3766 \ - --hash=sha256:7af244b012711a26196450d34f483357e42aeddb04128885d95a69bd8b14b69b \ - --hash=sha256:7d230bf856164de164ecb615ccc14c7fc6de6906ddd5b491f3af90d3514c925c \ - --hash=sha256:84609ade00a6ec59a89729e87a503c6e36af98ddcd566d5f3be52e29ba993182 \ - --hash=sha256:9a6673c1828db6270b76b22cc696f40cde9043eb90373da5c2f8f2158957f42f \ - --hash=sha256:9b6d717393dbae53d4e52684ef4f022444fc1cce3c48c38cb74fca29e1f08eaa \ - --hash=sha256:9c3fe6534d59d071ee82081ca3d71eed3210f76ebd0361798c74abc2bcf347d4 \ - --hash=sha256:a719399b99377b218dac6cf547b6ec54e6ef20207b6165126a280b0ce97e0d2a \ - --hash=sha256:b332cba64d99a70c1e0836902720887fb4529ea49ea7f5462cf6640e095e11d2 \ - --hash=sha256:d124682c7a23c9764e54ca9ab5b308b14b18eba02722b8659fb238546de83a76 \ - --hash=sha256:d73f419a56d74fef257955f51b18d046f3506270a5fd2ac5febbfa259d6c0fa5 \ - --hash=sha256:f0dc40e6f7aa37af01aba07277d3d64d5a03dc66d682097541ec4da03cc140ee \ - --hash=sha256:f14ad275364c8b4e525d018f6716537ae7b6d369c094805cae45300847e0894f \ - --hash=sha256:f772610fe364372de33d76edcd313636a25684edb94cee53fd790195f5989d14 +cryptography==41.0.6 \ + --hash=sha256:068bc551698c234742c40049e46840843f3d98ad7ce265fd2bd4ec0d11306596 \ + --hash=sha256:0f27acb55a4e77b9be8d550d762b0513ef3fc658cd3eb15110ebbcbd626db12c \ + --hash=sha256:2132d5865eea673fe6712c2ed5fb4fa49dba10768bb4cc798345748380ee3660 \ + --hash=sha256:3288acccef021e3c3c10d58933f44e8602cf04dba96d9796d70d537bb2f4bbc4 \ + --hash=sha256:35f3f288e83c3f6f10752467c48919a7a94b7d88cc00b0668372a0d2ad4f8ead \ + --hash=sha256:398ae1fc711b5eb78e977daa3cbf47cec20f2c08c5da129b7a296055fbb22aed \ + --hash=sha256:422e3e31d63743855e43e5a6fcc8b4acab860f560f9321b0ee6269cc7ed70cc3 \ + --hash=sha256:48783b7e2bef51224020efb61b42704207dde583d7e371ef8fc2a5fb6c0aabc7 \ + --hash=sha256:4d03186af98b1c01a4eda396b137f29e4e3fb0173e30f885e27acec8823c1b09 \ + --hash=sha256:5daeb18e7886a358064a68dbcaf441c036cbdb7da52ae744e7b9207b04d3908c \ + --hash=sha256:60e746b11b937911dc70d164060d28d273e31853bb359e2b2033c9e93e6f3c43 \ + --hash=sha256:742ae5e9a2310e9dade7932f9576606836ed174da3c7d26bc3d3ab4bd49b9f65 \ + --hash=sha256:7e00fb556bda398b99b0da289ce7053639d33b572847181d6483ad89835115f6 \ + --hash=sha256:85abd057699b98fce40b41737afb234fef05c67e116f6f3650782c10862c43da \ + --hash=sha256:8efb2af8d4ba9dbc9c9dd8f04d19a7abb5b49eab1f3694e7b5a16a5fc2856f5c \ + --hash=sha256:ae236bb8760c1e55b7a39b6d4d32d2279bc6c7c8500b7d5a13b6fb9fc97be35b \ + --hash=sha256:afda76d84b053923c27ede5edc1ed7d53e3c9f475ebaf63c68e69f1403c405a8 \ + --hash=sha256:b27a7fd4229abef715e064269d98a7e2909ebf92eb6912a9603c7e14c181928c \ + --hash=sha256:b648fe2a45e426aaee684ddca2632f62ec4613ef362f4d681a9a6283d10e079d \ + --hash=sha256:c5a550dc7a3b50b116323e3d376241829fd326ac47bc195e04eb33a8170902a9 \ + --hash=sha256:da46e2b5df770070412c46f87bac0849b8d685c5f2679771de277a422c7d0b86 \ + --hash=sha256:f39812f70fc5c71a15aa3c97b2bbe213c3f2a460b79bd21c40d033bb34a9bf36 \ + --hash=sha256:ff369dd19e8fe0528b02e8df9f2aeb2479f89b1270d90f96a63500afe9af5cae # via # gcp-releasetool # secretstorage diff --git a/renovate.json b/renovate.json index d85059fc5..0751ef09c 100644 --- a/renovate.json +++ b/renovate.json @@ -14,6 +14,17 @@ ".kokoro/requirements.txt", ".github/workflows/**" ], + "customManagers": [ + { + "customType": "regex", + "fileMatch": [ + "^.kokoro/presubmit/graalvm-native.*.cfg$" + ], + "matchStrings": ["value: \"gcr.io/cloud-devrel-public-resources/graalvm.*:(?.*?)\""], + "depNameTemplate": "com.google.cloud:sdk-platform-java-config", + "datasourceTemplate": "maven" + } + ], "packageRules": [ { "packagePatterns": [ @@ -55,7 +66,8 @@ "^com.google.truth:truth", "^org.mockito:mockito-core", "^org.objenesis:objenesis", - "^com.google.cloud:google-cloud-conformance-tests" + "^com.google.cloud:google-cloud-conformance-tests", + "^org.graalvm.buildtools:junit-platform-native" ], "semanticCommitType": "test", "semanticCommitScope": "deps" From d78a453a13f358a50eadff8212aa4991a907e426 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:36:40 +0000 Subject: [PATCH 21/42] deps: bump com.google.cloud:google-cloud-shared-dependencies from 3.24.0 to 3.25.0 (#1335) Bumps com.google.cloud:google-cloud-shared-dependencies from 3.24.0 to 3.25.0. [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.cloud:google-cloud-shared-dependencies&package-manager=maven&previous-version=3.24.0&new-version=3.25.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c71e85d91..d39a87f0d 100644 --- a/pom.xml +++ b/pom.xml @@ -151,7 +151,7 @@ com.google.cloud google-cloud-shared-dependencies - 3.24.0 + 3.25.0 pom import From fc4ae8976ed8767d9cd89e828d2be7383a24fd65 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:26:16 +0000 Subject: [PATCH 22/42] deps: bump com.google.truth:truth from 1.4.0 to 1.4.1 (#1341) Bumps [com.google.truth:truth](https://togithub.com/google/truth) from 1.4.0 to 1.4.1.
Release notes

Sourced from com.google.truth:truth's releases.

1.4.1

This release deprecates Truth8.

All its methods have become available on the main Truth class. In most cases, you can migrate your whole project mechanically: git grep -l Truth8 | xargs perl -pi -e 's/\bTruth8\b/Truth/g;'

While we do not plan to delete Truth8, we recommend migrating off it, at least if you static import assertThat: If you do not migrate, such static imports will become ambiguous in Truth 1.4.2, breaking your build.

Commits
  • a920d7d Set version number for truth-parent to 1.4.1.
  • 3406074 Document more about how and why to migrate off Truth8.
  • 2be0061 Update docs to reflect that the Java 8 assertions have "moved" to the main `T...
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.truth:truth&package-manager=maven&previous-version=1.4.0&new-version=1.4.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- datastore-v1-proto-client/pom.xml | 2 +- google-cloud-datastore/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/datastore-v1-proto-client/pom.xml b/datastore-v1-proto-client/pom.xml index 142798e94..ebeae864e 100644 --- a/datastore-v1-proto-client/pom.xml +++ b/datastore-v1-proto-client/pom.xml @@ -98,7 +98,7 @@ com.google.truth truth - 1.4.0 + 1.4.1 test diff --git a/google-cloud-datastore/pom.xml b/google-cloud-datastore/pom.xml index 3f13224de..e80fb2908 100644 --- a/google-cloud-datastore/pom.xml +++ b/google-cloud-datastore/pom.xml @@ -157,7 +157,7 @@ com.google.truth truth - 1.4.0 + 1.4.1 test From ffcd01244e33f3071758f478e1cc88be978a4b27 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:32:17 +0000 Subject: [PATCH 23/42] deps: bump com.google.errorprone:error_prone_core from 2.24.1 to 2.25.0 (#1340) Bumps [com.google.errorprone:error_prone_core](https://togithub.com/google/error-prone) from 2.24.1 to 2.25.0.
Release notes

Sourced from com.google.errorprone:error_prone_core's releases.

Error Prone 2.25.0

New checks:

Closed issues: #4195, #4224, #4228, #4248, #4249, #4251

Full Changelog: https://togithub.com/google/error-prone/compare/v2.24.1...v2.25.0

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.errorprone:error_prone_core&package-manager=maven&previous-version=2.24.1&new-version=2.25.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d39a87f0d..b6cb9767f 100644 --- a/pom.xml +++ b/pom.xml @@ -143,7 +143,7 @@ github google-cloud-datastore-parent https://googleapis.dev/java/google-api-grpc/latest - 2.24.1 + 2.25.0 From b30ee061f2352556124a4e10a4c8c9c524e291fc Mon Sep 17 00:00:00 2001 From: kolea2 <45548808+kolea2@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:16:43 -0500 Subject: [PATCH 24/42] =?UTF-8?q?revert:=20"test:=20Creating=20multi=20db?= =?UTF-8?q?=20rule=20to=20run=20tests=20multiple=20times=20agai=E2=80=A6?= =?UTF-8?q?=20(#1346)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Revert "test: Creating multi db rule to run tests multiple times against different named databases. (#1270)" This reverts commit 780c9f40f1ae04d0ec919d203bf256e3cff8fcc1. * 🦉 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 --- README.md | 8 +- .../it/ITDatastoreAggregationsTest.java | 51 ++- .../cloud/datastore/it/ITDatastoreTest.java | 313 ++++++++++-------- .../cloud/datastore/it/MultiDbRule.java | 92 ----- 4 files changed, 209 insertions(+), 255 deletions(-) delete mode 100644 google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/MultiDbRule.java diff --git a/README.md b/README.md index e4f708557..17e717738 100644 --- a/README.md +++ b/README.md @@ -50,20 +50,20 @@ If you are using Maven without the BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies: ```Groovy -implementation platform('com.google.cloud:libraries-bom:26.31.0') +implementation platform('com.google.cloud:libraries-bom:26.33.0') implementation 'com.google.cloud:google-cloud-datastore' ``` If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-datastore:2.18.3' +implementation 'com.google.cloud:google-cloud-datastore:2.18.4' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.18.3" +libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.18.4" ``` @@ -380,7 +380,7 @@ Java is a registered trademark of Oracle and/or its affiliates. [kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-datastore/java11.html [stability-image]: https://img.shields.io/badge/stability-stable-green [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-datastore.svg -[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-datastore/2.18.3 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-datastore/2.18.4 [authentication]: https://github.com/googleapis/google-cloud-java#authentication [auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes [predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java index 555c309fa..e04f5e55f 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java @@ -26,6 +26,7 @@ import com.google.cloud.datastore.AggregationResult; import com.google.cloud.datastore.Datastore; import com.google.cloud.datastore.Datastore.TransactionCallable; +import com.google.cloud.datastore.DatastoreOptions; import com.google.cloud.datastore.Entity; import com.google.cloud.datastore.EntityQuery; import com.google.cloud.datastore.GqlQuery; @@ -33,6 +34,7 @@ import com.google.cloud.datastore.Query; import com.google.cloud.datastore.QueryResults; import com.google.cloud.datastore.Transaction; +import com.google.cloud.datastore.testing.RemoteDatastoreHelper; import com.google.common.collect.ImmutableList; import com.google.datastore.v1.TransactionOptions; import com.google.datastore.v1.TransactionOptions.ReadOnly; @@ -41,24 +43,18 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import org.junit.After; -import org.junit.BeforeClass; -import org.junit.ClassRule; +import org.junit.AfterClass; import org.junit.Test; // TODO(jainsahab) Move all the aggregation related tests from ITDatastoreTest to this file public class ITDatastoreAggregationsTest { - @ClassRule public static MultiDbRule multiDbRule = new MultiDbRule(); - - private static Datastore DATASTORE; + private static final RemoteDatastoreHelper HELPER = RemoteDatastoreHelper.create(); + private static final DatastoreOptions OPTIONS = HELPER.getOptions(); + private static final Datastore DATASTORE = OPTIONS.getService(); private static final String KIND = "Marks"; - @BeforeClass - public static void beforeClass() throws Exception { - DATASTORE = multiDbRule.getDatastore(); - } - @After public void tearDown() { EntityQuery allEntitiesQuery = Query.newEntityQueryBuilder().build(); @@ -68,6 +64,11 @@ public void tearDown() { DATASTORE.delete(keysToDelete); } + @AfterClass + public static void afterClass() throws Exception { + DATASTORE.close(); + } + Key key1 = DATASTORE.newKeyFactory().setKind(KIND).newKey(1); Key key2 = DATASTORE.newKeyFactory().setKind(KIND).newKey(2); Key key3 = DATASTORE.newKeyFactory().setKind(KIND).newKey(3); @@ -88,6 +89,7 @@ public void testSumAggregation() { Query.newAggregationQueryBuilder() .over(baseQuery) .addAggregations(sum("marks").as("total_marks")) + .setNamespace(OPTIONS.getNamespace()) .build(); // sum of 2 entities @@ -106,7 +108,11 @@ public void testSumAggregationWithAutoGeneratedAlias() { EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(KIND).build(); AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder().over(baseQuery).addAggregations(sum("marks")).build(); + Query.newAggregationQueryBuilder() + .over(baseQuery) + .addAggregations(sum("marks")) + .setNamespace(OPTIONS.getNamespace()) + .build(); // sum of 2 entities assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("property_1")) @@ -127,7 +133,11 @@ public void testSumAggregationInGqlQuery() { "AGGREGATE SUM(marks) AS total_marks OVER (SELECT * FROM Marks)") .build(); - AggregationQuery aggregationQuery = Query.newAggregationQueryBuilder().over(gqlQuery).build(); + AggregationQuery aggregationQuery = + Query.newAggregationQueryBuilder() + .over(gqlQuery) + .setNamespace(OPTIONS.getNamespace()) + .build(); // sum of 2 entities assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("total_marks")) @@ -148,6 +158,7 @@ public void testSumAggregationWithResultOfDoubleType() { Query.newAggregationQueryBuilder() .over(baseQuery) .addAggregations(sum("cgpa").as("total_cgpa")) + .setNamespace(OPTIONS.getNamespace()) .build(); // sum of 2 entities @@ -169,6 +180,7 @@ public void testAvgAggregation() { Query.newAggregationQueryBuilder() .over(baseQuery) .addAggregations(avg("marks").as("avg_marks")) + .setNamespace(OPTIONS.getNamespace()) .build(); // avg of 2 entities @@ -187,7 +199,11 @@ public void testAvgAggregationWithAutoGeneratedAlias() { EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(KIND).build(); AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder().over(baseQuery).addAggregations(avg("marks")).build(); + Query.newAggregationQueryBuilder() + .over(baseQuery) + .addAggregations(avg("marks")) + .setNamespace(OPTIONS.getNamespace()) + .build(); // avg of 2 entities assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getDouble("property_1")) @@ -207,7 +223,11 @@ public void testAvgAggregationInGqlQuery() { Query.newGqlQueryBuilder("AGGREGATE AVG(marks) AS avg_marks OVER (SELECT * FROM Marks)") .build(); - AggregationQuery aggregationQuery = Query.newAggregationQueryBuilder().over(gqlQuery).build(); + AggregationQuery aggregationQuery = + Query.newAggregationQueryBuilder() + .over(gqlQuery) + .setNamespace(OPTIONS.getNamespace()) + .build(); // avg of 2 entities assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getDouble("avg_marks")) @@ -229,6 +249,7 @@ public void testSumAndAvgAggregationTogether() { .over(baseQuery) .addAggregations(sum("marks").as("total_marks")) .addAggregations(avg("marks").as("avg_marks")) + .setNamespace(OPTIONS.getNamespace()) .build(); // sum of 2 entities @@ -250,6 +271,7 @@ public void testTransactionShouldReturnAConsistentSnapshot() { .addAggregation(count().as("count")) .addAggregations(sum("marks").as("total_marks")) .addAggregations(avg("marks").as("avg_marks")) + .setNamespace(OPTIONS.getNamespace()) .build(); // original entity count is 2 @@ -310,6 +332,7 @@ public void testReadOnlyTransactionShouldNotLockTheDocuments() .addAggregation(count().as("count")) .addAggregations(sum("marks").as("total_marks")) .addAggregations(avg("marks").as("avg_marks")) + .setNamespace(OPTIONS.getNamespace()) .build(); TransactionOptions transactionOptions = diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java index 778fb6535..3f00fe2cf 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java @@ -67,11 +67,13 @@ import com.google.cloud.datastore.TimestampValue; import com.google.cloud.datastore.Transaction; import com.google.cloud.datastore.ValueType; +import com.google.cloud.datastore.testing.RemoteDatastoreHelper; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.datastore.v1.TransactionOptions; import com.google.datastore.v1.TransactionOptions.ReadOnly; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; @@ -83,17 +85,28 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.rules.Timeout; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +@RunWith(Parameterized.class) public class ITDatastoreTest { - private static DatastoreOptions DATASTORE_OPTIONS; - private static Datastore DATASTORE; + private static final RemoteDatastoreHelper HELPER = RemoteDatastoreHelper.create(); + private static final DatastoreOptions OPTIONS_1 = HELPER.getOptions(); + private static final Datastore DATASTORE_1 = OPTIONS_1.getService(); + + private static final String CUSTOM_DB_ID = "test-db"; + private static final RemoteDatastoreHelper HELPER2 = RemoteDatastoreHelper.create(CUSTOM_DB_ID); + private static final DatastoreOptions OPTIONS_2 = HELPER2.getOptions(); + private static final Datastore DATASTORE_2 = OPTIONS_2.getService(); + + private final DatastoreOptions options; + private final Datastore datastore; private static String PROJECT_ID; private static String NAMESPACE; @@ -126,30 +139,37 @@ public class ITDatastoreTest { private static Entity ENTITY2; private static Entity ENTITY3; - @ClassRule public static MultiDbRule multiDbRule = new MultiDbRule(); - @Rule public Timeout globalTimeout = Timeout.seconds(100); @Rule public MultipleAttemptsRule multipleAttemptsRule = new MultipleAttemptsRule(3); - @BeforeClass - public static void beforeClass() throws Exception { + @AfterClass + public static void afterClass() throws Exception { + HELPER.deleteNamespace(); + DATASTORE_1.close(); + DATASTORE_2.close(); + } - DATASTORE_OPTIONS = multiDbRule.getCurrentOptions(); - DATASTORE = multiDbRule.getDatastore(); + public ITDatastoreTest( + DatastoreOptions options, + Datastore datastore, + // databaseType is unused as a variable, but used as a parameterized label when running tests + String databaseType) { + this.options = options; + this.datastore = datastore; - PROJECT_ID = DATASTORE_OPTIONS.getProjectId(); - NAMESPACE = DATASTORE_OPTIONS.getNamespace(); + PROJECT_ID = this.options.getProjectId(); + NAMESPACE = this.options.getNamespace(); ROOT_KEY = - Key.newBuilder(PROJECT_ID, "rootkey", "default", DATASTORE_OPTIONS.getDatabaseId()) + Key.newBuilder(PROJECT_ID, "rootkey", "default", options.getDatabaseId()) .setNamespace(NAMESPACE) .build(); INCOMPLETE_KEY1 = IncompleteKey.newBuilder(ROOT_KEY, KIND1).setNamespace(NAMESPACE).build(); IncompleteKey INCOMPLETE_KEY2 = IncompleteKey.newBuilder(PROJECT_ID, KIND2) - .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) + .setDatabaseId(options.getDatabaseId()) .setNamespace(NAMESPACE) .build(); @@ -178,7 +198,7 @@ public static void beforeClass() throws Exception { .setKey( IncompleteKey.newBuilder(PROJECT_ID, KIND3) .setNamespace(NAMESPACE) - .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) + .setDatabaseId(options.getDatabaseId()) .build()) .build(); ENTITY1 = @@ -211,30 +231,36 @@ public static void beforeClass() throws Exception { @Before public void setUp() { - DATASTORE.put(ENTITY1, ENTITY2); + datastore.put(ENTITY1, ENTITY2); } @After public void tearDown() { EntityQuery allEntitiesQuery = Query.newEntityQueryBuilder().build(); - QueryResults allEntities = DATASTORE.run(allEntitiesQuery); + QueryResults allEntities = datastore.run(allEntitiesQuery); Key[] keysToDelete = ImmutableList.copyOf(allEntities).stream().map(Entity::getKey).toArray(Key[]::new); - DATASTORE.delete(keysToDelete); + datastore.delete(keysToDelete); + } + + @Parameterized.Parameters(name = "database: {2}") + public static Iterable data() { + return Arrays.asList( + new Object[][] {{OPTIONS_1, DATASTORE_1, "default"}, {OPTIONS_2, DATASTORE_2, "test-db"}}); } private Iterator getStronglyConsistentResults(Query scQuery, Query query) throws InterruptedException { // scQuery is equivalent to query, but with an ancestor filter in it // this makes scQuery strongly consistent - QueryResults scResults = DATASTORE.run(scQuery); + QueryResults scResults = datastore.run(scQuery); List scResultsCopy = makeResultsCopy(scResults); Set scResultsSet = new HashSet<>(scResultsCopy); int maxAttempts = 20; while (maxAttempts > 0) { --maxAttempts; - QueryResults results = DATASTORE.run(query); + QueryResults results = datastore.run(query); List resultsCopy = makeResultsCopy(results); Set resultsSet = new HashSet<>(resultsCopy); if (scResultsSet.size() == resultsSet.size() && scResultsSet.containsAll(resultsSet)) { @@ -267,7 +293,7 @@ public void orQuery() { .setNull("null") .set("age", 19) .build(); - DATASTORE.put(entity3); + datastore.put(entity3); // age == 19 || age == 20 CompositeFilter orFilter = @@ -278,7 +304,7 @@ public void orQuery() { .setKind(KIND2) .setFilter(orFilter) .build(); - QueryResults results = DATASTORE.run(simpleOrQuery); + QueryResults results = datastore.run(simpleOrQuery); assertTrue(results.hasNext()); assertEquals(ENTITY2, results.next()); assertTrue(results.hasNext()); @@ -293,7 +319,7 @@ public void orQuery() { .setFilter(orFilter) .setLimit(1) .build(); - QueryResults results2 = DATASTORE.run(simpleOrQueryLimit); + QueryResults results2 = datastore.run(simpleOrQueryLimit); assertTrue(results2.hasNext()); assertEquals(ENTITY2, results2.next()); assertFalse(results2.hasNext()); @@ -311,7 +337,7 @@ public void orQuery() { .setKind(KIND2) .setFilter(compositeFilter) .build(); - QueryResults results3 = DATASTORE.run(orQueryNested); + QueryResults results3 = datastore.run(orQueryNested); assertTrue(results3.hasNext()); assertEquals(ENTITY2, results3.next()); assertFalse(results3.hasNext()); @@ -329,7 +355,7 @@ public void orQuery() { .setFilter(ancestorAndFilter) .setLimit(1) .build(); - QueryResults results4 = DATASTORE.run(orQueryNested2); + QueryResults results4 = datastore.run(orQueryNested2); assertTrue(results4.hasNext()); assertEquals(ENTITY2, results4.next()); assertFalse(results4.hasNext()); @@ -337,7 +363,7 @@ public void orQuery() { @Test public void testNewTransactionCommit() { - Transaction transaction = DATASTORE.newTransaction(); + Transaction transaction = datastore.newTransaction(); transaction.add(ENTITY3); Entity entity2 = Entity.newBuilder(ENTITY2).clear().setNull("bla").build(); transaction.update(entity2); @@ -345,7 +371,7 @@ public void testNewTransactionCommit() { transaction.commit(); assertFalse(transaction.isActive()); - List list = DATASTORE.fetch(KEY1, KEY2, KEY3); + List list = datastore.fetch(KEY1, KEY2, KEY3); assertNull(list.get(0)); assertEquals(entity2, list.get(1)); assertEquals(ENTITY3, list.get(2)); @@ -369,20 +395,20 @@ public void testNewTransactionCommit() { @Test public void testTransactionWithRead() throws Exception { StatementExecutor statementExecutor = new StatementExecutor(); - Transaction baseTransaction = DATASTORE.newTransaction(); + Transaction baseTransaction = datastore.newTransaction(); assertNull(baseTransaction.get(KEY3)); baseTransaction.add(ENTITY3); baseTransaction.commit(); - assertEquals(ENTITY3, DATASTORE.get(KEY3)); + assertEquals(ENTITY3, datastore.get(KEY3)); - Transaction transaction = DATASTORE.newTransaction(); + Transaction transaction = datastore.newTransaction(); statementExecutor.execute( Tuple.of("T1", () -> assertEquals(ENTITY3, transaction.get(KEY3))), // update entity3 during the transaction, will be blocked in case of pessimistic concurrency Tuple.of( "T2", () -> - DATASTORE.put(Entity.newBuilder(ENTITY3).clear().set("from", "datastore").build())), + datastore.put(Entity.newBuilder(ENTITY3).clear().set("from", "datastore").build())), Tuple.of( "T1", () -> @@ -410,16 +436,16 @@ public void testTransactionWithQuery() throws Exception { .setFilter(PropertyFilter.hasAncestor(KEY2)) .setNamespace(NAMESPACE) .build(); - Transaction baseTransaction = DATASTORE.newTransaction(); + Transaction baseTransaction = datastore.newTransaction(); QueryResults baseResults = baseTransaction.run(query); assertTrue(baseResults.hasNext()); assertEquals(ENTITY2, baseResults.next()); assertFalse(baseResults.hasNext()); baseTransaction.add(ENTITY3); baseTransaction.commit(); - assertEquals(ENTITY3, DATASTORE.get(KEY3)); + assertEquals(ENTITY3, datastore.get(KEY3)); - Transaction transaction = DATASTORE.newTransaction(); + Transaction transaction = datastore.newTransaction(); statementExecutor.execute( Tuple.of( "T1", @@ -431,7 +457,7 @@ public void testTransactionWithQuery() throws Exception { }), Tuple.of("T1", () -> transaction.delete(ENTITY3.getKey())), // update entity2 during the transaction, will be blocked in case of pessimistic concurrency - Tuple.of("T2", () -> DATASTORE.put(Entity.newBuilder(ENTITY2).clear().build())), + Tuple.of("T2", () -> datastore.put(Entity.newBuilder(ENTITY2).clear().build())), Tuple.of("T1", transaction::commit) // T1 will throw error in case of optimistic concurrency ); @@ -447,7 +473,7 @@ public void testTransactionWithQuery() throws Exception { @Test public void testNewTransactionRollback() { - Transaction transaction = DATASTORE.newTransaction(); + Transaction transaction = datastore.newTransaction(); transaction.add(ENTITY3); Entity entity2 = Entity.newBuilder(ENTITY2) @@ -467,7 +493,7 @@ public void testNewTransactionRollback() { assertEquals("FAILED_PRECONDITION", expected.getReason()); } - List list = DATASTORE.fetch(KEY1, KEY2, KEY3); + List list = datastore.fetch(KEY1, KEY2, KEY3); assertEquals(ENTITY1, list.get(0)); assertEquals(ENTITY2, list.get(1)); assertNull(list.get(2)); @@ -476,7 +502,7 @@ public void testNewTransactionRollback() { @Test public void testNewBatch() { - Batch batch = DATASTORE.newBatch(); + Batch batch = datastore.newBatch(); Entity entity1 = Entity.newBuilder(ENTITY1).clear().build(); Entity entity2 = Entity.newBuilder(ENTITY2).clear().setNull("bla").build(); Entity entity4 = Entity.newBuilder(KEY4).set("value", StringValue.of("value")).build(); @@ -499,7 +525,7 @@ public void testNewBatch() { Batch.Response response = batch.submit(); entities = - DATASTORE.fetch(KEY1, KEY2, KEY3, entity4.getKey(), entity5.getKey(), entity6.getKey()); + datastore.fetch(KEY1, KEY2, KEY3, entity4.getKey(), entity5.getKey(), entity6.getKey()); assertEquals(entity1, entities.get(0)); assertEquals(entity2, entities.get(1)); assertEquals(ENTITY3, entities.get(2)); @@ -509,7 +535,7 @@ public void testNewBatch() { assertEquals(6, entities.size()); List generatedKeys = response.getGeneratedKeys(); assertEquals(1, generatedKeys.size()); - assertEquals(PARTIAL_ENTITY3.getNames(), DATASTORE.get(generatedKeys.get(0)).getNames()); + assertEquals(PARTIAL_ENTITY3.getNames(), datastore.get(generatedKeys.get(0)).getNames()); assertEquals(PARTIAL_ENTITY3.getKey(), IncompleteKey.newBuilder(generatedKeys.get(0)).build()); try { @@ -519,12 +545,12 @@ public void testNewBatch() { assertEquals("FAILED_PRECONDITION", expected.getReason()); } - batch = DATASTORE.newBatch(); + batch = datastore.newBatch(); batch.delete(entity4.getKey(), entity5.getKey(), entity6.getKey()); batch.update(ENTITY1, ENTITY2, ENTITY3); batch.submit(); entities = - DATASTORE.fetch(KEY1, KEY2, KEY3, entity4.getKey(), entity5.getKey(), entity6.getKey()); + datastore.fetch(KEY1, KEY2, KEY3, entity4.getKey(), entity5.getKey(), entity6.getKey()); assertEquals(ENTITY1, entities.get(0)); assertEquals(ENTITY2, entities.get(1)); assertEquals(ENTITY3, entities.get(2)); @@ -553,7 +579,7 @@ public void testRunGqlQueryNoCasting() throws InterruptedException { assertEquals(ENTITY1, results1.next()); assertFalse(results1.hasNext()); - DATASTORE.put(ENTITY3); + datastore.put(ENTITY3); Query query2 = Query.newGqlQueryBuilder(ResultType.ENTITY, "select * from " + KIND2 + " order by __key__") .setNamespace(NAMESPACE) @@ -620,7 +646,7 @@ public void testRunGqlQueryNoCasting() throws InterruptedException { assertEquals(KEY1, projectionEntity.getKey()); assertTrue(projectionEntity.getNames().isEmpty()); assertFalse(keyProjectionResult.hasNext()); - DATASTORE.delete(ENTITY3.getKey()); + datastore.delete(ENTITY3.getKey()); } @Test @@ -643,7 +669,7 @@ public void testRunGqlQueryWithCasting() throws InterruptedException { Query query2 = Query.newGqlQueryBuilder("select * from " + KIND1).setNamespace(NAMESPACE).build(); - QueryResults results2 = DATASTORE.run(query2); + QueryResults results2 = datastore.run(query2); assertSame(Entity.class, results2.getResultClass()); @@ -798,11 +824,11 @@ public void testRunAggregationQueryInTransactionShouldReturnAConsistentSnapshot( .build(); // original entity count is 2 - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) .isEqualTo(2L); // FIRST TRANSACTION - DATASTORE.runInTransaction( + datastore.runInTransaction( (TransactionCallable) inFirstTransaction -> { // creating a new entity @@ -816,16 +842,16 @@ public void testRunAggregationQueryInTransactionShouldReturnAConsistentSnapshot( .getLong("count")) .isEqualTo(2L); assertThat( - getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) + getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) .isEqualTo(2L); return null; }); // after first transaction is committed, count is updated to 3 now. - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) .isEqualTo(3L); // SECOND TRANSACTION - DATASTORE.runInTransaction( + datastore.runInTransaction( (TransactionCallable) inSecondTransaction -> { // deleting ENTITY2 @@ -837,14 +863,14 @@ public void testRunAggregationQueryInTransactionShouldReturnAConsistentSnapshot( .getLong("count")) .isEqualTo(3L); assertThat( - getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) + getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) .isEqualTo(3L); return null; }); // after second transaction is committed, count is updated to 2 now. - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) .isEqualTo(2L); - DATASTORE.delete(newEntityKey); + datastore.delete(newEntityKey); } @Test @@ -865,7 +891,7 @@ public void testRunAggregationQueryInAReadOnlyTransactionShouldNotLockTheCounted TransactionOptions transactionOptions = TransactionOptions.newBuilder().setReadOnly(ReadOnly.newBuilder().build()).build(); - Transaction readOnlyTransaction = DATASTORE.newTransaction(transactionOptions); + Transaction readOnlyTransaction = datastore.newTransaction(transactionOptions); // Executing query in transaction assertThat( @@ -881,7 +907,7 @@ public void testRunAggregationQueryInAReadOnlyTransactionShouldNotLockTheCounted .setKey(Key.newBuilder(KEY1, "newKind", "name-01").build()) .set("v_int", 10) .build(); - DATASTORE.put(aNewEntity); + datastore.put(aNewEntity); return null; }); @@ -892,7 +918,7 @@ public void testRunAggregationQueryInAReadOnlyTransactionShouldNotLockTheCounted readOnlyTransaction.commit(); executor.shutdownNow(); - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) .isEqualTo(3L); } @@ -1025,7 +1051,7 @@ public void testInNotInNeqFilters() throws InterruptedException { .setKey(Key.newBuilder(INCOMPLETE_KEY1, "e2").build()) .set("v_int", 20) .build(); - DATASTORE.put(e1, e2); + datastore.put(e1, e2); Query queryIn = Query.newEntityQueryBuilder() @@ -1095,21 +1121,21 @@ public void testInNotInNeqFilters() throws InterruptedException { PropertyFilter.eq("v_int", 10000))) .build(); - QueryResults run = DATASTORE.run(scQueryInEqOr); + QueryResults run = datastore.run(scQueryInEqOr); assertTrue(run.hasNext()); assertEquals(e1, run.next()); assertFalse(run.hasNext()); - DATASTORE.delete(e1.getKey()); - DATASTORE.delete(e2.getKey()); + datastore.delete(e1.getKey()); + datastore.delete(e2.getKey()); } @Test public void testAllocateId() { - KeyFactory keyFactory = DATASTORE.newKeyFactory().setKind(KIND1); + KeyFactory keyFactory = datastore.newKeyFactory().setKind(KIND1); IncompleteKey pk1 = keyFactory.newKey(); - Key key1 = DATASTORE.allocateId(pk1); + Key key1 = datastore.allocateId(pk1); assertEquals(key1.getProjectId(), pk1.getProjectId()); assertEquals(key1.getNamespace(), pk1.getNamespace()); assertEquals(key1.getAncestors(), pk1.getAncestors()); @@ -1118,31 +1144,31 @@ public void testAllocateId() { assertFalse(key1.hasName()); assertEquals(Key.newBuilder(pk1, key1.getId()).build(), key1); - Key key2 = DATASTORE.allocateId(pk1); + Key key2 = datastore.allocateId(pk1); assertNotEquals(key1, key2); assertEquals(Key.newBuilder(pk1, key2.getId()).build(), key2); } @Test public void testReserveIds() { - KeyFactory keyFactory = DATASTORE.newKeyFactory().setKind("MyKind"); + KeyFactory keyFactory = datastore.newKeyFactory().setKind("MyKind"); Key key1 = keyFactory.newKey(10); Key key2 = keyFactory.newKey("name"); - List keyList = DATASTORE.reserveIds(key1, key2); + List keyList = datastore.reserveIds(key1, key2); assertEquals(2, keyList.size()); } @Test public void testAllocateIdArray() { - KeyFactory keyFactory = DATASTORE.newKeyFactory().setKind(KIND1); + KeyFactory keyFactory = datastore.newKeyFactory().setKind(KIND1); IncompleteKey incompleteKey1 = keyFactory.newKey(); IncompleteKey incompleteKey2 = keyFactory .setKind(KIND2) - .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) + .setDatabaseId(options.getDatabaseId()) .addAncestors(PathElement.of(KIND1, 10)) .newKey(); - List result = DATASTORE.allocateId(incompleteKey1, incompleteKey2, incompleteKey1); + List result = datastore.allocateId(incompleteKey1, incompleteKey2, incompleteKey1); assertEquals(3, result.size()); assertEquals(Key.newBuilder(incompleteKey1, result.get(0).getId()).build(), result.get(0)); assertEquals(Key.newBuilder(incompleteKey1, result.get(2).getId()).build(), result.get(2)); @@ -1151,10 +1177,10 @@ public void testAllocateIdArray() { @Test public void testGet() { - Entity entity = DATASTORE.get(KEY3); + Entity entity = datastore.get(KEY3); assertNull(entity); - entity = DATASTORE.get(KEY1); + entity = datastore.get(KEY1); assertEquals(ENTITY1, entity); StringValue value1 = entity.getValue("str"); assertEquals(STR_VALUE, value1); @@ -1177,36 +1203,36 @@ public void testGet() { @Test public void testGetWithReadTime() throws InterruptedException { Key key = - Key.newBuilder(PROJECT_ID, "new_kind", "name", DATASTORE_OPTIONS.getDatabaseId()) + Key.newBuilder(PROJECT_ID, "new_kind", "name", options.getDatabaseId()) .setNamespace(NAMESPACE) .build(); try { - DATASTORE.put(Entity.newBuilder(key).set("str", "old_str_value").build()); + datastore.put(Entity.newBuilder(key).set("str", "old_str_value").build()); Thread.sleep(1000); Timestamp now = Timestamp.now(); Thread.sleep(1000); - DATASTORE.put(Entity.newBuilder(key).set("str", "new_str_value").build()); + datastore.put(Entity.newBuilder(key).set("str", "new_str_value").build()); - Entity entity = DATASTORE.get(key); + Entity entity = datastore.get(key); StringValue value1 = entity.getValue("str"); assertEquals(StringValue.of("new_str_value"), value1); - entity = DATASTORE.get(key, ReadOption.readTime(now)); + entity = datastore.get(key, ReadOption.readTime(now)); value1 = entity.getValue("str"); assertEquals(StringValue.of("old_str_value"), value1); } finally { - DATASTORE.delete(key); + datastore.delete(key); } } @Test public void testGetArrayNoDeferredResults() { - DATASTORE.put(ENTITY3); + datastore.put(ENTITY3); Iterator result = - DATASTORE.fetch(KEY1, Key.newBuilder(KEY1).setName("bla").build(), KEY2, KEY3).iterator(); + datastore.fetch(KEY1, Key.newBuilder(KEY1).setName("bla").build(), KEY2, KEY3).iterator(); assertEquals(ENTITY1, result.next()); assertNull(result.next()); assertEquals(ENTITY2, result.next()); @@ -1231,93 +1257,93 @@ public void testGetArrayNoDeferredResults() { // expected - no such property } assertFalse(result.hasNext()); - DATASTORE.delete(ENTITY3.getKey()); + datastore.delete(ENTITY3.getKey()); } @Test public void testAddEntity() { - List keys = DATASTORE.fetch(ENTITY1.getKey(), ENTITY3.getKey()); + List keys = datastore.fetch(ENTITY1.getKey(), ENTITY3.getKey()); assertEquals(ENTITY1, keys.get(0)); assertNull(keys.get(1)); assertEquals(2, keys.size()); try { - DATASTORE.add(ENTITY1); + datastore.add(ENTITY1); fail("Expecting a failure"); } catch (DatastoreException expected) { // expected; } - List entities = DATASTORE.add(ENTITY3, PARTIAL_ENTITY1, PARTIAL_ENTITY2); - assertEquals(ENTITY3, DATASTORE.get(ENTITY3.getKey())); + List entities = datastore.add(ENTITY3, PARTIAL_ENTITY1, PARTIAL_ENTITY2); + assertEquals(ENTITY3, datastore.get(ENTITY3.getKey())); assertEquals(ENTITY3, entities.get(0)); assertEquals(PARTIAL_ENTITY1.getNames(), entities.get(1).getNames()); assertEquals(PARTIAL_ENTITY1.getKey().getAncestors(), entities.get(1).getKey().getAncestors()); - assertNotNull(DATASTORE.get(entities.get(1).getKey())); + assertNotNull(datastore.get(entities.get(1).getKey())); assertEquals(PARTIAL_ENTITY2.getNames(), entities.get(2).getNames()); assertEquals(PARTIAL_ENTITY2.getKey().getAncestors(), entities.get(2).getKey().getAncestors()); - assertNotNull(DATASTORE.get(entities.get(2).getKey())); + assertNotNull(datastore.get(entities.get(2).getKey())); for (Entity entity : entities) { - DATASTORE.delete(entity.getKey()); + datastore.delete(entity.getKey()); } } @Test public void testUpdate() { - List keys = DATASTORE.fetch(ENTITY1.getKey(), ENTITY3.getKey()); + List keys = datastore.fetch(ENTITY1.getKey(), ENTITY3.getKey()); assertEquals(ENTITY1, keys.get(0)); assertNull(keys.get(1)); assertEquals(2, keys.size()); try { - DATASTORE.update(ENTITY3); + datastore.update(ENTITY3); fail("Expecting a failure"); } catch (DatastoreException expected) { // expected; } - DATASTORE.add(ENTITY3); - assertEquals(ENTITY3, DATASTORE.get(ENTITY3.getKey())); + datastore.add(ENTITY3); + assertEquals(ENTITY3, datastore.get(ENTITY3.getKey())); Entity entity3 = Entity.newBuilder(ENTITY3).clear().set("bla", new NullValue()).build(); assertNotEquals(ENTITY3, entity3); - DATASTORE.update(entity3); - assertEquals(entity3, DATASTORE.get(ENTITY3.getKey())); - DATASTORE.delete(ENTITY3.getKey()); + datastore.update(entity3); + assertEquals(entity3, datastore.get(ENTITY3.getKey())); + datastore.delete(ENTITY3.getKey()); } @Test public void testPut() { Entity updatedEntity = Entity.newBuilder(ENTITY1).set("new_property", 42L).build(); - assertEquals(updatedEntity, DATASTORE.put(updatedEntity)); - assertEquals(updatedEntity, DATASTORE.get(updatedEntity.getKey())); + assertEquals(updatedEntity, datastore.put(updatedEntity)); + assertEquals(updatedEntity, datastore.get(updatedEntity.getKey())); Entity entity2 = Entity.newBuilder(ENTITY2).clear().set("bla", new NullValue()).build(); assertNotEquals(ENTITY2, entity2); - List entities = DATASTORE.put(ENTITY1, entity2, ENTITY3, PARTIAL_ENTITY1); + List entities = datastore.put(ENTITY1, entity2, ENTITY3, PARTIAL_ENTITY1); assertEquals(ENTITY1, entities.get(0)); assertEquals(entity2, entities.get(1)); assertEquals(ENTITY3, entities.get(2)); assertEquals(PARTIAL_ENTITY1.getNames(), entities.get(3).getNames()); assertEquals(PARTIAL_ENTITY1.getKey().getAncestors(), entities.get(3).getKey().getAncestors()); - assertEquals(ENTITY1, DATASTORE.get(ENTITY1.getKey())); - assertEquals(entity2, DATASTORE.get(entity2.getKey())); - assertEquals(ENTITY3, DATASTORE.get(ENTITY3.getKey())); - Entity entity = DATASTORE.get(entities.get(3).getKey()); + assertEquals(ENTITY1, datastore.get(ENTITY1.getKey())); + assertEquals(entity2, datastore.get(entity2.getKey())); + assertEquals(ENTITY3, datastore.get(ENTITY3.getKey())); + Entity entity = datastore.get(entities.get(3).getKey()); assertEquals(entities.get(3), entity); for (Entity entityToDelete : entities) { - DATASTORE.delete(entityToDelete.getKey()); + datastore.delete(entityToDelete.getKey()); } } @Test public void testDelete() { Iterator keys = - DATASTORE.fetch(ENTITY1.getKey(), ENTITY2.getKey(), ENTITY3.getKey()).iterator(); + datastore.fetch(ENTITY1.getKey(), ENTITY2.getKey(), ENTITY3.getKey()).iterator(); assertEquals(ENTITY1, keys.next()); assertEquals(ENTITY2, keys.next()); assertNull(keys.next()); assertFalse(keys.hasNext()); - DATASTORE.delete(ENTITY1.getKey(), ENTITY2.getKey(), ENTITY3.getKey()); - keys = DATASTORE.fetch(ENTITY1.getKey(), ENTITY2.getKey(), ENTITY3.getKey()).iterator(); + datastore.delete(ENTITY1.getKey(), ENTITY2.getKey(), ENTITY3.getKey()); + keys = datastore.fetch(ENTITY1.getKey(), ENTITY2.getKey(), ENTITY3.getKey()).iterator(); assertNull(keys.next()); assertNull(keys.next()); assertNull(keys.next()); @@ -1342,7 +1368,7 @@ public Integer run(DatastoreReaderWriter transaction) { } }; - int result = DATASTORE.runInTransaction(callable1); + int result = datastore.runInTransaction(callable1); assertEquals(result, 2); Datastore.TransactionCallable callable2 = @@ -1361,7 +1387,7 @@ public Integer run(DatastoreReaderWriter transaction) { }; try { - DATASTORE.runInTransaction(callable2); + datastore.runInTransaction(callable2); fail("Expecting a failure"); } catch (DatastoreException expected) { assertEquals(4, ((DatastoreException) expected.getCause()).getCode()); @@ -1389,7 +1415,7 @@ public Integer run(DatastoreReaderWriter transaction) { } }; - int result = DATASTORE.runInTransaction(callable1); + int result = datastore.runInTransaction(callable1); assertEquals(result, 2); final Entity entity2 = Entity.newBuilder(ENTITY2).clear().setNull("bla").build(); @@ -1415,7 +1441,7 @@ public Integer run(DatastoreReaderWriter transaction) { .build(); try { - DATASTORE.runInTransaction(callable2, readOnlyOptions); + datastore.runInTransaction(callable2, readOnlyOptions); fail("Expecting a failure"); } catch (DatastoreException expected) { assertEquals( @@ -1427,20 +1453,20 @@ public Integer run(DatastoreReaderWriter transaction) { @Test public void testSkippedResults() { Query query = Query.newKeyQueryBuilder().setOffset(Integer.MAX_VALUE).build(); - int numberOfEntities = DATASTORE.run(query).getSkippedResults(); + int numberOfEntities = datastore.run(query).getSkippedResults(); assertEquals(2, numberOfEntities); } @Test public void testSetLimit() { - DATASTORE.put(ENTITY1); + datastore.put(ENTITY1); Query keyQuery = Query.newKeyQueryBuilder().setLimit(1).build(); - QueryResults queryResults = DATASTORE.run(keyQuery); + QueryResults queryResults = datastore.run(keyQuery); assertTrue(queryResults.hasNext()); assertEquals(KEY1, queryResults.next()); Query query = Query.newEntityQueryBuilder().setLimit(0).build(); - QueryResults results = DATASTORE.run(query); + QueryResults results = datastore.run(query); assertFalse(results.hasNext()); } @@ -1451,7 +1477,7 @@ public void testGqlQueryWithNullBinding() { .setNamespace(NAMESPACE) .setNullBinding("name") .build(); - Iterator results = DATASTORE.run(query); + Iterator results = datastore.run(query); assertTrue(results.hasNext()); assertEquals(ENTITY1, results.next()); assertFalse(results.hasNext()); @@ -1461,30 +1487,27 @@ public void testGqlQueryWithNullBinding() { public void testQueryWithStartCursor() { Entity entity1 = Entity.newBuilder( - Key.newBuilder(PROJECT_ID, KIND1, "name-01", DATASTORE_OPTIONS.getDatabaseId()) - .build()) + Key.newBuilder(PROJECT_ID, KIND1, "name-01", options.getDatabaseId()).build()) .build(); Entity entity2 = Entity.newBuilder( - Key.newBuilder(PROJECT_ID, KIND1, "name-02", DATASTORE_OPTIONS.getDatabaseId()) - .build()) + Key.newBuilder(PROJECT_ID, KIND1, "name-02", options.getDatabaseId()).build()) .build(); Entity entity3 = Entity.newBuilder( - Key.newBuilder(PROJECT_ID, KIND1, "name-03", DATASTORE_OPTIONS.getDatabaseId()) - .build()) + Key.newBuilder(PROJECT_ID, KIND1, "name-03", options.getDatabaseId()).build()) .build(); - DATASTORE.put(entity1, entity2, entity3); - QueryResults run1 = DATASTORE.run(Query.newEntityQueryBuilder().setKind(KIND1).build()); + datastore.put(entity1, entity2, entity3); + QueryResults run1 = datastore.run(Query.newEntityQueryBuilder().setKind(KIND1).build()); run1.next(); Cursor cursor1 = run1.getCursorAfter(); assertNotNull(cursor1); QueryResults run2 = - DATASTORE.run(Query.newEntityQueryBuilder().setKind(KIND1).setStartCursor(cursor1).build()); + datastore.run(Query.newEntityQueryBuilder().setKind(KIND1).setStartCursor(cursor1).build()); Cursor cursor2 = run2.getCursorAfter(); assertNotNull(cursor2); assertEquals(cursor2, cursor1); - DATASTORE.delete(entity1.getKey(), entity2.getKey(), entity3.getKey()); + datastore.delete(entity1.getKey(), entity2.getKey(), entity3.getKey()); } @Test @@ -1492,35 +1515,35 @@ public void testQueryWithReadTime() throws InterruptedException { Entity entity1 = Entity.newBuilder( Key.newBuilder(PROJECT_ID, "new_kind", "name-01") - .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) + .setDatabaseId(options.getDatabaseId()) .setNamespace(NAMESPACE) .build()) .build(); Entity entity2 = Entity.newBuilder( Key.newBuilder(PROJECT_ID, "new_kind", "name-02") - .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) + .setDatabaseId(options.getDatabaseId()) .setNamespace(NAMESPACE) .build()) .build(); Entity entity3 = Entity.newBuilder( Key.newBuilder(PROJECT_ID, "new_kind", "name-03") - .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) + .setDatabaseId(options.getDatabaseId()) .setNamespace(NAMESPACE) .build()) .build(); - DATASTORE.put(entity1, entity2); + datastore.put(entity1, entity2); Thread.sleep(1000); Timestamp now = Timestamp.now(); Thread.sleep(1000); - DATASTORE.put(entity3); + datastore.put(entity3); try { Query query = Query.newEntityQueryBuilder().setKind("new_kind").build(); - QueryResults withoutReadTime = DATASTORE.run(query); + QueryResults withoutReadTime = datastore.run(query); assertTrue(withoutReadTime.hasNext()); assertEquals(entity1, withoutReadTime.next()); assertTrue(withoutReadTime.hasNext()); @@ -1529,14 +1552,14 @@ public void testQueryWithReadTime() throws InterruptedException { assertEquals(entity3, withoutReadTime.next()); assertFalse(withoutReadTime.hasNext()); - QueryResults withReadTime = DATASTORE.run(query, ReadOption.readTime(now)); + QueryResults withReadTime = datastore.run(query, ReadOption.readTime(now)); assertTrue(withReadTime.hasNext()); assertEquals(entity1, withReadTime.next()); assertTrue(withReadTime.hasNext()); assertEquals(entity2, withReadTime.next()); assertFalse(withReadTime.hasNext()); } finally { - DATASTORE.delete(entity1.getKey(), entity2.getKey(), entity3.getKey()); + datastore.delete(entity1.getKey(), entity2.getKey(), entity3.getKey()); } } @@ -1546,7 +1569,7 @@ private void testCountAggregationWith(Consumer configu AggregationQuery aggregationQuery = builder.build(); String alias = "total_count"; - Long countBeforeAdd = getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong(alias); + Long countBeforeAdd = getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong(alias); long expectedCount = countBeforeAdd + 1; Entity newEntity = @@ -1556,12 +1579,12 @@ private void testCountAggregationWith(Consumer configu .set("partial1", PARTIAL_ENTITY2) .set("partial2", ENTITY2) .build(); - DATASTORE.put(newEntity); + datastore.put(newEntity); - Long countAfterAdd = getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong(alias); + Long countAfterAdd = getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong(alias); assertThat(countAfterAdd).isEqualTo(expectedCount); - DATASTORE.delete(newEntity.getKey()); + datastore.delete(newEntity.getKey()); } private void testCountAggregationWithLimit( @@ -1574,7 +1597,7 @@ private void testCountAggregationWithLimit( withoutLimitConfigurer.accept(withoutLimitBuilder); Long currentCount = - getOnlyElement(DATASTORE.runAggregation(withoutLimitBuilder.build())).getLong(alias); + getOnlyElement(datastore.runAggregation(withoutLimitBuilder.build())).getLong(alias); long limit = currentCount - 1; AggregationQuery.Builder withLimitBuilder = @@ -1582,7 +1605,7 @@ private void testCountAggregationWithLimit( withLimitConfigurer.accept(withLimitBuilder, limit); Long countWithLimit = - getOnlyElement(DATASTORE.runAggregation(withLimitBuilder.build())).getLong(alias); + getOnlyElement(datastore.runAggregation(withLimitBuilder.build())).getLong(alias); assertThat(countWithLimit).isEqualTo(limit); } @@ -1591,7 +1614,7 @@ private void testCountAggregationReadTimeWith(Consumer Entity entity1 = Entity.newBuilder( Key.newBuilder(PROJECT_ID, "new_kind", "name-01") - .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) + .setDatabaseId(options.getDatabaseId()) .setNamespace(NAMESPACE) .build()) .set("name", "Tyrion Lannister") @@ -1599,7 +1622,7 @@ private void testCountAggregationReadTimeWith(Consumer Entity entity2 = Entity.newBuilder( Key.newBuilder(PROJECT_ID, "new_kind", "name-02") - .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) + .setDatabaseId(options.getDatabaseId()) .setNamespace(NAMESPACE) .build()) .set("name", "Jaime Lannister") @@ -1607,17 +1630,17 @@ private void testCountAggregationReadTimeWith(Consumer Entity entity3 = Entity.newBuilder( Key.newBuilder(PROJECT_ID, "new_kind", "name-03") - .setDatabaseId(DATASTORE_OPTIONS.getDatabaseId()) + .setDatabaseId(options.getDatabaseId()) .setNamespace(NAMESPACE) .build()) .set("name", "Cersei Lannister") .build(); - DATASTORE.put(entity1, entity2); + datastore.put(entity1, entity2); Thread.sleep(1000); Timestamp now = Timestamp.now(); Thread.sleep(1000); - DATASTORE.put(entity3); + datastore.put(entity3); try { AggregationQuery.Builder builder = Query.newAggregationQueryBuilder().setNamespace(NAMESPACE); @@ -1625,15 +1648,15 @@ private void testCountAggregationReadTimeWith(Consumer AggregationQuery countAggregationQuery = builder.build(); Long latestCount = - getOnlyElement(DATASTORE.runAggregation(countAggregationQuery)).getLong("total_count"); + getOnlyElement(datastore.runAggregation(countAggregationQuery)).getLong("total_count"); assertThat(latestCount).isEqualTo(3L); Long oldCount = - getOnlyElement(DATASTORE.runAggregation(countAggregationQuery, ReadOption.readTime(now))) + getOnlyElement(datastore.runAggregation(countAggregationQuery, ReadOption.readTime(now))) .getLong("total_count"); assertThat(oldCount).isEqualTo(2L); } finally { - DATASTORE.delete(entity1.getKey(), entity2.getKey(), entity3.getKey()); + datastore.delete(entity1.getKey(), entity2.getKey(), entity3.getKey()); } } } diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/MultiDbRule.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/MultiDbRule.java deleted file mode 100644 index 099ca01ee..000000000 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/MultiDbRule.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2023 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.datastore.it; - -import com.google.cloud.datastore.Datastore; -import com.google.cloud.datastore.DatastoreOptions; -import com.google.cloud.datastore.testing.RemoteDatastoreHelper; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -public class MultiDbRule implements TestRule { - - private static final String CUSTOM_DB_ID = "test-db"; - private static final Logger logger = Logger.getLogger(MultiDbRule.class.getName()); - - private final RemoteDatastoreHelper HELPER_1; - private final DatastoreOptions OPTIONS_1; - private final Datastore DATASTORE_1; - private final RemoteDatastoreHelper HELPER_2; - private final DatastoreOptions OPTIONS_2; - private final Datastore DATASTORE_2; - - private Datastore currentDatastore; - private DatastoreOptions currentDatastoreOptions; - - public MultiDbRule() { - HELPER_1 = RemoteDatastoreHelper.create(); - OPTIONS_1 = HELPER_1.getOptions(); - - HELPER_2 = RemoteDatastoreHelper.create(CUSTOM_DB_ID); - OPTIONS_2 = HELPER_2.getOptions(); - - DATASTORE_1 = OPTIONS_1.getService(); - DATASTORE_2 = OPTIONS_2.getService(); - this.currentDatastore = DATASTORE_1; - this.currentDatastoreOptions = OPTIONS_1; - } - - @Override - public Statement apply(Statement base, Description description) { - return new Statement() { - @Override - public void evaluate() throws Throwable { - try { - String testName = description.getDisplayName(); - // running with default Datastore - logger.log( - Level.INFO, "Running {0} with database {1}", new Object[] {testName, "default"}); - base.evaluate(); - - // running with test-db Datastore - logger.log( - Level.INFO, "Running {0} with database {1}", new Object[] {testName, CUSTOM_DB_ID}); - MultiDbRule.this.currentDatastore = DATASTORE_2; - MultiDbRule.this.currentDatastoreOptions = OPTIONS_2; - base.evaluate(); - - } finally { - HELPER_1.deleteNamespace(); - HELPER_2.deleteNamespace(); - DATASTORE_1.close(); - DATASTORE_2.close(); - } - } - }; - } - - public Datastore getDatastore() { - return this.currentDatastore; - } - - public DatastoreOptions getCurrentOptions() { - return this.currentDatastoreOptions; - } -} From 508e150d584c4bdbf386af46e2e8e1040111ffcc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 17:02:17 +0000 Subject: [PATCH 25/42] deps: bump com.google.truth:truth from 1.4.1 to 1.4.2 (#1354) Bumps [com.google.truth:truth](https://togithub.com/google/truth) from 1.4.1 to 1.4.2.
Release notes

Sourced from com.google.truth:truth's releases.

1.4.2

This release is the final step of copying all our methods from Truth8 to Truth. If you have not already migrated your usages from Truth8 to Truth, you may see build errors:

OptionalSubjectTest.java:39: error: reference to assertThat is ambiguous
    assertThat(Optional.of("foo")).isPresent();
    ^
  both method assertThat(@org.checkerframework.checker.nullness.qual.Nullable Optional<?>) in Truth8 and method assertThat(@org.checkerframework.checker.nullness.qual.Nullable Optional<?>) in Truth match

In most cases, you can migrate your whole project mechanically: git grep -l Truth8 | xargs perl -pi -e 's/\bTruth8\b/Truth/g;'. (You can make that change before upgrading to Truth 1.4.2 or as part of the same commit.)

If you instead need to migrate your project incrementally (for example, because it is very large), you may want to upgrade your version of Truth incrementally, too, following our instructions for 1.3.0 and 1.4.0.

For help

Please feel welcome to open an issue to report problems or request help.

Changelog

  • Removed temporary type parameters from Truth.assertThat(Stream) and Truth.assertThat(Optional). This can create build errors, which you can fix by replacing all your references to Truth8 with references to Truth. (45782bd0e)
Commits
  • 0ca7ef0 Set version number for truth-parent to 1.4.2.
  • e3b4354 Enable a few more Guava Primitives tests for J2KT
  • ae78f4a Bump actions/setup-java from 4.0.0 to 4.1.0
  • 996a844 Remove more copies of a workaround for an ancient Android bug.
  • a43223e Suppress TruthSelfEquals violations in Truth.
  • 559d636 Suppress NullableOptional, as we already do in, e.g., `Truth.assertThat(Opt...
  • 3efe353 Automated Code Change
  • 5efd53f Change assertThat(array) to allow arrays of non-nullable elements
  • bbd8d12 Bump com.google.errorprone:error_prone_annotations from 2.24.1 to 2.25.0
  • c243961 Remove @J2ktIncompatible from StringSubject#matches
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.truth:truth&package-manager=maven&previous-version=1.4.1&new-version=1.4.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- datastore-v1-proto-client/pom.xml | 2 +- google-cloud-datastore/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/datastore-v1-proto-client/pom.xml b/datastore-v1-proto-client/pom.xml index ebeae864e..dd200d90e 100644 --- a/datastore-v1-proto-client/pom.xml +++ b/datastore-v1-proto-client/pom.xml @@ -98,7 +98,7 @@ com.google.truth truth - 1.4.1 + 1.4.2 test diff --git a/google-cloud-datastore/pom.xml b/google-cloud-datastore/pom.xml index e80fb2908..e5d32bda4 100644 --- a/google-cloud-datastore/pom.xml +++ b/google-cloud-datastore/pom.xml @@ -157,7 +157,7 @@ com.google.truth truth - 1.4.1 + 1.4.2 test From 59c2de7fbd457130f37d36ea53a5b1f20e219a2f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 17:04:16 +0000 Subject: [PATCH 26/42] deps: bump com.google.cloud:google-cloud-shared-dependencies from 3.25.0 to 3.27.0 (#1353) Bumps com.google.cloud:google-cloud-shared-dependencies from 3.25.0 to 3.27.0. [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.cloud:google-cloud-shared-dependencies&package-manager=maven&previous-version=3.25.0&new-version=3.27.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b6cb9767f..06146a2f5 100644 --- a/pom.xml +++ b/pom.xml @@ -151,7 +151,7 @@ com.google.cloud google-cloud-shared-dependencies - 3.25.0 + 3.27.0 pom import From 1123e16c877b207801bbc63abccec5418a4fd337 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 17:08:17 +0000 Subject: [PATCH 27/42] deps: bump com.google.cloud:google-cloud-shared-config from 1.7.1 to 1.7.4 (#1350) Bumps [com.google.cloud:google-cloud-shared-config](https://togithub.com/googleapis/java-shared-config) from 1.7.1 to 1.7.4.
Release notes

Sourced from com.google.cloud:google-cloud-shared-config's releases.

v1.7.4

1.7.4 (2024-02-28)

Bug Fixes

  • deps: Revert dependency org.codehaus.mojo:flatten-maven-plugin to v1.3.0 (2c3e38a)

v1.7.3

1.7.3 (2024-02-27)

Dependencies

  • Update dependency org.graalvm.sdk:graal-sdk to v22.3.5 (#751) (4d76805)

v1.7.2

1.7.2 (2024-02-26)

Bug Fixes

Dependencies

  • Update actions/github-script action to v7 (#708) (a4738d1)
  • Update dependency org.graalvm.buildtools:native-maven-plugin to v0.9.28 (#647) (28b2c77)
  • Update dependency org.junit.vintage:junit-vintage-engine to v5.10.2 (#638) (4fa0021)
Changelog

Sourced from com.google.cloud:google-cloud-shared-config's changelog.

1.7.4 (2024-02-28)

Bug Fixes

  • deps: Revert dependency org.codehaus.mojo:flatten-maven-plugin to v1.3.0 (2c3e38a)

1.7.3 (2024-02-27)

Dependencies

  • Update dependency org.graalvm.sdk:graal-sdk to v22.3.5 (#751) (4d76805)

1.7.2 (2024-02-26)

Bug Fixes

Dependencies

  • Update actions/github-script action to v7 (#708) (a4738d1)
  • Update dependency org.graalvm.buildtools:native-maven-plugin to v0.9.28 (#647) (28b2c77)
  • Update dependency org.junit.vintage:junit-vintage-engine to v5.10.2 (#638) (4fa0021)
Commits
  • 94452fc chore(main): release 1.7.4 (#769)
  • 2c3e38a Revert "build(deps): update dependency org.codehaus.mojo:flatten-maven-plugin...
  • 010e8e7 chore(main): release 1.7.4-SNAPSHOT (#765)
  • a89db76 chore(main): release 1.7.3 (#764)
  • 8afa0ad chore(main): release 1.7.3-SNAPSHOT (#761)
  • 4d76805 deps: update dependency org.graalvm.sdk:graal-sdk to v22.3.5 (#751)
  • 1be9df1 chore(main): release 1.7.2 (#733)
  • efc5fc6 build(deps): update dependency org.apache.maven.plugins:maven-javadoc-plugin ...
  • 046a932 chore: remove Kokoro - Docker Image Validation check (#758)
  • 927909b chore: fix storage downstream check to use sdk-platform-java-config artifact ...
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.cloud:google-cloud-shared-config&package-manager=maven&previous-version=1.7.1&new-version=1.7.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- google-cloud-datastore-bom/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/google-cloud-datastore-bom/pom.xml b/google-cloud-datastore-bom/pom.xml index 8620ce3a6..0ba852d58 100644 --- a/google-cloud-datastore-bom/pom.xml +++ b/google-cloud-datastore-bom/pom.xml @@ -8,7 +8,7 @@ com.google.cloud google-cloud-shared-config - 1.7.1 + 1.7.4 Google Cloud datastore BOM diff --git a/pom.xml b/pom.xml index 06146a2f5..630267d80 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ com.google.cloud google-cloud-shared-config - 1.7.1 + 1.7.4 From 45df7f5b76b9b978fa55754be4777de93990fda7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:34:16 +0000 Subject: [PATCH 28/42] deps: bump com.google.errorprone:error_prone_core from 2.25.0 to 2.26.0 (#1362) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [com.google.errorprone:error_prone_core](https://togithub.com/google/error-prone) from 2.25.0 to 2.26.0.
Release notes

Sourced from com.google.errorprone:error_prone_core's releases.

Error Prone 2.26.0

Changes:

  • The 'annotations' artifact now includes a module-info.java for Java Platform Module System support, thanks to @​sgammon in #4311.
  • Disabled checks passed to -XepPatchChecks are now ignored, instead of causing a crash. Thanks to @​oxkitsune in #4028.

New checks:

  • SystemConsoleNull: Null-checking System.console() is not a reliable way to detect if the console is connected to a terminal.
  • EnumOrdinal: Discourage uses of Enum.ordinal()

Closed issues: #2649, #3908, #4028, #4311, #4314

Full Changelog: https://togithub.com/google/error-prone/compare/v2.25.0...v2.26.0

Commits
  • ad1c05b Release Error Prone 2.26.0
  • ea5ef6d Add the 'compile' goal for 'compile-java9'
  • 0e95364 feat: add jpms definition for annotations
  • 9da2d55 Ignore disabled checks passed to -XepPatchChecks
  • 3292632 Increase year range on Date usages.
  • ad513d5 Recommend using var for var unused = ...; and `var thrown = assertThrows(...
  • af37d35 ImpossibleNullComparison: emit empty fixes.
  • 297019c Fix some mistakes in the EnumOrdinal examples
  • f3dbb09 Move the EnumOrdinal.md doc to the right place (it got overwritten by automat...
  • f768b0b Fix handling of default cases in arrow switches
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.errorprone:error_prone_core&package-manager=maven&previous-version=2.25.0&new-version=2.26.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 630267d80..3a44442cd 100644 --- a/pom.xml +++ b/pom.xml @@ -143,7 +143,7 @@ github google-cloud-datastore-parent https://googleapis.dev/java/google-api-grpc/latest - 2.25.0 + 2.26.0 From 2bdadba42845144833d34c09f9fed2d888d244f9 Mon Sep 17 00:00:00 2001 From: kolea2 <45548808+kolea2@users.noreply.github.com> Date: Wed, 13 Mar 2024 12:25:39 -0400 Subject: [PATCH 29/42] test: parameterize tests for http and grpc transports (#1360) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Revert "test: Creating multi db rule to run tests multiple times against different named databases. (#1270)" This reverts commit 780c9f40f1ae04d0ec919d203bf256e3cff8fcc1. * test: run on both grpc and http transports * merge aggregation ITs with abstract test * cleanup * fix test cleanups * test * fix tests * fix again * 🦉 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 --- README.md | 8 +- .../testing/RemoteDatastoreHelper.java | 15 +- ...Test.java => AbstractITDatastoreTest.java} | 368 ++++++++++++++++-- .../it/ITDatastoreAggregationsTest.java | 367 ----------------- .../datastore/it/ITDatastoreTestGrpc.java | 59 +++ .../datastore/it/ITDatastoreTestHttp.java | 61 +++ .../cloud/datastore/it/StatementExecutor.java | 7 +- 7 files changed, 465 insertions(+), 420 deletions(-) rename google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/{ITDatastoreTest.java => AbstractITDatastoreTest.java} (83%) delete mode 100644 google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java create mode 100644 google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestGrpc.java create mode 100644 google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestHttp.java diff --git a/README.md b/README.md index 17e717738..c582f2b63 100644 --- a/README.md +++ b/README.md @@ -50,20 +50,20 @@ If you are using Maven without the BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies: ```Groovy -implementation platform('com.google.cloud:libraries-bom:26.33.0') +implementation platform('com.google.cloud:libraries-bom:26.34.0') implementation 'com.google.cloud:google-cloud-datastore' ``` If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-datastore:2.18.4' +implementation 'com.google.cloud:google-cloud-datastore:2.18.5' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.18.4" +libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.18.5" ``` @@ -380,7 +380,7 @@ Java is a registered trademark of Oracle and/or its affiliates. [kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-datastore/java11.html [stability-image]: https://img.shields.io/badge/stability-stable-green [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-datastore.svg -[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-datastore/2.18.4 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-datastore/2.18.5 [authentication]: https://github.com/googleapis/google-cloud-java#authentication [auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes [predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/RemoteDatastoreHelper.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/RemoteDatastoreHelper.java index cb1d96309..329b20dca 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/RemoteDatastoreHelper.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/RemoteDatastoreHelper.java @@ -18,13 +18,13 @@ import com.google.api.core.InternalApi; import com.google.api.gax.retrying.RetrySettings; +import com.google.cloud.TransportOptions; import com.google.cloud.datastore.Datastore; import com.google.cloud.datastore.DatastoreOptions; import com.google.cloud.datastore.Key; import com.google.cloud.datastore.Query; import com.google.cloud.datastore.QueryResults; import com.google.cloud.datastore.StructuredQuery; -import com.google.cloud.grpc.GrpcTransportOptions; import com.google.cloud.http.HttpTransportOptions; import java.util.UUID; import org.threeten.bp.Duration; @@ -75,12 +75,19 @@ public void deleteNamespace() { /** Creates a {@code RemoteStorageHelper} object. */ public static RemoteDatastoreHelper create() { - return create(""); + return create("", DatastoreOptions.getDefaultGrpcTransportOptions()); } - /** Creates a {@code RemoteStorageHelper} object. */ public static RemoteDatastoreHelper create(String databaseId) { - GrpcTransportOptions transportOptions = DatastoreOptions.getDefaultGrpcTransportOptions(); + return create(databaseId, DatastoreOptions.getDefaultGrpcTransportOptions()); + } + + public static RemoteDatastoreHelper create(TransportOptions transportOptions) { + return create("", transportOptions); + } + + /** Creates a {@code RemoteStorageHelper} object. */ + public static RemoteDatastoreHelper create(String databaseId, TransportOptions transportOptions) { DatastoreOptions datastoreOption = DatastoreOptions.newBuilder() .setDatabaseId(databaseId) diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java similarity index 83% rename from google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java rename to google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java index 3f00fe2cf..357471abc 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java @@ -17,7 +17,9 @@ package com.google.cloud.datastore.it; import static com.google.api.gax.rpc.StatusCode.Code.INVALID_ARGUMENT; +import static com.google.cloud.datastore.aggregation.Aggregation.avg; import static com.google.cloud.datastore.aggregation.Aggregation.count; +import static com.google.cloud.datastore.aggregation.Aggregation.sum; import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; @@ -32,6 +34,7 @@ import com.google.cloud.Timestamp; import com.google.cloud.Tuple; import com.google.cloud.datastore.AggregationQuery; +import com.google.cloud.datastore.AggregationResult; import com.google.cloud.datastore.Batch; import com.google.cloud.datastore.BooleanValue; import com.google.cloud.datastore.Cursor; @@ -67,52 +70,40 @@ import com.google.cloud.datastore.TimestampValue; import com.google.cloud.datastore.Transaction; import com.google.cloud.datastore.ValueType; -import com.google.cloud.datastore.testing.RemoteDatastoreHelper; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.datastore.v1.TransactionOptions; import com.google.datastore.v1.TransactionOptions.ReadOnly; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.function.BiConsumer; import java.util.function.Consumer; import org.junit.After; -import org.junit.AfterClass; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.Timeout; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -@RunWith(Parameterized.class) -public class ITDatastoreTest { +public abstract class AbstractITDatastoreTest { + protected static final String CUSTOM_DB_ID = "test-db"; - private static final RemoteDatastoreHelper HELPER = RemoteDatastoreHelper.create(); - private static final DatastoreOptions OPTIONS_1 = HELPER.getOptions(); - private static final Datastore DATASTORE_1 = OPTIONS_1.getService(); - - private static final String CUSTOM_DB_ID = "test-db"; - private static final RemoteDatastoreHelper HELPER2 = RemoteDatastoreHelper.create(CUSTOM_DB_ID); - private static final DatastoreOptions OPTIONS_2 = HELPER2.getOptions(); - private static final Datastore DATASTORE_2 = OPTIONS_2.getService(); - - private final DatastoreOptions options; - private final Datastore datastore; + protected DatastoreOptions options; + protected Datastore datastore; private static String PROJECT_ID; private static String NAMESPACE; private static final String KIND1 = "kind1"; private static final String KIND2 = "kind2"; private static final String KIND3 = "kind3"; + private static final String MARKS_KIND = "Marks"; private static final NullValue NULL_VALUE = NullValue.of(); private static final StringValue STR_VALUE = StringValue.of("str"); private static final BooleanValue BOOL_VALUE = @@ -139,18 +130,29 @@ public class ITDatastoreTest { private static Entity ENTITY2; private static Entity ENTITY3; + private static Entity AGGREGATION_ENTITY_1; + private static Entity AGGREGATION_ENTITY_2; + private static Entity AGGREGATION_ENTITY_3; + @Rule public Timeout globalTimeout = Timeout.seconds(100); @Rule public MultipleAttemptsRule multipleAttemptsRule = new MultipleAttemptsRule(3); - @AfterClass - public static void afterClass() throws Exception { - HELPER.deleteNamespace(); - DATASTORE_1.close(); - DATASTORE_2.close(); + @Before + public void setUp() { + datastore.put(ENTITY1, ENTITY2); + } + + @After + public void tearDown() { + EntityQuery allEntitiesQuery = Query.newEntityQueryBuilder().build(); + QueryResults allEntities = datastore.run(allEntitiesQuery); + Key[] keysToDelete = + ImmutableList.copyOf(allEntities).stream().map(Entity::getKey).toArray(Key[]::new); + datastore.delete(keysToDelete); } - public ITDatastoreTest( + public AbstractITDatastoreTest( DatastoreOptions options, Datastore datastore, // databaseType is unused as a variable, but used as a parameterized label when running tests @@ -227,26 +229,29 @@ public ITDatastoreTest( .set("partial1", PARTIAL_ENTITY2) .set("partial2", ENTITY2) .build(); - } - @Before - public void setUp() { - datastore.put(ENTITY1, ENTITY2); - } - - @After - public void tearDown() { - EntityQuery allEntitiesQuery = Query.newEntityQueryBuilder().build(); - QueryResults allEntities = datastore.run(allEntitiesQuery); - Key[] keysToDelete = - ImmutableList.copyOf(allEntities).stream().map(Entity::getKey).toArray(Key[]::new); - datastore.delete(keysToDelete); - } + Key aggregationKey1 = datastore.newKeyFactory().setKind(MARKS_KIND).newKey(1); + Key aggregationKey2 = datastore.newKeyFactory().setKind(MARKS_KIND).newKey(2); + Key aggregationKey3 = datastore.newKeyFactory().setKind(MARKS_KIND).newKey(3); - @Parameterized.Parameters(name = "database: {2}") - public static Iterable data() { - return Arrays.asList( - new Object[][] {{OPTIONS_1, DATASTORE_1, "default"}, {OPTIONS_2, DATASTORE_2, "test-db"}}); + AGGREGATION_ENTITY_1 = + Entity.newBuilder(aggregationKey1) + .set("name", "Person1") + .set("marks", 89) + .set("cgpa", 7.34) + .build(); + AGGREGATION_ENTITY_2 = + Entity.newBuilder(aggregationKey2) + .set("name", "Person2") + .set("marks", 95) + .set("cgpa", 9.27) + .build(); + AGGREGATION_ENTITY_3 = + Entity.newBuilder(aggregationKey3) + .set("name", "Person3") + .set("marks", 55) + .set("cgpa", 5.16) + .build(); } private Iterator getStronglyConsistentResults(Query scQuery, Query query) @@ -1563,6 +1568,285 @@ public void testQueryWithReadTime() throws InterruptedException { } } + @Test + public void testSumAggregation() { + datastore.put(AGGREGATION_ENTITY_1, AGGREGATION_ENTITY_2); + + EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(MARKS_KIND).build(); + AggregationQuery aggregationQuery = + Query.newAggregationQueryBuilder() + .over(baseQuery) + .addAggregations(sum("marks").as("total_marks")) + .setNamespace(NAMESPACE) + .build(); + + // sum of 2 entities + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("total_marks")) + .isEqualTo(184L); + + // sum of 3 entities + datastore.put(AGGREGATION_ENTITY_3); + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("total_marks")) + .isEqualTo(239L); + } + + @Test + public void testSumAggregationWithAutoGeneratedAlias() { + datastore.put(AGGREGATION_ENTITY_1, AGGREGATION_ENTITY_2); + + EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(MARKS_KIND).build(); + AggregationQuery aggregationQuery = + Query.newAggregationQueryBuilder() + .over(baseQuery) + .addAggregations(sum("marks")) + .setNamespace(NAMESPACE) + .build(); + + // sum of 2 entities + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("property_1")) + .isEqualTo(184L); + + // sum of 3 entities + datastore.put(AGGREGATION_ENTITY_3); + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("property_1")) + .isEqualTo(239L); + } + + @Test + public void testSumAggregationInGqlQuery() { + datastore.put(AGGREGATION_ENTITY_1, AGGREGATION_ENTITY_2); + + GqlQuery gqlQuery = + GqlQuery.newGqlQueryBuilder( + "AGGREGATE SUM(marks) AS total_marks OVER (SELECT * FROM Marks)") + .build(); + + AggregationQuery aggregationQuery = + Query.newAggregationQueryBuilder().over(gqlQuery).setNamespace(NAMESPACE).build(); + + // sum of 2 entities + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("total_marks")) + .isEqualTo(184L); + + // sum of 3 entities + datastore.put(AGGREGATION_ENTITY_3); + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("total_marks")) + .isEqualTo(239L); + } + + @Test + public void testSumAggregationWithResultOfDoubleType() { + datastore.put(AGGREGATION_ENTITY_1, AGGREGATION_ENTITY_2); + + EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(MARKS_KIND).build(); + AggregationQuery aggregationQuery = + Query.newAggregationQueryBuilder() + .over(baseQuery) + .addAggregations(sum("cgpa").as("total_cgpa")) + .setNamespace(NAMESPACE) + .build(); + + // sum of 2 entities + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getDouble("total_cgpa")) + .isEqualTo(16.61); + + // sum of 3 entities + datastore.put(AGGREGATION_ENTITY_3); + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getDouble("total_cgpa")) + .isEqualTo(21.77); + } + + @Test + public void testAvgAggregation() { + datastore.put(AGGREGATION_ENTITY_1, AGGREGATION_ENTITY_2); + + EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(MARKS_KIND).build(); + AggregationQuery aggregationQuery = + Query.newAggregationQueryBuilder() + .over(baseQuery) + .addAggregations(avg("marks").as("avg_marks")) + .setNamespace(NAMESPACE) + .build(); + + // avg of 2 entities + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getDouble("avg_marks")) + .isEqualTo(92D); + + // avg of 3 entities + datastore.put(AGGREGATION_ENTITY_3); + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getDouble("avg_marks")) + .isEqualTo(79.66666666666667); + } + + @Test + public void testAvgAggregationWithAutoGeneratedAlias() { + datastore.put(AGGREGATION_ENTITY_1, AGGREGATION_ENTITY_2); + + EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(MARKS_KIND).build(); + AggregationQuery aggregationQuery = + Query.newAggregationQueryBuilder() + .over(baseQuery) + .addAggregations(avg("marks")) + .setNamespace(NAMESPACE) + .build(); + + // avg of 2 entities + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getDouble("property_1")) + .isEqualTo(92D); + + // avg of 3 entities + datastore.put(AGGREGATION_ENTITY_3); + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getDouble("property_1")) + .isEqualTo(79.66666666666667); + } + + @Test + public void testAvgAggregationInGqlQuery() { + datastore.put(AGGREGATION_ENTITY_1, AGGREGATION_ENTITY_2); + + GqlQuery gqlQuery = + Query.newGqlQueryBuilder("AGGREGATE AVG(marks) AS avg_marks OVER (SELECT * FROM Marks)") + .build(); + + AggregationQuery aggregationQuery = + Query.newAggregationQueryBuilder().over(gqlQuery).setNamespace(NAMESPACE).build(); + + // avg of 2 entities + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getDouble("avg_marks")) + .isEqualTo(92D); + + // avg of 3 entities + datastore.put(AGGREGATION_ENTITY_3); + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getDouble("avg_marks")) + .isEqualTo(79.66666666666667); + } + + @Test + public void testSumAndAvgAggregationTogether() { + datastore.put(AGGREGATION_ENTITY_1, AGGREGATION_ENTITY_2); + + EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(MARKS_KIND).build(); + AggregationQuery aggregationQuery = + Query.newAggregationQueryBuilder() + .over(baseQuery) + .addAggregations(sum("marks").as("total_marks")) + .addAggregations(avg("marks").as("avg_marks")) + .setNamespace(NAMESPACE) + .build(); + + // sum of 2 entities + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("total_marks")) + .isEqualTo(184L); + // avg of 2 entities + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getDouble("avg_marks")) + .isEqualTo(92D); + } + + @Test + public void testTransactionShouldReturnAConsistentSnapshot() { + datastore.put(AGGREGATION_ENTITY_1, AGGREGATION_ENTITY_2); + + EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(MARKS_KIND).build(); + AggregationQuery aggregationQuery = + Query.newAggregationQueryBuilder() + .over(baseQuery) + .addAggregation(count().as("count")) + .addAggregations(sum("marks").as("total_marks")) + .addAggregations(avg("marks").as("avg_marks")) + .setNamespace(NAMESPACE) + .build(); + + // original entity count is 2 + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) + .isEqualTo(2L); + + // FIRST TRANSACTION + datastore.runInTransaction( + (TransactionCallable) + inFirstTransaction -> { + // creating a new entity + inFirstTransaction.put(AGGREGATION_ENTITY_3); + + // aggregation result consistently being produced for original 2 entities + AggregationResult aggregationResult = + getOnlyElement(inFirstTransaction.runAggregation(aggregationQuery)); + assertThat(aggregationResult.getLong("count")).isEqualTo(2L); + assertThat(aggregationResult.getLong("total_marks")).isEqualTo(184L); + assertThat(aggregationResult.getDouble("avg_marks")).isEqualTo(92D); + return null; + }); + + // after first transaction is committed, we have 3 entities now. + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) + .isEqualTo(3L); + + // SECOND TRANSACTION + datastore.runInTransaction( + (TransactionCallable) + inSecondTransaction -> { + // deleting ENTITY3 + inSecondTransaction.delete(AGGREGATION_ENTITY_3.getKey()); + + // aggregation result still coming for 3 entities + AggregationResult aggregationResult = + getOnlyElement(inSecondTransaction.runAggregation(aggregationQuery)); + assertThat(aggregationResult.getLong("count")).isEqualTo(3L); + assertThat(aggregationResult.getLong("total_marks")).isEqualTo(239L); + assertThat(aggregationResult.getDouble("avg_marks")).isEqualTo(79.66666666666667); + return null; + }); + + // after second transaction is committed, we are back to 2 entities now. + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) + .isEqualTo(2L); + } + + @Test + public void testReadOnlyTransactionShouldNotLockTheDocuments() + throws ExecutionException, InterruptedException { + ExecutorService executor = Executors.newSingleThreadExecutor(); + datastore.put(AGGREGATION_ENTITY_1, AGGREGATION_ENTITY_2); + + EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(MARKS_KIND).build(); + AggregationQuery aggregationQuery = + Query.newAggregationQueryBuilder() + .over(baseQuery) + .addAggregation(count().as("count")) + .addAggregations(sum("marks").as("total_marks")) + .addAggregations(avg("marks").as("avg_marks")) + .setNamespace(NAMESPACE) + .build(); + + TransactionOptions transactionOptions = + TransactionOptions.newBuilder().setReadOnly(ReadOnly.newBuilder().build()).build(); + Transaction readOnlyTransaction = datastore.newTransaction(transactionOptions); + + // Executing query in transaction, results for original 2 entities + AggregationResult aggregationResult = + getOnlyElement(readOnlyTransaction.runAggregation(aggregationQuery)); + assertThat(aggregationResult.getLong("count")).isEqualTo(2L); + assertThat(aggregationResult.getLong("total_marks")).isEqualTo(184L); + assertThat(aggregationResult.getDouble("avg_marks")).isEqualTo(92D); + + // Concurrent write task. + Future addNewEntityTaskOutsideTransaction = + executor.submit( + () -> { + datastore.put(AGGREGATION_ENTITY_3); + return null; + }); + + // should not throw exception and complete successfully as the ongoing transaction is read-only. + addNewEntityTaskOutsideTransaction.get(); + + // cleanup + readOnlyTransaction.commit(); + executor.shutdownNow(); + + assertThat(getOnlyElement(datastore.runAggregation(aggregationQuery)).getLong("count")) + .isEqualTo(3L); + } + private void testCountAggregationWith(Consumer configurer) { AggregationQuery.Builder builder = Query.newAggregationQueryBuilder().setNamespace(NAMESPACE); configurer.accept(builder); diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java deleted file mode 100644 index e04f5e55f..000000000 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreAggregationsTest.java +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright 2023 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.datastore.it; - -import static com.google.cloud.datastore.aggregation.Aggregation.avg; -import static com.google.cloud.datastore.aggregation.Aggregation.count; -import static com.google.cloud.datastore.aggregation.Aggregation.sum; -import static com.google.common.collect.Iterables.getOnlyElement; -import static com.google.common.truth.Truth.assertThat; - -import com.google.cloud.datastore.AggregationQuery; -import com.google.cloud.datastore.AggregationResult; -import com.google.cloud.datastore.Datastore; -import com.google.cloud.datastore.Datastore.TransactionCallable; -import com.google.cloud.datastore.DatastoreOptions; -import com.google.cloud.datastore.Entity; -import com.google.cloud.datastore.EntityQuery; -import com.google.cloud.datastore.GqlQuery; -import com.google.cloud.datastore.Key; -import com.google.cloud.datastore.Query; -import com.google.cloud.datastore.QueryResults; -import com.google.cloud.datastore.Transaction; -import com.google.cloud.datastore.testing.RemoteDatastoreHelper; -import com.google.common.collect.ImmutableList; -import com.google.datastore.v1.TransactionOptions; -import com.google.datastore.v1.TransactionOptions.ReadOnly; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Test; - -// TODO(jainsahab) Move all the aggregation related tests from ITDatastoreTest to this file -public class ITDatastoreAggregationsTest { - - private static final RemoteDatastoreHelper HELPER = RemoteDatastoreHelper.create(); - private static final DatastoreOptions OPTIONS = HELPER.getOptions(); - private static final Datastore DATASTORE = OPTIONS.getService(); - - private static final String KIND = "Marks"; - - @After - public void tearDown() { - EntityQuery allEntitiesQuery = Query.newEntityQueryBuilder().build(); - QueryResults allEntities = DATASTORE.run(allEntitiesQuery); - Key[] keysToDelete = - ImmutableList.copyOf(allEntities).stream().map(Entity::getKey).toArray(Key[]::new); - DATASTORE.delete(keysToDelete); - } - - @AfterClass - public static void afterClass() throws Exception { - DATASTORE.close(); - } - - Key key1 = DATASTORE.newKeyFactory().setKind(KIND).newKey(1); - Key key2 = DATASTORE.newKeyFactory().setKind(KIND).newKey(2); - Key key3 = DATASTORE.newKeyFactory().setKind(KIND).newKey(3); - - Entity entity1 = - Entity.newBuilder(key1).set("name", "Jon Stark").set("marks", 89).set("cgpa", 7.34).build(); - Entity entity2 = - Entity.newBuilder(key2).set("name", "Arya Stark").set("marks", 95).set("cgpa", 9.27).build(); - Entity entity3 = - Entity.newBuilder(key3).set("name", "Night king").set("marks", 55).set("cgpa", 5.16).build(); - - @Test - public void testSumAggregation() { - DATASTORE.put(entity1, entity2); - - EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(KIND).build(); - AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder() - .over(baseQuery) - .addAggregations(sum("marks").as("total_marks")) - .setNamespace(OPTIONS.getNamespace()) - .build(); - - // sum of 2 entities - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("total_marks")) - .isEqualTo(184L); - - // sum of 3 entities - DATASTORE.put(entity3); - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("total_marks")) - .isEqualTo(239L); - } - - @Test - public void testSumAggregationWithAutoGeneratedAlias() { - DATASTORE.put(entity1, entity2); - - EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(KIND).build(); - AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder() - .over(baseQuery) - .addAggregations(sum("marks")) - .setNamespace(OPTIONS.getNamespace()) - .build(); - - // sum of 2 entities - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("property_1")) - .isEqualTo(184L); - - // sum of 3 entities - DATASTORE.put(entity3); - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("property_1")) - .isEqualTo(239L); - } - - @Test - public void testSumAggregationInGqlQuery() { - DATASTORE.put(entity1, entity2); - - GqlQuery gqlQuery = - GqlQuery.newGqlQueryBuilder( - "AGGREGATE SUM(marks) AS total_marks OVER (SELECT * FROM Marks)") - .build(); - - AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder() - .over(gqlQuery) - .setNamespace(OPTIONS.getNamespace()) - .build(); - - // sum of 2 entities - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("total_marks")) - .isEqualTo(184L); - - // sum of 3 entities - DATASTORE.put(entity3); - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("total_marks")) - .isEqualTo(239L); - } - - @Test - public void testSumAggregationWithResultOfDoubleType() { - DATASTORE.put(entity1, entity2); - - EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(KIND).build(); - AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder() - .over(baseQuery) - .addAggregations(sum("cgpa").as("total_cgpa")) - .setNamespace(OPTIONS.getNamespace()) - .build(); - - // sum of 2 entities - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getDouble("total_cgpa")) - .isEqualTo(16.61); - - // sum of 3 entities - DATASTORE.put(entity3); - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getDouble("total_cgpa")) - .isEqualTo(21.77); - } - - @Test - public void testAvgAggregation() { - DATASTORE.put(entity1, entity2); - - EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(KIND).build(); - AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder() - .over(baseQuery) - .addAggregations(avg("marks").as("avg_marks")) - .setNamespace(OPTIONS.getNamespace()) - .build(); - - // avg of 2 entities - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getDouble("avg_marks")) - .isEqualTo(92D); - - // avg of 3 entities - DATASTORE.put(entity3); - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getDouble("avg_marks")) - .isEqualTo(79.66666666666667); - } - - @Test - public void testAvgAggregationWithAutoGeneratedAlias() { - DATASTORE.put(entity1, entity2); - - EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(KIND).build(); - AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder() - .over(baseQuery) - .addAggregations(avg("marks")) - .setNamespace(OPTIONS.getNamespace()) - .build(); - - // avg of 2 entities - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getDouble("property_1")) - .isEqualTo(92D); - - // avg of 3 entities - DATASTORE.put(entity3); - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getDouble("property_1")) - .isEqualTo(79.66666666666667); - } - - @Test - public void testAvgAggregationInGqlQuery() { - DATASTORE.put(entity1, entity2); - - GqlQuery gqlQuery = - Query.newGqlQueryBuilder("AGGREGATE AVG(marks) AS avg_marks OVER (SELECT * FROM Marks)") - .build(); - - AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder() - .over(gqlQuery) - .setNamespace(OPTIONS.getNamespace()) - .build(); - - // avg of 2 entities - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getDouble("avg_marks")) - .isEqualTo(92D); - - // avg of 3 entities - DATASTORE.put(entity3); - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getDouble("avg_marks")) - .isEqualTo(79.66666666666667); - } - - @Test - public void testSumAndAvgAggregationTogether() { - DATASTORE.put(entity1, entity2); - - EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(KIND).build(); - AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder() - .over(baseQuery) - .addAggregations(sum("marks").as("total_marks")) - .addAggregations(avg("marks").as("avg_marks")) - .setNamespace(OPTIONS.getNamespace()) - .build(); - - // sum of 2 entities - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("total_marks")) - .isEqualTo(184L); - // avg of 2 entities - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getDouble("avg_marks")) - .isEqualTo(92D); - } - - @Test - public void testTransactionShouldReturnAConsistentSnapshot() { - DATASTORE.put(entity1, entity2); - - EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(KIND).build(); - AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder() - .over(baseQuery) - .addAggregation(count().as("count")) - .addAggregations(sum("marks").as("total_marks")) - .addAggregations(avg("marks").as("avg_marks")) - .setNamespace(OPTIONS.getNamespace()) - .build(); - - // original entity count is 2 - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) - .isEqualTo(2L); - - // FIRST TRANSACTION - DATASTORE.runInTransaction( - (TransactionCallable) - inFirstTransaction -> { - // creating a new entity - inFirstTransaction.put(entity3); - - // aggregation result consistently being produced for original 2 entities - AggregationResult aggregationResult = - getOnlyElement(inFirstTransaction.runAggregation(aggregationQuery)); - assertThat(aggregationResult.getLong("count")).isEqualTo(2L); - assertThat(aggregationResult.getLong("total_marks")).isEqualTo(184L); - assertThat(aggregationResult.getDouble("avg_marks")).isEqualTo(92D); - return null; - }); - - // after first transaction is committed, we have 3 entities now. - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) - .isEqualTo(3L); - - // SECOND TRANSACTION - DATASTORE.runInTransaction( - (TransactionCallable) - inSecondTransaction -> { - // deleting ENTITY3 - inSecondTransaction.delete(entity3.getKey()); - - // aggregation result still coming for 3 entities - AggregationResult aggregationResult = - getOnlyElement(inSecondTransaction.runAggregation(aggregationQuery)); - assertThat(aggregationResult.getLong("count")).isEqualTo(3L); - assertThat(aggregationResult.getLong("total_marks")).isEqualTo(239L); - assertThat(aggregationResult.getDouble("avg_marks")).isEqualTo(79.66666666666667); - return null; - }); - - // after second transaction is committed, we are back to 2 entities now. - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) - .isEqualTo(2L); - } - - @Test - public void testReadOnlyTransactionShouldNotLockTheDocuments() - throws ExecutionException, InterruptedException { - ExecutorService executor = Executors.newSingleThreadExecutor(); - DATASTORE.put(entity1, entity2); - - EntityQuery baseQuery = Query.newEntityQueryBuilder().setKind(KIND).build(); - AggregationQuery aggregationQuery = - Query.newAggregationQueryBuilder() - .over(baseQuery) - .addAggregation(count().as("count")) - .addAggregations(sum("marks").as("total_marks")) - .addAggregations(avg("marks").as("avg_marks")) - .setNamespace(OPTIONS.getNamespace()) - .build(); - - TransactionOptions transactionOptions = - TransactionOptions.newBuilder().setReadOnly(ReadOnly.newBuilder().build()).build(); - Transaction readOnlyTransaction = DATASTORE.newTransaction(transactionOptions); - - // Executing query in transaction, results for original 2 entities - AggregationResult aggregationResult = - getOnlyElement(readOnlyTransaction.runAggregation(aggregationQuery)); - assertThat(aggregationResult.getLong("count")).isEqualTo(2L); - assertThat(aggregationResult.getLong("total_marks")).isEqualTo(184L); - assertThat(aggregationResult.getDouble("avg_marks")).isEqualTo(92D); - - // Concurrent write task. - Future addNewEntityTaskOutsideTransaction = - executor.submit( - () -> { - DATASTORE.put(entity3); - return null; - }); - - // should not throw exception and complete successfully as the ongoing transaction is read-only. - addNewEntityTaskOutsideTransaction.get(); - - // cleanup - readOnlyTransaction.commit(); - executor.shutdownNow(); - - assertThat(getOnlyElement(DATASTORE.runAggregation(aggregationQuery)).getLong("count")) - .isEqualTo(3L); - } -} diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestGrpc.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestGrpc.java new file mode 100644 index 000000000..d9acbd088 --- /dev/null +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestGrpc.java @@ -0,0 +1,59 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.cloud.datastore.it; + +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.testing.RemoteDatastoreHelper; +import java.util.Arrays; +import org.junit.AfterClass; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class ITDatastoreTestGrpc extends AbstractITDatastoreTest { + // setup for default db, grpc transport + protected static final RemoteDatastoreHelper HELPER_DEFAULT_GRPC = RemoteDatastoreHelper.create(); + private static final DatastoreOptions OPTIONS_DEFAULT_GRPC = HELPER_DEFAULT_GRPC.getOptions(); + private static final Datastore DATASTORE_DEFAULT_GRPC = OPTIONS_DEFAULT_GRPC.getService(); + + // setup for custom db, grpc transport + private static final RemoteDatastoreHelper HELPER_CUSTOM_DB_GRPC = + RemoteDatastoreHelper.create(CUSTOM_DB_ID); + private static final DatastoreOptions OPTIONS_CUSTOM_DB_GRPC = HELPER_CUSTOM_DB_GRPC.getOptions(); + private static final Datastore DATASTORE_CUSTOM_DB_GRPC = OPTIONS_CUSTOM_DB_GRPC.getService(); + + public ITDatastoreTestGrpc(DatastoreOptions options, Datastore datastore, String databaseType) { + super(options, datastore, databaseType); + } + + @Parameterized.Parameters(name = "database: {2}") + public static Iterable data() { + return Arrays.asList( + new Object[][] { + {OPTIONS_DEFAULT_GRPC, DATASTORE_DEFAULT_GRPC, "default"}, + {OPTIONS_CUSTOM_DB_GRPC, DATASTORE_CUSTOM_DB_GRPC, CUSTOM_DB_ID}, + }); + } + + @AfterClass + public static void afterClass() throws Exception { + HELPER_DEFAULT_GRPC.deleteNamespace(); + HELPER_CUSTOM_DB_GRPC.deleteNamespace(); + DATASTORE_DEFAULT_GRPC.close(); + DATASTORE_CUSTOM_DB_GRPC.close(); + } +} diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestHttp.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestHttp.java new file mode 100644 index 000000000..0a453bbb4 --- /dev/null +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestHttp.java @@ -0,0 +1,61 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.cloud.datastore.it; + +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.testing.RemoteDatastoreHelper; +import com.google.cloud.http.HttpTransportOptions; +import java.util.Arrays; +import org.junit.AfterClass; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class ITDatastoreTestHttp extends AbstractITDatastoreTest { + // setup for default db, http transport + private static final RemoteDatastoreHelper HELPER_DEFAULT_HTTP = + RemoteDatastoreHelper.create(HttpTransportOptions.newBuilder().build()); + private static final DatastoreOptions OPTIONS_DEFAULT_HTTP = HELPER_DEFAULT_HTTP.getOptions(); + private static final Datastore DATASTORE_DEFAULT_HTTP = OPTIONS_DEFAULT_HTTP.getService(); + + // setup for custom db, http transport + private static final RemoteDatastoreHelper HELPER_CUSTOM_DB_HTTP = + RemoteDatastoreHelper.create(CUSTOM_DB_ID, HttpTransportOptions.newBuilder().build()); + private static final DatastoreOptions OPTIONS_CUSTOM_DB_HTTP = HELPER_CUSTOM_DB_HTTP.getOptions(); + private static final Datastore DATASTORE_CUSTOM_DB_HTTP = OPTIONS_CUSTOM_DB_HTTP.getService(); + + public ITDatastoreTestHttp(DatastoreOptions options, Datastore datastore, String databaseType) { + super(options, datastore, databaseType); + } + + @Parameterized.Parameters(name = "database: {2}") + public static Iterable data() { + return Arrays.asList( + new Object[][] { + {OPTIONS_DEFAULT_HTTP, DATASTORE_DEFAULT_HTTP, "default"}, + {OPTIONS_CUSTOM_DB_HTTP, DATASTORE_CUSTOM_DB_HTTP, CUSTOM_DB_ID}, + }); + } + + @AfterClass + public static void afterClass() throws Exception { + HELPER_DEFAULT_HTTP.deleteNamespace(); + HELPER_CUSTOM_DB_HTTP.deleteNamespace(); + DATASTORE_DEFAULT_HTTP.close(); + DATASTORE_CUSTOM_DB_HTTP.close(); + } +} diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/StatementExecutor.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/StatementExecutor.java index c8ded3d89..f2209be9c 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/StatementExecutor.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/StatementExecutor.java @@ -80,9 +80,10 @@ private boolean transactionConflict(Exception exception) { } return exception instanceof ExecutionException && exception.getCause().getClass() == DatastoreException.class - && exception - .getMessage() - .contains("contention"); // exception raise coz of optimistic concurrency + && (exception.getMessage().contains("contention") + || exception + .getMessage() + .contains("Conflict")); // exception raise coz of optimistic concurrency } interface Statement { From 1daca4902112aad78c8a7f131386c6ed7e852deb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 18:46:16 +0000 Subject: [PATCH 30/42] deps: bump com.google.errorprone:error_prone_core from 2.26.0 to 2.26.1 (#1367) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [com.google.errorprone:error_prone_core](https://togithub.com/google/error-prone) from 2.26.0 to 2.26.1.
Release notes

Sourced from com.google.errorprone:error_prone_core's releases.

Error Prone 2.26.1

This release contains all of the changes in 2.26.0, plus a bug fix to the module name of the annotations artifact com.google.errorprone.annotations (https://togithub.com/google/error-prone/commit/9d99ee76f2ca8568b69150f5df7fe845c8545d16)

Starting in 2.26.x, the 'annotations' artifact now includes a module-info.java for Java Platform Module System support, thanks to @​sgammon in #4311.


Compatibility note:

Now that the annotations artifact explicit declares a module instead of relying on Automatic-Module-Name, JDK 17 and newer perform stricter module encapsulation checks. Modularized libraries depending on Error Prone annotations 2.26.x and newer may see errors like:

error: package com.google.errorprone.annotations is not visible
import com.google.errorprone.annotations.CheckReturnValue;
                            ^
  (package com.google.errorprone.annotations is declared in module com.google.errorprone.annotations, but module ... does not read it)

The fix is to add requires static to the module declaration of modularized libraries that depend on Error Prone annotations:

 module your.module {
...
+  requires static com.google.errorprone.annotations;
 }

Full Changelog: https://togithub.com/google/error-prone/compare/v2.26.0...v2.26.1

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.errorprone:error_prone_core&package-manager=maven&previous-version=2.26.0&new-version=2.26.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3a44442cd..9e1a434d9 100644 --- a/pom.xml +++ b/pom.xml @@ -143,7 +143,7 @@ github google-cloud-datastore-parent https://googleapis.dev/java/google-api-grpc/latest - 2.26.0 + 2.26.1 From 8c432724b0bb5f205ad8b424daec433590bf7698 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 16:38:17 +0000 Subject: [PATCH 31/42] deps: bump com.google.guava:guava-testlib from 33.0.0-jre to 33.1.0-jre (#1370) Bumps [com.google.guava:guava-testlib](https://togithub.com/google/guava) from 33.0.0-jre to 33.1.0-jre.
Release notes

Sourced from com.google.guava:guava-testlib's releases.

33.1.0

Request for Android users

If you know of Guava Android users who have not yet upgraded to at least the previous release 33.0.0, please encourage them to do so. Starting with that version, we are experimenting with including Java 8+ APIs in guava-android. Before we commit to adding such APIs, we want as much testing as we can get: If we later expose a set of Java 8+ APIs and then discover that they break users, we won't want to remove them, as the removal would break users, too.

Maven

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>33.1.0-jre</version>
  <!-- or, for Android: -->
  <version>33.1.0-android</version>
</dependency>

Jar files

Guava requires one runtime dependency, which you can download here:

Javadoc

JDiff

Changelog

  • Updated our Error Prone dependency to 2.26.1, which includes a JPMS-ready jar of annotations. If you use the Error Prone annotations in a modular build of your own code, you may need to add a requires line for them. (d48c6dfbb8, c6e91c498ced26631029d1bdfdb9154d4a217368)
  • base: Added a Duration overload for Suppliers.memoizeWithExpiration. (76e46ec35b)
  • base: Deprecated the remaining two overloads of Throwables.propagateIfPossible. They won't be deleted, but we recommend migrating off them. (cf86414a87)
  • cache: Fixed a bug that could cause false "recursive load" reports during refresh. (0e1aebf73e)
  • graph: Changed the return types of transitiveClosure() and reachableNodes() to Immutable* types. reachableNodes() already returned an immutable object (even though that was not reflected in the declared return type); transitiveClosure() used to return a mutable object. The old signatures remain available, so this change does not break binary compatibility. (09e655f6c1)
  • graph: Changed the behavior of views returned by graph accessor methods that take a graph element as input: They now throw IllegalStateException when that element is removed from the graph. (8dca776341)
  • hash: Optimized Checksum-based hash functions for Java 9+. (afb35a5d1b)
  • testing: Exposed FakeTicker Duration methods to Android users. (f346bbb6a7)
  • util.concurrent: Deprecated the constructors of UncheckedExecutionException and ExecutionError that don't accept a cause. We won't remove these constructors, but we recommend migrating off them, as users of those classes often assume that instances will contain a cause. (1bb3c4386b)
  • util.concurrent: Improved the correctness of racy accesses for J2ObjC users. (d3232b71ce)
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.guava:guava-testlib&package-manager=maven&previous-version=33.0.0-jre&new-version=33.1.0-jre)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- google-cloud-datastore/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-datastore/pom.xml b/google-cloud-datastore/pom.xml index e5d32bda4..e07c6912d 100644 --- a/google-cloud-datastore/pom.xml +++ b/google-cloud-datastore/pom.xml @@ -122,7 +122,7 @@ com.google.guava guava-testlib - 33.0.0-jre + 33.1.0-jre test From 2a87d08ebc4a7f498fe946b021c822d9454a78fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 16:40:18 +0000 Subject: [PATCH 32/42] deps: bump com.google.cloud:google-cloud-shared-config from 1.7.4 to 1.7.5 (#1369) Bumps [com.google.cloud:google-cloud-shared-config](https://togithub.com/googleapis/java-shared-config) from 1.7.4 to 1.7.5.
Release notes

Sourced from com.google.cloud:google-cloud-shared-config's releases.

v1.7.5

1.7.5 (2024-03-13)

Dependencies

  • Update actions/github-script action to v7 (#753) (863c03e)
  • Update actions/setup-java action to v4 (#782) (cecc8bb)
  • Update dependency com.puppycrawl.tools:checkstyle to v10.14.1 (#780) (0b787c6)
  • Update dependency org.graalvm.buildtools:native-maven-plugin to v0.10.1 (#781) (9dcac17)
Changelog

Sourced from com.google.cloud:google-cloud-shared-config's changelog.

1.7.5 (2024-03-13)

Dependencies

  • Update actions/github-script action to v7 (#753) (863c03e)
  • Update actions/setup-java action to v4 (#782) (cecc8bb)
  • Update dependency com.puppycrawl.tools:checkstyle to v10.14.1 (#780) (0b787c6)
  • Update dependency org.graalvm.buildtools:native-maven-plugin to v0.10.1 (#781) (9dcac17)
Commits
  • 087d625 chore(main): release 1.7.5 (#774)
  • 27564bc ci: simplify graalvm docker configs (#784)
  • 9dcac17 deps: update dependency org.graalvm.buildtools:native-maven-plugin to v0.10.1...
  • 0b787c6 deps: update dependency com.puppycrawl.tools:checkstyle to v10.14.1 (#780)
  • f9478f4 build(deps): update dependency org.codehaus.mojo:extra-enforcer-rules to v1.8...
  • cecc8bb deps: update actions/setup-java action to v4 (#782)
  • 309495c build(deps): update dependency org.codehaus.mojo:build-helper-maven-plugin to...
  • c528a2f build(deps): update dependency org.codehaus.mojo:exec-maven-plugin to v3.2.0 ...
  • a8d6b6a build(deps): update dependency org.codehaus.mojo:flatten-maven-plugin to v1.6...
  • 90ffb54 build(deps): update dependency org.apache.maven.plugins:maven-gpg-plugin to v...
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.cloud:google-cloud-shared-config&package-manager=maven&previous-version=1.7.4&new-version=1.7.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- google-cloud-datastore-bom/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/google-cloud-datastore-bom/pom.xml b/google-cloud-datastore-bom/pom.xml index 0ba852d58..04a351e95 100644 --- a/google-cloud-datastore-bom/pom.xml +++ b/google-cloud-datastore-bom/pom.xml @@ -8,7 +8,7 @@ com.google.cloud google-cloud-shared-config - 1.7.4 + 1.7.5 Google Cloud datastore BOM diff --git a/pom.xml b/pom.xml index 9e1a434d9..53b18befa 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ com.google.cloud google-cloud-shared-config - 1.7.4 + 1.7.5 From 7e86e881be5f8573a723b56966f3570a963dbfb2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 19:44:17 +0000 Subject: [PATCH 33/42] deps: bump com.google.cloud:google-cloud-shared-config from 1.7.5 to 1.7.6 (#1371) Bumps [com.google.cloud:google-cloud-shared-config](https://togithub.com/googleapis/java-shared-config) from 1.7.5 to 1.7.6.
Release notes

Sourced from com.google.cloud:google-cloud-shared-config's releases.

v1.7.6

1.7.6 (2024-03-14)

Bug Fixes

  • Revert update dependency org.codehaus.mojo:flatten-maven-plugin to v1.6.0 (597683f)
Changelog

Sourced from com.google.cloud:google-cloud-shared-config's changelog.

1.7.6 (2024-03-14)

Bug Fixes

  • Revert update dependency org.codehaus.mojo:flatten-maven-plugin to v1.6.0 (597683f)
Commits
  • 3416405 chore(main): release 1.7.6 (#788)
  • be321c3 chore(main): release 1.7.6-SNAPSHOT (#785)
  • 597683f Revert "build(deps): update dependency org.codehaus.mojo:flatten-maven-plugin...
  • 47d38d5 chore: ignore flatten-maven-plugin updates temporarily (#786)
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.cloud:google-cloud-shared-config&package-manager=maven&previous-version=1.7.5&new-version=1.7.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- google-cloud-datastore-bom/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/google-cloud-datastore-bom/pom.xml b/google-cloud-datastore-bom/pom.xml index 04a351e95..fa0c39ed2 100644 --- a/google-cloud-datastore-bom/pom.xml +++ b/google-cloud-datastore-bom/pom.xml @@ -8,7 +8,7 @@ com.google.cloud google-cloud-shared-config - 1.7.5 + 1.7.6 Google Cloud datastore BOM diff --git a/pom.xml b/pom.xml index 53b18befa..0e26d66f6 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ com.google.cloud google-cloud-shared-config - 1.7.5 + 1.7.6 From 48a54d595ff500b3805a31ccb04276b8823c7add Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 16:52:16 +0000 Subject: [PATCH 34/42] deps: bump com.google.cloud:google-cloud-shared-dependencies from 3.27.0 to 3.28.1 (#1374) Bumps com.google.cloud:google-cloud-shared-dependencies from 3.27.0 to 3.28.1. [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.cloud:google-cloud-shared-dependencies&package-manager=maven&previous-version=3.27.0&new-version=3.28.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0e26d66f6..9240f0d19 100644 --- a/pom.xml +++ b/pom.xml @@ -151,7 +151,7 @@ com.google.cloud google-cloud-shared-dependencies - 3.27.0 + 3.28.1 pom import From 2fdc10b50b2fd8533ce1240ba7468c890a701f34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 16:36:17 +0000 Subject: [PATCH 35/42] deps: bump org.apache.maven.plugins:maven-compiler-plugin from 3.12.1 to 3.13.0 (#1378) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://togithub.com/apache/maven-compiler-plugin) from 3.12.1 to 3.13.0.
Release notes

Sourced from org.apache.maven.plugins:maven-compiler-plugin's releases.

3.13.0

🚀 New features and improvements

📦 Dependency updates

📝 Documentation updates

👻 Maintenance

Commits
  • a1415aa [maven-release-plugin] prepare release maven-compiler-plugin-3.13.0
  • b2b9196 [MCOMPILER-574] Propagate cause of exception in AbstractCompilerMojo
  • 6d2ce5a [MCOMPILER-584] Refresh page - Using Non-Javac Compilers
  • eebad60 [MCOMPILER-585] Refresh plugins versions in ITs
  • ceacf68 [MCOMPILER-582] Automatic detection of release option for JDK < 9
  • 110293f [MCOMPILER-583] Require Maven 3.6.3
  • 90131df [MCOMPILER-575] Bump plexusCompilerVersion from 2.14.2 to 2.15.0 (#227)
  • 74cfc72 [MCOMPILER-548] JDK 21 throws annotations processing warning that can not be ...
  • f85aa27 Bump apache/maven-gh-actions-shared from 3 to 4
  • d59ef49 extract Maven 3.3.1 specific method call
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-compiler-plugin&package-manager=maven&previous-version=3.12.1&new-version=3.13.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9240f0d19..a545f5914 100644 --- a/pom.xml +++ b/pom.xml @@ -237,7 +237,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.12.1 + 3.13.0 UTF-8 true From f2c19c727f5d25beea2966e3afa753310d644784 Mon Sep 17 00:00:00 2001 From: kolea2 <45548808+kolea2@users.noreply.github.com> Date: Tue, 23 Apr 2024 12:47:16 -0400 Subject: [PATCH 36/42] feat: allow opt-in for gRPC, have datastore-v1-proto-client as default (#1400) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: allow opt-in for gRPC, have datastore-v1-proto-client as default transport * chore: update concepts test (#1382) Fixes #1379 (cherry picked from commit 9818aeec24eb6da9d4726358b03bb6a5ca384f25) * fix host setting logic * fix test * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * update test * 🦉 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 --- README.md | 8 +- google-cloud-datastore/pom.xml | 8 + .../cloud/datastore/DatastoreOptions.java | 43 ++-- .../datastore/spi/v1/HttpDatastoreRpc.java | 198 ++++++++++++------ .../testing/RemoteDatastoreHelper.java | 17 +- .../cloud/datastore/DatastoreOptionsTest.java | 57 ++++- .../google/cloud/datastore/DatastoreTest.java | 21 +- .../datastore/it/AbstractITDatastoreTest.java | 11 +- .../datastore/it/ITDatastoreConceptsTest.java | 10 +- .../datastore/it/ITDatastoreTestGrpc.java | 9 +- .../datastore/it/ITDatastoreTestHttp.java | 9 +- 11 files changed, 260 insertions(+), 131 deletions(-) diff --git a/README.md b/README.md index c582f2b63..dcb40a9cc 100644 --- a/README.md +++ b/README.md @@ -50,20 +50,20 @@ If you are using Maven without the BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies: ```Groovy -implementation platform('com.google.cloud:libraries-bom:26.34.0') +implementation platform('com.google.cloud:libraries-bom:26.37.0') implementation 'com.google.cloud:google-cloud-datastore' ``` If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-datastore:2.18.5' +implementation 'com.google.cloud:google-cloud-datastore:2.19.0' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.18.5" +libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.19.0" ``` @@ -380,7 +380,7 @@ Java is a registered trademark of Oracle and/or its affiliates. [kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-datastore/java11.html [stability-image]: https://img.shields.io/badge/stability-stable-green [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-datastore.svg -[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-datastore/2.18.5 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-datastore/2.19.0 [authentication]: https://github.com/googleapis/google-cloud-java#authentication [auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes [predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles diff --git a/google-cloud-datastore/pom.xml b/google-cloud-datastore/pom.xml index e07c6912d..45ffa5998 100644 --- a/google-cloud-datastore/pom.xml +++ b/google-cloud-datastore/pom.xml @@ -42,6 +42,10 @@ com.google.api.grpc proto-google-cloud-datastore-admin-v1
+ + com.google.cloud.datastore + datastore-v1-proto-client + io.grpc grpc-api @@ -102,6 +106,10 @@ com.google.oauth-client google-oauth-client + + com.google.auth + google-auth-library-oauth2-http + io.opencensus opencensus-api diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java index c852fdb7f..7e5192b52 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java @@ -18,6 +18,7 @@ import static com.google.cloud.datastore.Validator.validateNamespace; +import com.google.api.core.BetaApi; import com.google.api.gax.core.CredentialsProvider; import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; import com.google.api.gax.rpc.TransportChannelProvider; @@ -74,15 +75,8 @@ public ServiceRpc create(DatastoreOptions options) { try { if (options.getTransportOptions() instanceof GrpcTransportOptions) { return new GrpcDatastoreRpc(options); - } else if (options.getTransportOptions() instanceof HttpTransportOptions) { - // todo see if we can remove this check - if (DatastoreUtils.isEmulator(options)) { - throw new IllegalArgumentException("Only GRPC channels are allowed for emulator."); - } - return new HttpDatastoreRpc(options); } else { - throw new IllegalArgumentException( - "unknown transport type: " + options.getTransportOptions()); + return new HttpDatastoreRpc(options); } } catch (IOException e) { throw new RuntimeException(e); @@ -96,6 +90,8 @@ public static class Builder extends ServiceOptions.Builder datastore.get(KEY3)); - } - private void checkKeyProperties(BaseKey key) { assertEquals(options.getDatabaseId(), key.getDatabaseId()); assertEquals(options.getProjectId(), key.getProjectId()); diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java index 357471abc..7c105672c 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java @@ -70,6 +70,7 @@ import com.google.cloud.datastore.TimestampValue; import com.google.cloud.datastore.Transaction; import com.google.cloud.datastore.ValueType; +import com.google.cloud.grpc.GrpcTransportOptions; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.datastore.v1.TransactionOptions; @@ -1449,9 +1450,13 @@ public Integer run(DatastoreReaderWriter transaction) { datastore.runInTransaction(callable2, readOnlyOptions); fail("Expecting a failure"); } catch (DatastoreException expected) { - assertEquals( - INVALID_ARGUMENT.getHttpStatusCode(), - ((DatastoreException) expected.getCause()).getCode()); + if (datastore.getOptions().getTransportOptions() instanceof GrpcTransportOptions) { + assertEquals( + INVALID_ARGUMENT.getHttpStatusCode(), + ((DatastoreException) expected.getCause()).getCode()); + } else { + assertEquals(3, ((DatastoreException) expected.getCause()).getCode()); + } } } diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreConceptsTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreConceptsTest.java index f61db4f48..1d6b2f838 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreConceptsTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreConceptsTest.java @@ -67,7 +67,6 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import org.junit.After; -import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -132,11 +131,6 @@ public void tearDown() { datastore.delete(taskKeysToDelete); } - @AfterClass - public static void afterClass() throws Exception { - datastore.close(); - } - private void assertValidKey(Key taskKey) { datastore.put(Entity.newBuilder(taskKey, TEST_FULL_ENTITY).build()); } @@ -575,7 +569,7 @@ public void testInequalityRange() { } @Test - public void testInequalityInvalid() { + public void testInequalityValid() { Query query = Query.newEntityQueryBuilder() .setKind(TASK_CONCEPTS) @@ -583,7 +577,7 @@ public void testInequalityInvalid() { CompositeFilter.and( PropertyFilter.gt("created", startDate), PropertyFilter.gt("priority", 3))) .build(); - assertInvalidQuery(query); + assertValidQuery(query); } @Test diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestGrpc.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestGrpc.java index d9acbd088..7bb809997 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestGrpc.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestGrpc.java @@ -18,6 +18,8 @@ import com.google.cloud.datastore.Datastore; import com.google.cloud.datastore.DatastoreOptions; import com.google.cloud.datastore.testing.RemoteDatastoreHelper; +import com.google.cloud.grpc.GrpcTransportOptions; +import com.google.common.truth.Truth; import java.util.Arrays; import org.junit.AfterClass; import org.junit.runner.RunWith; @@ -26,13 +28,14 @@ @RunWith(Parameterized.class) public class ITDatastoreTestGrpc extends AbstractITDatastoreTest { // setup for default db, grpc transport - protected static final RemoteDatastoreHelper HELPER_DEFAULT_GRPC = RemoteDatastoreHelper.create(); + protected static final RemoteDatastoreHelper HELPER_DEFAULT_GRPC = + RemoteDatastoreHelper.create(GrpcTransportOptions.newBuilder().build()); private static final DatastoreOptions OPTIONS_DEFAULT_GRPC = HELPER_DEFAULT_GRPC.getOptions(); private static final Datastore DATASTORE_DEFAULT_GRPC = OPTIONS_DEFAULT_GRPC.getService(); // setup for custom db, grpc transport private static final RemoteDatastoreHelper HELPER_CUSTOM_DB_GRPC = - RemoteDatastoreHelper.create(CUSTOM_DB_ID); + RemoteDatastoreHelper.create(CUSTOM_DB_ID, GrpcTransportOptions.newBuilder().build()); private static final DatastoreOptions OPTIONS_CUSTOM_DB_GRPC = HELPER_CUSTOM_DB_GRPC.getOptions(); private static final Datastore DATASTORE_CUSTOM_DB_GRPC = OPTIONS_CUSTOM_DB_GRPC.getService(); @@ -55,5 +58,7 @@ public static void afterClass() throws Exception { HELPER_CUSTOM_DB_GRPC.deleteNamespace(); DATASTORE_DEFAULT_GRPC.close(); DATASTORE_CUSTOM_DB_GRPC.close(); + Truth.assertThat(DATASTORE_DEFAULT_GRPC.isClosed()).isTrue(); + Truth.assertThat(DATASTORE_CUSTOM_DB_GRPC.isClosed()).isTrue(); } } diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestHttp.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestHttp.java index 0a453bbb4..3546bfcaf 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestHttp.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTestHttp.java @@ -18,7 +18,6 @@ import com.google.cloud.datastore.Datastore; import com.google.cloud.datastore.DatastoreOptions; import com.google.cloud.datastore.testing.RemoteDatastoreHelper; -import com.google.cloud.http.HttpTransportOptions; import java.util.Arrays; import org.junit.AfterClass; import org.junit.runner.RunWith; @@ -27,14 +26,14 @@ @RunWith(Parameterized.class) public class ITDatastoreTestHttp extends AbstractITDatastoreTest { // setup for default db, http transport - private static final RemoteDatastoreHelper HELPER_DEFAULT_HTTP = - RemoteDatastoreHelper.create(HttpTransportOptions.newBuilder().build()); + private static final RemoteDatastoreHelper HELPER_DEFAULT_HTTP = RemoteDatastoreHelper.create(); + private static final DatastoreOptions OPTIONS_DEFAULT_HTTP = HELPER_DEFAULT_HTTP.getOptions(); private static final Datastore DATASTORE_DEFAULT_HTTP = OPTIONS_DEFAULT_HTTP.getService(); // setup for custom db, http transport private static final RemoteDatastoreHelper HELPER_CUSTOM_DB_HTTP = - RemoteDatastoreHelper.create(CUSTOM_DB_ID, HttpTransportOptions.newBuilder().build()); + RemoteDatastoreHelper.create(CUSTOM_DB_ID); private static final DatastoreOptions OPTIONS_CUSTOM_DB_HTTP = HELPER_CUSTOM_DB_HTTP.getOptions(); private static final Datastore DATASTORE_CUSTOM_DB_HTTP = OPTIONS_CUSTOM_DB_HTTP.getService(); @@ -55,7 +54,5 @@ public static Iterable data() { public static void afterClass() throws Exception { HELPER_DEFAULT_HTTP.deleteNamespace(); HELPER_CUSTOM_DB_HTTP.deleteNamespace(); - DATASTORE_DEFAULT_HTTP.close(); - DATASTORE_CUSTOM_DB_HTTP.close(); } } From a35c9ee8aaa458ee2074bd76b1559740b09a8ea5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 17:20:19 +0000 Subject: [PATCH 37/42] deps: bump com.google.cloud:google-cloud-shared-dependencies from 3.28.1 to 3.29.0 (#1405) Bumps com.google.cloud:google-cloud-shared-dependencies from 3.28.1 to 3.29.0. [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.cloud:google-cloud-shared-dependencies&package-manager=maven&previous-version=3.28.1&new-version=3.29.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a545f5914..493cdd3e6 100644 --- a/pom.xml +++ b/pom.xml @@ -151,7 +151,7 @@ com.google.cloud google-cloud-shared-dependencies - 3.28.1 + 3.29.0 pom import From 77d9c1881717865737b9867c6cf3ba944a72d6e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 17:26:19 +0000 Subject: [PATCH 38/42] deps: bump com.google.cloud:google-cloud-shared-config from 1.7.6 to 1.7.7 (#1401) Bumps [com.google.cloud:google-cloud-shared-config](https://togithub.com/googleapis/java-shared-config) from 1.7.6 to 1.7.7.
Release notes

Sourced from com.google.cloud:google-cloud-shared-config's releases.

v1.7.7

1.7.7 (2024-04-17)

Bug Fixes

Dependencies

  • Update dependency com.puppycrawl.tools:checkstyle to v10.15.0 (#792) (984f434)
  • Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.13.0 (8136d33)
  • Update dependency org.apache.maven.plugins:maven-gpg-plugin to v3.2.3 (e485b45)
  • Update dependency org.apache.maven.plugins:maven-jar-plugin to v3.4.0 (567ba39)
  • Update dependency org.apache.maven.plugins:maven-source-plugin to v3.3.1 (8b625c0)
  • Update dependency org.jacoco:jacoco-maven-plugin to v0.8.12 (15870f4)
Changelog

Sourced from com.google.cloud:google-cloud-shared-config's changelog.

1.7.7 (2024-04-17)

Bug Fixes

Dependencies

  • Update dependency com.puppycrawl.tools:checkstyle to v10.15.0 (#792) (984f434)
  • Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.13.0 (8136d33)
  • Update dependency org.apache.maven.plugins:maven-gpg-plugin to v3.2.3 (e485b45)
  • Update dependency org.apache.maven.plugins:maven-jar-plugin to v3.4.0 (567ba39)
  • Update dependency org.apache.maven.plugins:maven-source-plugin to v3.3.1 (8b625c0)
  • Update dependency org.jacoco:jacoco-maven-plugin to v0.8.12 (15870f4)
Commits
  • e1effa0 chore(main): release 1.7.7 (#808)
  • a0beeed chore(main): release 1.7.7-SNAPSHOT (#789)
  • 567ba39 build(deps): update dependency org.apache.maven.plugins:maven-jar-plugin to v...
  • 984f434 deps: update dependency com.puppycrawl.tools:checkstyle to v10.15.0 (#792)
  • e485b45 build(deps): update dependency org.apache.maven.plugins:maven-gpg-plugin to v...
  • 15870f4 build(deps): update dependency org.jacoco:jacoco-maven-plugin to v0.8.12 (#799)
  • 8136d33 build(deps): update dependency org.apache.maven.plugins:maven-compiler-plugin...
  • 8b625c0 build(deps): update dependency org.apache.maven.plugins:maven-source-plugin t...
  • 96589ef fix: graalvm image terraform install (#806)
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.cloud:google-cloud-shared-config&package-manager=maven&previous-version=1.7.6&new-version=1.7.7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- google-cloud-datastore-bom/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/google-cloud-datastore-bom/pom.xml b/google-cloud-datastore-bom/pom.xml index fa0c39ed2..cf4ec08ad 100644 --- a/google-cloud-datastore-bom/pom.xml +++ b/google-cloud-datastore-bom/pom.xml @@ -8,7 +8,7 @@ com.google.cloud google-cloud-shared-config - 1.7.6 + 1.7.7 Google Cloud datastore BOM diff --git a/pom.xml b/pom.xml index 493cdd3e6..2e83152e5 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ com.google.cloud google-cloud-shared-config - 1.7.6 + 1.7.7 From 4c2d4cec423d070c3d3a57d7fb78ce7b0292d54d Mon Sep 17 00:00:00 2001 From: kolea2 <45548808+kolea2@users.noreply.github.com> Date: Thu, 25 Apr 2024 15:03:22 -0400 Subject: [PATCH 39/42] feat: have DatastoreException extend BaseHttpServiceException, convert gRPC status codes to existing Datastore codes (#1409) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: have DatastoreException extend BaseHttpServiceException, convert gRPC status codes to existing Datastore codes * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * review feedback --------- Co-authored-by: Owl Bot --- README.md | 6 +- .../cloud/datastore/DatastoreException.java | 157 +++++++++--------- .../GrpcToDatastoreCodeTranslation.java | 93 +++++++++++ .../datastore/DatastoreExceptionTest.java | 121 +++----------- .../GrpcToDatastoreCodeTranslationTest.java | 53 ++++++ .../datastore/it/AbstractITDatastoreTest.java | 100 +++++------ 6 files changed, 287 insertions(+), 243 deletions(-) create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/GrpcToDatastoreCodeTranslation.java create mode 100644 google-cloud-datastore/src/test/java/com/google/cloud/datastore/GrpcToDatastoreCodeTranslationTest.java diff --git a/README.md b/README.md index dcb40a9cc..577bd7e03 100644 --- a/README.md +++ b/README.md @@ -57,13 +57,13 @@ implementation 'com.google.cloud:google-cloud-datastore' If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-datastore:2.19.0' +implementation 'com.google.cloud:google-cloud-datastore:2.19.1' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.19.0" +libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.19.1" ``` @@ -380,7 +380,7 @@ Java is a registered trademark of Oracle and/or its affiliates. [kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-datastore/java11.html [stability-image]: https://img.shields.io/badge/stability-stable-green [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-datastore.svg -[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-datastore/2.19.0 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-datastore/2.19.1 [authentication]: https://github.com/googleapis/google-cloud-java#authentication [auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes [predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java index 5d01c3b9d..d258feac8 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java @@ -16,16 +16,17 @@ package com.google.cloud.datastore; -import static com.google.cloud.BaseServiceException.isRetryable; - +import com.google.api.gax.grpc.GrpcStatusCode; import com.google.api.gax.rpc.ApiException; -import com.google.api.gax.rpc.ErrorDetails; +import com.google.api.gax.rpc.StatusCode; import com.google.cloud.BaseServiceException; import com.google.cloud.RetryHelper.RetryHelperException; -import com.google.cloud.grpc.BaseGrpcServiceException; +import com.google.cloud.http.BaseHttpServiceException; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableSet; +import io.grpc.StatusException; +import io.grpc.StatusRuntimeException; import java.io.IOException; -import java.util.Map; import java.util.Set; /** @@ -34,7 +35,7 @@ * @see Google Cloud * Datastore error codes */ -public final class DatastoreException extends BaseGrpcServiceException { +public final class DatastoreException extends BaseHttpServiceException { // see https://cloud.google.com/datastore/docs/concepts/errors#Error_Codes" private static final Set RETRYABLE_ERRORS = @@ -43,110 +44,106 @@ public final class DatastoreException extends BaseGrpcServiceException { new Error(4, "DEADLINE_EXCEEDED", false), new Error(14, "UNAVAILABLE", true)); private static final long serialVersionUID = 2663750991205874435L; - private String reason; - private ApiException apiException; public DatastoreException(int code, String message, String reason) { this(code, message, reason, true, null); - this.reason = reason; + } + + public DatastoreException(int code, String message, Throwable cause) { + super(code, message, null, true, RETRYABLE_ERRORS, cause); } public DatastoreException(int code, String message, String reason, Throwable cause) { - super(message, cause, code, isRetryable(code, reason, true, RETRYABLE_ERRORS)); - this.reason = reason; + super(code, message, reason, true, RETRYABLE_ERRORS, cause); } public DatastoreException( int code, String message, String reason, boolean idempotent, Throwable cause) { - super(message, cause, code, isRetryable(code, reason, idempotent, RETRYABLE_ERRORS)); - this.reason = reason; + super(code, message, reason, idempotent, RETRYABLE_ERRORS, cause); } public DatastoreException(IOException exception) { - super(exception, true); - } - - public DatastoreException(ApiException apiException) { - super(apiException); - this.apiException = apiException; + super(exception, true, RETRYABLE_ERRORS); } /** - * Checks the underlying reason of the exception and if it's {@link ApiException} then return the - * specific domain otherwise null. + * Translate RetryHelperException to the DatastoreException that caused the error. This method + * will always throw an exception. * - * @see Domain - * @return the logical grouping to which the "reason" belongs. + * @throws DatastoreException when {@code ex} was caused by a {@code DatastoreException} */ - public String getDomain() { - if (this.apiException != null) { - return this.apiException.getDomain(); - } - return null; + static DatastoreException translateAndThrow(RetryHelperException ex) { + BaseServiceException.translate(ex); + throw transformThrowable(ex); } - /** - * Checks the underlying reason of the exception and if it's {@link ApiException} then return a - * map of key-value pairs otherwise null. - * - * @see Metadata - * @return the map of additional structured details about an error. - */ - public Map getMetadata() { - if (this.apiException != null) { - return this.apiException.getMetadata(); + static BaseServiceException transformThrowable(Throwable t) { + if (t instanceof BaseServiceException) { + return (BaseServiceException) t; } - return null; + if (t.getCause() instanceof BaseServiceException) { + return (BaseServiceException) t.getCause(); + } + if (t instanceof ApiException) { + return asDatastoreException((ApiException) t); + } + if (t.getCause() instanceof ApiException) { + return asDatastoreException((ApiException) t.getCause()); + } + return getDatastoreException(t); } - /** - * Checks the underlying reason of the exception and if it's {@link ApiException} then return the - * ErrorDetails otherwise null. - * - * @see Status - * @see Error - * Details - * @return An object containing getters for structured objects from error_details.proto. - */ - public ErrorDetails getErrorDetails() { - if (this.apiException != null) { - return this.apiException.getErrorDetails(); + private static DatastoreException getDatastoreException(Throwable t) { + // unwrap a RetryHelperException if that is what is being translated + if (t instanceof RetryHelperException) { + return new DatastoreException(UNKNOWN_CODE, t.getMessage(), null, t.getCause()); } - return null; + return new DatastoreException(UNKNOWN_CODE, t.getMessage(), t); } - /** - * Checks the underlying reason of the exception and if it's {@link ApiException} then return the - * reason otherwise null/custom reason. - * - * @see Reason - * @return the reason of an error. - */ - @Override - public String getReason() { - if (this.apiException != null) { - return this.apiException.getReason(); + static DatastoreException asDatastoreException(ApiException apiEx) { + int datastoreStatusCode = 0; + StatusCode statusCode = apiEx.getStatusCode(); + if (statusCode instanceof GrpcStatusCode) { + GrpcStatusCode gsc = (GrpcStatusCode) statusCode; + datastoreStatusCode = + GrpcToDatastoreCodeTranslation.grpcCodeToDatastoreStatusCode(gsc.getTransportCode()); + } + + // If there is a gRPC exception in our cause, pull its error message up to be our + // message otherwise, create a generic error message with the status code. + String statusCodeName = statusCode.getCode().name(); + String statusExceptionMessage = getStatusExceptionMessage(apiEx); + + String message; + if (statusExceptionMessage != null) { + message = statusCodeName + ": " + statusExceptionMessage; + } else { + message = "Error: " + statusCodeName; + } + + String reason = ""; + if (Strings.isNullOrEmpty(apiEx.getReason())) { + if (apiEx.getStatusCode() != null) { + reason = apiEx.getStatusCode().getCode().name(); + } } - return this.reason; + // It'd be better to use ExceptionData and BaseServiceException#(ExceptionData) but, + // BaseHttpServiceException does not pass that through so we're stuck using this for now. + // TODO: When we can break the coupling to BaseHttpServiceException replace this + return new DatastoreException(datastoreStatusCode, message, reason, apiEx); } - /** - * Translate RetryHelperException to the DatastoreException that caused the error. This method - * will always throw an exception. - * - * @throws DatastoreException when {@code ex} was caused by a {@code DatastoreException} - */ - static DatastoreException translateAndThrow(RetryHelperException ex) { - BaseServiceException.translate(ex); - if (ex.getCause() instanceof ApiException) { - throw new DatastoreException((ApiException) ex.getCause()); + private static String getStatusExceptionMessage(Exception apiEx) { + if (apiEx.getMessage() != null) { + return apiEx.getMessage(); + } else { + Throwable cause = apiEx.getCause(); + if (cause instanceof StatusRuntimeException || cause instanceof StatusException) { + return cause.getMessage(); + } + return null; } - throw new DatastoreException(UNKNOWN_CODE, ex.getMessage(), null, ex.getCause()); } /** diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/GrpcToDatastoreCodeTranslation.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/GrpcToDatastoreCodeTranslation.java new file mode 100644 index 000000000..1d63fb19a --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/GrpcToDatastoreCodeTranslation.java @@ -0,0 +1,93 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.cloud.datastore; + +import com.google.api.gax.grpc.GrpcStatusCode; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.rpc.Code; +import io.grpc.Status; +import java.util.Map; +import java.util.function.Function; + +final class GrpcToDatastoreCodeTranslation { + /** Mappings between gRPC status codes and their corresponding code numbers. */ + private static final ImmutableList STATUS_CODE_MAPPINGS = + ImmutableList.of( + StatusCodeMapping.of(Code.OK.getNumber(), Status.Code.OK), + StatusCodeMapping.of(Code.DATA_LOSS.getNumber(), Status.Code.DATA_LOSS), + StatusCodeMapping.of(Code.INVALID_ARGUMENT.getNumber(), Status.Code.INVALID_ARGUMENT), + StatusCodeMapping.of(Code.OUT_OF_RANGE.getNumber(), Status.Code.OUT_OF_RANGE), + StatusCodeMapping.of(Code.UNAUTHENTICATED.getNumber(), Status.Code.UNAUTHENTICATED), + StatusCodeMapping.of(Code.PERMISSION_DENIED.getNumber(), Status.Code.PERMISSION_DENIED), + StatusCodeMapping.of(Code.NOT_FOUND.getNumber(), Status.Code.NOT_FOUND), + StatusCodeMapping.of(Code.ALREADY_EXISTS.getNumber(), Status.Code.ALREADY_EXISTS), + StatusCodeMapping.of( + Code.FAILED_PRECONDITION.getNumber(), Status.Code.FAILED_PRECONDITION), + StatusCodeMapping.of(Code.RESOURCE_EXHAUSTED.getNumber(), Status.Code.RESOURCE_EXHAUSTED), + StatusCodeMapping.of(Code.INTERNAL.getNumber(), Status.Code.INTERNAL), + StatusCodeMapping.of(Code.UNIMPLEMENTED.getNumber(), Status.Code.UNIMPLEMENTED), + StatusCodeMapping.of(Code.UNAVAILABLE.getNumber(), Status.Code.UNAVAILABLE), + StatusCodeMapping.of(Code.DEADLINE_EXCEEDED.getNumber(), Status.Code.DEADLINE_EXCEEDED), + StatusCodeMapping.of(Code.ABORTED.getNumber(), Status.Code.ABORTED), + StatusCodeMapping.of(Code.CANCELLED.getNumber(), Status.Code.CANCELLED), + StatusCodeMapping.of(Code.UNKNOWN.getNumber(), Status.Code.UNKNOWN)); + + /** Index our {@link StatusCodeMapping} for constant time lookup by {@link Status.Code} */ + private static final Map GRPC_CODE_INDEX = + STATUS_CODE_MAPPINGS.stream() + .collect( + ImmutableMap.toImmutableMap(StatusCodeMapping::getGrpcCode, Function.identity())); + + static int grpcCodeToDatastoreStatusCode(Status.Code code) { + StatusCodeMapping found = GRPC_CODE_INDEX.get(code); + // theoretically it's possible for gRPC to add a new code we haven't mapped here, if this + // happens fall through to our default of 0 + if (found != null) { + return found.getDatastoreCode(); + } else { + return 0; + } + } + + /** + * Simple tuple class to bind together our corresponding http status code and {@link Status.Code} + * while providing easy access to the correct {@link GrpcStatusCode} where necessary. + */ + private static final class StatusCodeMapping { + + private final int datastoreCode; + + private final Status.Code grpcCode; + + private StatusCodeMapping(int datastoreCode, Status.Code grpcCode) { + this.datastoreCode = datastoreCode; + this.grpcCode = grpcCode; + } + + public int getDatastoreCode() { + return datastoreCode; + } + + public Status.Code getGrpcCode() { + return grpcCode; + } + + static StatusCodeMapping of(int datastoreCode, Status.Code grpcCode) { + return new StatusCodeMapping(datastoreCode, grpcCode); + } + } +} diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java index 33f5ebb9c..8c52b5519 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java @@ -16,9 +16,6 @@ package com.google.cloud.datastore; -import static com.google.common.truth.Truth.assertThat; -import static com.google.rpc.Code.FAILED_PRECONDITION; -import static java.util.Collections.singletonMap; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; @@ -27,20 +24,11 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.api.gax.grpc.GrpcStatusCode; -import com.google.api.gax.rpc.ApiException; -import com.google.api.gax.rpc.ApiExceptionFactory; -import com.google.api.gax.rpc.ErrorDetails; -import com.google.api.gax.rpc.StatusCode; import com.google.cloud.BaseServiceException; import com.google.cloud.RetryHelper; -import com.google.protobuf.Any; -import com.google.rpc.ErrorInfo; -import io.grpc.Status; import java.io.IOException; import java.net.SocketTimeoutException; import org.junit.Test; @@ -88,78 +76,39 @@ public void testDatastoreException() { assertEquals("message", exception.getMessage()); assertFalse(exception.isRetryable()); assertSame(cause, exception.getCause()); - - exception = new DatastoreException(2, "message", "INTERNAL", true, cause); - assertEquals(2, exception.getCode()); - assertEquals("INTERNAL", exception.getReason()); - assertEquals("message", exception.getMessage()); - assertFalse(exception.isRetryable()); - assertSame(cause, exception.getCause()); - - ApiException apiException = createApiException(); - exception = new DatastoreException(apiException); - assertEquals(400, exception.getCode()); - assertEquals("MISSING_INDEXES", exception.getReason()); - assertThat(exception.getMetadata()) - .isEqualTo(singletonMap("missing_indexes_url", "__some__url__")); - assertSame(apiException, exception.getCause()); - } - - @Test - public void testApiException() { - ApiException apiException = createApiException(); - DatastoreException datastoreException = new DatastoreException(apiException); - - assertThat(datastoreException.getReason()).isEqualTo("MISSING_INDEXES"); - assertThat(datastoreException.getDomain()).isEqualTo("datastore.googleapis.com"); - assertThat(datastoreException.getMetadata()) - .isEqualTo(singletonMap("missing_indexes_url", "__some__url__")); - assertThat(datastoreException.getErrorDetails()).isEqualTo(apiException.getErrorDetails()); } @Test public void testTranslateAndThrow() { Exception cause = new DatastoreException(14, "message", "UNAVAILABLE"); - final RetryHelper.RetryHelperException exceptionMock = + RetryHelper.RetryHelperException exceptionMock = createMock(RetryHelper.RetryHelperException.class); expect(exceptionMock.getCause()).andReturn(cause).times(2); replay(exceptionMock); - BaseServiceException ex = - assertThrows( - BaseServiceException.class, () -> DatastoreException.translateAndThrow(exceptionMock)); - assertEquals(14, ex.getCode()); - assertEquals("message", ex.getMessage()); - assertTrue(ex.isRetryable()); - verify(exceptionMock); - - cause = createApiException(); - final RetryHelper.RetryHelperException exceptionMock2 = - createMock(RetryHelper.RetryHelperException.class); - expect(exceptionMock2.getCause()).andReturn(cause).times(3); - replay(exceptionMock2); - DatastoreException ex2 = - assertThrows( - DatastoreException.class, () -> DatastoreException.translateAndThrow(exceptionMock2)); - assertThat(ex2.getReason()).isEqualTo("MISSING_INDEXES"); - assertThat(ex2.getDomain()).isEqualTo("datastore.googleapis.com"); - assertThat(ex2.getMetadata()).isEqualTo(singletonMap("missing_indexes_url", "__some__url__")); - assertThat(ex2.getErrorDetails()).isEqualTo(((ApiException) cause).getErrorDetails()); - verify(exceptionMock2); - + try { + DatastoreException.translateAndThrow(exceptionMock); + } catch (BaseServiceException ex) { + assertEquals(14, ex.getCode()); + assertEquals("message", ex.getMessage()); + assertTrue(ex.isRetryable()); + } finally { + verify(exceptionMock); + } cause = new IllegalArgumentException("message"); - final RetryHelper.RetryHelperException exceptionMock3 = - createMock(RetryHelper.RetryHelperException.class); - expect(exceptionMock3.getMessage()).andReturn("message").times(1); - expect(exceptionMock3.getCause()).andReturn(cause).times(3); - replay(exceptionMock3); - BaseServiceException ex3 = - assertThrows( - BaseServiceException.class, () -> DatastoreException.translateAndThrow(exceptionMock3)); - assertEquals(DatastoreException.UNKNOWN_CODE, ex3.getCode()); - assertEquals("message", ex3.getMessage()); - assertFalse(ex3.isRetryable()); - assertSame(cause, ex3.getCause()); - verify(exceptionMock3); + exceptionMock = createMock(RetryHelper.RetryHelperException.class); + expect(exceptionMock.getMessage()).andReturn("message").times(1); + expect(exceptionMock.getCause()).andReturn(cause).times(4); + replay(exceptionMock); + try { + DatastoreException.translateAndThrow(exceptionMock); + } catch (BaseServiceException ex) { + assertEquals(DatastoreException.UNKNOWN_CODE, ex.getCode()); + assertEquals("message", ex.getMessage()); + assertFalse(ex.isRetryable()); + assertSame(cause, ex.getCause()); + } finally { + verify(exceptionMock); + } } @Test @@ -172,26 +121,4 @@ public void testThrowInvalidRequest() { assertEquals("message a 1", ex.getMessage()); } } - - private ApiException createApiException() { - // Simulating google.rpc.Status with an ErrorInfo - ErrorInfo errorInfo = - ErrorInfo.newBuilder() - .setDomain("datastore.googleapis.com") - .setReason("MISSING_INDEXES") - .putMetadata("missing_indexes_url", "__some__url__") - .build(); - com.google.rpc.Status status = - com.google.rpc.Status.newBuilder() - .setCode(FAILED_PRECONDITION.getNumber()) - .setMessage("The query requires indexes.") - .addDetails(Any.pack(errorInfo)) - .build(); - - // Using Gax to convert to ApiException - StatusCode statusCode = GrpcStatusCode.of(Status.fromCodeValue(status.getCode()).getCode()); - ErrorDetails errorDetails = - ErrorDetails.builder().setRawErrorMessages(status.getDetailsList()).build(); - return ApiExceptionFactory.createException(null, statusCode, true, errorDetails); - } } diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/GrpcToDatastoreCodeTranslationTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/GrpcToDatastoreCodeTranslationTest.java new file mode 100644 index 000000000..3f297989f --- /dev/null +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/GrpcToDatastoreCodeTranslationTest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.cloud.datastore; + +import static com.google.common.truth.Truth.assertThat; + +import io.grpc.Status.Code; +import java.util.EnumMap; +import org.junit.Test; + +public class GrpcToDatastoreCodeTranslationTest { + @Test + public void grpcCodeToDatastoreCode_expectedMapping() { + EnumMap expected = new EnumMap<>(Code.class); + expected.put(Code.OK, com.google.rpc.Code.OK.getNumber()); + expected.put(Code.INVALID_ARGUMENT, com.google.rpc.Code.INVALID_ARGUMENT.getNumber()); + expected.put(Code.OUT_OF_RANGE, com.google.rpc.Code.OUT_OF_RANGE.getNumber()); + expected.put(Code.UNAUTHENTICATED, com.google.rpc.Code.UNAUTHENTICATED.getNumber()); + expected.put(Code.PERMISSION_DENIED, com.google.rpc.Code.PERMISSION_DENIED.getNumber()); + expected.put(Code.NOT_FOUND, com.google.rpc.Code.NOT_FOUND.getNumber()); + expected.put(Code.FAILED_PRECONDITION, com.google.rpc.Code.FAILED_PRECONDITION.getNumber()); + expected.put(Code.ALREADY_EXISTS, com.google.rpc.Code.ALREADY_EXISTS.getNumber()); + expected.put(Code.RESOURCE_EXHAUSTED, com.google.rpc.Code.RESOURCE_EXHAUSTED.getNumber()); + expected.put(Code.INTERNAL, com.google.rpc.Code.INTERNAL.getNumber()); + expected.put(Code.UNIMPLEMENTED, com.google.rpc.Code.UNIMPLEMENTED.getNumber()); + expected.put(Code.UNAVAILABLE, com.google.rpc.Code.UNAVAILABLE.getNumber()); + expected.put(Code.ABORTED, com.google.rpc.Code.ABORTED.getNumber()); + expected.put(Code.CANCELLED, com.google.rpc.Code.CANCELLED.getNumber()); + expected.put(Code.UNKNOWN, com.google.rpc.Code.UNKNOWN.getNumber()); + expected.put(Code.DEADLINE_EXCEEDED, com.google.rpc.Code.DEADLINE_EXCEEDED.getNumber()); + expected.put(Code.DATA_LOSS, com.google.rpc.Code.DATA_LOSS.getNumber()); + + EnumMap actual = new EnumMap<>(Code.class); + for (Code c : Code.values()) { + actual.put(c, GrpcToDatastoreCodeTranslation.grpcCodeToDatastoreStatusCode(c)); + } + + assertThat(actual).isEqualTo(expected); + } +} diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java index 7c105672c..ac9587b2a 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java @@ -16,7 +16,11 @@ package com.google.cloud.datastore.it; +import static com.google.api.gax.rpc.StatusCode.Code.ALREADY_EXISTS; +import static com.google.api.gax.rpc.StatusCode.Code.DEADLINE_EXCEEDED; +import static com.google.api.gax.rpc.StatusCode.Code.FAILED_PRECONDITION; import static com.google.api.gax.rpc.StatusCode.Code.INVALID_ARGUMENT; +import static com.google.api.gax.rpc.StatusCode.Code.NOT_FOUND; import static com.google.cloud.datastore.aggregation.Aggregation.avg; import static com.google.cloud.datastore.aggregation.Aggregation.count; import static com.google.cloud.datastore.aggregation.Aggregation.sum; @@ -28,8 +32,8 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import com.google.cloud.Timestamp; import com.google.cloud.Tuple; @@ -70,9 +74,9 @@ import com.google.cloud.datastore.TimestampValue; import com.google.cloud.datastore.Transaction; import com.google.cloud.datastore.ValueType; -import com.google.cloud.grpc.GrpcTransportOptions; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import com.google.common.truth.Truth; import com.google.datastore.v1.TransactionOptions; import com.google.datastore.v1.TransactionOptions.ReadOnly; import java.util.ArrayList; @@ -383,19 +387,8 @@ public void testNewTransactionCommit() { assertEquals(ENTITY3, list.get(2)); assertEquals(3, list.size()); - try { - transaction.commit(); - fail("Expecting a failure"); - } catch (DatastoreException expected) { - assertEquals("FAILED_PRECONDITION", expected.getReason()); - } - - try { - transaction.rollback(); - fail("Expecting a failure"); - } catch (DatastoreException expected) { - assertEquals("FAILED_PRECONDITION", expected.getReason()); - } + DatastoreException expected = assertThrows(DatastoreException.class, transaction::commit); + assertDatastoreException(expected, FAILED_PRECONDITION.name(), 0); } @Test @@ -492,12 +485,8 @@ public void testNewTransactionRollback() { transaction.rollback(); transaction.rollback(); // should be safe to repeat rollback calls - try { - transaction.commit(); - fail("Expecting a failure"); - } catch (DatastoreException expected) { - assertEquals("FAILED_PRECONDITION", expected.getReason()); - } + DatastoreException expected = assertThrows(DatastoreException.class, transaction::commit); + assertDatastoreException(expected, FAILED_PRECONDITION.name(), 0); List list = datastore.fetch(KEY1, KEY2, KEY3); assertEquals(ENTITY1, list.get(0)); @@ -544,12 +533,8 @@ public void testNewBatch() { assertEquals(PARTIAL_ENTITY3.getNames(), datastore.get(generatedKeys.get(0)).getNames()); assertEquals(PARTIAL_ENTITY3.getKey(), IncompleteKey.newBuilder(generatedKeys.get(0)).build()); - try { - batch.submit(); - fail("Expecting a failure"); - } catch (DatastoreException expected) { - assertEquals("FAILED_PRECONDITION", expected.getReason()); - } + DatastoreException expected = assertThrows(DatastoreException.class, batch::submit); + assertDatastoreException(expected, FAILED_PRECONDITION.name(), 0); batch = datastore.newBatch(); batch.delete(entity4.getKey(), entity5.getKey(), entity6.getKey()); @@ -1256,12 +1241,11 @@ public void testGetArrayNoDeferredResults() { assertEquals(EMPTY_LIST_VALUE, entity3.getValue("emptyList")); assertEquals(8, entity3.getNames().size()); assertFalse(entity3.contains("bla")); - try { - entity3.getString("str"); - fail("Expecting a failure"); - } catch (DatastoreException expected) { - // expected - no such property - } + + DatastoreException expected = + assertThrows(DatastoreException.class, () -> entity3.getString("str")); + assertDatastoreException(expected, FAILED_PRECONDITION.name(), 0); + assertFalse(result.hasNext()); datastore.delete(ENTITY3.getKey()); } @@ -1273,12 +1257,9 @@ public void testAddEntity() { assertNull(keys.get(1)); assertEquals(2, keys.size()); - try { - datastore.add(ENTITY1); - fail("Expecting a failure"); - } catch (DatastoreException expected) { - // expected; - } + DatastoreException expected = + assertThrows(DatastoreException.class, () -> datastore.add(ENTITY1)); + assertDatastoreException(expected, ALREADY_EXISTS.name(), 6); List entities = datastore.add(ENTITY3, PARTIAL_ENTITY1, PARTIAL_ENTITY2); assertEquals(ENTITY3, datastore.get(ENTITY3.getKey())); @@ -1301,12 +1282,10 @@ public void testUpdate() { assertNull(keys.get(1)); assertEquals(2, keys.size()); - try { - datastore.update(ENTITY3); - fail("Expecting a failure"); - } catch (DatastoreException expected) { - // expected; - } + DatastoreException expected = + assertThrows(DatastoreException.class, () -> datastore.update(ENTITY3)); + assertDatastoreException(expected, NOT_FOUND.name(), 5); + datastore.add(ENTITY3); assertEquals(ENTITY3, datastore.get(ENTITY3.getKey())); Entity entity3 = Entity.newBuilder(ENTITY3).clear().set("bla", new NullValue()).build(); @@ -1316,6 +1295,12 @@ public void testUpdate() { datastore.delete(ENTITY3.getKey()); } + private void assertDatastoreException( + DatastoreException expected, String reason, int datastoreStatusCode) { + Truth.assertThat(expected.getReason()).isEqualTo(reason); + Truth.assertThat(expected.getCode()).isEqualTo(datastoreStatusCode); + } + @Test public void testPut() { Entity updatedEntity = Entity.newBuilder(ENTITY1).set("new_property", 42L).build(); @@ -1392,12 +1377,9 @@ public Integer run(DatastoreReaderWriter transaction) { } }; - try { - datastore.runInTransaction(callable2); - fail("Expecting a failure"); - } catch (DatastoreException expected) { - assertEquals(4, ((DatastoreException) expected.getCause()).getCode()); - } + DatastoreException expected = + assertThrows(DatastoreException.class, () -> datastore.runInTransaction(callable2)); + assertDatastoreException((DatastoreException) expected.getCause(), DEADLINE_EXCEEDED.name(), 4); } @Test @@ -1446,18 +1428,10 @@ public Integer run(DatastoreReaderWriter transaction) { .setReadOnly(TransactionOptions.ReadOnly.getDefaultInstance()) .build(); - try { - datastore.runInTransaction(callable2, readOnlyOptions); - fail("Expecting a failure"); - } catch (DatastoreException expected) { - if (datastore.getOptions().getTransportOptions() instanceof GrpcTransportOptions) { - assertEquals( - INVALID_ARGUMENT.getHttpStatusCode(), - ((DatastoreException) expected.getCause()).getCode()); - } else { - assertEquals(3, ((DatastoreException) expected.getCause()).getCode()); - } - } + DatastoreException expected = + assertThrows( + DatastoreException.class, () -> datastore.runInTransaction(callable2, readOnlyOptions)); + assertDatastoreException((DatastoreException) expected.getCause(), INVALID_ARGUMENT.name(), 3); } @Test From ca0fc00f6ad87ff13bfe7de2d3d2fc689a9eea5b Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Wed, 1 May 2024 15:42:04 +0000 Subject: [PATCH 40/42] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20?= =?UTF-8?q?post-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- google-cloud-datastore-bom/pom.xml | 5 ----- .../java/com/google/cloud/datastore/Datastore.java | 3 +-- .../cloud/datastore/it/AbstractITDatastoreTest.java | 1 - pom.xml | 2 +- renovate.json | 11 ----------- 5 files changed, 2 insertions(+), 20 deletions(-) diff --git a/google-cloud-datastore-bom/pom.xml b/google-cloud-datastore-bom/pom.xml index 170bcdf8e..9e829b11f 100644 --- a/google-cloud-datastore-bom/pom.xml +++ b/google-cloud-datastore-bom/pom.xml @@ -59,11 +59,6 @@ grpc-google-cloud-datastore-admin-v1 2.17.6-SNAPSHOT
- - com.google.api.grpc - grpc-google-cloud-datastore-v1 - 2.17.6-SNAPSHOT - com.google.api.grpc proto-google-cloud-datastore-v1 diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Datastore.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Datastore.java index 1f3a90152..791446de5 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Datastore.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Datastore.java @@ -483,8 +483,7 @@ interface TransactionCallable { * @throws DatastoreException upon failure */ @BetaApi - QueryResults run( - Query query, ExplainOptions explainOptions, ReadOption... options); + QueryResults run(Query query, ExplainOptions explainOptions, ReadOption... options); /** * Submits a {@link AggregationQuery} and returns {@link AggregationResults}. {@link ReadOption}s diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java index a1b23b493..c25e87f2f 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/AbstractITDatastoreTest.java @@ -34,7 +34,6 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import com.google.cloud.Timestamp; import com.google.cloud.Tuple; diff --git a/pom.xml b/pom.xml index 068a9242c..35b40a3ca 100644 --- a/pom.xml +++ b/pom.xml @@ -272,9 +272,9 @@ google-cloud-datastore grpc-google-cloud-datastore-admin-v1 - grpc-google-cloud-datastore-v1 proto-google-cloud-datastore-v1 proto-google-cloud-datastore-admin-v1 + grpc-google-cloud-datastore-v1 datastore-v1-proto-client google-cloud-datastore-bom diff --git a/renovate.json b/renovate.json index ac96f549a..7b2939806 100644 --- a/renovate.json +++ b/renovate.json @@ -37,17 +37,6 @@ "datasourceTemplate": "maven" } ], - "customManagers": [ - { - "customType": "regex", - "fileMatch": [ - "^.kokoro/presubmit/graalvm-native.*.cfg$" - ], - "matchStrings": ["value: \"gcr.io/cloud-devrel-public-resources/graalvm.*:(?.*?)\""], - "depNameTemplate": "com.google.cloud:sdk-platform-java-config", - "datasourceTemplate": "maven" - } - ], "packageRules": [ { "packagePatterns": [ From 6db6188a1022401a7793e3d87bf21449e9c580dd Mon Sep 17 00:00:00 2001 From: kolea2 Date: Wed, 1 May 2024 13:41:10 -0400 Subject: [PATCH 41/42] update clirr --- .../clirr-ignored-differences.xml | 40 +++++++++++++++++++ .../google/cloud/datastore/QueryResults.java | 4 +- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/google-cloud-datastore/clirr-ignored-differences.xml b/google-cloud-datastore/clirr-ignored-differences.xml index 9972e93e5..0037fa807 100644 --- a/google-cloud-datastore/clirr-ignored-differences.xml +++ b/google-cloud-datastore/clirr-ignored-differences.xml @@ -45,5 +45,45 @@ boolean isClosed() 7012 + + com/google/cloud/datastore/Datastore + com.google.cloud.datastore.QueryResults run(com.google.cloud.datastore.Query, com.google.cloud.datastore.models.ExplainOptions, com.google.cloud.datastore.ReadOption[]) + 7012 + + + com/google/cloud/datastore/Datastore + com.google.cloud.datastore.AggregationResults runAggregation(com.google.cloud.datastore.AggregationQuery, com.google.cloud.datastore.models.ExplainOptions, com.google.cloud.datastore.ReadOption[]) + 7012 + + + com/google/cloud/datastore/DatastoreReader + com.google.cloud.datastore.AggregationResults runAggregation(com.google.cloud.datastore.AggregationQuery, com.google.cloud.datastore.models.ExplainOptions) + 7012 + + + com/google/cloud/datastore/QueryResults + java.util.Optional getExplainMetrics() + 7012 + + + com/google/cloud/datastore/Transaction + com.google.cloud.datastore.QueryResults run(com.google.cloud.datastore.Query, com.google.cloud.datastore.models.ExplainOptions) + 7012 + + + com/google/cloud/datastore/execution/AggregationQueryExecutor + com.google.cloud.datastore.AggregationResults execute(com.google.cloud.datastore.AggregationQuery, com.google.cloud.datastore.ReadOption[]) + 7004 + + + com/google/cloud/datastore/execution/AggregationQueryExecutor + java.lang.Object execute(com.google.cloud.datastore.Query, com.google.cloud.datastore.ReadOption[]) + 7004 + + + com/google/cloud/datastore/execution/QueryExecutor + java.lang.Object execute(com.google.cloud.datastore.Query, com.google.cloud.datastore.ReadOption[]) + 7004 + diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java index fe9396761..ca5b240ad 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java @@ -77,7 +77,5 @@ public interface QueryResults extends Iterator { QueryResultBatch.MoreResultsType getMoreResults(); @BetaApi - default Optional getExplainMetrics() { - throw new UnsupportedOperationException("Not implemented."); - } + Optional getExplainMetrics(); } From b744e9af14bdec0bf7db40c171673b98d8973838 Mon Sep 17 00:00:00 2001 From: kolea2 Date: Wed, 1 May 2024 14:23:18 -0400 Subject: [PATCH 42/42] revert version changes --- datastore-v1-proto-client/pom.xml | 4 ++-- google-cloud-datastore-bom/pom.xml | 10 +++++----- google-cloud-datastore/pom.xml | 4 ++-- grpc-google-cloud-datastore-admin-v1/pom.xml | 4 ++-- grpc-google-cloud-datastore-v1/pom.xml | 4 ++-- pom.xml | 14 +++++++------- proto-google-cloud-datastore-admin-v1/pom.xml | 4 ++-- proto-google-cloud-datastore-v1/pom.xml | 4 ++-- samples/snapshot/pom.xml | 2 +- versions.txt | 14 +++++++------- 10 files changed, 32 insertions(+), 32 deletions(-) diff --git a/datastore-v1-proto-client/pom.xml b/datastore-v1-proto-client/pom.xml index dd200d90e..e136a9d8c 100644 --- a/datastore-v1-proto-client/pom.xml +++ b/datastore-v1-proto-client/pom.xml @@ -19,12 +19,12 @@ 4.0.0 com.google.cloud.datastore datastore-v1-proto-client - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT com.google.cloud google-cloud-datastore-parent - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT jar diff --git a/google-cloud-datastore-bom/pom.xml b/google-cloud-datastore-bom/pom.xml index 9e829b11f..2651713e3 100644 --- a/google-cloud-datastore-bom/pom.xml +++ b/google-cloud-datastore-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-datastore-bom - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT pom com.google.cloud @@ -52,22 +52,22 @@ com.google.cloud google-cloud-datastore - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT com.google.api.grpc grpc-google-cloud-datastore-admin-v1 - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT com.google.api.grpc proto-google-cloud-datastore-v1 - 0.108.6-SNAPSHOT + 0.110.2-SNAPSHOT com.google.api.grpc proto-google-cloud-datastore-admin-v1 - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT
diff --git a/google-cloud-datastore/pom.xml b/google-cloud-datastore/pom.xml index 45ffa5998..2624f863c 100644 --- a/google-cloud-datastore/pom.xml +++ b/google-cloud-datastore/pom.xml @@ -2,7 +2,7 @@ 4.0.0 google-cloud-datastore - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT jar Google Cloud Datastore https://github.com/googleapis/java-datastore @@ -12,7 +12,7 @@ com.google.cloud google-cloud-datastore-parent - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT google-cloud-datastore diff --git a/grpc-google-cloud-datastore-admin-v1/pom.xml b/grpc-google-cloud-datastore-admin-v1/pom.xml index e5648f270..150832cde 100644 --- a/grpc-google-cloud-datastore-admin-v1/pom.xml +++ b/grpc-google-cloud-datastore-admin-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-datastore-admin-v1 - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT grpc-google-cloud-datastore-admin-v1 GRPC library for google-cloud-datastore com.google.cloud google-cloud-datastore-parent - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT diff --git a/grpc-google-cloud-datastore-v1/pom.xml b/grpc-google-cloud-datastore-v1/pom.xml index 003dd8432..754197440 100644 --- a/grpc-google-cloud-datastore-v1/pom.xml +++ b/grpc-google-cloud-datastore-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-datastore-v1 - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT grpc-google-cloud-datastore-v1 GRPC library for google-cloud-datastore com.google.cloud google-cloud-datastore-parent - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 35b40a3ca..96bc6d6ce 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-datastore-parent pom - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT Google Cloud Datastore Parent https://github.com/googleapis/java-datastore @@ -159,32 +159,32 @@ com.google.api.grpc proto-google-cloud-datastore-admin-v1 - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT com.google.api.grpc grpc-google-cloud-datastore-admin-v1 - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT com.google.cloud google-cloud-datastore - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT com.google.api.grpc proto-google-cloud-datastore-v1 - 0.108.6-SNAPSHOT + 0.110.2-SNAPSHOT com.google.api.grpc grpc-google-cloud-datastore-v1 - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT com.google.cloud.datastore datastore-v1-proto-client - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT com.google.api.grpc diff --git a/proto-google-cloud-datastore-admin-v1/pom.xml b/proto-google-cloud-datastore-admin-v1/pom.xml index ed2f991f2..58e80a474 100644 --- a/proto-google-cloud-datastore-admin-v1/pom.xml +++ b/proto-google-cloud-datastore-admin-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-datastore-admin-v1 - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT proto-google-cloud-datastore-admin-v1 Proto library for google-cloud-datastore com.google.cloud google-cloud-datastore-parent - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT diff --git a/proto-google-cloud-datastore-v1/pom.xml b/proto-google-cloud-datastore-v1/pom.xml index 888dd0ab2..f7533666e 100644 --- a/proto-google-cloud-datastore-v1/pom.xml +++ b/proto-google-cloud-datastore-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-datastore-v1 - 0.108.6-SNAPSHOT + 0.110.2-SNAPSHOT proto-google-cloud-datastore-v1 PROTO library for proto-google-cloud-datastore-v1 com.google.cloud google-cloud-datastore-parent - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 31ffe9bce..45331e46b 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -28,7 +28,7 @@ com.google.cloud google-cloud-datastore - 2.17.6-SNAPSHOT + 2.19.2-SNAPSHOT diff --git a/versions.txt b/versions.txt index 474769910..c5f940aa9 100644 --- a/versions.txt +++ b/versions.txt @@ -1,10 +1,10 @@ # Format: # module:released-version:current-version -google-cloud-datastore:2.17.5:2.17.6-SNAPSHOT -google-cloud-datastore-bom:2.17.5:2.17.6-SNAPSHOT -proto-google-cloud-datastore-v1:0.108.5:0.108.6-SNAPSHOT -datastore-v1-proto-client:2.17.5:2.17.6-SNAPSHOT -proto-google-cloud-datastore-admin-v1:2.17.5:2.17.6-SNAPSHOT -grpc-google-cloud-datastore-admin-v1:2.17.5:2.17.6-SNAPSHOT -grpc-google-cloud-datastore-v1:2.17.5:2.17.6-SNAPSHOT +google-cloud-datastore:2.19.1:2.19.2-SNAPSHOT +google-cloud-datastore-bom:2.19.1:2.19.2-SNAPSHOT +proto-google-cloud-datastore-v1:0.110.1:0.110.2-SNAPSHOT +datastore-v1-proto-client:2.19.1:2.19.2-SNAPSHOT +proto-google-cloud-datastore-admin-v1:2.19.1:2.19.2-SNAPSHOT +grpc-google-cloud-datastore-admin-v1:2.19.1:2.19.2-SNAPSHOT +grpc-google-cloud-datastore-v1:2.19.1:2.19.2-SNAPSHOT