From e48e7fcb3393896b6efa8d991b6c04d5614c47e6 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 21 Oct 2022 14:52:13 +0000 Subject: [PATCH 1/6] chore(main): release 2.12.3-SNAPSHOT (#894) :robot: I have created a release *beep* *boop* --- ### Updating meta-information for bleeding-edge SNAPSHOT release. --- This PR was generated with [Release Please](https://togithub.com/googleapis/release-please). See [documentation](https://togithub.com/googleapis/release-please#release-please). --- 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 ++-- pom.xml | 12 ++++++------ proto-google-cloud-datastore-admin-v1/pom.xml | 4 ++-- proto-google-cloud-datastore-v1/pom.xml | 4 ++-- versions.txt | 12 ++++++------ 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/datastore-v1-proto-client/pom.xml b/datastore-v1-proto-client/pom.xml index 6384e19b1..d646a57f3 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.12.2 + 2.12.3-SNAPSHOT com.google.cloud google-cloud-datastore-parent - 2.12.2 + 2.12.3-SNAPSHOT jar diff --git a/google-cloud-datastore-bom/pom.xml b/google-cloud-datastore-bom/pom.xml index 4d887f01f..20a386fdd 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.12.2 + 2.12.3-SNAPSHOT pom com.google.cloud @@ -52,22 +52,22 @@ com.google.cloud google-cloud-datastore - 2.12.2 + 2.12.3-SNAPSHOT com.google.api.grpc grpc-google-cloud-datastore-admin-v1 - 2.12.2 + 2.12.3-SNAPSHOT com.google.api.grpc proto-google-cloud-datastore-v1 - 0.103.2 + 0.103.3-SNAPSHOT com.google.api.grpc proto-google-cloud-datastore-admin-v1 - 2.12.2 + 2.12.3-SNAPSHOT diff --git a/google-cloud-datastore/pom.xml b/google-cloud-datastore/pom.xml index cadf38274..7b46e70c1 100644 --- a/google-cloud-datastore/pom.xml +++ b/google-cloud-datastore/pom.xml @@ -2,7 +2,7 @@ 4.0.0 google-cloud-datastore - 2.12.2 + 2.12.3-SNAPSHOT jar Google Cloud Datastore https://github.com/googleapis/java-datastore @@ -12,7 +12,7 @@ com.google.cloud google-cloud-datastore-parent - 2.12.2 + 2.12.3-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 ef0630cf5..885cadb61 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.12.2 + 2.12.3-SNAPSHOT grpc-google-cloud-datastore-admin-v1 GRPC library for google-cloud-datastore com.google.cloud google-cloud-datastore-parent - 2.12.2 + 2.12.3-SNAPSHOT diff --git a/pom.xml b/pom.xml index bbd35d1f9..3c7dd0d83 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-datastore-parent pom - 2.12.2 + 2.12.3-SNAPSHOT Google Cloud Datastore Parent https://github.com/googleapis/java-datastore @@ -159,27 +159,27 @@ com.google.api.grpc proto-google-cloud-datastore-admin-v1 - 2.12.2 + 2.12.3-SNAPSHOT com.google.api.grpc grpc-google-cloud-datastore-admin-v1 - 2.12.2 + 2.12.3-SNAPSHOT com.google.cloud google-cloud-datastore - 2.12.2 + 2.12.3-SNAPSHOT com.google.api.grpc proto-google-cloud-datastore-v1 - 0.103.2 + 0.103.3-SNAPSHOT com.google.cloud.datastore datastore-v1-proto-client - 2.12.2 + 2.12.3-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 e7a54ec7f..4d96ca4ba 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.12.2 + 2.12.3-SNAPSHOT proto-google-cloud-datastore-admin-v1 Proto library for google-cloud-datastore com.google.cloud google-cloud-datastore-parent - 2.12.2 + 2.12.3-SNAPSHOT diff --git a/proto-google-cloud-datastore-v1/pom.xml b/proto-google-cloud-datastore-v1/pom.xml index 3fbef4a96..91566d665 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.103.2 + 0.103.3-SNAPSHOT proto-google-cloud-datastore-v1 PROTO library for proto-google-cloud-datastore-v1 com.google.cloud google-cloud-datastore-parent - 2.12.2 + 2.12.3-SNAPSHOT diff --git a/versions.txt b/versions.txt index abf449415..f1e200e07 100644 --- a/versions.txt +++ b/versions.txt @@ -1,9 +1,9 @@ # Format: # module:released-version:current-version -google-cloud-datastore:2.12.2:2.12.2 -google-cloud-datastore-bom:2.12.2:2.12.2 -proto-google-cloud-datastore-v1:0.103.2:0.103.2 -datastore-v1-proto-client:2.12.2:2.12.2 -proto-google-cloud-datastore-admin-v1:2.12.2:2.12.2 -grpc-google-cloud-datastore-admin-v1:2.12.2:2.12.2 +google-cloud-datastore:2.12.2:2.12.3-SNAPSHOT +google-cloud-datastore-bom:2.12.2:2.12.3-SNAPSHOT +proto-google-cloud-datastore-v1:0.103.2:0.103.3-SNAPSHOT +datastore-v1-proto-client:2.12.2:2.12.3-SNAPSHOT +proto-google-cloud-datastore-admin-v1:2.12.2:2.12.3-SNAPSHOT +grpc-google-cloud-datastore-admin-v1:2.12.2:2.12.3-SNAPSHOT From cf9983d5dd5f2982dd659429e478f1ff76055344 Mon Sep 17 00:00:00 2001 From: Prateek Date: Fri, 21 Oct 2022 20:24:04 +0530 Subject: [PATCH 2/6] samples: Add sample snippets for count aggregations (#871) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add method in Datastore client to invoke rpc for aggregation query * Creating count aggregation and using it to populate Aggregation proto * Moving aggregation builder method to root level aggregation class * Introducing RecordQuery to represent queries which returns entity records when executed * Updating gitignore with patch extension * Setting up structure of Aggregation query and its builder * Introducing ProtoPreparer to populate the request protos * Delegating responsibility of preparing query proto to QueryPreparer * Populating aggregation query with nested structured query * Delegating responsibility of preparing query proto in GqlQuery to QueryPreparer * Removing RecordQuery from the query hierarchy and making it a standalone interface for now * Populating aggregation query with nested gql query * Removing deprecation warning by using assertThrows instead of ExpectedException rule * Making DatastoreRpc call aggregation query method on client * Creating response transformer to transform aggregation query response into domain objects * Implementing aggregation query executor to execute AggergationQuery * Adding missing assertion statements * Creating RetryExecutor to inject it as a dependency in other components * Making RetryExecutor accept RetrySettings when creating it * Revert "Making RetryExecutor accept RetrySettings when creating it" This reverts commit 1dfafb7f8adcdd4ec566ac6fc712d2233623d33b. * Revert "Creating RetryExecutor to inject it as a dependency in other components" This reverts commit 8872a55cd1b1e22643222aa62a17049169dee71f. * Introducing RetryAndTraceDatastoreRpcDecorator to have retry and traceability logic on top of another DatastoreRpc * Extracting out the responsibility of preparing ReadOption in it's own ProtoPreparer * Making QueryExecutor to execute query with provided ReadOptions * Exposing readTime to the user * Ignoring runAggregationQuery method from clirr check * Making readTime final * Allowing namespace to be optional in AggregationQuery * Add capability to fetch aggregation result by passing alias * Implementing User facing datastore.runAggrgation method to run aggregation query * Add integration test for count aggregation * Add transaction Id support in ReadOptionsProtoPreparer * Supporting aggregation query with transactions * Allowing user to create Aggregation directly without involving its builder * Preventing creating duplicated aggregation when creating an aggregation query * Marking RecordQuery implemented method as InternalApi * Writing comments and JavaDoc for aggregation query related class * Adding a default implementation in the public interfaces to avoid compile time failures * covering a scenario to maintain consistent snapshot when executing aggregation query in a transaction * Creating emulator proxy to simulate AggregationQuery response from emulator * Integration test to execute an aggregation query in a read only transaction * Count aggregation samples with structuredQuery and gql query * Count aggregation samples to demonstrate stale read * Getting rid off limit operation on count aggregation as same behaviour can be achieved by using 'limit' operation on the underlying query * Removing import statement from javadoc and undo changes in .gitignore file * Using Optional instead of returning null from ReadOptionsProtoPreparer * using assertThat from Truth library * Removing 'limit' api from count query samples * fixing unit test * Getting rid off Double braces initialization syntax * Fixing lint * Getting rid off emulator proxy and using easy mock to check the aggregationQuery triggered * Deleting a entity created locally in other test which is causing failure in other test * Deleting all keys in datastore in integration test so that new test can start fresh * Executing two read write transaction simultaneously and verifying their behaviour * Removing tests to verify serializability as it's an underlying implementation detail * Fixing lint * Adding runAggregationQuery method to reflect config so that it's available and accessible in native image through reflection * Aggregation query samples with limit and order by option * Aggregation query samples with transactions * fixing lint and reusing sysoutRule * correcting region tag * simplifying tearDown method * Reverting back to using Task domain for aggregation query samples * Limiting tearDown method to delete only Task entities * Splitting count aggregation query samples into individual java files * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * Adding missing header * Sticking to the practise of deleting the old created data in setUp of test * Moving comment to the top of statement. Co-authored-by: Sita Lakshmi Sangameswaran * Making builder syntax multiline Co-authored-by: Sita Lakshmi Sangameswaran * Adding comment describing the purpose of GQL query Co-authored-by: Sita Lakshmi Sangameswaran * Rephrasing the comment Co-authored-by: Sita Lakshmi Sangameswaran * Adding a comment describing the purpose of the GQL query Co-authored-by: Sita Lakshmi Sangameswaran * Rephrasing the comment Co-authored-by: Sita Lakshmi Sangameswaran * Relocating region tags to include import statments * Few styling and comment fixes * Adding comment in the transaction block * Adding fullstop to the comment lines * Showcasing with/without alias usage separately * Importing static methods are we are now including import statements in samples * 🦉 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 Co-authored-by: Sita Lakshmi Sangameswaran --- README.md | 7 ++ .../CountAggregationInTransaction.java | 85 +++++++++++++++ .../aggregation/CountAggregationOnKind.java | 90 ++++++++++++++++ .../CountAggregationWithGqlQuery.java | 87 +++++++++++++++ .../CountAggregationWithLimit.java | 65 +++++++++++ .../CountAggregationWithOrderBy.java | 70 ++++++++++++ .../CountAggregationWithPropertyFilter.java | 90 ++++++++++++++++ .../CountAggregationWithStaleRead.java | 80 ++++++++++++++ .../AggregationQuerySampleTestIT.java | 101 ++++++++++++++++++ .../example/datastore/QuickstartSampleIT.java | 19 ++-- .../test/java/com/rule/SystemsOutRule.java | 53 +++++++++ 11 files changed, 734 insertions(+), 13 deletions(-) create mode 100644 samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationInTransaction.java create mode 100644 samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationOnKind.java create mode 100644 samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithGqlQuery.java create mode 100644 samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithLimit.java create mode 100644 samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithOrderBy.java create mode 100644 samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithPropertyFilter.java create mode 100644 samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithStaleRead.java create mode 100644 samples/snippets/src/test/java/com/example/datastore/AggregationQuerySampleTestIT.java create mode 100644 samples/snippets/src/test/java/com/rule/SystemsOutRule.java diff --git a/README.md b/README.md index 1e4971f86..e6b5f5fea 100644 --- a/README.md +++ b/README.md @@ -234,6 +234,13 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-datastore/tre | --------------------------- | --------------------------------- | ------ | | Native Image Datastore Sample | [source code](https://github.com/googleapis/java-datastore/blob/main/samples/native-image-sample/src/main/java/com/example/datastore/NativeImageDatastoreSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-datastore&page=editor&open_in_editor=samples/native-image-sample/src/main/java/com/example/datastore/NativeImageDatastoreSample.java) | | Quickstart Sample | [source code](https://github.com/googleapis/java-datastore/blob/main/samples/snippets/src/main/java/com/example/datastore/QuickstartSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-datastore&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/datastore/QuickstartSample.java) | +| Count Aggregation In Transaction | [source code](https://github.com/googleapis/java-datastore/blob/main/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationInTransaction.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-datastore&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationInTransaction.java) | +| Count Aggregation On Kind | [source code](https://github.com/googleapis/java-datastore/blob/main/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationOnKind.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-datastore&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationOnKind.java) | +| Count Aggregation With Gql Query | [source code](https://github.com/googleapis/java-datastore/blob/main/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithGqlQuery.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-datastore&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithGqlQuery.java) | +| Count Aggregation With Limit | [source code](https://github.com/googleapis/java-datastore/blob/main/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithLimit.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-datastore&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithLimit.java) | +| Count Aggregation With Order By | [source code](https://github.com/googleapis/java-datastore/blob/main/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithOrderBy.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-datastore&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithOrderBy.java) | +| Count Aggregation With Property Filter | [source code](https://github.com/googleapis/java-datastore/blob/main/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithPropertyFilter.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-datastore&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithPropertyFilter.java) | +| Count Aggregation With Stale Read | [source code](https://github.com/googleapis/java-datastore/blob/main/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithStaleRead.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-datastore&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithStaleRead.java) | | Task List | [source code](https://github.com/googleapis/java-datastore/blob/main/samples/snippets/src/main/java/com/google/datastore/snippets/TaskList.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-datastore&page=editor&open_in_editor=samples/snippets/src/main/java/com/google/datastore/snippets/TaskList.java) | diff --git a/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationInTransaction.java b/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationInTransaction.java new file mode 100644 index 000000000..ca62e2cab --- /dev/null +++ b/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationInTransaction.java @@ -0,0 +1,85 @@ +/* + * Copyright 2022 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.example.datastore.aggregation; + +// [START datastore_count_aggregation_query_in_transaction] + +import static com.google.cloud.datastore.aggregation.Aggregation.count; + +import com.google.cloud.datastore.AggregationQuery; +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.Key; +import com.google.cloud.datastore.Query; +import com.google.cloud.datastore.StructuredQuery.PropertyFilter; +import com.google.common.collect.Iterables; + +public class CountAggregationInTransaction { + + public static void invoke() { + // Instantiates a client. + Datastore datastore = DatastoreOptions.getDefaultInstance().getService(); + + // The kind for the new entity. + String kind = "Task"; + + Key task1Key = datastore.newKeyFactory().setKind(kind).newKey("task1"); + Key task2Key = datastore.newKeyFactory().setKind(kind).newKey("task2"); + + // Save all the tasks. + datastore.put( + Entity.newBuilder(task1Key).set("owner", "john").build(), + Entity.newBuilder(task2Key).set("owner", "john").build()); + + // Using transactions to maintain consistent application state. + datastore.runInTransaction( + (TransactionCallable) + transaction -> { + // Create a query to get the count of all tasks of owner 'John'. + EntityQuery tasksOfJohn = + Query.newEntityQueryBuilder() + .setKind(kind) + .setFilter(PropertyFilter.eq("owner", "john")) + .build(); + AggregationQuery totalTasksQuery = + Query.newAggregationQueryBuilder() + .over(tasksOfJohn) + .addAggregation(count().as("tasks_count")) + .build(); + + // Executing aggregation query in the ongoing transaction. + Long tasksCount = + Iterables.getOnlyElement(transaction.runAggregation(totalTasksQuery)) + .get("tasks_count"); + + if (tasksCount < 2) { + Key newTaskKey = datastore.newKeyFactory().setKind(kind).newKey("task3"); + Entity newTask = Entity.newBuilder(newTaskKey).set("owner", "john").build(); + // Inserting a new entity in the transaction. + transaction.put(newTask); + } else { + System.out.printf("Found existing %d tasks, rolling back", tasksCount); + throw new Exception("User 'John' cannot have more than 2 tasks"); + } + return null; + }); + } +} +// [END datastore_count_aggregation_query_in_transaction] diff --git a/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationOnKind.java b/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationOnKind.java new file mode 100644 index 000000000..b2673653a --- /dev/null +++ b/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationOnKind.java @@ -0,0 +1,90 @@ +/* + * Copyright 2022 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.example.datastore.aggregation; + +// [START datastore_count_aggregation_query_on_kind] +import static com.google.cloud.datastore.aggregation.Aggregation.count; + +import com.google.cloud.datastore.AggregationQuery; +import com.google.cloud.datastore.AggregationResult; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.EntityQuery; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.Query; +import com.google.common.collect.Iterables; + +public class CountAggregationOnKind { + // Instantiates a client. + private static final Datastore datastore = DatastoreOptions.getDefaultInstance().getService(); + + // The kind for the new entity. + private static final String kind = "Task"; + + // Setting up Tasks in database + private static void setUpTasks() { + Key task1Key = datastore.newKeyFactory().setKind(kind).newKey("task1"); + Key task2Key = datastore.newKeyFactory().setKind(kind).newKey("task2"); + Key task3Key = datastore.newKeyFactory().setKind(kind).newKey("task3"); + + // Save all the tasks. + datastore.put( + Entity.newBuilder(task1Key).set("done", true).build(), + Entity.newBuilder(task2Key).set("done", false).build(), + Entity.newBuilder(task3Key).set("done", true).build()); + } + + // Accessing aggregation result by the generated alias. + private static void usageWithGeneratedAlias() { + EntityQuery selectAllTasks = Query.newEntityQueryBuilder().setKind(kind).build(); + // Creating an aggregation query to get the count of all tasks. + AggregationQuery allTasksCountQuery = + Query.newAggregationQueryBuilder().over(selectAllTasks).addAggregation(count()).build(); + // Executing aggregation query. + AggregationResult aggregationResult = + Iterables.getOnlyElement(datastore.runAggregation(allTasksCountQuery)); + + System.out.printf( + "Total tasks (accessible from default alias) is %d", + aggregationResult.get("property_1")); // 3 + } + + // Accessing aggregation result by the provided custom alias. + private static void usageWithCustomAlias() { + EntityQuery selectAllTasks = Query.newEntityQueryBuilder().setKind(kind).build(); + // Creating an aggregation query to get the count of all tasks. + AggregationQuery allTasksCountQuery = + Query.newAggregationQueryBuilder() + .over(selectAllTasks) + // passing 'total_count' as alias in the aggregation query. + .addAggregation(count().as("total_count")) + .build(); + // Executing aggregation query. + AggregationResult aggregationResult = + Iterables.getOnlyElement(datastore.runAggregation(allTasksCountQuery)); + + System.out.printf("Total tasks count is %d", aggregationResult.get("total_count")); // 3 + } + + public static void invoke() { + setUpTasks(); + usageWithGeneratedAlias(); + usageWithCustomAlias(); + } +} +// [END datastore_count_aggregation_query_on_kind] diff --git a/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithGqlQuery.java b/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithGqlQuery.java new file mode 100644 index 000000000..fd2bf8cc4 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithGqlQuery.java @@ -0,0 +1,87 @@ +/* + * Copyright 2022 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.example.datastore.aggregation; + +// [START datastore_count_aggregation_query_gql] +import com.google.cloud.datastore.AggregationQuery; +import com.google.cloud.datastore.AggregationResult; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.GqlQuery; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.Query; +import com.google.common.collect.Iterables; + +public class CountAggregationWithGqlQuery { + + public static void invoke() { + // Instantiates a client. + Datastore datastore = DatastoreOptions.getDefaultInstance().getService(); + + // The kind for the new entity. + String kind = "Task"; + + Key task1Key = datastore.newKeyFactory().setKind(kind).newKey("task1"); + Key task2Key = datastore.newKeyFactory().setKind(kind).newKey("task2"); + Key task3Key = datastore.newKeyFactory().setKind(kind).newKey("task3"); + + // Save all the tasks. + datastore.put( + Entity.newBuilder(task1Key).set("done", true).build(), + Entity.newBuilder(task2Key).set("done", false).build(), + Entity.newBuilder(task3Key).set("done", true).build()); + + // Create a GQL query to get the count of all tasks. + GqlQuery selectAllTasks = + Query.newGqlQueryBuilder( + "AGGREGATE COUNT(*) AS total_count, COUNT_UP_TO(2) AS count_with_limit " + + "OVER (SELECT * FROM Task)") + .setAllowLiteral(true) + .build(); + // Create the aggregation query builder and set the query. + AggregationQuery allTasksCountQuery = + Query.newAggregationQueryBuilder().over(selectAllTasks).build(); + // Executing aggregation query. + AggregationResult allTasksCountQueryResult = + Iterables.getOnlyElement(datastore.runAggregation(allTasksCountQuery)); + + System.out.printf( + "We have at least %d tasks", allTasksCountQueryResult.get("count_with_limit")); // 2 + System.out.printf("Total tasks count is %d", allTasksCountQueryResult.get("total_count")); // 3 + + // Create a query to get the count of all completed tasks. + GqlQuery completedTasks = + Query.newGqlQueryBuilder( + "AGGREGATE COUNT(*) AS total_completed_count " + + "OVER (SELECT * FROM Task WHERE done = true)") + .setAllowLiteral(true) + .build(); + // Create the aggregation query builder and set the query. + AggregationQuery completedTasksCountQuery = + Query.newAggregationQueryBuilder().over(completedTasks).build(); + + // Executing aggregation query. + AggregationResult completedTasksCountQueryResult = + Iterables.getOnlyElement(datastore.runAggregation(completedTasksCountQuery)); + + System.out.printf( + "Total completed tasks count is %d", + completedTasksCountQueryResult.get("total_completed_count")); // 2 + } +} +// [END datastore_count_aggregation_query_gql] diff --git a/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithLimit.java b/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithLimit.java new file mode 100644 index 000000000..a6a1a4c55 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithLimit.java @@ -0,0 +1,65 @@ +/* + * Copyright 2022 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.example.datastore.aggregation; + +// [START datastore_count_aggregation_query_with_limit] + +import static com.google.cloud.datastore.aggregation.Aggregation.count; + +import com.google.cloud.datastore.AggregationQuery; +import com.google.cloud.datastore.AggregationResult; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.EntityQuery; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.Query; +import com.google.common.collect.Iterables; + +public class CountAggregationWithLimit { + public static void invoke() { + // Instantiates a client. + Datastore datastore = DatastoreOptions.getDefaultInstance().getService(); + + // The kind for the new entity. + String kind = "Task"; + + Key task1Key = datastore.newKeyFactory().setKind(kind).newKey("task1"); + Key task2Key = datastore.newKeyFactory().setKind(kind).newKey("task2"); + Key task3Key = datastore.newKeyFactory().setKind(kind).newKey("task3"); + + // Save all the tasks. + datastore.put( + Entity.newBuilder(task1Key).set("done", true).build(), + Entity.newBuilder(task2Key).set("done", false).build(), + Entity.newBuilder(task3Key).set("done", true).build()); + + EntityQuery selectAllTasks = Query.newEntityQueryBuilder().setKind(kind).setLimit(2).build(); + // Creating an aggregation query to get the count of all tasks. + AggregationQuery allTasksCountQuery = + Query.newAggregationQueryBuilder() + .over(selectAllTasks) + .addAggregation(count().as("at_least")) + .build(); + // Executing aggregation query. + AggregationResult limitQueryResult = + Iterables.getOnlyElement(datastore.runAggregation(allTasksCountQuery)); + + System.out.printf("We have at least %d tasks", limitQueryResult.get("at_least")); // 2 + } +} +// [END datastore_count_aggregation_query_with_limit] diff --git a/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithOrderBy.java b/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithOrderBy.java new file mode 100644 index 000000000..247bbdefe --- /dev/null +++ b/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithOrderBy.java @@ -0,0 +1,70 @@ +/* + * Copyright 2022 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.example.datastore.aggregation; + +// [START datastore_count_aggregation_query_with_order_by] + +import static com.google.cloud.datastore.StructuredQuery.OrderBy.asc; +import static com.google.cloud.datastore.aggregation.Aggregation.count; + +import com.google.cloud.datastore.AggregationQuery; +import com.google.cloud.datastore.AggregationResult; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.EntityQuery; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.Query; +import com.google.common.collect.Iterables; + +public class CountAggregationWithOrderBy { + public static void invoke() { + // Instantiates a client. + Datastore datastore = DatastoreOptions.getDefaultInstance().getService(); + + // The kind for the new entity. + String kind = "Task"; + + Key task1Key = datastore.newKeyFactory().setKind(kind).newKey("task1"); + Key task2Key = datastore.newKeyFactory().setKind(kind).newKey("task2"); + Key task3Key = datastore.newKeyFactory().setKind(kind).newKey("task3"); + + // Save all the tasks. + datastore.put( + Entity.newBuilder(task1Key).set("done", true).set("priority", 1).build(), + // Priority not specified. + Entity.newBuilder(task2Key).set("done", false).build(), + Entity.newBuilder(task3Key).set("done", true).set("priority", 2).build()); + + // OrderBy acts as an existence filter. + EntityQuery selectAllTasks = + Query.newEntityQueryBuilder().setKind(kind).addOrderBy(asc("priority")).build(); + // Creating an aggregation query to get the count of all tasks. + AggregationQuery allTasksCountQuery = + Query.newAggregationQueryBuilder() + .over(selectAllTasks) + .addAggregation(count().as("count")) + .build(); + // Executing aggregation query. + AggregationResult limitQueryResult = + Iterables.getOnlyElement(datastore.runAggregation(allTasksCountQuery)); + + System.out.printf( + "Total %d tasks found with priority field", limitQueryResult.get("count")); // 2 + } +} +// [END datastore_count_aggregation_query_with_order_by] diff --git a/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithPropertyFilter.java b/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithPropertyFilter.java new file mode 100644 index 000000000..ecc53b496 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithPropertyFilter.java @@ -0,0 +1,90 @@ +/* + * Copyright 2022 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.example.datastore.aggregation; + +// [START datastore_count_aggregation_query_with_filters] + +import static com.google.cloud.datastore.aggregation.Aggregation.count; + +import com.google.cloud.datastore.AggregationQuery; +import com.google.cloud.datastore.AggregationResult; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.EntityQuery; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.Query; +import com.google.cloud.datastore.StructuredQuery.PropertyFilter; +import com.google.common.collect.Iterables; + +public class CountAggregationWithPropertyFilter { + + public static void invoke() { + // Instantiates a client. + Datastore datastore = DatastoreOptions.getDefaultInstance().getService(); + + // The kind for the new entity. + String kind = "Task"; + + Key task1Key = datastore.newKeyFactory().setKind(kind).newKey("task1"); + Key task2Key = datastore.newKeyFactory().setKind(kind).newKey("task2"); + Key task3Key = datastore.newKeyFactory().setKind(kind).newKey("task3"); + + // Save all the tasks. + datastore.put( + Entity.newBuilder(task1Key).set("done", true).build(), + Entity.newBuilder(task2Key).set("done", false).build(), + Entity.newBuilder(task3Key).set("done", true).build()); + + EntityQuery completedTasks = + Query.newEntityQueryBuilder() + .setKind(kind) + .setFilter(PropertyFilter.eq("done", true)) + .build(); + EntityQuery remainingTasks = + Query.newEntityQueryBuilder() + .setKind(kind) + .setFilter(PropertyFilter.eq("done", false)) + .build(); + // Creating an aggregation query to get the count of all completed tasks. + AggregationQuery completedTasksCountQuery = + Query.newAggregationQueryBuilder() + .over(completedTasks) + .addAggregation(count().as("total_completed_count")) + .build(); + // Creating an aggregation query to get the count of all remaining tasks. + AggregationQuery remainingTasksCountQuery = + Query.newAggregationQueryBuilder() + .over(remainingTasks) + .addAggregation(count().as("total_remaining_count")) + .build(); + + // Executing aggregation query. + AggregationResult completedTasksCountQueryResult = + Iterables.getOnlyElement(datastore.runAggregation(completedTasksCountQuery)); + AggregationResult remainingTasksCountQueryResult = + Iterables.getOnlyElement(datastore.runAggregation(remainingTasksCountQuery)); + + System.out.printf( + "Total completed tasks count is %d", + completedTasksCountQueryResult.get("total_completed_count")); // 2 + System.out.printf( + "Total remaining tasks count is %d", + remainingTasksCountQueryResult.get("total_remaining_count")); // 1 + } +} +// [END datastore_count_aggregation_query_with_filters] diff --git a/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithStaleRead.java b/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithStaleRead.java new file mode 100644 index 000000000..e46670b98 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/datastore/aggregation/CountAggregationWithStaleRead.java @@ -0,0 +1,80 @@ +/* + * Copyright 2022 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.example.datastore.aggregation; + +// [START datastore_count_aggregation_query_stale_read] + +import static com.google.cloud.datastore.aggregation.Aggregation.count; + +import com.google.cloud.Timestamp; +import com.google.cloud.datastore.AggregationQuery; +import com.google.cloud.datastore.AggregationResult; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.EntityQuery; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.Query; +import com.google.cloud.datastore.ReadOption; +import com.google.common.collect.Iterables; + +public class CountAggregationWithStaleRead { + + public static void invoke() throws InterruptedException { + // Instantiates a client. + Datastore datastore = DatastoreOptions.getDefaultInstance().getService(); + + // The kind for the new entity. + String kind = "Task"; + + Key task1Key = datastore.newKeyFactory().setKind(kind).newKey("task1"); + Key task2Key = datastore.newKeyFactory().setKind(kind).newKey("task2"); + + // Saving only two tasks. + datastore.put( + Entity.newBuilder(task1Key).set("done", true).build(), + Entity.newBuilder(task2Key).set("done", false).build()); + Thread.sleep(1000); + final Timestamp pastTimestamp = Timestamp.now(); // we have two tasks in database at this time. + + Thread.sleep(1000); + // Saving third tasks. + Key task3Key = datastore.newKeyFactory().setKind(kind).newKey("task3"); + datastore.put(Entity.newBuilder(task3Key).set("done", false).build()); + + EntityQuery selectAllTasks = Query.newEntityQueryBuilder().setKind(kind).build(); + + // Creating an aggregation query to get the count of all tasks. + AggregationQuery allTasksCountQuery = + Query.newAggregationQueryBuilder() + .over(selectAllTasks) + .addAggregation(count().as("total_count")) + .build(); + + // Executing aggregation query. + AggregationResult tasksCountLatest = + Iterables.getOnlyElement(datastore.runAggregation(allTasksCountQuery)); + System.out.printf("Latest tasks count is %d", tasksCountLatest.get("total_count")); // 3 + + // Executing aggregation query with past timestamp. + AggregationResult tasksCountInPast = + Iterables.getOnlyElement( + datastore.runAggregation(allTasksCountQuery, ReadOption.readTime(pastTimestamp))); + System.out.printf("Stale tasks count is %d", tasksCountInPast.get("total_count")); // 2 + } +} +// [END datastore_count_aggregation_query_stale_read] diff --git a/samples/snippets/src/test/java/com/example/datastore/AggregationQuerySampleTestIT.java b/samples/snippets/src/test/java/com/example/datastore/AggregationQuerySampleTestIT.java new file mode 100644 index 000000000..662802e51 --- /dev/null +++ b/samples/snippets/src/test/java/com/example/datastore/AggregationQuerySampleTestIT.java @@ -0,0 +1,101 @@ +/* + * Copyright 2022 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.example.datastore; + +import static org.junit.Assert.assertThrows; + +import com.example.datastore.aggregation.CountAggregationInTransaction; +import com.example.datastore.aggregation.CountAggregationOnKind; +import com.example.datastore.aggregation.CountAggregationWithGqlQuery; +import com.example.datastore.aggregation.CountAggregationWithLimit; +import com.example.datastore.aggregation.CountAggregationWithOrderBy; +import com.example.datastore.aggregation.CountAggregationWithPropertyFilter; +import com.example.datastore.aggregation.CountAggregationWithStaleRead; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.KeyQuery; +import com.google.cloud.datastore.Query; +import com.google.cloud.datastore.QueryResults; +import com.google.common.collect.ImmutableList; +import com.rule.SystemsOutRule; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +public class AggregationQuerySampleTestIT { + + private final Datastore datastore = DatastoreOptions.getDefaultInstance().getService(); + + @Rule public final SystemsOutRule systemsOutRule = new SystemsOutRule(); + + @Before + public void setUp() throws Exception { + // Retrieving and deleting all the 'Task' entities. + KeyQuery allKeysQuery = Query.newKeyQueryBuilder().setKind("Task").build(); + QueryResults allKeys = datastore.run(allKeysQuery); + Key[] keysToDelete = ImmutableList.copyOf(allKeys).toArray(new Key[0]); + datastore.delete(keysToDelete); + } + + @Test + public void testAggregationQueryAndCountAggregationSample() { + CountAggregationOnKind.invoke(); + systemsOutRule.assertContains("Total tasks count is 3"); + systemsOutRule.assertContains("Total tasks (accessible from default alias) is 3"); + } + + @Test + public void testAggregationQueryAndCountAggregationWithLimitSample() { + CountAggregationWithLimit.invoke(); + systemsOutRule.assertContains("We have at least 2 tasks"); + } + + @Test + public void testAggregationQueryAndCountAggregationWithOrderBySample() { + CountAggregationWithOrderBy.invoke(); + systemsOutRule.assertContains("Total 2 tasks found with priority field"); + } + + @Test + public void testAggregationQueryAndCountAggregationWithPropertyFilterSample() { + CountAggregationWithPropertyFilter.invoke(); + systemsOutRule.assertContains("Total completed tasks count is 2"); + systemsOutRule.assertContains("Total remaining tasks count is 1"); + } + + @Test + public void testAggregationQueryAndCountAggregationSampleWithGqlQuery() { + CountAggregationWithGqlQuery.invoke(); + systemsOutRule.assertContains("We have at least 2 tasks"); + systemsOutRule.assertContains("Total tasks count is 3"); + systemsOutRule.assertContains("Total completed tasks count is 2"); + } + + @Test + public void testAggregationQueryAndCountWithStaleRead() throws InterruptedException { + CountAggregationWithStaleRead.invoke(); + systemsOutRule.assertContains("Latest tasks count is 3"); + systemsOutRule.assertContains("Stale tasks count is 2"); + } + + @Test + public void testAggregationQueryAndCountWithTransaction() throws InterruptedException { + assertThrows(Exception.class, CountAggregationInTransaction::invoke); + systemsOutRule.assertContains("Found existing 2 tasks, rolling back"); + } +} diff --git a/samples/snippets/src/test/java/com/example/datastore/QuickstartSampleIT.java b/samples/snippets/src/test/java/com/example/datastore/QuickstartSampleIT.java index 1d46f20a4..09823479f 100644 --- a/samples/snippets/src/test/java/com/example/datastore/QuickstartSampleIT.java +++ b/samples/snippets/src/test/java/com/example/datastore/QuickstartSampleIT.java @@ -16,15 +16,13 @@ package com.example.datastore; -import static com.google.common.truth.Truth.assertThat; - import com.google.cloud.datastore.Datastore; import com.google.cloud.datastore.DatastoreOptions; import com.google.cloud.datastore.Key; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; +import com.rule.SystemsOutRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -33,8 +31,8 @@ @RunWith(JUnit4.class) @SuppressWarnings("checkstyle:abbreviationaswordinname") public class QuickstartSampleIT { - private ByteArrayOutputStream bout; - private PrintStream out; + + @Rule public final SystemsOutRule systemsOutRule = new SystemsOutRule(); private static final void deleteTestEntity() { Datastore datastore = DatastoreOptions.getDefaultInstance().getService(); @@ -47,10 +45,6 @@ private static final void deleteTestEntity() { @Before public void setUp() { deleteTestEntity(); - - bout = new ByteArrayOutputStream(); - out = new PrintStream(bout); - System.setOut(out); } @After @@ -62,8 +56,7 @@ public void tearDown() { @Test public void testQuickstart() throws Exception { QuickstartSample.main(); - String got = bout.toString(); - assertThat(got).contains("Saved sampletask1: Buy milk"); - assertThat(got).contains("Retrieved sampletask1: Buy milk"); + systemsOutRule.assertContains("Saved sampletask1: Buy milk"); + systemsOutRule.assertContains("Retrieved sampletask1: Buy milk"); } } diff --git a/samples/snippets/src/test/java/com/rule/SystemsOutRule.java b/samples/snippets/src/test/java/com/rule/SystemsOutRule.java new file mode 100644 index 000000000..9cdb2744e --- /dev/null +++ b/samples/snippets/src/test/java/com/rule/SystemsOutRule.java @@ -0,0 +1,53 @@ +/* + * Copyright 2022 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.rule; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +public class SystemsOutRule implements TestRule { + private ByteArrayOutputStream currentOut; + + @Override + public Statement apply(Statement statement, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + // Setting up customized PrintStream + final PrintStream originalOut = System.out; + currentOut = new ByteArrayOutputStream(); + System.setOut(new PrintStream(currentOut)); + + // Running tests + statement.evaluate(); + + // Restoring original PrintStream + System.setOut(originalOut); + currentOut = null; + } + }; + } + + public void assertContains(String content) { + assertThat(currentOut.toString()).contains(content); + } +} From 0382c3ddfcf13192e483e371ab470f2dd83607aa Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Mon, 24 Oct 2022 18:57:21 +0200 Subject: [PATCH 3/6] deps: update dependency org.easymock:easymock to v5.0.1 (#896) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * deps: update dependency org.easymock:easymock to v5.0.1 * 🦉 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 | 4 ++-- pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e6b5f5fea..a2b026bb6 100644 --- a/README.md +++ b/README.md @@ -56,13 +56,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.12.1' +implementation 'com.google.cloud:google-cloud-datastore:2.12.2' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.12.1" +libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.12.2" ``` ## Authentication diff --git a/pom.xml b/pom.xml index 3c7dd0d83..666c1f936 100644 --- a/pom.xml +++ b/pom.xml @@ -197,7 +197,7 @@ org.easymock easymock - 5.0.0 + 5.0.1 test From cf15491abc289fd781becad7e8d8e244d20b13b5 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Mon, 24 Oct 2022 12:57:37 -0400 Subject: [PATCH 4/6] chore: [java] remove flatten plugin dependency check (#1663) (#897) chore: remove check for flatten plugin We have had the check for the flatten-maven-plugin in each Cloud Java client repository. However, the behavior of the plugin has been stable and its not each repository's responsibility to assert the plugin's behavior. A new check is going to be added at the googleapis/java-shared-config repository to assert the plugin's behavior when we upgrade its version. Source-Link: https://github.com/googleapis/synthtool/commit/9266ddc3b17fc15f34d2fb88ce8c5f1a4bfe64b0 Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-java:latest@sha256:ae72564aa9c368b9ccd96f4af21f87889fd83b9e60635b80844deb5a2ccd08aa Co-authored-by: Owl Bot --- .github/.OwlBot.lock.yaml | 2 +- .kokoro/dependencies.sh | 51 --------------------------------------- 2 files changed, 1 insertion(+), 52 deletions(-) diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 7649651cc..459487d38 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -13,4 +13,4 @@ # limitations under the License. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-java:latest - digest: sha256:264c6d5da60ff1684fbdd2b268d6a3ffca2038246e0948a06f15ca0c3cf28ce8 + digest: sha256:ae72564aa9c368b9ccd96f4af21f87889fd83b9e60635b80844deb5a2ccd08aa diff --git a/.kokoro/dependencies.sh b/.kokoro/dependencies.sh index d7476cfe9..bd8960246 100755 --- a/.kokoro/dependencies.sh +++ b/.kokoro/dependencies.sh @@ -57,54 +57,3 @@ retry_with_backoff 3 10 \ -Dclirr.skip=true mvn -B dependency:analyze -DfailOnWarning=true - -echo "****************** DEPENDENCY LIST COMPLETENESS CHECK *******************" -## Run dependency list completeness check -function completenessCheck() { - # Output dep list with compile scope generated using the original pom - # Running mvn dependency:list on Java versions that support modules will also include the module of the dependency. - # This is stripped from the output as it is not present in the flattened pom. - # Only dependencies with 'compile' or 'runtime' scope are included from original dependency list. - msg "Generating dependency list using original pom..." - mvn dependency:list -f pom.xml -DincludeScope=runtime -Dsort=true | grep '\[INFO] .*:.*:.*:.*:.*' | sed -e 's/ --.*//' >.org-list.txt - - # Output dep list generated using the flattened pom (only 'compile' and 'runtime' scopes) - msg "Generating dependency list using flattened pom..." - mvn dependency:list -f .flattened-pom.xml -DincludeScope=runtime -Dsort=true | grep '\[INFO] .*:.*:.*:.*:.*' >.new-list.txt - - # Compare two dependency lists - msg "Comparing dependency lists..." - diff .org-list.txt .new-list.txt >.diff.txt - if [[ $? == 0 ]] - then - msg "Success. No diff!" - else - msg "Diff found. See below: " - msg "You can also check .diff.txt file located in $1." - cat .diff.txt - return 1 - fi -} - -# Allow failures to continue running the script -set +e - -error_count=0 -for path in **/.flattened-pom.xml -do - # Check flattened pom in each dir that contains it for completeness - dir=$(dirname "$path") - pushd "$dir" - completenessCheck "$dir" - error_count=$(($error_count + $?)) - popd -done - -if [[ $error_count == 0 ]] -then - msg "All checks passed." - exit 0 -else - msg "Errors found. See log statements above." - exit 1 -fi From 36b09468b96ce09db33df31955724c8000f5ce8c Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Mon, 24 Oct 2022 18:57:52 +0200 Subject: [PATCH 5/6] chore(deps): update dependency com.google.cloud:google-cloud-datastore to v2.12.2 (#895) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(deps): update dependency com.google.cloud:google-cloud-datastore to v2.12.2 * 🦉 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 | 2 +- samples/install-without-bom/pom.xml | 2 +- samples/snapshot/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a2b026bb6..93e5228db 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ If you are using Maven without BOM, add this to your dependencies: com.google.cloud google-cloud-datastore - 2.12.1 + 2.12.2 ``` diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index dd883c592..d26ea36f1 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -29,7 +29,7 @@ com.google.cloud google-cloud-datastore - 2.12.1 + 2.12.2 diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index c00f576d5..ee9799e83 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -28,7 +28,7 @@ com.google.cloud google-cloud-datastore - 2.12.1 + 2.12.2 From da5d62c7f435ef5b8894a4f28499e65ca8b5102c Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 24 Oct 2022 17:18:41 +0000 Subject: [PATCH 6/6] chore(main): release 2.12.3 (#898) :robot: I have created a release *beep* *boop* --- ## [2.12.3](https://togithub.com/googleapis/java-datastore/compare/v2.12.2...v2.12.3) (2022-10-24) ### Dependencies * Update dependency org.easymock:easymock to v5.0.1 ([#896](https://togithub.com/googleapis/java-datastore/issues/896)) ([0382c3d](https://togithub.com/googleapis/java-datastore/commit/0382c3ddfcf13192e483e371ab470f2dd83607aa)) --- This PR was generated with [Release Please](https://togithub.com/googleapis/release-please). See [documentation](https://togithub.com/googleapis/release-please#release-please). --- CHANGELOG.md | 7 +++++++ README.md | 2 +- 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 ++-- pom.xml | 12 ++++++------ proto-google-cloud-datastore-admin-v1/pom.xml | 4 ++-- proto-google-cloud-datastore-v1/pom.xml | 4 ++-- samples/install-without-bom/pom.xml | 2 +- samples/snapshot/pom.xml | 2 +- versions.txt | 12 ++++++------ 12 files changed, 37 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4eefc0e2..d9b3bc40c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.12.3](https://github.com/googleapis/java-datastore/compare/v2.12.2...v2.12.3) (2022-10-24) + + +### Dependencies + +* Update dependency org.easymock:easymock to v5.0.1 ([#896](https://github.com/googleapis/java-datastore/issues/896)) ([0382c3d](https://github.com/googleapis/java-datastore/commit/0382c3ddfcf13192e483e371ab470f2dd83607aa)) + ## [2.12.2](https://github.com/googleapis/java-datastore/compare/v2.12.1...v2.12.2) (2022-10-21) diff --git a/README.md b/README.md index 93e5228db..a2b026bb6 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ If you are using Maven without BOM, add this to your dependencies: com.google.cloud google-cloud-datastore - 2.12.2 + 2.12.1 ``` diff --git a/datastore-v1-proto-client/pom.xml b/datastore-v1-proto-client/pom.xml index d646a57f3..58ac1e772 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.12.3-SNAPSHOT + 2.12.3 com.google.cloud google-cloud-datastore-parent - 2.12.3-SNAPSHOT + 2.12.3 jar diff --git a/google-cloud-datastore-bom/pom.xml b/google-cloud-datastore-bom/pom.xml index 20a386fdd..7f94e2b5b 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.12.3-SNAPSHOT + 2.12.3 pom com.google.cloud @@ -52,22 +52,22 @@ com.google.cloud google-cloud-datastore - 2.12.3-SNAPSHOT + 2.12.3 com.google.api.grpc grpc-google-cloud-datastore-admin-v1 - 2.12.3-SNAPSHOT + 2.12.3 com.google.api.grpc proto-google-cloud-datastore-v1 - 0.103.3-SNAPSHOT + 0.103.3 com.google.api.grpc proto-google-cloud-datastore-admin-v1 - 2.12.3-SNAPSHOT + 2.12.3 diff --git a/google-cloud-datastore/pom.xml b/google-cloud-datastore/pom.xml index 7b46e70c1..f0d6425ba 100644 --- a/google-cloud-datastore/pom.xml +++ b/google-cloud-datastore/pom.xml @@ -2,7 +2,7 @@ 4.0.0 google-cloud-datastore - 2.12.3-SNAPSHOT + 2.12.3 jar Google Cloud Datastore https://github.com/googleapis/java-datastore @@ -12,7 +12,7 @@ com.google.cloud google-cloud-datastore-parent - 2.12.3-SNAPSHOT + 2.12.3 google-cloud-datastore diff --git a/grpc-google-cloud-datastore-admin-v1/pom.xml b/grpc-google-cloud-datastore-admin-v1/pom.xml index 885cadb61..7f8643198 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.12.3-SNAPSHOT + 2.12.3 grpc-google-cloud-datastore-admin-v1 GRPC library for google-cloud-datastore com.google.cloud google-cloud-datastore-parent - 2.12.3-SNAPSHOT + 2.12.3 diff --git a/pom.xml b/pom.xml index 666c1f936..31656d64c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-datastore-parent pom - 2.12.3-SNAPSHOT + 2.12.3 Google Cloud Datastore Parent https://github.com/googleapis/java-datastore @@ -159,27 +159,27 @@ com.google.api.grpc proto-google-cloud-datastore-admin-v1 - 2.12.3-SNAPSHOT + 2.12.3 com.google.api.grpc grpc-google-cloud-datastore-admin-v1 - 2.12.3-SNAPSHOT + 2.12.3 com.google.cloud google-cloud-datastore - 2.12.3-SNAPSHOT + 2.12.3 com.google.api.grpc proto-google-cloud-datastore-v1 - 0.103.3-SNAPSHOT + 0.103.3 com.google.cloud.datastore datastore-v1-proto-client - 2.12.3-SNAPSHOT + 2.12.3 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 4d96ca4ba..a5dce64ad 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.12.3-SNAPSHOT + 2.12.3 proto-google-cloud-datastore-admin-v1 Proto library for google-cloud-datastore com.google.cloud google-cloud-datastore-parent - 2.12.3-SNAPSHOT + 2.12.3 diff --git a/proto-google-cloud-datastore-v1/pom.xml b/proto-google-cloud-datastore-v1/pom.xml index 91566d665..06db222b0 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.103.3-SNAPSHOT + 0.103.3 proto-google-cloud-datastore-v1 PROTO library for proto-google-cloud-datastore-v1 com.google.cloud google-cloud-datastore-parent - 2.12.3-SNAPSHOT + 2.12.3 diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index d26ea36f1..dd883c592 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -29,7 +29,7 @@ com.google.cloud google-cloud-datastore - 2.12.2 + 2.12.1 diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index ee9799e83..c00f576d5 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -28,7 +28,7 @@ com.google.cloud google-cloud-datastore - 2.12.2 + 2.12.1 diff --git a/versions.txt b/versions.txt index f1e200e07..cd8731ba8 100644 --- a/versions.txt +++ b/versions.txt @@ -1,9 +1,9 @@ # Format: # module:released-version:current-version -google-cloud-datastore:2.12.2:2.12.3-SNAPSHOT -google-cloud-datastore-bom:2.12.2:2.12.3-SNAPSHOT -proto-google-cloud-datastore-v1:0.103.2:0.103.3-SNAPSHOT -datastore-v1-proto-client:2.12.2:2.12.3-SNAPSHOT -proto-google-cloud-datastore-admin-v1:2.12.2:2.12.3-SNAPSHOT -grpc-google-cloud-datastore-admin-v1:2.12.2:2.12.3-SNAPSHOT +google-cloud-datastore:2.12.3:2.12.3 +google-cloud-datastore-bom:2.12.3:2.12.3 +proto-google-cloud-datastore-v1:0.103.3:0.103.3 +datastore-v1-proto-client:2.12.3:2.12.3 +proto-google-cloud-datastore-admin-v1:2.12.3:2.12.3 +grpc-google-cloud-datastore-admin-v1:2.12.3:2.12.3