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 d0d690ad9fe2..9246533ed6ca 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 @@ -18,15 +18,23 @@ import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; +import com.google.bigtable.admin.v2.ClusterName; +import com.google.bigtable.admin.v2.DeleteClusterRequest; import com.google.bigtable.admin.v2.DeleteInstanceRequest; +import com.google.bigtable.admin.v2.GetClusterRequest; import com.google.bigtable.admin.v2.GetInstanceRequest; import com.google.bigtable.admin.v2.InstanceName; +import com.google.bigtable.admin.v2.ListClustersRequest; +import com.google.bigtable.admin.v2.ListClustersResponse; import com.google.bigtable.admin.v2.ListInstancesRequest; import com.google.bigtable.admin.v2.ListInstancesResponse; import com.google.bigtable.admin.v2.LocationName; import com.google.bigtable.admin.v2.ProjectName; +import com.google.cloud.bigtable.admin.v2.models.Cluster; +import com.google.cloud.bigtable.admin.v2.models.CreateClusterRequest; import com.google.cloud.bigtable.admin.v2.models.CreateInstanceRequest; import com.google.cloud.bigtable.admin.v2.models.Instance; +import com.google.cloud.bigtable.admin.v2.models.PartialListClustersException; import com.google.cloud.bigtable.admin.v2.models.PartialListInstancesException; import com.google.cloud.bigtable.admin.v2.models.UpdateInstanceRequest; import com.google.cloud.bigtable.admin.v2.stub.BigtableInstanceAdminStub; @@ -397,6 +405,282 @@ public Void apply(Empty input) { ); } + /** + * Creates a new cluster in the specified instance. + * + *
Sample code: + * + *
{@code + * Cluster cluster = client.createCluster( + * CreateClusterRequest.of("my-instance", "my-new-cluster") + * .setZone("us-east1-c") + * .setServeNodes(3) + * .setStorageType(StorageType.SSD) + * ); + * }+ */ + @SuppressWarnings("WeakerAccess") + public Cluster createCluster(CreateClusterRequest request) { + return awaitFuture(createClusterAsync(request)); + } + + /** + * Asynchronously creates a new cluster in the specified instance. + * + *
Sample code: + * + *
{@code + * ApiFuture+ */ + @SuppressWarnings("WeakerAccess") + public ApiFutureclusterFuture = client.createClusterAsync( + * CreateClusterRequest.of("my-instance", "my-new-cluster") + * .setZone("us-east1-c") + * .setServeNodes(3) + * .setStorageType(StorageType.SSD) + * ); + * + * Cluster cluster = clusterFuture.get(); + * }
Sample code: + * + *
{@code + * Cluster cluster = client.getCluster("my-instance", "my-cluster"); + * }+ */ + @SuppressWarnings("WeakerAccess") + public Cluster getCluster(String instanceId, String clusterId) { + return awaitFuture(getClusterAsync(instanceId, clusterId)); + } + + /** + * Asynchronously gets the cluster representation by ID. + * + *
Sample code: + * + *
{@code + * ApiFuture+ */ + @SuppressWarnings("WeakerAccess") + public ApiFutureclusterFuture = client.getClusterAsync("my-instance", "my-cluster"); + * Cluster cluster = clusterFuture.get(); + * }
This method will throw a {@link PartialListClustersException} when any zone is + * unavailable. If partial listing are ok, the exception can be caught and inspected. + * + *
Sample code: + * + *
{@code + * try { + * List+ */ + @SuppressWarnings("WeakerAccess") + public Listclusters = cluster.listClusters("my-instance"); + * } catch (PartialListClustersException e) { + * System.out.println("The following zones are unavailable: " + e.getUnavailableZones()); + * System.out.println("But the following clusters are reachable: " + e.getClusters()) + * } + * }
This method will throw a {@link PartialListClustersException} when any zone is + * unavailable. If partial listing are ok, the exception can be caught and inspected. + * + *
Sample code: + * + *
{@code + * ApiFuture+ */ + @SuppressWarnings("WeakerAccess") + public ApiFutureclustersFuture = client.listClustersAsync("my-instance"); + * + * ApiFutures.addCallback(clustersFuture, new ApiFutureCallback >() { + * public void onFailure(Throwable t) { + * if (t instanceof PartialListClustersException) { + * PartialListClustersException partialError = (PartialListClustersException)t; + * System.out.println("The following zones are unavailable: " + partialError.getUnavailableZones()); + * System.out.println("But the following clusters are reachable: " + partialError.getClusters()); + * } else { + * t.printStackTrace(); + * } + * } + * + * public void onSuccess(List
result) { + * System.out.println("Found a complete set of instances: " + result); + * } + * }, MoreExecutors.directExecutor()); + * }
Sample code: + * + *
{@code + * Cluster cluster = cluster.resizeCluster("my-instance", "my-cluster", 30); + * }+ */ + @SuppressWarnings("WeakerAccess") + public Cluster resizeCluster(String instanceId, String clusterId, int numServeNodes) { + return awaitFuture(resizeClusterAsync(instanceId, clusterId, numServeNodes)); + } + + /** + * Asynchronously resizes the cluster's node count. Please note that only clusters that belong to + * a PRODUCTION instance can be resized. + * + *
{@code + * ApiFuture+ */ + @SuppressWarnings("WeakerAccess") + public ApiFutureclusterFuture = cluster.resizeCluster("my-instance", "my-cluster", 30); + * Cluster cluster = clusterFuture.get(); + * }
Sample code: + * + *
{@code + * client.deleteCluster("my-instance", "my-cluster"); + * }+ */ + @SuppressWarnings("WeakerAccess") + public void deleteCluster(String instanceId, String clusterId) { + awaitFuture(deleteClusterAsync(instanceId, clusterId)); + } + + /** + * Asynchronously deletes the specified cluster. Please note that an instance must have at least 1 + * cluster. To remove the last cluster, please use {@link BigtableInstanceAdminClient#deleteInstanceAsync(String)}. + * + *
Sample code: + * + *
{@code + * ApiFuture+ */ + @SuppressWarnings("WeakerAccess") + public ApiFuturefuture = client.deleteClusterAsync("my-instance", "my-cluster"); + * future.get(); + * }
This method is considered an internal implementation detail and not meant to be used by + * applications. + */ + @InternalApi + public static Cluster fromProto(com.google.bigtable.admin.v2.Cluster proto) { + return new Cluster(proto); + } + + private Cluster(@Nonnull com.google.bigtable.admin.v2.Cluster proto) { + Preconditions.checkNotNull(proto); + Preconditions.checkArgument(!proto.getName().isEmpty(), "Name must be set"); + this.proto = proto; + } + + + /** Gets the cluster's id. */ + @SuppressWarnings("WeakerAccess") + public String getId() { + // Constructor ensures that name is not null + ClusterName fullName = Verify.verifyNotNull( + ClusterName.parse(proto.getName()), + "Name can never be null"); + //noinspection ConstantConditions + return fullName.getCluster(); + } + + /** Gets the instance id. */ + @SuppressWarnings("WeakerAccess") + public String getInstanceId() { + // Constructor ensures that name is not null + ClusterName fullName = Verify.verifyNotNull( + ClusterName.parse(proto.getName()), + "Name can never be null"); + //noinspection ConstantConditions + return fullName.getInstance(); + + } + + + /** Get the zone where this cluster is located. */ + @SuppressWarnings("WeakerAccess") + public String getZone() { + LocationName location = Verify.verifyNotNull(LocationName.parse(proto.getLocation())); + //noinspection ConstantConditions + return location.getLocation(); + } + + /** Gets the current state of the cluster */ + // TODO(igorbernstein2): try to avoid exposing proto enums + @SuppressWarnings("WeakerAccess") + public State getState() { + return proto.getState(); + } + + /** + * Get the number of nodes allocated to this cluster. More nodes enable higher throughput and more + * consistent performance. + */ + @SuppressWarnings("WeakerAccess") + public int getServeNodes() { + return proto.getServeNodes(); + } + + /** + * The type of storage used by this cluster to serve its parent instance's tables, unless + * explicitly overridden. + */ + // TODO(igorbernstein2): try to avoid exposing proto enums + @SuppressWarnings("WeakerAccess") + public StorageType getStorageType() { + return proto.getDefaultStorageType(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Cluster cluster = (Cluster) o; + return Objects.equal(proto, cluster.proto); + } + + @Override + public int hashCode() { + return Objects.hashCode(proto); + } +} diff --git a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/CreateClusterRequest.java b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/CreateClusterRequest.java index d653be2ac99b..aefccd3f692b 100644 --- a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/CreateClusterRequest.java +++ b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/CreateClusterRequest.java @@ -112,6 +112,9 @@ public com.google.bigtable.admin.v2.CreateClusterRequest toProto(ProjectName pro /** * Gets the clusterId. This method is meant to be used by {@link CreateClusterRequest} and is * considered an internal implementation detail and not meant to be used by applications. + * + *
This method is considered an internal implementation detail and not meant to be used by + * applications. */ @InternalApi String getClusterId() { @@ -121,6 +124,9 @@ String getClusterId() { /** * Creates the request protobuf to be used in {@link CreateInstanceRequest}. This method is * considered an internal implementation detail and not meant to be used by applications. + * + *
This method is considered an internal implementation detail and not meant to be used by
+ * applications.
*/
@InternalApi
com.google.bigtable.admin.v2.Cluster toEmbeddedProto(ProjectName projectName) {
diff --git a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/PartialListClustersException.java b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/PartialListClustersException.java
new file mode 100644
index 000000000000..1696877ca443
--- /dev/null
+++ b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/PartialListClustersException.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.cloud.bigtable.admin.v2.models;
+
+import com.google.api.core.InternalApi;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+
+/**
+ * Exception thrown when some zones are unavailable and listClusters is unable to return a full
+ * cluster list. This exception can be inspected to get a partial list.
+ */
+public class PartialListClustersException extends RuntimeException {
+ private final List This method is considered an internal implementation detail and not meant to be used by
+ * applications.
+ */
+ @InternalApi
+ public PartialListClustersException(List