From 10ae878a7470e468cf2929f8c796071fed185dd0 Mon Sep 17 00:00:00 2001 From: Igor Bernstein Date: Tue, 7 Aug 2018 18:44:17 -0400 Subject: [PATCH] Bigtable: Decouple TableAdminClient from BigtableTableAdminSettings. (#3512) This is in preparation for renaming the auto generated GAPIC clients & settings to be prefixed with 'Base'. This will make it easier to understand the layout of the code: the GAPIC generated client/settings will be called BaseBigtableTableAdmin{Client,Settings}, while the handwritten overlay will be called BigtableTableAdmin{Client,Settings}. --- .../bigtable/admin/v2/TableAdminClient.java | 88 +++++-------- .../bigtable/admin/v2/TableAdminSettings.java | 119 ++++++++++++++++++ .../admin/v2/TableAdminSettingsTest.java | 69 ++++++++++ 3 files changed, 216 insertions(+), 60 deletions(-) create mode 100644 google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/TableAdminSettings.java create mode 100644 google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/TableAdminSettingsTest.java diff --git a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/TableAdminClient.java b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/TableAdminClient.java index 89f3ee6ccdb1..da24bd59fa79 100644 --- a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/TableAdminClient.java +++ b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/TableAdminClient.java @@ -21,7 +21,6 @@ import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; -import com.google.api.core.BetaApi; import com.google.bigtable.admin.v2.CheckConsistencyResponse; import com.google.bigtable.admin.v2.DeleteTableRequest; import com.google.bigtable.admin.v2.DropRowRangeRequest; @@ -40,11 +39,11 @@ import com.google.cloud.bigtable.admin.v2.models.TableAdminResponses.ConsistencyToken; import com.google.cloud.bigtable.admin.v2.models.TableAdminResponses.Table; import com.google.cloud.bigtable.admin.v2.stub.BigtableTableAdminStub; -import com.google.cloud.bigtable.admin.v2.stub.BigtableTableAdminStubSettings; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.protobuf.ByteString; import com.google.protobuf.Empty; +import javax.annotation.Nonnull; /** * Client for creating, configuring, and deleting Cloud Bigtable tables @@ -64,95 +63,64 @@ * .addSplit(ByteString.copyFromUtf8("b")) * .addSplit(ByteString.copyFromUtf8("q")); * client.createTable(createTableReq); - * } - * } + * } + * } * - *

Note: close() needs to be called on the bigtableTableAdminClient object to clean up resources - * such as threads. In the example above, try-with-resources is used, which automatically calls - * close(). + *

Note: close() needs to be called on the client object to clean up resources such as threads. + * In the example above, try-with-resources is used, which automatically calls close(). * - *

This class can be customized by passing in a custom instance of BigtableTableAdminSettings to + *

This class can be customized by passing in a custom instance of TableAdminSettings to * create(). For example: * *

To customize credentials: * *

{@code
- * BigtableTableAdminSettings bigtableTableAdminSettings =
- *   BigtableTableAdminSettings.newBuilder()
+ * TableAdminSettings tableAdminSettings = TableAdminSettings.newBuilder()
+ *   .setInstanceName(InstanceName.of("[PROJECT]", "[INSTANCE]"))
  *   .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials))
  *   .build();
+ *
  * TableAdminClient client =
- *   TableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"), bigtableTableAdminSettings);
+ *   TableAdminClient.create(tableAdminSettings);
  * }
* * To customize the endpoint: * *
{@code
- * BigtableTableAdminSettings bigtableTableAdminSettings =
- *     BigtableTableAdminSettings.newBuilder().setEndpoint(myEndpoint).build();
- * TableAdminClient client =
- *   TableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"), bigtableTableAdminSettings);
+ * TableAdminSettings tableAdminSettings = TableAdminSettings.newBuilder()
+ *   .setInstanceName(InstanceName.of("[PROJECT]", "[INSTANCE]"))
+ *   .setEndpoint(myEndpoint).build();
+ *
+ * TableAdminClient client = TableAdminClient.create(tableAdminSettings);
  * }
