diff --git a/google-cloud-clients/google-cloud-bigtable-admin/README.md b/google-cloud-clients/google-cloud-bigtable-admin/README.md index 20ad11f480f2..423b394558a1 100644 --- a/google-cloud-clients/google-cloud-bigtable-admin/README.md +++ b/google-cloud-clients/google-cloud-bigtable-admin/README.md @@ -72,22 +72,23 @@ at the top of your file: ```java -import com.google.bigtable.admin.v2.ColumnFamily; +import static com.google.cloud.bigtable.admin.v2.models.GCRules.GCRULES; import com.google.bigtable.admin.v2.InstanceName; import com.google.cloud.bigtable.admin.v2.BigtableTableAdminClient; +import com.google.cloud.bigtable.admin.v2.models.CreateTableRequest; +import com.google.cloud.bigtable.admin.v2.models.Table; ``` Then, to create a table, use the following code: ```java InstanceName instanceName = InstanceName.of("my-project", "my-instance"); -TableAdminClient tableAdminClient = TableAdminClient.create(instanceName); +BigtableTableAdminClient tableAdminClient = BigtableTableAdminClient.create(instanceName); try { - CreateTable createTableReq = TableAdminRequests.createTable("tableId") + Table createdTable = tableAdminClient.createTable( + CreateTableRequest.of("my-table") .addFamily("cf2", GCRULES.maxVersions(10)); - client.createTable(createTableReq); - } finally { tableAdminClient.close(); } diff --git a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/BigtableInstanceAdminClient.java b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/BigtableInstanceAdminClient.java index 823842f5bcfe..3f85e45658b2 100644 --- a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/BigtableInstanceAdminClient.java +++ b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/BigtableInstanceAdminClient.java @@ -19,6 +19,7 @@ import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; +import com.google.api.gax.rpc.ApiExceptions; import com.google.api.resourcenames.ResourceName; import com.google.bigtable.admin.v2.AppProfileName; import com.google.bigtable.admin.v2.ClusterName; @@ -46,9 +47,7 @@ import com.google.common.base.Verify; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; -import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.MoreExecutors; -import com.google.common.util.concurrent.UncheckedExecutionException; import com.google.iam.v1.GetIamPolicyRequest; import com.google.iam.v1.SetIamPolicyRequest; import com.google.iam.v1.TestIamPermissionsRequest; @@ -160,7 +159,7 @@ public void close() { */ @SuppressWarnings("WeakerAccess") public Instance createInstance(CreateInstanceRequest request) { - return awaitFuture(createInstanceAsync(request)); + return ApiExceptions.callAndTranslateApiException(createInstanceAsync(request)); } /** @@ -208,7 +207,7 @@ public Instance apply(com.google.bigtable.admin.v2.Instance proto) { */ @SuppressWarnings("WeakerAccess") public Instance updateInstance(UpdateInstanceRequest request) { - return awaitFuture(updateInstanceAsync(request)); + return ApiExceptions.callAndTranslateApiException(updateInstanceAsync(request)); } /** @@ -251,7 +250,7 @@ public Instance apply(com.google.bigtable.admin.v2.Instance proto) { */ @SuppressWarnings("WeakerAccess") public Instance getInstance(String id) { - return awaitFuture(getInstanceAsync(id)); + return ApiExceptions.callAndTranslateApiException(getInstanceAsync(id)); } /** @@ -302,7 +301,7 @@ public Instance apply(com.google.bigtable.admin.v2.Instance proto) { */ @SuppressWarnings("WeakerAccess") public List listInstances() { - return awaitFuture(listInstancesAsync()); + return ApiExceptions.callAndTranslateApiException(listInstancesAsync()); } /** @@ -385,7 +384,7 @@ public List apply(com.google.bigtable.admin.v2.ListInstancesResponse p */ @SuppressWarnings("WeakerAccess") public void deleteInstance(String instanceId) { - awaitFuture(deleteInstanceAsync(instanceId)); + ApiExceptions.callAndTranslateApiException(deleteInstanceAsync(instanceId)); } /** @@ -434,7 +433,7 @@ public Void apply(Empty input) { */ @SuppressWarnings("WeakerAccess") public Cluster createCluster(CreateClusterRequest request) { - return awaitFuture(createClusterAsync(request)); + return ApiExceptions.callAndTranslateApiException(createClusterAsync(request)); } /** @@ -478,7 +477,7 @@ public Cluster apply(com.google.bigtable.admin.v2.Cluster proto) { */ @SuppressWarnings("WeakerAccess") public Cluster getCluster(String instanceId, String clusterId) { - return awaitFuture(getClusterAsync(instanceId, clusterId)); + return ApiExceptions.callAndTranslateApiException(getClusterAsync(instanceId, clusterId)); } /** @@ -531,7 +530,7 @@ public Cluster apply(com.google.bigtable.admin.v2.Cluster proto) { */ @SuppressWarnings("WeakerAccess") public List listClusters(String instanceId) { - return awaitFuture(listClustersAsync(instanceId)); + return ApiExceptions.callAndTranslateApiException(listClustersAsync(instanceId)); } /** @@ -615,7 +614,8 @@ public List apply(com.google.bigtable.admin.v2.ListClustersResponse pro */ @SuppressWarnings("WeakerAccess") public Cluster resizeCluster(String instanceId, String clusterId, int numServeNodes) { - return awaitFuture(resizeClusterAsync(instanceId, clusterId, numServeNodes)); + return ApiExceptions.callAndTranslateApiException( + resizeClusterAsync(instanceId, clusterId, numServeNodes)); } /** @@ -662,7 +662,7 @@ public Cluster apply(com.google.bigtable.admin.v2.Cluster proto) { */ @SuppressWarnings("WeakerAccess") public void deleteCluster(String instanceId, String clusterId) { - awaitFuture(deleteClusterAsync(instanceId, clusterId)); + ApiExceptions.callAndTranslateApiException(deleteClusterAsync(instanceId, clusterId)); } /** @@ -713,7 +713,7 @@ public Void apply(Empty input) { */ @SuppressWarnings("WeakerAccess") public AppProfile createAppProfile(CreateAppProfileRequest request) { - return awaitFuture(createAppProfileAsync(request)); + return ApiExceptions.callAndTranslateApiException(createAppProfileAsync(request)); } /** @@ -759,7 +759,7 @@ public AppProfile apply(com.google.bigtable.admin.v2.AppProfile proto) { */ @SuppressWarnings("WeakerAccess") public AppProfile getAppProfile(String instanceId, String appProfileId) { - return awaitFuture(getAppProfileAsync(instanceId, appProfileId)); + return ApiExceptions.callAndTranslateApiException(getAppProfileAsync(instanceId, appProfileId)); } /** @@ -808,7 +808,7 @@ public AppProfile apply(com.google.bigtable.admin.v2.AppProfile proto) { */ @SuppressWarnings("WeakerAccess") public List listAppProfiles(String instanceId) { - return awaitFuture(listAppProfilesAsync(instanceId)); + return ApiExceptions.callAndTranslateApiException(listAppProfilesAsync(instanceId)); } /** @@ -911,7 +911,7 @@ public List apply(List inpu */ @SuppressWarnings("WeakerAccess") public AppProfile updateAppProfile(UpdateAppProfileRequest request) { - return awaitFuture(updateAppProfileAsync(request)); + return ApiExceptions.callAndTranslateApiException(updateAppProfileAsync(request)); } /** @@ -966,7 +966,7 @@ public AppProfile apply(com.google.bigtable.admin.v2.AppProfile proto) { */ @SuppressWarnings("WeakerAccess") public void deleteAppProfile(String instanceId, String appProfileId) { - awaitFuture(deleteAppProfileAsync(instanceId, appProfileId)); + ApiExceptions.callAndTranslateApiException(deleteAppProfileAsync(instanceId, appProfileId)); } /** @@ -1016,7 +1016,7 @@ public Void apply(Empty input) { */ @SuppressWarnings("WeakerAccess") public Policy getIamPolicy(String instanceId) { - return awaitFuture(getIamPolicyAsync(instanceId)); + return ApiExceptions.callAndTranslateApiException(getIamPolicyAsync(instanceId)); } /** @@ -1083,7 +1083,7 @@ public Policy apply(com.google.iam.v1.Policy proto) { */ @SuppressWarnings("WeakerAccess") public Policy setIamPolicy(String instanceId, Policy policy) { - return awaitFuture(setIamPolicyAsync(instanceId, policy)); + return ApiExceptions.callAndTranslateApiException(setIamPolicyAsync(instanceId, policy)); } /** @@ -1210,7 +1210,8 @@ public ApiFuture> testIamPermissionAsync(String instanceId, String. */ @SuppressWarnings("WeakerAccess") public List testIamPermission(ResourceName resourceName, String... permissions) { - return awaitFuture(testIamPermissionAsync(resourceName, permissions)); + return ApiExceptions.callAndTranslateApiException( + testIamPermissionAsync(resourceName, permissions)); } @@ -1276,29 +1277,4 @@ public com.google.iam.v1.Policy toPb(Policy policy) { return super.toPb(policy); } } - - /** - * Awaits the result of a future, taking care to propagate errors while maintaining the call site - * in a suppressed exception. This allows semantic errors to be caught across threads, while - * preserving the call site in the error. The caller's stacktrace will be made available as a - * suppressed exception. - */ - // TODO(igorbernstein2): try to move this into gax - private T awaitFuture(ApiFuture future) { - RuntimeException error; - try { - return Futures.getUnchecked(future); - } catch (UncheckedExecutionException e) { - if (e.getCause() instanceof RuntimeException) { - error = (RuntimeException) e.getCause(); - } else { - error = e; - } - } catch (RuntimeException e) { - error = e; - } - // Add the caller's stack as a suppressed exception - error.addSuppressed(new RuntimeException("Encountered error while awaiting future")); - throw error; - } } diff --git a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClient.java b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClient.java index 694aa2bc4838..6c886514e25a 100644 --- a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClient.java +++ b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClient.java @@ -19,6 +19,7 @@ import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; +import com.google.api.gax.rpc.ApiExceptions; import com.google.bigtable.admin.v2.DeleteTableRequest; import com.google.bigtable.admin.v2.DropRowRangeRequest; import com.google.bigtable.admin.v2.GetTableRequest; @@ -33,9 +34,7 @@ import com.google.cloud.bigtable.admin.v2.stub.EnhancedBigtableTableAdminStub; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; -import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.MoreExecutors; -import com.google.common.util.concurrent.UncheckedExecutionException; import com.google.protobuf.ByteString; import com.google.protobuf.Empty; import java.io.IOException; @@ -149,7 +148,7 @@ public void close() { */ @SuppressWarnings("WeakerAccess") public Table createTable(CreateTableRequest request) { - return awaitFuture(createTableAsync(request)); + return ApiExceptions.callAndTranslateApiException(createTableAsync(request)); } /** @@ -222,7 +221,7 @@ public ApiFuture createTableAsync(CreateTableRequest request) { */ @SuppressWarnings("WeakerAccess") public Table modifyFamilies(ModifyColumnFamiliesRequest request) { - return awaitFuture(modifyFamiliesAsync(request)); + return ApiExceptions.callAndTranslateApiException(modifyFamiliesAsync(request)); } /** @@ -289,7 +288,7 @@ public ApiFuture
modifyFamiliesAsync(ModifyColumnFamiliesRequest request) */ @SuppressWarnings("WeakerAccess") public void deleteTable(String tableId) { - awaitFuture(deleteTableAsync(tableId)); + ApiExceptions.callAndTranslateApiException(deleteTableAsync(tableId)); } /** @@ -342,7 +341,7 @@ public ApiFuture deleteTableAsync(String tableId) { */ @SuppressWarnings("WeakerAccess") public Table getTable(String tableId) { - return awaitFuture(getTableAsync(tableId)); + return ApiExceptions.callAndTranslateApiException(getTableAsync(tableId)); } /** @@ -397,7 +396,7 @@ public ApiFuture
getTableAsync(String tableId) { // TODO(igorbernstein2): consider changing this method to use relative table ids. @SuppressWarnings("WeakerAccess") public List listTables() { - return awaitFuture(listTablesAsync()); + return ApiExceptions.callAndTranslateApiException(listTablesAsync()); } /** @@ -506,7 +505,7 @@ public List apply(List protos) { */ @SuppressWarnings("WeakerAccess") public void dropRowRange(String tableId, String rowKeyPrefix) { - awaitFuture(dropRowRangeAsync(tableId, rowKeyPrefix)); + ApiExceptions.callAndTranslateApiException(dropRowRangeAsync(tableId, rowKeyPrefix)); } /** @@ -552,7 +551,7 @@ public ApiFuture dropRowRangeAsync(String tableId, String rowKeyPrefix) { */ @SuppressWarnings("WeakerAccess") public void dropRowRange(String tableId, ByteString rowKeyPrefix) { - awaitFuture(dropRowRangeAsync(tableId, rowKeyPrefix)); + ApiExceptions.callAndTranslateApiException(dropRowRangeAsync(tableId, rowKeyPrefix)); } /** @@ -604,7 +603,7 @@ public ApiFuture dropRowRangeAsync(String tableId, ByteString rowKeyPrefix */ @SuppressWarnings("WeakerAccess") public void dropAllRows(String tableId) { - awaitFuture(dropAllRowsAsync(tableId)); + ApiExceptions.callAndTranslateApiException(dropAllRowsAsync(tableId)); } /** @@ -659,7 +658,8 @@ public ApiFuture dropAllRowsAsync(String tableId) { public void awaitReplication(String tableId) { TableName tableName = TableName .of(instanceName.getProject(), instanceName.getInstance(), tableId); - awaitFuture(stub.awaitReplicationCallable().futureCall(tableName)); + ApiExceptions + .callAndTranslateApiException(stub.awaitReplicationCallable().futureCall(tableName)); } /** @@ -734,29 +734,4 @@ public Void apply(Empty empty) { }, MoreExecutors.directExecutor()); } - - /** - * Awaits the result of a future, taking care to propagate errors while maintaining the call site - * in a suppressed exception. This allows semantic errors to be caught across threads, while - * preserving the call site in the error. The caller's stacktrace will be made available as a - * suppressed exception. - */ - // TODO(igorbernstein2): try to move this into gax - private T awaitFuture(ApiFuture future) { - RuntimeException error; - try { - return Futures.getUnchecked(future); - } catch (UncheckedExecutionException e) { - if (e.getCause() instanceof RuntimeException) { - error = (RuntimeException) e.getCause(); - } else { - error = e; - } - } catch (RuntimeException e) { - error = e; - } - // Add the caller's stack as a suppressed exception - error.addSuppressed(new RuntimeException("Encountered error while awaiting future")); - throw error; - } } diff --git a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java index 59165a764c2e..873220131845 100644 --- a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java +++ b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java @@ -68,6 +68,14 @@ * service. * * + *

All RPC related errors are represented as subclasses of {@link com.google.api.gax.rpc.ApiException}. + * For example, a nonexistent table will trigger a {@link com.google.api.gax.rpc.NotFoundException}. + * Async methods will wrap the error inside the future. Synchronous methods will re-throw the async + * error but will try to preserve the caller's stacktrace by attaching a suppressed exception at the + * callsite. This allows callers to use typesafe exceptions, without losing their callsite. + * Streaming methods (ie. readRows) will re-throw the async exception (like sync methods) when + * starting iteration. + * *

See the individual methods for example code. * *

This class can be customized by passing in a custom instance of BigtableDataSettings to @@ -139,7 +147,20 @@ public static BigtableDataClient create(BigtableDataSettings settings) throws IO * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) { * String tableId = "[TABLE]"; * - * ApiFuture result = bigtableDataClient.readRowAsync(tableId, "key"); + * ApiFuture futureResult = bigtableDataClient.readRowAsync(tableId, "key"); + * + * ApiFutures.addCallback(futureResult, new ApiFutureCallback() { + * public void onFailure(Throwable t) { + * if (t instanceof NotFoundException) { + * System.out.println("Tried to read a non-existent table"); + * } else { + * t.printStackTrace(); + * } + * } + * public void onSuccess(Row result) { + * System.out.println("Got row: " + result); + * } + * }, MoreExecutors.directExecutor()); * } * } */ @@ -158,7 +179,20 @@ public ApiFuture readRowAsync(String tableId, String rowKey) { * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) { * String tableId = "[TABLE]"; * - * ApiFuture result = bigtableDataClient.readRowAsync(tableId, ByteString.copyFromUtf8("key")); + * ApiFuture futureResult = bigtableDataClient.readRowAsync(tableId, ByteString.copyFromUtf8("key")); + * + * ApiFutures.addCallback(futureResult, new ApiFutureCallback() { + * public void onFailure(Throwable t) { + * if (t instanceof NotFoundException) { + * System.out.println("Tried to read a non-existent table"); + * } else { + * t.printStackTrace(); + * } + * } + * public void onSuccess(Row row) { + * System.out.println("Got row: " + row); + * } + * }, MoreExecutors.directExecutor()); * } * } */ @@ -184,8 +218,14 @@ public ApiFuture readRowAsync(String tableId, ByteString rowKey) { * .filter(FILTERS.qualifier().regex("[COLUMN PREFIX].*")); * * // Iterator style - * for(Row row : bigtableDataClient.readRows(query)) { - * // Do something with row + * try { + * for(Row row : bigtableDataClient.readRows(query)) { + * // Do something with row + * } + * } catch (NotFoundException e) { + * System.out.println("Tried to read a non-existent table"); + * } catch (RuntimeException e) { + * e.printStackTrace(); * } * } * } @@ -214,11 +254,15 @@ public ServerStream readRows(Query query) { * * bigtableDataClient.readRowsAsync(query, new ResponseObserver() { * public void onStart(StreamController controller) { } - * public void onResponse(Row response) { + * public void onResponse(Row row) { * // Do something with Row * } * public void onError(Throwable t) { - * // Handle error before the stream completes + * if (t instanceof NotFoundException) { + * System.out.println("Tried to read a non-existent table"); + * } else { + * t.printStackTrace(); + * } * } * public void onComplete() { * // Handle stream completion @@ -247,13 +291,41 @@ public void readRowsAsync(Query query, ResponseObserver observer) { * .filter(FILTERS.qualifier().regex("[COLUMN PREFIX].*")); * * // Iterator style - * for(Row row : bigtableDataClient.readRowsCallable().call(query)) { - * // Do something with row - * } + * try { + * for(Row row : bigtableDataClient.readRowsCallable().call(query)) { + * // Do something with row + * } + * } catch (NotFoundException e) { + * System.out.println("Tried to read a non-existent table"); + * } catch (RuntimeException e) { + * e.printStackTrace(); + * }} + * + * // Sync style + * try { + * List rows = bigtableDataClient.readRowsCallable().all().call(query); + * } catch (NotFoundException e) { + * System.out.println("Tried to read a non-existent table"); + * } catch (RuntimeException e) { + * e.printStackTrace(); + * }} * * // Point look up * ApiFuture rowFuture = bigtableDataClient.readRowsCallable().first().futureCall(query); * + * ApiFutures.addCallback(rowFuture, new ApiFutureCallback() { + * public void onFailure(Throwable t) { + * if (t instanceof NotFoundException) { + * System.out.println("Tried to read a non-existent table"); + * } else { + * t.printStackTrace(); + * } + * } + * public void onSuccess(Row result) { + * System.out.println("Got row: " + result); + * } + * }, MoreExecutors.directExecutor()); + * * // etc * } * } @@ -282,8 +354,14 @@ public ServerStreamingCallable readRowsCallable() { * .filter(FILTERS.qualifier().regex("[COLUMN PREFIX].*")); * * // Iterator style - * for(CustomRow row : bigtableDataClient.readRowsCallable(new CustomRowAdapter()).call(query)) { - * // Do something with row + * try { + * for(CustomRow row : bigtableDataClient.readRowsCallable(new CustomRowAdapter()).call(query)) { + * // Do something with row + * } + * } catch (NotFoundException e) { + * System.out.println("Tried to read a non-existent table"); + * } catch (RuntimeException e) { + * e.printStackTrace(); * } * } * } @@ -305,8 +383,21 @@ public ServerStreamingCallable readRowsCallable(RowAdapter{@code * InstanceName instanceName = InstanceName.of("[PROJECT]", "[INSTANCE]"); - * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) { - * ApiFuture> keyOffsets = bigtableDataClient.sampleRowKeysAsync("[TABLE]"); + * try (BigtableClient bigtableDataClient = BigtableClient.create(instanceName)) { + * ApiFuture> keyOffsetsFuture = bigtableClient.sampleRowKeysAsync("[TABLE]"); + * + * ApiFutures.addCallback(keyOffsetsFuture, new ApiFutureCallback>() { + * public void onFailure(Throwable t) { + * if (t instanceof NotFoundException) { + * System.out.println("Tried to sample keys of a non-existent table"); + * } else { + * t.printStackTrace(); + * } + * } + * public void onSuccess(List keyOffsets) { + * System.out.println("Got key offsets: " + keyOffsets); + * } + * }, MoreExecutors.directExecutor()); * } * } */ @@ -326,10 +417,29 @@ public ApiFuture> sampleRowKeysAsync(String tableId) { * InstanceName instanceName = InstanceName.of("[PROJECT]", "[INSTANCE]"); * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) { * // Synchronous invocation - * List keyOffsets = bigtableDataClient.sampleRowKeysCallable().call("[TABLE]"); + * try { + * List keyOffsets = bigtableDataClient.sampleRowKeysCallable().call("[TABLE]"); + * } catch (NotFoundException e) { + * System.out.println("Tried to sample keys of a non-existent table"); + * } catch (RuntimeException e) { + * e.printStackTrace(); + * } * * // Asynchronous invocation - * ApiFuture> keyOffsets = bigtableDataClient.sampleRowKeysCallable().futureCall("[TABLE]"); + * ApiFuture> keyOffsetsFuture = bigtableDataClient.sampleRowKeysCallable().futureCall("[TABLE]"); + * + * ApiFutures.addCallback(keyOffsetsFuture, new ApiFutureCallback>() { + * public void onFailure(Throwable t) { + * if (t instanceof NotFoundException) { + * System.out.println("Tried to sample keys of a non-existent table"); + * } else { + * t.printStackTrace(); + * } + * } + * public void onSuccess(List keyOffsets) { + * System.out.println("Got key offsets: " + keyOffsets); + * } + * }, MoreExecutors.directExecutor()); * } * } */ @@ -349,7 +459,20 @@ public UnaryCallable> sampleRowKeysCallable() { * RowMutation mutation = RowMutation.create("[TABLE]", "[ROW KEY]") * .setCell("[FAMILY NAME]", "[QUALIFIER]", "[VALUE]"); * - * ApitFuture future = bigtableDataClient.mutateRowAsync(mutation); + * ApiFuture future = bigtableDataClient.mutateRowAsync(mutation); + * + * ApiFutures.addCallback(future, new ApiFutureCallback() { + * public void onFailure(Throwable t) { + * if (t instanceof NotFoundException) { + * System.out.println("Tried to mutate a non-existent table"); + * } else { + * t.printStackTrace(); + * } + * } + * public void onSuccess(Void ignored) { + * System.out.println("Successfully applied mutation"); + * } + * }, MoreExecutors.directExecutor()); * } * } */ @@ -369,7 +492,14 @@ public ApiFuture mutateRowAsync(RowMutation rowMutation) { * RowMutation mutation = RowMutation.create("[TABLE]", "[ROW KEY]") * .setCell("[FAMILY NAME]", "[QUALIFIER]", "[VALUE]"); * - * bigtableDataClient.mutateRowCallable().call(mutation); + * // Sync style + * try { + * bigtableDataClient.mutateRowCallable().call(mutation); + * } catch (NotFoundException e) { + * System.out.println("Tried to mutate a non-existent table"); + * } catch (RuntimeException e) { + * e.printStackTrace(); + * } * } * } */ @@ -391,7 +521,7 @@ public UnaryCallable mutateRowCallable() { * RowMutation mutation = RowMutation.create("[TABLE]", "[ROW KEY]") * .setCell("[FAMILY NAME]", "[QUALIFIER]", "[VALUE]"); * - * batcher.add(mutation); + * ApiFuture entryFuture = batcher.add(mutation); * } * } catch (BulkMutationFailure failure) { * // Handle error @@ -417,9 +547,23 @@ public BulkMutationBatcher newBulkMutationBatcher() { * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) { * BulkMutation batch = BulkMutation.create("[TABLE]"); * for (String someValue : someCollection) { - * batch.add("[ROW KEY]", Mutation.create().setCell("[FAMILY NAME]", "[QUALIFIER]", "[VALUE]"); + * ApiFuture entryFuture = batch.add("[ROW KEY]", + * Mutation.create().setCell("[FAMILY NAME]", "[QUALIFIER]", "[VALUE]")); * } - * ApiFuture result = bigtableDataClient.bulkMutateRowsAsync(batch); + * ApiFuture resultFuture = bigtableDataClient.bulkMutateRowsAsync(batch); + * + * ApiFutures.addCallback(resultFuture, new ApiFutureCallback() { + * public void onFailure(Throwable t) { + * if (t instanceof BulkMutationFailure) { + * System.out.println("Some entries failed to apply"); + * } else { + * t.printStackTrace(); + * } + * } + * public void onSuccess(Void ignored) { + * System.out.println("Successfully applied all mutation"); + * } + * }, MoreExecutors.directExecutor()); * } * } */ @@ -439,7 +583,8 @@ public ApiFuture bulkMutateRowsAsync(BulkMutation mutation) { * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) { * BulkMutation batch = BulkMutation.create("[TABLE]"); * for (String someValue : someCollection) { - * batch.add("[ROW KEY]", Mutation.create().setCell("[FAMILY NAME]", "[QUALIFIER]", "[VALUE]"); + * ApiFuture entryFuture = batch.add("[ROW KEY]", + * Mutation.create().setCell("[FAMILY NAME]", "[QUALIFIER]", "[VALUE]"); * } * bigtableDataClient.bulkMutationCallable().call(batch); * } @@ -465,6 +610,19 @@ public UnaryCallable bulkMutationCallable() { * ); * * ApiFuture future = bigtableDataClient.checkAndMutateRowAsync(mutation); + * + * ApiFutures.addCallback(future, new ApiFutureCallback() { + * public void onFailure(Throwable t) { + * if (t instanceof NotFoundException) { + * System.out.println("Tried to mutate a non-existent table"); + * } else { + * t.printStackTrace(); + * } + * } + * public void onSuccess(Boolean wasApplied) { + * System.out.println("Row was modified: " + wasApplied); + * } + * }, MoreExecutors.directExecutor()); * } * } */ @@ -487,7 +645,17 @@ public ApiFuture checkAndMutateRowAsync(ConditionalRowMutation mutation * .setCell("[FAMILY]", "[QUALIFIER]", "[VALUE]") * ); * - * boolean success = bigtableDataClient.checkAndMutateRowCallable().call(mutation); + * // Sync style + * try { + * boolean success = bigtableDataClient.checkAndMutateRowCallable().call(mutation); + * if (!success) { + * System.out.println("Row did not match conditions"); + * } + * } catch (NotFoundException e) { + * System.out.println("Tried to mutate a non-existent table"); + * } catch (RuntimeException e) { + * e.printStackTrace(); + * } * } * } */ @@ -510,7 +678,20 @@ public UnaryCallable checkAndMutateRowCallable( * .increment("[FAMILY]", "[QUALIFIER]", 1) * .append("[FAMILY2]", "[QUALIFIER2]", "suffix"); * - * ApiFuture success = bigtableDataClient.readModifyWriteRowAsync(mutation); + * ApiFuture rowFuture = bigtableDataClient.readModifyWriteRowAsync(mutation); + * + * ApiFutures.addCallback(rowFuture, new ApiFutureCallback() { + * public void onFailure(Throwable t) { + * if (t instanceof NotFoundException) { + * System.out.println("Tried to mutate a non-existent table"); + * } else { + * t.printStackTrace(); + * } + * } + * public void onSuccess(Row resultingRow) { + * System.out.println("Resulting row: " + resultingRow); + * } + * }, MoreExecutors.directExecutor()); * } * } */ @@ -533,7 +714,13 @@ public ApiFuture readModifyWriteRowAsync(ReadModifyWriteRow mutation) { * .increment("[FAMILY]", "[QUALIFIER]", 1) * .append("[FAMILY2]", "[QUALIFIER2]", "suffix"); * - * Row row = bigtableDataClient.readModifyWriteRowCallable().call(mutation); + * try { + * Row row = bigtableDataClient.readModifyWriteRowCallable().call(mutation); + * } catch (NotFoundException e) { + * System.out.println("Tried to mutate a non-existent table"); + * } catch (RuntimeException e) { + * e.printStackTrace(); + * } * } * } */