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 16b70188afdd..06f593c0fee1 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 @@ -15,34 +15,34 @@ */ package com.google.cloud.bigtable.admin.v2; -import com.google.cloud.bigtable.admin.v2.BaseBigtableTableAdminClient.ListTablesPagedResponse; -import com.google.common.util.concurrent.MoreExecutors; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.bigtable.admin.v2.CheckConsistencyResponse; import com.google.bigtable.admin.v2.DeleteTableRequest; import com.google.bigtable.admin.v2.DropRowRangeRequest; -import com.google.bigtable.admin.v2.DropRowRangeRequest.Builder; import com.google.bigtable.admin.v2.GenerateConsistencyTokenRequest; import com.google.bigtable.admin.v2.GenerateConsistencyTokenResponse; import com.google.bigtable.admin.v2.GetTableRequest; import com.google.bigtable.admin.v2.InstanceName; import com.google.bigtable.admin.v2.ListTablesRequest; -import com.google.bigtable.admin.v2.ListTablesResponse; import com.google.bigtable.admin.v2.TableName; +import com.google.cloud.bigtable.admin.v2.BaseBigtableTableAdminClient.ListTablesPagedResponse; +import com.google.cloud.bigtable.admin.v2.models.ConsistencyToken; import com.google.cloud.bigtable.admin.v2.models.CreateTableRequest; import com.google.cloud.bigtable.admin.v2.models.ModifyColumnFamiliesRequest; -import com.google.cloud.bigtable.admin.v2.models.ConsistencyToken; import com.google.cloud.bigtable.admin.v2.models.Table; import com.google.cloud.bigtable.admin.v2.stub.BigtableTableAdminStub; import com.google.common.annotations.VisibleForTesting; 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; +import java.util.List; import javax.annotation.Nonnull; /** @@ -57,7 +57,7 @@ *
{@code
  * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
  *   CreateTable request =
- *     CreateTableRequest.of("tableId")
+ *     CreateTableRequest.of("my-table")
  *       .addFamily("cf1")
  *       .addFamily("cf2", GCRULES.maxVersions(10))
  *       .addSplit(ByteString.copyFromUtf8("b"))
@@ -99,21 +99,25 @@ public final class BigtableTableAdminClient implements AutoCloseable {
   private final InstanceName instanceName;
 
   /** Constructs an instance of BigtableTableAdminClient with the given instanceName. */
