Repository: GoogleCloudPlatform/cloud-bigtable-client
Pull request #2094 (2019-02-12 10:57:13)

Delegating snapshot related operation to wrapper
To delegate snapshot operations from `grpc.BigtableTableAdminClient` to `BigtableTableAdminClientWrapper`.

Please let me know If I should create a separate interface for snapshot. These operations are available through `BaseBigtableTableAdminClient` callables.


Patch:
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/core/IBigtableTableAdminClient.java b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/core/IBigtableTableAdminClient.java
index 36afb558f..f5d62e337 100644
--- a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/core/IBigtableTableAdminClient.java
+++ b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/core/IBigtableTableAdminClient.java
@@ -15,10 +15,18 @@
  */
 package com.google.cloud.bigtable.core;
 
+import com.google.bigtable.admin.v2.CreateTableFromSnapshotRequest;
+import com.google.bigtable.admin.v2.DeleteSnapshotRequest;
+import com.google.bigtable.admin.v2.GetSnapshotRequest;
+import com.google.bigtable.admin.v2.ListSnapshotsRequest;
+import com.google.bigtable.admin.v2.ListSnapshotsResponse;
+import com.google.bigtable.admin.v2.Snapshot;
+import com.google.bigtable.admin.v2.SnapshotTableRequest;
 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.Table;
 import com.google.common.util.concurrent.ListenableFuture;
+import com.google.longrunning.Operation;
 import java.util.List;
 
 /**
@@ -125,4 +133,39 @@ public interface IBigtableTableAdminClient {
    */
   //TODO(rahulkql): Once it is adapted to v2.models, change the return type to ApiFuture.
   ListenableFuture<Void> dropRowRangeAsync(String tableId, String rowKeyPrefix);
+
+  // ////////////// SNAPSHOT methods /////////////
+  /**
+   * Creates a new snapshot from a table in a specific cluster.
+   * @param request a {@link SnapshotTableRequest} object.
+   * @return The long running {@link Operation} for the request.
+   */
+  ListenableFuture<Operation> snapshotTableAsync(SnapshotTableRequest request);
+
+  /**
+   * Gets metadata information about the specified snapshot.
+   * @param request a {@link GetSnapshotRequest} object.
+   * @return The {@link Snapshot} definied by the request.
+   */
+  ListenableFuture<Snapshot> getSnapshotAsync(GetSnapshotRequest request);
+
+  /**
+   * Lists all snapshots associated with the specified cluster.
+   * @param request a {@link ListSnapshotsRequest} object.
+   * @return The {@link ListSnapshotsResponse} which has the list of the snapshots in the cluster.
+   */
+  ListenableFuture<ListSnapshotsResponse> listSnapshotsAsync(ListSnapshotsRequest request);
+
+  /**
+   * Permanently deletes the specified snapshot.
+   * @param request a {@link DeleteSnapshotRequest} object.
+   */
+  ListenableFuture<Void> deleteSnapshotAsync(DeleteSnapshotRequest request);
+
+  /**
+   * Creates a new table from a snapshot.
+   * @param request a {@link CreateTableFromSnapshotRequest} object.
+   * @return The long running {@link Operation} for the request.
+   */
+  ListenableFuture<Operation> createTableFromSnapshotAsync(CreateTableFromSnapshotRequest request);
 }
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/BigtableTableAdminClientWrapper.java b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/BigtableTableAdminClientWrapper.java
index be31e2e52..eab62d2cd 100644
--- a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/BigtableTableAdminClientWrapper.java
+++ b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/BigtableTableAdminClientWrapper.java
@@ -15,11 +15,18 @@
  */
 package com.google.cloud.bigtable.grpc;
 
+import com.google.bigtable.admin.v2.CreateTableFromSnapshotRequest;
+import com.google.bigtable.admin.v2.DeleteSnapshotRequest;
 import com.google.bigtable.admin.v2.DeleteTableRequest;
 import com.google.bigtable.admin.v2.DropRowRangeRequest;
+import com.google.bigtable.admin.v2.GetSnapshotRequest;
 import com.google.bigtable.admin.v2.GetTableRequest;