*/ -@BetaApi public class TableAdminClient implements AutoCloseable { private final BigtableTableAdminStub stub; private final InstanceName instanceName; - /** - * Constructs an instance of TableAdminClient with the given instanceName - * - * @param instanceName - * @throws IOException - */ - public static TableAdminClient create(InstanceName instanceName) throws IOException { - return new TableAdminClient(instanceName, BigtableTableAdminSettings.newBuilder().build()); + /** Constructs an instance of TableAdminClient with the given instanceName. */ + public static TableAdminClient create(@Nonnull InstanceName instanceName) throws IOException { + return create(TableAdminSettings.newBuilder().setInstanceName(instanceName).build()); } - /** - * Constructs an instance of TableAdminClient with the given instanceName and - * bigtableTableAdminSettings - * - * @param instanceName - * @param adminSettings - * @throws IOException - */ - public static TableAdminClient create( - InstanceName instanceName, BigtableTableAdminSettings adminSettings) throws IOException { - return new TableAdminClient(instanceName, adminSettings); + /** Constructs an instance of TableAdminClient with the given settings. */ + public static TableAdminClient create(@Nonnull TableAdminSettings settings) throws IOException { + return create(settings.getInstanceName(), settings.getStubSettings().createStub()); } - /** - * Constructs an instance of TableAdminClient with the given instanceName and - * bigtableTableAdminStub - * - * @param instanceName - * @param stub - * @throws IOException - */ - public static TableAdminClient create(InstanceName instanceName, BigtableTableAdminStub stub) - throws IOException { + /** Constructs an instance of TableAdminClient with the given instanceName and stub. */ + public static TableAdminClient create(@Nonnull InstanceName instanceName, @Nonnull BigtableTableAdminStub stub) { return new TableAdminClient(instanceName, stub); } - private TableAdminClient(InstanceName instanceName, BigtableTableAdminSettings adminSettings) - throws IOException { - this( - instanceName, - ((BigtableTableAdminStubSettings) adminSettings.getStubSettings()).createStub()); - } - - private TableAdminClient(InstanceName instanceName, BigtableTableAdminStub stub) - throws IOException { + private TableAdminClient(@Nonnull InstanceName instanceName, @Nonnull BigtableTableAdminStub stub) { Preconditions.checkNotNull(instanceName); Preconditions.checkNotNull(stub); this.instanceName = instanceName; this.stub = stub; } - /** - * Gets the instanceName this client is associated to - */ + /** Gets the instanceName this client is associated with. */ public InstanceName getInstanceName() { return instanceName; } @@ -188,9 +156,9 @@ public Table createTable(CreateTable createTable) { /** * Creates a new table with the specified configuration asynchronously - * + * *

Sample code: - * + * *

{@code
    *  try(TableAdminClient client =  TableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
    *    CreateTable createTableReq =
@@ -343,7 +311,7 @@ public Table getTable(String tableId) {
    * Gets the Table by tableId
    *
    * 

Sample code: - * + * *

{@code
    * try(TableAdminClient client =  TableAdminClient.create(InstanceName.of("[PROJECT]", "[INSTANCE]"))) {
    *   client.getTableAsync("tableId");
diff --git a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/TableAdminSettings.java b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/TableAdminSettings.java
new file mode 100644
index 000000000000..4eea4bff59f4
--- /dev/null
+++ b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/TableAdminSettings.java
@@ -0,0 +1,119 @@
+/*
+ * 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;
+
+import com.google.bigtable.admin.v2.InstanceName;
+import com.google.cloud.bigtable.admin.v2.stub.BigtableTableAdminStubSettings;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Verify;
+import java.io.IOException;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+/**
+ * Settings class to configure an instance of {@link TableAdminClient}.
+ *
+ * 

It must be configured with an {@link InstanceName} and be used to change default RPC settings. + * + *

Example usage: + * + *

{@code
+ * TableAdminSettings.Builder tableAdminSettingsBuilder = TableAdminSettings.newBuilder()
+ *   .setInstanceName(InstanceName.of("my-project", "my-instance");
+ *
+ * tableAdminSettingsBuilder.stubSettings().createTableSettings()
+ *   .setRetrySettings(
+ *     RetrySettings.newBuilder()
+ *       .setTotalTimeout(Duration.ofMinutes(15))
+ *       .build());
+ *
+ * BigtableTableAdminSettings tableAdminSettings = tableAdminSettingsBuilder.build();
+ * }
+ */ +public final class TableAdminSettings { + private final InstanceName instanceName; + private final BigtableTableAdminStubSettings stubSettings; + + private TableAdminSettings(Builder builder) throws IOException { + this.instanceName = Preconditions.checkNotNull(builder.instanceName, "InstanceName must be set"); + this.stubSettings = Verify.verifyNotNull(builder.stubSettings, "stubSettings should never be null").build(); + } + + /** Gets the name of instance whose tables the client will manage. */ + @Nonnull + public InstanceName getInstanceName() { + return instanceName; + } + + /** Gets the underlying RPC settings. */ + public BigtableTableAdminStubSettings getStubSettings() { + return stubSettings; + } + + /** Returns a builder containing all the values of this settings class. */ + public Builder toBuilder() { + return new Builder(this); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder() { + return new Builder(); + } + + /** Builder for TableAdminSettings. */ + public static final class Builder { + @Nullable + private InstanceName instanceName; + private final BigtableTableAdminStubSettings.Builder stubSettings; + + private Builder() { + stubSettings = BigtableTableAdminStubSettings.newBuilder(); + } + + private Builder(TableAdminSettings settings) { + this.instanceName = settings.instanceName; + this.stubSettings = settings.stubSettings.toBuilder(); + } + + /** Sets the name of instance whose tables the client will manage. */ + public Builder setInstanceName(@Nonnull InstanceName instanceName) { + Preconditions.checkNotNull(instanceName); + this.instanceName = instanceName; + return this; + } + + /** Gets the name of instance whose tables the client will manage. */ + @Nullable + public InstanceName getInstanceName() { + return instanceName; + } + + /** + * Returns the builder for the settings used for all RPCs. + * + *

This is meant for advanced usage. The default RPC settings are set to their recommended + * values. + */ + public BigtableTableAdminStubSettings.Builder stubSettings() { + return stubSettings; + } + + /** Builds an instance of the settings. */ + public TableAdminSettings build() throws IOException { + return new TableAdminSettings(this); + } + } +} diff --git a/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/TableAdminSettingsTest.java b/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/TableAdminSettingsTest.java new file mode 100644 index 000000000000..8bf706cf8228 --- /dev/null +++ b/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/TableAdminSettingsTest.java @@ -0,0 +1,69 @@ +/* + * 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; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.api.gax.rpc.StatusCode.Code; +import com.google.bigtable.admin.v2.InstanceName; +import java.io.IOException; +import org.junit.Test; + +public class TableAdminSettingsTest { + + @Test + public void testInstanceName() throws IOException { + InstanceName instanceName = InstanceName.of("my-project", "my-instance"); + + TableAdminSettings.Builder builder = TableAdminSettings.newBuilder() + .setInstanceName(instanceName); + + assertThat(builder.getInstanceName()).isEqualTo(instanceName); + assertThat(builder.build().getInstanceName()).isEqualTo(instanceName); + assertThat(builder.build().toBuilder().getInstanceName()).isEqualTo(instanceName); + } + + @Test + public void testMissingInstanceName() { + Exception actualException = null; + + try { + TableAdminSettings.newBuilder().build(); + } catch (Exception e) { + actualException = e; + } + + assertThat(actualException).isInstanceOf(NullPointerException.class); + } + + @Test + public void testStubSettings() throws IOException { + InstanceName instanceName = InstanceName.of("my-project", "my-instance"); + + TableAdminSettings.Builder builder = TableAdminSettings.newBuilder() + .setInstanceName(instanceName); + + builder.stubSettings().createTableSettings() + .setRetryableCodes(Code.INVALID_ARGUMENT); + + assertThat(builder.build().getStubSettings().createTableSettings().getRetryableCodes()) + .containsExactly(Code.INVALID_ARGUMENT); + + assertThat(builder.build().toBuilder().build().getStubSettings().createTableSettings() + .getRetryableCodes()) + .containsExactly(Code.INVALID_ARGUMENT); + } +}