-  public static BigtableTableAdminClient create(@Nonnull InstanceName instanceName) throws IOException {
+  public static BigtableTableAdminClient create(@Nonnull InstanceName instanceName)
+      throws IOException {
     return create(BigtableTableAdminSettings.newBuilder().setInstanceName(instanceName).build());
   }
 
   /** Constructs an instance of BigtableTableAdminClient with the given settings. */
-  public static BigtableTableAdminClient create(@Nonnull BigtableTableAdminSettings settings) throws IOException {
+  public static BigtableTableAdminClient create(@Nonnull BigtableTableAdminSettings settings)
+      throws IOException {
     return create(settings.getInstanceName(), settings.getStubSettings().createStub());
   }
 
   /** Constructs an instance of BigtableTableAdminClient with the given instanceName and stub. */
-  public static BigtableTableAdminClient create(@Nonnull InstanceName instanceName, @Nonnull BigtableTableAdminStub stub) {
+  public static BigtableTableAdminClient create(@Nonnull InstanceName instanceName,
+      @Nonnull BigtableTableAdminStub stub) {
     return new BigtableTableAdminClient(instanceName, stub);
   }
 
-  private BigtableTableAdminClient(@Nonnull InstanceName instanceName, @Nonnull BigtableTableAdminStub stub) {
+  private BigtableTableAdminClient(@Nonnull InstanceName instanceName,
+      @Nonnull BigtableTableAdminStub stub) {
     Preconditions.checkNotNull(instanceName);
     Preconditions.checkNotNull(stub);
     this.instanceName = instanceName;
@@ -136,15 +140,15 @@ public void close() {
    * 

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   CreateTableRequest request = CreateTableRequest.of("tableId")
-   *       .addFamily("cf2", GCRULES.maxVersions(10))
-   *   client.createTable(request);
-   * }
+   * Table table = client.createTable(
+   *   CreateTableRequest.of("my-table")
+   *     .addFamily("cf2", GCRULES.maxVersions(1)
+   * );
    * }
* - * @see CreateTableRequest for createTable configurations + * @see CreateTableRequest for available options. */ + @SuppressWarnings("WeakerAccess") public Table createTable(CreateTableRequest request) { return awaitFuture(createTableAsync(request)); } @@ -155,15 +159,29 @@ public Table createTable(CreateTableRequest request) { *

Sample code: * *

{@code
-   *  try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *    CreateTableRequest request = CreateTableRequest.of("tableId")
-   *        .addFamily("cf2", GCRULES.maxVersions(10))
-   *    client.createTableAsync(request);
-   *  }
-   *  }
- * - * @see CreateTableRequest for createTable configurations + * ApiFuture tableFuture = client.createTableAsync( + * CreateTableRequest.of("my-table") + * .addFamily("cf", GCRules.GCRULES.maxVersions(1)) + * ); + * + * ApiFutures.addCallback( + * tableFuture, + * new ApiFutureCallback
() { + * public void onSuccess(Table table) { + * System.out.println("Created table: " + table.getTableName()); + * } + * + * public void onFailure(Throwable t) { + * t.printStackTrace(); + * } + * }, + * MoreExecutors.directExecutor() + * ); + * } + * + * @see CreateTableRequest for available options. */ + @SuppressWarnings("WeakerAccess") public ApiFuture
createTableAsync(CreateTableRequest request) { return transformToTableResponse( this.stub.createTableCallable().futureCall(request.toProto(instanceName))); @@ -175,129 +193,194 @@ public ApiFuture
createTableAsync(CreateTableRequest request) { *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   ModifyFamilies request = ModifyColumnFamiliesRequest.of(tableId)
-   *     .addFamily("mf1")
-   *     .addFamily(
-   *       "mf2", GCRULES.maxAge(Duration.ofSeconds(1000, 20000)))
+   * Table modifiedTable = client.modifyFamilies(
+   *   ModifyColumnFamiliesRequest.of(tableId)
+   *     .addFamily("cf1")
+   *     .addFamily("cf2", GCRULES.maxAge(Duration.ofSeconds(1000, 20000)))
    *     .updateFamily(
-   *       "mf1",
-   *          GCRULES
-   *            .union()
-   *              .rule(GCRULES.maxAge(Duration.ofSeconds(100)))
-   *              .rule(GCRULES.maxVersions(1)))
+   *       "cf3",
+   *       GCRULES.union()
+   *         .rule(GCRULES.maxAge(Duration.ofSeconds(100)))
+   *         .rule(GCRULES.maxVersions(1))
+   *       )
    *     .addFamily(
-   *       "mf3",
-   *         GCRULES
-   *           .intersection()
-   *           .rule(GCRULES.maxAge(Duration.ofSeconds(2000)))
-   *           .rule(GCRULES.maxVersions(10)))
-   *     .dropFamily("mf1")
-   *    client.modifyFamilies(request);
+   *       "cf4",
+   *       GCRULES.intersection()
+   *         .rule(GCRULES.maxAge(Duration.ofSeconds(2000)))
+   *         .rule(GCRULES.maxVersions(10))
+   *     )
+   *     .dropFamily("cf5")
+   * );
+   *
+   * System.out.println("Resulting families:");
+   *
+   * for (ColumnFamily cf : modifiedTable.getColumnFamilies()) {
+   *   System.out.println(cf.getId());
    * }
    * }
* - * @see ModifyColumnFamiliesRequest for modifyFamily options + * @see ModifyColumnFamiliesRequest for available options. */ + @SuppressWarnings("WeakerAccess") public Table modifyFamilies(ModifyColumnFamiliesRequest request) { return awaitFuture(modifyFamiliesAsync(request)); } /** - * Creates, Updates and drops ColumnFamilies as per the request asynchronously + * Asynchronously creates, updates and drops ColumnFamilies as per the request. * *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   ModifyFamilies request = ModifyColumnFamiliesRequest.of(tableId)
-   *     .addFamily("mf1")
-   *     .addFamily(
-   *       "mf2", GCRULES.maxAge(Duration.ofSeconds(1000, 20000)))
+   * ApiFuture
modifiedTableFuture = client.modifyFamiliesAsync( + * ModifyColumnFamiliesRequest.of(tableId) + * .addFamily("cf1") + * .addFamily("cf2", GCRULES.maxAge(Duration.ofSeconds(1000, 20000))) * .updateFamily( - * "mf1", - * GCRULES - * .union() - * .rule(GCRULES.maxAge(Duration.ofSeconds(100))) - * .rule(GCRULES.maxVersions(1))) + * "cf3", + * GCRULES.union() + * .rule(GCRULES.maxAge(Duration.ofSeconds(100))) + * .rule(GCRULES.maxVersions(1)) + * ) * .addFamily( - * "mf3", - * GCRULES - * .intersection() - * .rule(GCRULES.maxAge(Duration.ofSeconds(2000))) - * .rule(GCRULES.maxVersions(10))) - * .dropFamily("mf1") - * client.modifyFamilies(request); - * } + * "cf4", + * GCRULES.intersection() + * .rule(GCRULES.maxAge(Duration.ofSeconds(2000))) + * .rule(GCRULES.maxVersions(10)) + * ) + * .dropFamily("cf5") + * ); + * + * ApiFutures.addCallback( + * modifiedTableFuture, + * new ApiFutureCallback
() { + * public void onSuccess(Table table) { + * System.out.println("Modified table: " + table.getTableName()); + * System.out.println("Resulting families:"); + * + * for (ColumnFamily cf : modifiedTable.getColumnFamilies()) { + * System.out.println(cf.getId()); + * } + * } + * + * public void onFailure(Throwable t) { + * t.printStackTrace(); + * } + * }, + * MoreExecutors.directExecutor() + * ); * } * - * @see ModifyColumnFamiliesRequest for modifyFamily options + * @see ModifyColumnFamiliesRequest for available options. */ + @SuppressWarnings("WeakerAccess") public ApiFuture
modifyFamiliesAsync(ModifyColumnFamiliesRequest request) { return transformToTableResponse( this.stub.modifyColumnFamiliesCallable().futureCall(request.toProto(instanceName))); } /** - * Deletes the specified tableId + * Deletes the table specified by tableId * *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   client.deleteTable("tableId");
-   * }
+   * client.deleteTable("my-table");
    * }
*/ + @SuppressWarnings("WeakerAccess") public void deleteTable(String tableId) { awaitFuture(deleteTableAsync(tableId)); } /** - * Deletes the specified tableId asynchronously + * Asynchronously deletes the table specified by tableId. * *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   client.deleteTableAsync("tableId");
-   * }
+   * ApiFuture future = client.deleteTableAsync("my-table");
+   *
+   * ApiFutures.addCallback(
+   *   future,
+   *   new ApiFutureCallback() {
+   *     public void onSuccess(Void ignored) {
+   *       System.out.println("Successfully deleted the table");
+   *     }
+   *
+   *     public void onFailure(Throwable t) {
+   *       t.printStackTrace();
+   *     }
+   *   },
+   *   MoreExecutors.directExecutor()
+   * );
    * }
*/ + @SuppressWarnings("WeakerAccess") public ApiFuture deleteTableAsync(String tableId) { - return transformToVoid( - this.stub.deleteTableCallable().futureCall(composeDeleteTableRequest(tableId))); + DeleteTableRequest request = DeleteTableRequest.newBuilder() + .setName(getTableName(tableId)) + .build(); + + return transformToVoid(this.stub.deleteTableCallable().futureCall(request)); } /** - * Gets the Table by tableId + * Gets the table metadata by tableId. * *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   client.getTable("tableId");
+   * Table table = client.getTable("my-table");
+   *
+   * System.out.println("Got metadata for table: " + table.getId());
+   * System.out.println("Column families:");
+   *
+   * for (ColumnFamily cf : table.getColumnFamilies()) {
+   *   System.out.println(cf.getId());
    * }
    * }
*/ + @SuppressWarnings("WeakerAccess") public Table getTable(String tableId) { return awaitFuture(getTableAsync(tableId)); } /** - * Gets the Table by tableId + * Asynchronously gets the table metadata by tableId. * *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   client.getTableAsync("tableId");
-   * }
+   * ApiFuture
tableFuture = client.getTableAsync("my-table"); + * + * ApiFutures.addCallback( + * tableFuture, + * new ApiFutureCallback
() { + * public void onSuccess(Table table) { + * System.out.println("Got metadata for table: " + table.getId()); + * System.out.println("Column families:"); + * for (ColumnFamily cf : table.getColumnFamilies()) { + * System.out.println(cf.getId()); + * } + * } + * + * public void onFailure(Throwable t) { + * t.printStackTrace(); + * } + * }, + * MoreExecutors.directExecutor() + * ); * } */ + @SuppressWarnings("WeakerAccess") public ApiFuture
getTableAsync(String tableId) { + GetTableRequest request = GetTableRequest.newBuilder() + .setName(getTableName(tableId)) + .build(); + return transformToTableResponse( - this.stub.getTableCallable().futureCall(composeGetTableRequest(tableId))); + this.stub.getTableCallable().futureCall(request)); } /** @@ -306,36 +389,63 @@ public ApiFuture
getTableAsync(String tableId) { *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   client.listTables();
+   * List tableNames = client.listTables();
+   * for(TableName name : tableNames) {
+   *   System.out.println(name.getTable());
    * }
    * }
*/ + // TODO(igorbernstein2): consider changing this method to use relative table ids. + @SuppressWarnings("WeakerAccess") public List listTables() { return awaitFuture(listTablesAsync()); } /** - * Lists all TableNames in the instance asynchronously + * Asynchronously lists all TableNames in the instance. * *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   client.listTablesAsync();
-   * }
+   * ApiFuture> listFuture = client.listTables();
+   *
+   * ApiFutures.addCallback(
+   *   listFuture,
+   *   new ApiFutureCallback>() {
+   *     public void onSuccess(List tableNames) {
+   *       System.out.println("Got list of tables:");
+   *       for (TableName name : tableNames) {
+   *         System.out.println(name.getTable());
+   *       }
+   *     }
+   *
+   *     public void onFailure(Throwable t) {
+   *       t.printStackTrace();
+   *     }
+   *   },
+   *   MoreExecutors.directExecutor()
+   * );
    * }
