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 3f85e45658b2..8146ee97fd8c 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 @@ -20,6 +20,7 @@ import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.gax.rpc.ApiExceptions; +import com.google.api.gax.rpc.NotFoundException; import com.google.api.resourcenames.ResourceName; import com.google.bigtable.admin.v2.AppProfileName; import com.google.bigtable.admin.v2.ClusterName; @@ -417,6 +418,68 @@ public Void apply(Empty input) { ); } + /** + * Checks if the instance specified by the instanceId exists + * + *

Sample code: + * + *

{@code
+   * if(client.exists("my-instance")) {
+   *   System.out.println("Instance exists");
+   * }
+   * }
+ */ + public boolean exists(String instanceId) { + return ApiExceptions.callAndTranslateApiException(existsAsync(instanceId)); + } + + /** + * Asynchronously checks if the instance specified by the instanceId exists + * + *

Sample code: + * + *

{@code
+   * ApiFuture found = client.existsAsync("my-instance");
+   *
+   * ApiFutures.addCallback(
+   *  found,
+   *  new ApiFutureCallback() {
+   *    public void onSuccess(Boolean found) {
+   *      if (found) {
+   *        System.out.println("Instance exists");
+   *      } else {
+   *        System.out.println("Instance not found");
+   *      }
+   *    }
+   *
+   *    public void onFailure(Throwable t) {
+   *      t.printStackTrace();
+   *    }
+   *  },
+   *  MoreExecutors.directExecutor()
+   * );
+   * }
+ */ + public ApiFuture existsAsync(String instanceId) { + ApiFuture protoFuture = getInstanceAsync(instanceId); + + ApiFuture existsFuture = ApiFutures + .transform(protoFuture, new ApiFunction() { + @Override + public Boolean apply(Instance ignored) { + return true; + } + }, MoreExecutors.directExecutor()); + + return ApiFutures.catching(existsFuture, NotFoundException.class, + new ApiFunction() { + @Override + public Boolean apply(NotFoundException ignored) { + return false; + } + }, MoreExecutors.directExecutor()); + } + /** * Creates a new cluster in the specified instance. * diff --git a/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/BigtableInstanceAdminClientTest.java b/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/BigtableInstanceAdminClientTest.java index dadaa71d355c..65f1eed2efd4 100644 --- a/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/BigtableInstanceAdminClientTest.java +++ b/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/BigtableInstanceAdminClientTest.java @@ -23,12 +23,14 @@ import com.google.api.gax.longrunning.OperationFuture; import com.google.api.gax.longrunning.OperationFutures; import com.google.api.gax.longrunning.OperationSnapshot; +import com.google.api.gax.rpc.NotFoundException; import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.UnaryCallable; import com.google.api.gax.rpc.testing.FakeOperationSnapshot; import com.google.bigtable.admin.v2.AppProfileName; import com.google.bigtable.admin.v2.ClusterName; import com.google.bigtable.admin.v2.CreateInstanceMetadata; +import com.google.bigtable.admin.v2.GetInstanceRequest; import com.google.bigtable.admin.v2.InstanceName; import com.google.bigtable.admin.v2.LocationName; import com.google.bigtable.admin.v2.ProjectName; @@ -57,12 +59,14 @@ import com.google.protobuf.ByteString; import com.google.protobuf.Empty; import com.google.protobuf.FieldMask; +import io.grpc.Status; import io.grpc.Status.Code; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; @@ -842,4 +846,36 @@ public void testTestIamPermissions() { // Verify assertThat(actualResult).containsExactly("bigtable.tables.readRows"); } + + @Test + public void testExistsTrue() { + // Setup + com.google.bigtable.admin.v2.Instance expectedResponse = com.google.bigtable.admin.v2.Instance + .newBuilder().setName(INSTANCE_NAME.toString()).build(); + + Mockito.when(mockGetInstanceCallable.futureCall(Matchers.any(GetInstanceRequest.class))) + .thenReturn(ApiFutures.immediateFuture(expectedResponse)); + + // Execute + boolean found = adminClient.exists(INSTANCE_NAME.getInstance()); + + // Verify + assertThat(found).isTrue(); + } + + @Test + public void testExistsFalse() { + // Setup + NotFoundException exception = + new NotFoundException("fake-error", null, GrpcStatusCode.of(Status.Code.NOT_FOUND), false); + + Mockito.when(mockGetInstanceCallable.futureCall(Matchers.any(GetInstanceRequest.class))) + .thenReturn(ApiFutures.immediateFailedFuture(exception)); + + // Execute + boolean found = adminClient.exists(INSTANCE_NAME.getInstance()); + + // Verify + assertThat(found).isFalse(); + } }