Skip to content
This repository has been archived by the owner on Oct 3, 2023. It is now read-only.

docs(samples): add UpdateUserEventsJson implementation #388

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ If you are using Maven, add this to your pom.xml file:
If you are using Gradle without BOM, add this to your dependencies

```Groovy
implementation 'com.google.cloud:google-cloud-retail:2.0.18'
implementation 'com.google.cloud:google-cloud-retail:2.0.19'
```

If you are using SBT, add this to your dependencies

```Scala
libraryDependencies += "com.google.cloud" % "google-cloud-retail" % "2.0.18"
libraryDependencies += "com.google.cloud" % "google-cloud-retail" % "2.0.19"
```

## Authentication
Expand Down Expand Up @@ -85,8 +85,8 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-retail/tree/m
| Write User Event | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/events/WriteUserEvent.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/events/WriteUserEvent.java) |
| Events Create Big Query Table | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/events/setup/EventsCreateBigQueryTable.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/events/setup/EventsCreateBigQueryTable.java) |
| Events Create Gcs Bucket | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/events/setup/EventsCreateGcsBucket.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/events/setup/EventsCreateGcsBucket.java) |
| Create Test Resources | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/init/CreateTestResources.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/init/CreateTestResources.java) |
| Remove Test Resources | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/init/RemoveTestResources.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/init/RemoveTestResources.java) |
| Remove Events Resources | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/events/setup/RemoveEventsResources.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/events/setup/RemoveEventsResources.java) |
| Update User Events Json | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/events/setup/UpdateUserEventsJson.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/events/setup/UpdateUserEventsJson.java) |
| Add Fulfillment Places | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/product/AddFulfillmentPlaces.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/product/AddFulfillmentPlaces.java) |
| Create Product | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/product/CreateProduct.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/product/CreateProduct.java) |
| Crud Product | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/product/CrudProduct.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/product/CrudProduct.java) |
Expand All @@ -100,6 +100,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-retail/tree/m
| Update Product | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/product/UpdateProduct.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/product/UpdateProduct.java) |
| Products Create Bigquery Table | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/product/setup/ProductsCreateBigqueryTable.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/product/setup/ProductsCreateBigqueryTable.java) |
| Products Create Gcs Bucket | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/product/setup/ProductsCreateGcsBucket.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/product/setup/ProductsCreateGcsBucket.java) |
| Remove Products Resources | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/product/setup/RemoveProductsResources.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/product/setup/RemoveProductsResources.java) |
| Search Simple Query | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/search/SearchSimpleQuery.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/search/SearchSimpleQuery.java) |
| Search With Boost Spec | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/search/SearchWithBoostSpec.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/search/SearchWithBoostSpec.java) |
| Search With Facet Spec | [source code](https://github.com/googleapis/java-retail/blob/main/samples/interactive-tutorials/src/main/java/search/SearchWithFacetSpec.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-retail&page=editor&open_in_editor=samples/interactive-tutorials/src/main/java/search/SearchWithFacetSpec.java) |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

package events;

import com.google.api.gax.rpc.NotFoundException;
import com.google.cloud.ServiceOptions;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.retail.v2.BigQuerySource;
Expand All @@ -33,26 +34,28 @@
import com.google.longrunning.Operation;
import com.google.longrunning.OperationsClient;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class ImportUserEventsBigQuery {

public static void main(String[] args) throws IOException, InterruptedException {
// TODO(developer): Replace these variables before running the sample.
String projectId = ServiceOptions.getDefaultProjectId();
String defaultCatalog =
String.format("projects/%s/locations/global/catalogs/default_catalog", projectId);
// TO CHECK ERROR HANDLING PASTE THE INVALID CATALOG NAME HERE: defaultCatalog =
// "invalid_catalog_name"
// TO CHECK ERROR HANDLING PASTE THE INVALID CATALOG NAME HERE:
// defaultCatalog = "invalid_catalog_name"
String datasetId = "user_events";
String tableId = "events";
// TO CHECK ERROR HANDLING USE THE TABLE OF INVALID USER EVENTS: tableId = "events_some_invalid"
// TO CHECK ERROR HANDLING USE THE TABLE OF INVALID USER EVENTS:
// tableId = "events_some_invalid"

importUserEventsFromBigQuery(projectId, defaultCatalog, datasetId, tableId);
}

public static void importUserEventsFromBigQuery(
String projectId, String defaultCatalog, String datasetId, String tableId)
throws IOException, InterruptedException {

try {
String dataSchema = "user_event";

Expand All @@ -75,30 +78,32 @@ public static void importUserEventsFromBigQuery(

System.out.printf("Import user events from BigQuery source request: %s%n", importRequest);

// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the "close" method on the client to safely clean up any remaining background resources.
// Initialize client that will be used to send requests. This client only
// needs to be created once, and can be reused for multiple requests. After
// completing all of your requests, call the "close" method on the client to
// safely clean up any remaining background resources.
try (UserEventServiceClient serviceClient = UserEventServiceClient.create()) {
String operationName =
serviceClient.importUserEventsCallable().call(importRequest).getName();

System.out.printf("OperationName = %s\n", operationName);
System.out.printf("OperationName = %s%n", operationName);
OperationsClient operationsClient = serviceClient.getOperationsClient();
Operation operation = operationsClient.getOperation(operationName);

while (!operation.getDone()) {
long assuredBreak = System.currentTimeMillis() + 60000; // 60 seconds delay

while (!operation.getDone() || System.currentTimeMillis() < assuredBreak) {
// Keep polling the operation periodically until the import task is done.
int awaitDuration = 30000;
Thread.sleep(awaitDuration);
TimeUnit.SECONDS.sleep(30);
operation = operationsClient.getOperation(operationName);
}

if (operation.hasMetadata()) {
ImportMetadata metadata = operation.getMetadata().unpack(ImportMetadata.class);
System.out.printf(
"Number of successfully imported events: %s\n", metadata.getSuccessCount());
"Number of successfully imported events: %s%n", metadata.getSuccessCount());
System.out.printf(
"Number of failures during the importing: %s\n", metadata.getFailureCount());
"Number of failures during the importing: %s%n", metadata.getFailureCount());
}

if (operation.hasResponse()) {
Expand All @@ -109,6 +114,8 @@ public static void importUserEventsFromBigQuery(
}
} catch (BigQueryException e) {
System.out.printf("Exception message: %s", e.getMessage());
} catch (NotFoundException e) {
System.out.printf("Catalog name is not found.%n%s%n", e.getMessage());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
package events;

import com.google.api.gax.rpc.InvalidArgumentException;
import com.google.api.gax.rpc.PermissionDeniedException;
import com.google.cloud.ServiceOptions;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.retail.v2.GcsSource;
import com.google.cloud.retail.v2.ImportErrorsConfig;
import com.google.cloud.retail.v2.ImportMetadata;
Expand All @@ -34,91 +34,95 @@
import com.google.cloud.retail.v2.UserEventServiceClient;
import com.google.longrunning.Operation;
import com.google.longrunning.OperationsClient;
import events.setup.EventsCreateGcsBucket;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class ImportUserEventsGcs {

public static void main(String[] args) throws IOException, InterruptedException {
// TODO(developer): Replace these variables before running the sample.
String projectId = ServiceOptions.getDefaultProjectId();
String defaultCatalog =
String.format("projects/%s/locations/global/catalogs/default_catalog", projectId);
// TO CHECK ERROR HANDLING PASTE THE INVALID CATALOG NAME HERE: defaultCatalog =
// "invalid_catalog_name"
String gcsEventsObject = "user_events.json";
// TO CHECK ERROR HANDLING USE THE JSON WITH INVALID USER EVENT: gcsEventsObject =
// "user_events_some_invalid.json"
String bucketName = System.getenv("EVENTS_BUCKET_NAME");
String gcsUserEventsObject = "user_events.json";
// TO CHECK ERROR HANDLING USE THE JSON WITH INVALID USER EVENT:
// gcsEventsObject = "user_events_some_invalid.json"
Comment on lines +48 to +49
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be a separate test in your tests file. You can have one where you call a valid file (e.g.importUimportUserEventsFromGcs("your-catalog", "user-events.json) and one where you call an invalid file (e.g.importUimportUserEventsFromGcs("your-catalog", "some-invalid-file.json). You shouldn't be depending on someone to edit a comment out, because that means it's not being run the in the CI.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.


importUserEventsFromGcs(gcsEventsObject, defaultCatalog);
importUserEventsFromGcs(defaultCatalog, bucketName, gcsUserEventsObject);
}

public static void importUserEventsFromGcs(String gcsEventsObject, String defaultCatalog)
public static void importUserEventsFromGcs(
String defaultCatalog, String bucketName, String gcsUserEventsObject)
throws IOException, InterruptedException {
try {
String gcsBucket = String.format("gs://%s", EventsCreateGcsBucket.getBucketName());
String gcsErrorsBucket = String.format("%s/error", gcsBucket);

GcsSource gcsSource =
GcsSource.newBuilder()
.addInputUris(String.format("%s/%s", gcsBucket, gcsEventsObject))
.build();

UserEventInputConfig inputConfig =
UserEventInputConfig.newBuilder().setGcsSource(gcsSource).build();

ImportErrorsConfig errorsConfig =
ImportErrorsConfig.newBuilder().setGcsPrefix(gcsErrorsBucket).build();

ImportUserEventsRequest importRequest =
ImportUserEventsRequest.newBuilder()
.setParent(defaultCatalog)
.setInputConfig(inputConfig)
.setErrorsConfig(errorsConfig)
.build();

System.out.printf("Import user events from google cloud source request: %s%n", importRequest);

// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the "close" method on the client to safely clean up any remaining background resources.
try (UserEventServiceClient serviceClient = UserEventServiceClient.create()) {
String operationName =
serviceClient.importUserEventsCallable().call(importRequest).getName();

System.out.printf("OperationName = %s\n", operationName);

OperationsClient operationsClient = serviceClient.getOperationsClient();
Operation operation = operationsClient.getOperation(operationName);

while (!operation.getDone()) {
// Keep polling the operation periodically until the import task is done.
int awaitDuration = 30000;
Thread.sleep(awaitDuration);
operation = operationsClient.getOperation(operationName);
}

if (operation.hasMetadata()) {
ImportMetadata metadata = operation.getMetadata().unpack(ImportMetadata.class);
System.out.printf(
"Number of successfully imported events: %s\n", metadata.getSuccessCount());
System.out.printf(
"Number of failures during the importing: %s\n", metadata.getFailureCount());
}

if (operation.hasResponse()) {
ImportUserEventsResponse response =
operation.getResponse().unpack(ImportUserEventsResponse.class);
System.out.printf("Operation result: %s%n", response);
}
} catch (InvalidArgumentException e) {
String gcsBucket = String.format("gs://%s", bucketName);
String gcsErrorsBucket = String.format("%s/error", gcsBucket);

GcsSource gcsSource =
GcsSource.newBuilder()
.addInputUris(String.format("%s/%s", gcsBucket, gcsUserEventsObject))
.build();

UserEventInputConfig inputConfig =
UserEventInputConfig.newBuilder().setGcsSource(gcsSource).build();

System.out.println("GRS source: " + gcsSource.getInputUrisList());

ImportErrorsConfig errorsConfig =
ImportErrorsConfig.newBuilder().setGcsPrefix(gcsErrorsBucket).build();

ImportUserEventsRequest importRequest =
ImportUserEventsRequest.newBuilder()
.setParent(defaultCatalog)
.setInputConfig(inputConfig)
.setErrorsConfig(errorsConfig)
.build();
System.out.printf("Import user events from google cloud source request: %s%n", importRequest);

// Initialize client that will be used to send requests. This client only
// needs to be created once, and can be reused for multiple requests. After
// completing all of your requests, call the "close" method on the client to
// safely clean up any remaining background resources.
try (UserEventServiceClient serviceClient = UserEventServiceClient.create()) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure to include the comment regarding client best practices.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

String operationName = serviceClient.importUserEventsCallable().call(importRequest).getName();

System.out.println("The operation was started.");
System.out.printf("OperationName = %s%n", operationName);

OperationsClient operationsClient = serviceClient.getOperationsClient();
Operation operation = operationsClient.getOperation(operationName);

long assuredBreak = System.currentTimeMillis() + 60000; // 60 seconds delay

while (!operation.getDone() || System.currentTimeMillis() < assuredBreak) {
System.out.println("Please wait till operation is done.");
TimeUnit.SECONDS.sleep(30);
operation = operationsClient.getOperation(operationName);
}

if (operation.hasMetadata()) {
ImportMetadata metadata = operation.getMetadata().unpack(ImportMetadata.class);
System.out.printf(
"Given GCS input path was not found. %n%s%n "
+ "Please run CreateTestResources class to create resources.",
e.getMessage());
"Number of successfully imported events: %s%n", metadata.getSuccessCount());
System.out.printf(
"Number of failures during the importing: %s%n", metadata.getFailureCount());
} else {
System.out.println("Metadata is empty.");
}

if (operation.hasResponse()) {
ImportUserEventsResponse response =
operation.getResponse().unpack(ImportUserEventsResponse.class);
System.out.printf("Operation result: %s%n", response);
} else {
System.out.println("Operation result is empty.");
}
} catch (BigQueryException e) {
System.out.printf("Exception message: %s", e.getMessage());
} catch (InvalidArgumentException e) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When can this "InvalidArgumentException" happen? Can we add a try/catch for this exception just where it's relevant?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's relevant in that case when bucket has no specified file.
Also added PermissionDeniedException for case when env variable bucketName can't be read properly.

System.out.printf(
"%s%n'%s' file does not exist in the bucket. Please "
+ "make sure you have followed the setting up instructions.",
e.getMessage(), gcsUserEventsObject);
} catch (PermissionDeniedException e) {
System.out.println(e.getMessage());
}
}
}
Expand Down
Loading