*/ + // TODO(igorbernstein2): consider changing this method to use relative table ids. + @SuppressWarnings("WeakerAccess") public ApiFuture> listTablesAsync() { + ListTablesRequest request = ListTablesRequest.newBuilder().setParent(instanceName.toString()) + .build(); + ApiFuture listResp = - this.stub.listTablesPagedCallable().futureCall(composeListTableRequest()); + this.stub.listTablesPagedCallable().futureCall(request); return ApiFutures.transform( listResp, new ApiFunction>() { @Override - public List apply(ListTablesPagedResponse input) { - return convertToTableNames(input.iterateAll()); + public List apply(ListTablesPagedResponse response) { + List results = Lists.newArrayList(); + for (com.google.bigtable.admin.v2.Table proto : response.iterateAll()) { + results.add(TableName.parse(proto.getName())); + } + return results; } }, MoreExecutors.directExecutor()); @@ -344,14 +454,15 @@ public List apply(ListTablesPagedResponse input) { /** * Drops rows by the specified key prefix and tableId * + *

Please note that this method is considered part of the admin API and is rate limited. + * *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   client.dropRowRange("tableId");
-   * }
+   * client.dropRowRange("my-table", "prefix");
    * }
*/ + @SuppressWarnings("WeakerAccess") public void dropRowRange(String tableId, String rowKeyPrefix) { awaitFuture(dropRowRangeAsync(tableId, rowKeyPrefix)); } @@ -359,14 +470,29 @@ public void dropRowRange(String tableId, String rowKeyPrefix) { /** * Drops rows by the specified key prefix and tableId asynchronously * + *

Please note that this method is considered part of the admin API and is rate limited. + * *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   client.dropRowRangeAsync("tableId");
-   * }
+   * ApiFuture dropFuture = client.dropRowRangeAsync("my-table", "prefix");
+   *
+   * ApiFutures.addCallback(
+   *   dropFuture,
+   *   new ApiFutureCallback() {
+   *     public void onSuccess(Void tableNames) {
+   *       System.out.println("Successfully dropped row range.");
+   *     }
+   *
+   *     public void onFailure(Throwable t) {
+   *       t.printStackTrace();
+   *     }
+   *   },
+   *   MoreExecutors.directExecutor()
+   * );
    * }
*/ + @SuppressWarnings("WeakerAccess") public ApiFuture dropRowRangeAsync(String tableId, String rowKeyPrefix) { return dropRowRangeAsync(tableId, ByteString.copyFromUtf8(rowKeyPrefix)); } @@ -374,34 +500,55 @@ public ApiFuture dropRowRangeAsync(String tableId, String rowKeyPrefix) { /** * Drops rows by the specified key prefix and tableId * + *

Please note that this method is considered part of the admin API and is rate limited. + * *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   client.dropRowRange("tableId");
-   * }
+   * client.dropRowRange("my-table", ByteString.copyFromUtf8("prefix"));
    * }
*/ + @SuppressWarnings("WeakerAccess") public void dropRowRange(String tableId, ByteString rowKeyPrefix) { awaitFuture(dropRowRangeAsync(tableId, rowKeyPrefix)); } /** - * Drops rows by the specified key prefix and tableId + * Drops rows by the specified key prefix and tableId asynchronously + * + *

Please note that this method is considered part of the admin API and is rate limited. * *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   client.dropRowRangeAsync("tableId");
-   * }
+   * ApiFuture dropFuture = client.dropRowRangeAsync("my-table", ByteString.copyFromUtf8("prefix"));
+   *
+   * ApiFutures.addCallback(
+   *   dropFuture,
+   *   new ApiFutureCallback() {
+   *     public void onSuccess(Void tableNames) {
+   *       System.out.println("Successfully dropped row range.");
+   *     }
+   *
+   *     public void onFailure(Throwable t) {
+   *       t.printStackTrace();
+   *     }
+   *   },
+   *   MoreExecutors.directExecutor()
+   * );
    * }
*/ + @SuppressWarnings("WeakerAccess") public ApiFuture dropRowRangeAsync(String tableId, ByteString rowKeyPrefix) { + DropRowRangeRequest request = DropRowRangeRequest.newBuilder() + .setName(getTableName(tableId)) + .setRowKeyPrefix(rowKeyPrefix) + .build(); + return transformToVoid( this.stub .dropRowRangeCallable() - .futureCall(composeDropRowRangeRequest(tableId, rowKeyPrefix, false))); + .futureCall(request)); } /** @@ -410,31 +557,48 @@ public ApiFuture dropRowRangeAsync(String tableId, ByteString rowKeyPrefix *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   client.dropAllRows("tableId");
-   * }
+   * client.dropAllRows("my-table");
    * }
*/ + @SuppressWarnings("WeakerAccess") public void dropAllRows(String tableId) { awaitFuture(dropAllRowsAsync(tableId)); } /** - * Drops all data in the table asynchronously + * Asynchornously drops all data in the table. * *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   client.dropAllRowsAsync("tableId");
-   * }
+   * ApiFuture dropFuture = client.dropAllRowsAsync("my-table");
+   *
+   * ApiFutures.addCallback(
+   *   dropFuture,
+   *   new ApiFutureCallback() {
+   *     public void onSuccess(Void tableNames) {
+   *       System.out.println("Successfully dropped all data");
+   *     }
+   *
+   *     public void onFailure(Throwable t) {
+   *       t.printStackTrace();
+   *     }
+   *   },
+   *   MoreExecutors.directExecutor()
+   * );
    * }
*/ + @SuppressWarnings("WeakerAccess") public ApiFuture dropAllRowsAsync(String tableId) { + DropRowRangeRequest request = DropRowRangeRequest.newBuilder() + .setName(getTableName(tableId)) + .setDeleteAllDataFromTable(true) + .build(); + return transformToVoid( this.stub .dropRowRangeCallable() - .futureCall(composeDropRowRangeRequest(tableId, null, true))); + .futureCall(request)); } /** @@ -444,39 +608,38 @@ public ApiFuture dropAllRowsAsync(String tableId) { *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   ConsistencyToken consistencyToken = client.generateConsistencyToken("tableId");
-   * }
+   * ConsistencyToken consistencyToken = client.generateConsistencyToken("my-table");
    * }
*/ + @SuppressWarnings("WeakerAccess") public ConsistencyToken generateConsistencyToken(String tableId) { return awaitFuture(generateConsistencyTokenAsync(tableId)); } /** - * Generates a token to verify the replication status of table mutations invoked before this call - * asynchronously Token expires in 90 days + * Asynchornously generates a token to verify the replication status of table mutations invoked + * before this call. Token expires in 90 days * *

Sample code: * *

{@code
-   * try(BigtableTableAdminClient client =  BigtableTableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
-   *   ConsistencyToken consistencyToken = client.generateConsistencyToken("tableId");
-   * }
+   * ApiFuture consistencyTokenFuture = client.generateConsistencyToken("my-table");
    * }
*/ + // TODO(igorbernstein2): add sample code for waiting for the fetch consistency token + @SuppressWarnings("WeakerAccess") public ApiFuture generateConsistencyTokenAsync(final String tableId) { - ApiFuture tokenResp = - this.stub - .generateConsistencyTokenCallable() - .futureCall(composeGenerateConsistencyTokenRequest(tableId)); + GenerateConsistencyTokenRequest request = GenerateConsistencyTokenRequest.newBuilder() + .setName(getTableName(tableId)) + .build(); return ApiFutures.transform( - tokenResp, + stub.generateConsistencyTokenCallable().futureCall(request), new ApiFunction() { @Override public ConsistencyToken apply(GenerateConsistencyTokenResponse proto) { - TableName tableName = TableName.of(instanceName.getProject(), instanceName.getInstance(), tableId); + TableName tableName = TableName + .of(instanceName.getProject(), instanceName.getInstance(), tableId); return ConsistencyToken.of(tableName, proto.getConsistencyToken()); } }, @@ -501,6 +664,7 @@ public ConsistencyToken apply(GenerateConsistencyTokenResponse proto) { * } * } */ + @SuppressWarnings("WeakerAccess") public boolean isConsistent(ConsistencyToken token) { return awaitFuture(isConsistentAsync(token)); } @@ -524,76 +688,14 @@ public Boolean apply(CheckConsistencyResponse input) { // TODO(igorbernstein2): add awaitConsist() & awaitConsistAsync() that generate & poll a token /** - * Helper method to construct the table name in format: - * projects/{project}/instances/{instance}/tables/{tableId} + * Helper method to construct the table name in format: projects/{project}/instances/{instance}/tables/{tableId} */ - @VisibleForTesting - String getTableName(String tableId) { + private String getTableName(String tableId) { return TableName.of(instanceName.getProject(), instanceName.getInstance(), tableId).toString(); } - /** - * Helper method to build an instance of ListTablesRequest - */ - @VisibleForTesting - ListTablesRequest composeListTableRequest() { - return ListTablesRequest.newBuilder().setParent(instanceName.toString()).build(); - } - - /** - * Helper method to build an instance of GetTableRequest - */ - @VisibleForTesting - GetTableRequest composeGetTableRequest(String tableId) { - return GetTableRequest.newBuilder().setName(getTableName(tableId)).build(); - } - - /** - * Helper method to build an instance of DeleteTableRequest - */ - @VisibleForTesting - DeleteTableRequest composeDeleteTableRequest(String tableId) { - return DeleteTableRequest.newBuilder().setName(getTableName(tableId)).build(); - } - - /** - * Helper method to build an instance of DropRowRangeRequest - */ - @VisibleForTesting - DropRowRangeRequest composeDropRowRangeRequest( - String tableId, ByteString rowKeyPrefix, boolean dropAll) { - Builder dropRowReq = DropRowRangeRequest.newBuilder().setName(getTableName(tableId)); - - if (dropAll) { - dropRowReq.setDeleteAllDataFromTable(true); - } else { - dropRowReq.setRowKeyPrefix(rowKeyPrefix); - } - return dropRowReq.build(); - } - - /** - * Helper method to build an instance of GenerateConsistencyTokenRequest - */ - @VisibleForTesting - GenerateConsistencyTokenRequest composeGenerateConsistencyTokenRequest(String tableId) { - return GenerateConsistencyTokenRequest.newBuilder().setName(getTableName(tableId)).build(); - } - - /** - * Helper method to convert ListTablesResponse to List - */ - @VisibleForTesting - static List convertToTableNames(Iterable listTablesResponse) { - List tableNames = new ArrayList<>(); - - for (com.google.bigtable.admin.v2.Table table : listTablesResponse) { - tableNames.add(TableName.parse(table.getName())); - } - return tableNames; - } - // TODO(igorbernstein): rename methods to make clear that they deal with futures. + /** * Helper method to transform ApiFuture to ApiFuture
*/ @@ -625,12 +727,28 @@ 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 future.get(); - } catch(Throwable t) { - // TODO(igorbernstein2): figure out a better wrapper exception. - throw new RuntimeException(t); + 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/test/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClientTest.java b/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClientTest.java index 7ef43120597c..85eb60ec898c 100644 --- a/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClientTest.java +++ b/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClientTest.java @@ -132,32 +132,6 @@ public void testCreateTable() { assertThat(result).isEqualTo(Table.fromProto(expectedResponse)); } - @Test - public void testCreateTableAsync() throws Exception { - // Setup - com.google.bigtable.admin.v2.CreateTableRequest expectedRequest = com.google.bigtable.admin.v2.CreateTableRequest - .newBuilder() - .setParent(INSTANCE_NAME.toString()) - .setTableId(TABLE_NAME.getTable()) - .setTable(com.google.bigtable.admin.v2.Table.getDefaultInstance()) - .build(); - - com.google.bigtable.admin.v2.Table expectedResponse = com.google.bigtable.admin.v2.Table - .newBuilder() - .setName(TABLE_NAME.toString()) - .build(); - - Mockito.when(mockCreateTableCallable.futureCall(expectedRequest)) - .thenReturn(ApiFutures.immediateFuture(expectedResponse)); - - // Execute - ApiFuture
result = adminClient - .createTableAsync(CreateTableRequest.of(TABLE_NAME.getTable())); - - // Verify - assertThat(result.get()).isEqualTo(Table.fromProto(expectedResponse)); - } - @Test public void testModifyFamilies() { // Setup @@ -192,43 +166,6 @@ public void testModifyFamilies() { assertThat(actualResult).isEqualTo(Table.fromProto(fakeResponse)); } - @Test - public void testModifyFamiliesAsync() throws Exception { - // Setup - com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest expectedRequest = - com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest - .newBuilder() - .setName(TABLE_NAME.toString()) - .addModifications( - Modification.newBuilder() - .setId("cf") - .setCreate( - ColumnFamily.newBuilder() - .setGcRule(GcRule.getDefaultInstance()) - ) - ) - .build(); - - com.google.bigtable.admin.v2.Table expectedResponse = com.google.bigtable.admin.v2.Table - .newBuilder() - .setName(TABLE_NAME.toString()) - .putColumnFamilies("cf", - ColumnFamily.newBuilder().setGcRule(GcRule.getDefaultInstance()).build()) - .build(); - - Mockito.when(mockModifyTableCallable.futureCall(expectedRequest)) - .thenReturn(ApiFutures.immediateFuture(expectedResponse)); - - // Execute - ApiFuture
actualResult = adminClient.modifyFamiliesAsync( - ModifyColumnFamiliesRequest.of(TABLE_NAME.getTable()) - .addFamily("cf") - ); - - // Verify - assertThat(actualResult.get()).isEqualTo(Table.fromProto(expectedResponse)); - } - @Test public void testDeleteTable() { // Setup @@ -254,32 +191,6 @@ public ApiFuture answer(InvocationOnMock invocationOnMock) { assertThat(wasCalled.get()).isTrue(); } - @Test - public void testDeleteTableAsync() throws Exception { - // Setup - DeleteTableRequest expectedRequest = DeleteTableRequest.newBuilder() - .setName(TABLE_NAME.toString()) - .build(); - - final AtomicBoolean wasCalled = new AtomicBoolean(false); - - Mockito.when(mockDeleteTableCallable.futureCall(expectedRequest)) - .thenAnswer(new Answer>() { - @Override - public ApiFuture answer(InvocationOnMock invocationOnMock) { - wasCalled.set(true); - return ApiFutures.immediateFuture(Empty.getDefaultInstance()); - } - }); - - // Execute - ApiFuture result = adminClient.deleteTableAsync(TABLE_NAME.getTable()); - result.get(); - - // Verify - assertThat(wasCalled.get()).isTrue(); - } - @Test public void testGetTable() { // Setup @@ -302,28 +213,6 @@ public void testGetTable() { assertThat(actualResult).isEqualTo(Table.fromProto(expectedResponse)); } - @Test - public void testGetTableAsync() throws Exception { - // Setup - GetTableRequest expectedRequest = GetTableRequest.newBuilder() - .setName(TABLE_NAME.toString()) - .build(); - - com.google.bigtable.admin.v2.Table expectedResponse = com.google.bigtable.admin.v2.Table - .newBuilder() - .setName(TABLE_NAME.toString()) - .build(); - - Mockito.when(mockGetTableCallable.futureCall(expectedRequest)) - .thenReturn(ApiFutures.immediateFuture(expectedResponse)); - - // Execute - ApiFuture
actualResult = adminClient.getTableAsync(TABLE_NAME.getTable()); - - // Verify - assertThat(actualResult.get()).isEqualTo(Table.fromProto(expectedResponse)); - } - @Test public void testListTables() { // Setup @@ -357,39 +246,6 @@ public void testListTables() { ); } - @Test - public void testListTablesAsync() throws Exception { - // Setup - ListTablesRequest expectedRequest = ListTablesRequest.newBuilder() - .setParent(INSTANCE_NAME.toString()) - .build(); - - ListTablesPagedResponse expectedResponseWrapper = Mockito.mock(ListTablesPagedResponse.class); - - Iterable expectedResults = Lists.newArrayList( - com.google.bigtable.admin.v2.Table.newBuilder() - .setName(TABLE_NAME.toString() + "1") - .build(), - com.google.bigtable.admin.v2.Table.newBuilder() - .setName(TABLE_NAME.toString() + "2") - .build()); - - Mockito.when(mockListTableCallable.futureCall(expectedRequest)) - .thenReturn(ApiFutures.immediateFuture(expectedResponseWrapper)); - - Mockito.when(expectedResponseWrapper.iterateAll()) - .thenReturn(expectedResults); - - // Execute - ApiFuture> actualResults = adminClient.listTablesAsync(); - - // Verify - assertThat(actualResults.get()).containsExactly( - TableName.parse(TABLE_NAME.toString() + "1"), - TableName.parse(TABLE_NAME.toString() + "2") - ); - } - @Test public void testDropRowRange() { // Setup @@ -418,65 +274,6 @@ public ApiFuture answer(InvocationOnMock invocationOnMock) { assertThat(wasCalled.get()).isTrue(); } - @Test - public void testGetDropRowRangeRequest() { - DropRowRangeRequest expected = - DropRowRangeRequest.newBuilder() - .setName(adminClient.getTableName("tableId")) - .setRowKeyPrefix(ByteString.copyFromUtf8("rowKeyPrefix")) - .build(); - - DropRowRangeRequest actual = - adminClient.composeDropRowRangeRequest( - "tableId", ByteString.copyFromUtf8("rowKeyPrefix"), false); - - assertThat(actual).isEqualTo(expected); - } - - @Test - public void testGetDropRowRangeRequestDropAllData() { - DropRowRangeRequest expected = - DropRowRangeRequest.newBuilder() - .setName(adminClient.getTableName("tableId")) - .setDeleteAllDataFromTable(true) - .build(); - - DropRowRangeRequest actual = adminClient.composeDropRowRangeRequest("tableId", null, true); - - assertThat(actual).isEqualTo(expected); - } - - @Test - public void testDropRowRangeAsync() throws Exception { - // Setup - DropRowRangeRequest expectedRequest = DropRowRangeRequest.newBuilder() - .setName(TABLE_NAME.toString()) - .setRowKeyPrefix(ByteString.copyFromUtf8("rowKeyPrefix")) - .build(); - - final Empty expectedResponse = Empty.getDefaultInstance(); - - final AtomicBoolean wasCalled = new AtomicBoolean(false); - - Mockito.when(mockDropRowRangeCallable.futureCall(expectedRequest)) - .thenAnswer(new Answer>() { - @Override - public ApiFuture answer(InvocationOnMock invocationOnMock) { - wasCalled.set(true); - return ApiFutures.immediateFuture(expectedResponse); - } - }); - - // Execute - ApiFuture actualResult = adminClient - .dropRowRangeAsync(TABLE_NAME.getTable(), "rowKeyPrefix"); - - actualResult.get(); - - // Verify - assertThat(wasCalled.get()).isTrue(); - } - @Test public void testGenerateConsistencyToken() { // Setup @@ -499,29 +296,6 @@ public void testGenerateConsistencyToken() { assertThat(actualResult).isEqualTo(ConsistencyToken.of(TABLE_NAME, "fakeToken")); } - @Test - public void testGenerateConsistencyTokenAsync() throws Exception { - // Setup - GenerateConsistencyTokenRequest expectedRequest = GenerateConsistencyTokenRequest.newBuilder() - .setName(TABLE_NAME.toString()) - .build(); - - GenerateConsistencyTokenResponse expectedResponse = - GenerateConsistencyTokenResponse.newBuilder() - .setConsistencyToken("fakeToken") - .build(); - - Mockito.when(mockGenerateConsistencyTokenCallable.futureCall(expectedRequest)) - .thenReturn(ApiFutures.immediateFuture(expectedResponse)); - - // Execute - ApiFuture actualResult = adminClient - .generateConsistencyTokenAsync(TABLE_NAME.getTable()); - - // Verify - assertThat(actualResult.get()).isEqualTo(ConsistencyToken.of(TABLE_NAME, "fakeToken")); - } - @Test public void testCheckConsistencyToken() { // Setup @@ -545,23 +319,4 @@ public void testCheckConsistencyToken() { // Verify assertThat(actualResult).isTrue(); } - - @Test - public void testConvertToTableNames() { - List expected = Lists.newArrayList( - TableName.of("p", "i", "t1"), - TableName.of("p", "i", "t2") - ); - - List input = Lists.newArrayList( - com.google.bigtable.admin.v2.Table.newBuilder().setName("projects/p/instances/i/tables/t1") - .build(), - com.google.bigtable.admin.v2.Table.newBuilder().setName("projects/p/instances/i/tables/t2") - .build() - ); - - List actual = BigtableTableAdminClient.convertToTableNames(input); - - assertThat(actual).containsExactlyElementsIn(expected).inOrder(); - } }