+import com.google.bigtable.admin.v2.ListSnapshotsRequest;
+import com.google.bigtable.admin.v2.ListSnapshotsResponse;
 import com.google.bigtable.admin.v2.ListTablesRequest;
 import com.google.bigtable.admin.v2.ListTablesResponse;
+import com.google.bigtable.admin.v2.Snapshot;
+import com.google.bigtable.admin.v2.SnapshotTableRequest;
 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.Table;
@@ -32,6 +39,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.MoreExecutors;
+import com.google.longrunning.Operation;
 import com.google.protobuf.ByteString;
 import com.google.protobuf.Empty;
 import java.util.List;
@@ -43,14 +51,14 @@ import javax.annotation.Nonnull;
  */
 public class BigtableTableAdminClientWrapper implements IBigtableTableAdminClient {
 
-  private final BigtableTableAdminClient adminClient;
+  private final BigtableTableAdminClient delegate;
   private final BigtableInstanceName instanceName;
 
   public BigtableTableAdminClientWrapper(@Nonnull BigtableTableAdminClient adminClient,
       @Nonnull BigtableOptions options){
     Preconditions.checkNotNull(adminClient);
     Preconditions.checkNotNull(options);
-    this.adminClient = adminClient;
+    this.delegate = adminClient;
     this.instanceName = options.getInstanceName();
   }
 
@@ -59,7 +67,7 @@ public class BigtableTableAdminClientWrapper implements IBigtableTableAdminClien
   public Table createTable(CreateTableRequest request) {
     com.google.bigtable.admin.v2.CreateTableRequest requestProto =
         request.toProto(instanceName.getProjectId(), instanceName.getInstanceId());
-    adminClient.createTable(requestProto);
+    delegate.createTable(requestProto);
 
     return getTable(requestProto.getTableId());
   }
@@ -70,7 +78,7 @@ public class BigtableTableAdminClientWrapper implements IBigtableTableAdminClien
     com.google.bigtable.admin.v2.CreateTableRequest requestProto =
         request.toProto(instanceName.getProjectId(), instanceName.getInstanceId());
 
-    return Futures.transform(adminClient.createTableAsync(requestProto),
+    return Futures.transform(delegate.createTableAsync(requestProto),
         new Function<com.google.bigtable.admin.v2.Table, Table>() {
           @Override
           public Table apply(com.google.bigtable.admin.v2.Table tableProto) {
@@ -86,7 +94,7 @@ public class BigtableTableAdminClientWrapper implements IBigtableTableAdminClien
         .setName(instanceName.toTableNameStr(tableId))
         .build();
 
-    return Table.fromProto(adminClient.getTable(requestProto));
+    return Table.fromProto(delegate.getTable(requestProto));
   }
 
   /** {@inheritDoc} */
@@ -96,7 +104,7 @@ public class BigtableTableAdminClientWrapper implements IBigtableTableAdminClien
         .setName(instanceName.toTableNameStr(tableId))
         .build();
 
-    return Futures.transform(adminClient.getTableAsync(requestProto),
+    return Futures.transform(delegate.getTableAsync(requestProto),
         new Function<com.google.bigtable.admin.v2.Table, Table>() {
           @Override
           public Table apply(com.google.bigtable.admin.v2.Table tableProto) {
@@ -112,7 +120,7 @@ public class BigtableTableAdminClientWrapper implements IBigtableTableAdminClien
         .setParent(instanceName.toString())
         .build();
 
-    ListTablesResponse response = adminClient.listTables(requestProto);
+    ListTablesResponse response = delegate.listTables(requestProto);
 
     ImmutableList.Builder<String> tableIdsBuilder = ImmutableList.builder();
     for(com.google.bigtable.admin.v2.Table tableProto : response.getTablesList()){
@@ -128,7 +136,7 @@ public class BigtableTableAdminClientWrapper implements IBigtableTableAdminClien
     ListTablesRequest request = ListTablesRequest.newBuilder()
         .setParent(instanceName.toString())
         .build();
-    ListenableFuture<ListTablesResponse> response = adminClient.listTablesAsync(request);
+    ListenableFuture<ListTablesResponse> response = delegate.listTablesAsync(request);
 
     return Futures.transform(response, new Function<ListTablesResponse, List<String>>() {
       @Override
@@ -150,7 +158,7 @@ public class BigtableTableAdminClientWrapper implements IBigtableTableAdminClien
         .setName(instanceName.toTableNameStr(tableId))
         .build();
 
-    adminClient.deleteTable(request);
+    delegate.deleteTable(request);
   }
 
   /** {@inheritDoc} */
@@ -160,7 +168,7 @@ public class BigtableTableAdminClientWrapper implements IBigtableTableAdminClien
         .setName(instanceName.toTableNameStr(tableId))
         .build();
 
-    return Futures.transform(adminClient.deleteTableAsync(request), new Function<Empty, Void>() {
+    return Futures.transform(delegate.deleteTableAsync(request), new Function<Empty, Void>() {
       @Override
       public Void apply(Empty empty) {
         return null;
@@ -174,7 +182,7 @@ public class BigtableTableAdminClientWrapper implements IBigtableTableAdminClien
     com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest modifyColumnRequestProto =
         request.toProto(instanceName.getProjectId(), instanceName.getInstanceId());
 
-    return Table.fromProto(adminClient.modifyColumnFamily(modifyColumnRequestProto));
+    return Table.fromProto(delegate.modifyColumnFamily(modifyColumnRequestProto));
   }
 
   /** {@inheritDoc} */
@@ -183,7 +191,7 @@ public class BigtableTableAdminClientWrapper implements IBigtableTableAdminClien
     com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest modifyColumnRequestProto =
         request.toProto(instanceName.getProjectId(), instanceName.getInstanceId());
 
-    return Futures.transform(adminClient.modifyColumnFamilyAsync(modifyColumnRequestProto),
+    return Futures.transform(delegate.modifyColumnFamilyAsync(modifyColumnRequestProto),
         new Function<com.google.bigtable.admin.v2.Table, Table>() {
       @Override
       public Table apply(com.google.bigtable.admin.v2.Table tableProto) {
@@ -196,7 +204,7 @@ public class BigtableTableAdminClientWrapper implements IBigtableTableAdminClien
   @Override
   public void dropRowRange(String tableId, String rowKeyPrefix) {
 
-    adminClient.dropRowRange(buildDropRowRangeRequest(tableId, rowKeyPrefix));
+    delegate.dropRowRange(buildDropRowRangeRequest(tableId, rowKeyPrefix));
   }
 
   /** {@inheritDoc} */
@@ -204,7 +212,7 @@ public class BigtableTableAdminClientWrapper implements IBigtableTableAdminClien
   public ListenableFuture<Void> dropRowRangeAsync(String tableId, String rowKeyPrefix) {
 
     return Futures.transform(
-        adminClient.dropRowRangeAsync(buildDropRowRangeRequest(tableId, rowKeyPrefix)),
+        delegate.dropRowRangeAsync(buildDropRowRangeRequest(tableId, rowKeyPrefix)),
         new Function<Empty, Void>() {
           @Override
           public Void apply(Empty empty) {
@@ -213,6 +221,37 @@ public class BigtableTableAdminClientWrapper implements IBigtableTableAdminClien
         }, MoreExecutors.directExecutor());
   }
 
+  @Override
+  public ListenableFuture<Operation> snapshotTableAsync(SnapshotTableRequest request) {
+    return delegate.snapshotTableAsync(request);
+  }
+
+  @Override
+  public ListenableFuture<Snapshot> getSnapshotAsync(GetSnapshotRequest request) {
+    return delegate.getSnapshotAsync(request);
+  }
+
+  @Override
+  public ListenableFuture<ListSnapshotsResponse> listSnapshotsAsync(ListSnapshotsRequest request) {
+    return delegate.listSnapshotsAsync(request);
+  }
+
+  @Override
+  public ListenableFuture<Void> deleteSnapshotAsync(DeleteSnapshotRequest request) {
+    return Futures.transform(delegate.deleteSnapshotAsync(request), new Function<Empty, Void>() {
+      @Override
+      public Void apply(Empty input) {
+        return null;
+      }
+    }, MoreExecutors.directExecutor());
+  }
+
+  @Override
+  public ListenableFuture<Operation> createTableFromSnapshotAsync(
+      CreateTableFromSnapshotRequest request) {
+    return delegate.createTableFromSnapshotAsync(request);
+  }
+
   private DropRowRangeRequest buildDropRowRangeRequest(String tableId, String rowKeyPrefix) {
     DropRowRangeRequest.Builder dropRequestProtoBuiler =
         DropRowRangeRequest.newBuilder()
diff --git a/bigtable-client-core-parent/bigtable-hbase/src/main/java/org/apache/hadoop/hbase/client/AbstractBigtableAdmin.java b/bigtable-client-core-parent/bigtable-hbase/src/main/java/org/apache/hadoop/hbase/client/AbstractBigtableAdmin.java
index f0191d5ab..2ddd9c7b6 100644
--- a/bigtable-client-core-parent/bigtable-hbase/src/main/java/org/apache/hadoop/hbase/client/AbstractBigtableAdmin.java
+++ b/bigtable-client-core-parent/bigtable-hbase/src/main/java/org/apache/hadoop/hbase/client/AbstractBigtableAdmin.java
@@ -28,7 +28,6 @@ import com.google.cloud.bigtable.config.Logger;
 import com.google.cloud.bigtable.core.IBigtableTableAdminClient;
 import com.google.cloud.bigtable.grpc.BigtableClusterName;
 import com.google.cloud.bigtable.grpc.BigtableInstanceName;
-import com.google.cloud.bigtable.grpc.BigtableTableAdminClient;
 import com.google.cloud.bigtable.hbase.BigtableOptionsFactory;
 import com.google.cloud.bigtable.hbase.adapters.admin.TableAdapter;
 import com.google.cloud.bigtable.hbase.util.ModifyTableBuilder;
@@ -97,7 +96,6 @@ public abstract class AbstractBigtableAdmin implements Admin {
   private final Configuration configuration;
   private final BigtableOptions options;
   protected final CommonConnection connection;
-  protected final BigtableTableAdminClient bigtableTableAdminClient;
   protected final IBigtableTableAdminClient tableAdminClientWrapper;
   protected final BigtableInstanceName bigtableInstanceName;
   private BigtableClusterName bigtableSnapshotClusterName;
@@ -115,7 +113,6 @@ public abstract class AbstractBigtableAdmin implements Admin {
     configuration = connection.getConfiguration();
     options = connection.getOptions();
     this.connection = connection;
-    bigtableTableAdminClient = connection.getSession().getTableAdminClient();
     disabledTables = connection.getDisabledTables();
     bigtableInstanceName = options.getInstanceName();
     tableAdapter = new TableAdapter(bigtableInstanceName);
@@ -848,7 +845,7 @@ public abstract class AbstractBigtableAdmin implements Admin {
       );
     }
 
-    ListenableFuture<Operation> future = bigtableTableAdminClient
+    ListenableFuture<Operation> future = tableAdminClientWrapper
         .snapshotTableAsync(requestBuilder.build());
 
     return Futures.getChecked(future, IOException.class);
@@ -890,7 +887,7 @@ public abstract class AbstractBigtableAdmin implements Admin {
         .setSourceSnapshot(getClusterName().toSnapshotName(snapshotName))
         .build();
     Operation operation = Futures
-        .getChecked(bigtableTableAdminClient.createTableFromSnapshotAsync(request),
+        .getChecked(tableAdminClientWrapper.createTableFromSnapshotAsync(request),
             IOException.class);
 
     try {
@@ -932,7 +929,7 @@ public abstract class AbstractBigtableAdmin implements Admin {
         .setName(btSnapshotName)
         .build();
 
-    Futures.getUnchecked(bigtableTableAdminClient.deleteSnapshotAsync(request));
+    Futures.getUnchecked(tableAdminClientWrapper.deleteSnapshotAsync(request));
   }
 
   /**
diff --git a/bigtable-hbase-1.x-parent/bigtable-hbase-1.x/src/main/java/com/google/cloud/bigtable/hbase1_x/BigtableAdmin.java b/bigtable-hbase-1.x-parent/bigtable-hbase-1.x/src/main/java/com/google/cloud/bigtable/hbase1_x/BigtableAdmin.java
index 265200bb8..1e46499f7 100644
--- a/bigtable-hbase-1.x-parent/bigtable-hbase-1.x/src/main/java/com/google/cloud/bigtable/hbase1_x/BigtableAdmin.java
+++ b/bigtable-hbase-1.x-parent/bigtable-hbase-1.x/src/main/java/com/google/cloud/bigtable/hbase1_x/BigtableAdmin.java
@@ -140,7 +140,7 @@ public class BigtableAdmin extends AbstractBigtableAdmin {
         .build();
 
     ListSnapshotsResponse snapshotList = Futures.getChecked(
-        bigtableTableAdminClient.listSnapshotsAsync(request),
+        tableAdminClientWrapper.listSnapshotsAsync(request),
         IOException.class
     );
 
diff --git a/bigtable-hbase-2.x-parent/bigtable-hbase-2.x/src/main/java/com/google/cloud/bigtable/hbase2_x/BigtableAdmin.java b/bigtable-hbase-2.x-parent/bigtable-hbase-2.x/src/main/java/com/google/cloud/bigtable/hbase2_x/BigtableAdmin.java
index e7718b008..2ff1eeb92 100644
--- a/bigtable-hbase-2.x-parent/bigtable-hbase-2.x/src/main/java/com/google/cloud/bigtable/hbase2_x/BigtableAdmin.java
+++ b/bigtable-hbase-2.x-parent/bigtable-hbase-2.x/src/main/java/com/google/cloud/bigtable/hbase2_x/BigtableAdmin.java
@@ -135,7 +135,7 @@ public class BigtableAdmin extends AbstractBigtableAdmin {
         .setParent(getSnapshotClusterName().toString())
         .build();
 
-    ListSnapshotsResponse snapshotList = Futures.getChecked(bigtableTableAdminClient
+    ListSnapshotsResponse snapshotList = Futures.getChecked(tableAdminClientWrapper
         .listSnapshotsAsync(request), IOException.class);
     List<SnapshotDescription> response = new ArrayList<>();
     for (Snapshot snapshot : snapshotList.getSnapshotsList()) {
diff --git a/bigtable-hbase-2.x-parent/bigtable-hbase-2.x/src/main/java/com/google/cloud/bigtable/hbase2_x/BigtableAsyncAdmin.java b/bigtable-hbase-2.x-parent/bigtable-hbase-2.x/src/main/java/com/google/cloud/bigtable/hbase2_x/BigtableAsyncAdmin.java
index 4285becec..3bdcc1a5b 100644
--- a/bigtable-hbase-2.x-parent/bigtable-hbase-2.x/src/main/java/com/google/cloud/bigtable/hbase2_x/BigtableAsyncAdmin.java
+++ b/bigtable-hbase-2.x-parent/bigtable-hbase-2.x/src/main/java/com/google/cloud/bigtable/hbase2_x/BigtableAsyncAdmin.java
@@ -297,7 +297,7 @@ public class BigtableAsyncAdmin implements AsyncAdmin {
         throw new CompletionException(e);
       }
     }).thenCompose(
-        d -> bigtableTableAdminClient.deleteSnapshotAsync(d).thenApply(r -> null));
+        d -> bigtableTableAdminClient.deleteSnapshotAsync(d));
   }
 
   @Override
diff --git a/bigtable-hbase-2.x-parent/bigtable-hbase-2.x/src/main/java/com/google/cloud/bigtable/hbase2_x/BigtableTableAdminClient.java b/bigtable-hbase-2.x-parent/bigtable-hbase-2.x/src/main/java/com/google/cloud/bigtable/hbase2_x/BigtableTableAdminClient.java
index 03a4f029a..b10519347 100644
--- a/bigtable-hbase-2.x-parent/bigtable-hbase-2.x/src/main/java/com/google/cloud/bigtable/hbase2_x/BigtableTableAdminClient.java
+++ b/bigtable-hbase-2.x-parent/bigtable-hbase-2.x/src/main/java/com/google/cloud/bigtable/hbase2_x/BigtableTableAdminClient.java
@@ -124,7 +124,7 @@ public class BigtableTableAdminClient {
    * @return The long running {@link Operation} for the request.
    */
   public CompletableFuture<Operation> snapshotTableAsync(SnapshotTableRequest request) {
-    return toCompletableFuture(adminClient.snapshotTableAsync(request));
+    return toCompletableFuture(adminClientWrapper.snapshotTableAsync(request));
   }
 
   /**
@@ -133,7 +133,7 @@ public class BigtableTableAdminClient {
    * @return The {@link Snapshot} definied by the request.
    */
   public CompletableFuture<Snapshot> getSnapshotAsync(GetSnapshotRequest request) {
-    return toCompletableFuture(adminClient.getSnapshotAsync(request));
+    return toCompletableFuture(adminClientWrapper.getSnapshotAsync(request));
   }
 
   /**
@@ -142,15 +142,15 @@ public class BigtableTableAdminClient {
    * @return The {@link ListSnapshotsResponse} which has the list of the snapshots in the cluster.
    */
   public CompletableFuture<ListSnapshotsResponse> listSnapshotsAsync(ListSnapshotsRequest request) {
-    return toCompletableFuture(adminClient.listSnapshotsAsync(request));
+    return toCompletableFuture(adminClientWrapper.listSnapshotsAsync(request));
   }
 
   /**
    * Permanently deletes the specified snapshot.
    * @param request a {@link DeleteSnapshotRequest} object.
    */
-  public CompletableFuture<Empty> deleteSnapshotAsync(DeleteSnapshotRequest request) {
-    return toCompletableFuture(adminClient.deleteSnapshotAsync(request));
+  public CompletableFuture<Void> deleteSnapshotAsync(DeleteSnapshotRequest request) {
+    return toCompletableFuture(adminClientWrapper.deleteSnapshotAsync(request));
   }
 
   /**
@@ -159,6 +159,6 @@ public class BigtableTableAdminClient {
    * @return The long running {@link Operation} for the request.
    */
   public CompletableFuture<Operation> createTableFromSnapshotAsync(CreateTableFromSnapshotRequest request) {
-    return toCompletableFuture(adminClient.createTableFromSnapshotAsync(request));
+    return toCompletableFuture(adminClientWrapper.createTableFromSnapshotAsync(request));
   }
 }


Test patch:
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/TestBigtableTableAdminClientWrapper.java b/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/TestBigtableTableAdminClientWrapper.java
index f7f33c807..bf8c04021 100644
--- a/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/TestBigtableTableAdminClientWrapper.java
+++ b/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/TestBigtableTableAdminClientWrapper.java
@@ -23,18 +23,27 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import com.google.bigtable.admin.v2.ColumnFamily;
+import com.google.bigtable.admin.v2.CreateTableFromSnapshotRequest;
+import com.google.bigtable.admin.v2.DeleteSnapshotRequest;
 import com.google.bigtable.admin.v2.DeleteTableRequest;
 import com.google.bigtable.admin.v2.DropRowRangeRequest;
+import com.google.bigtable.admin.v2.GetSnapshotRequest;
 import com.google.bigtable.admin.v2.GetTableRequest;
+import com.google.bigtable.admin.v2.ListSnapshotsRequest;
+import com.google.bigtable.admin.v2.ListSnapshotsResponse;
 import com.google.bigtable.admin.v2.ListTablesRequest;
 import com.google.bigtable.admin.v2.ListTablesResponse;
+import com.google.bigtable.admin.v2.Snapshot;
+import com.google.bigtable.admin.v2.SnapshotTableRequest;
 import com.google.cloud.bigtable.admin.v2.models.CreateTableRequest;
 import com.google.cloud.bigtable.admin.v2.models.GCRules;
 import com.google.cloud.bigtable.admin.v2.models.ModifyColumnFamiliesRequest;
 import com.google.cloud.bigtable.admin.v2.models.Table;
 import com.google.cloud.bigtable.config.BigtableOptions;
 import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
+import com.google.longrunning.Operation;
 import com.google.protobuf.ByteString;
 import com.google.protobuf.Empty;
 import java.util.List;
@@ -271,6 +280,69 @@ public class TestBigtableTableAdminClientWrapper {
     verify(mockAdminClient).dropRowRangeAsync(request);
   }
 
+  @Test
+  public void testSnapshotTableAsync() throws Exception {
+    SnapshotTableRequest request = SnapshotTableRequest.newBuilder()
+        .setSnapshotId("snaphsotId")
+        .setName(TABLE_NAME)
+        .build();
+    Operation response = Operation.getDefaultInstance();
+    when(mockAdminClient.snapshotTableAsync(request)).thenReturn(Futures.immediateFuture(response));
+    ListenableFuture<Operation> actualResponse = clientWrapper.snapshotTableAsync(request);
+    assertEquals(response, actualResponse.get());
+    verify(mockAdminClient).snapshotTableAsync(request);
+  }
+
+  @Test
+  public void testGetSnapshotAsync() throws Exception {
+    GetSnapshotRequest request = GetSnapshotRequest.newBuilder()
+        .setName(TABLE_NAME)
+        .build();
+    Snapshot response = Snapshot.getDefaultInstance();
+    when(mockAdminClient.getSnapshotAsync(request)).thenReturn(Futures.immediateFuture(response));
+    ListenableFuture<Snapshot> actualResponse = clientWrapper.getSnapshotAsync(request);
+    assertEquals(response, actualResponse.get());
+    verify(mockAdminClient).getSnapshotAsync(request);
+  }
+
+  @Test
+  public void testListSnapshotsAsync() throws Exception {
+    ListSnapshotsRequest request = ListSnapshotsRequest.newBuilder()
+        .setParent(TABLE_NAME)
+        .build();
+    ListSnapshotsResponse response = ListSnapshotsResponse.getDefaultInstance();
+    when(mockAdminClient.listSnapshotsAsync(request)).thenReturn(Futures.immediateFuture(response));
+    ListenableFuture<ListSnapshotsResponse> actualResponse = clientWrapper.listSnapshotsAsync(request);
+    assertEquals(response, actualResponse.get());
+    verify(mockAdminClient).listSnapshotsAsync(request);
+  }
+
+
+  @Test
+  public void testDeleteSnapshotAsync() {
+    DeleteSnapshotRequest request = DeleteSnapshotRequest.newBuilder()
+        .setName(TABLE_NAME)
+        .build();
+    when(mockAdminClient.deleteSnapshotAsync(request))
+        .thenReturn(Futures.immediateFuture(Empty.getDefaultInstance()));
+    clientWrapper.deleteSnapshotAsync(request);
+    verify(mockAdminClient).deleteSnapshotAsync(request);
+  }
+
+  @Test
+  public void testCreateTableFromSnapshotAsync() throws Exception {
+    CreateTableFromSnapshotRequest request = CreateTableFromSnapshotRequest.newBuilder()
+        .setTableId(TABLE_ID)
+        .setSourceSnapshot("test-snapshot")
+        .build();
+    Operation response = Operation.getDefaultInstance();
+    when(mockAdminClient.createTableFromSnapshotAsync(request))
+        .thenReturn(Futures.immediateFuture(response));
+    ListenableFuture<Operation> actualResponse = clientWrapper.createTableFromSnapshotAsync(request);
+    assertEquals(response, actualResponse.get());
+    verify(mockAdminClient).createTableFromSnapshotAsync(request);
+  }
+
   private static com.google.bigtable.admin.v2.Table createTableData(){
     GCRules.GCRule gcRule = GCRULES.maxVersions(1);
     ColumnFamily columnFamily = ColumnFamily.newBuilder()