diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClient.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClient.java index f44f70b63..6eb712e6a 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClient.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClient.java @@ -50,6 +50,7 @@ import com.google.cloud.bigtable.admin.v2.models.RestoredTableResult; import com.google.cloud.bigtable.admin.v2.models.Table; import com.google.cloud.bigtable.admin.v2.models.UpdateBackupRequest; +import com.google.cloud.bigtable.admin.v2.models.UpdateTableRequest; import com.google.cloud.bigtable.admin.v2.stub.EnhancedBigtableTableAdminStub; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -258,6 +259,72 @@ public ApiFuture createTableAsync(CreateTableRequest request) { this.stub.createTableCallable().futureCall(request.toProto(projectId, instanceId))); } + /** + * Update a table with the specified configuration. + * + *

Sample code: + * + *

{@code
+   * // Alter change stream retention period.
+   * Table table = client.updateTable(
+   *   UpdateTableRequest.of("my-table")
+   *     .addChangeStreamRetention(Duration.ofHours(24))
+   * );
+   *
+   * // Disable change stream
+   * Table table = client.updateTable(
+   *   UpdateTableRequest.of("my-table")
+   *     .disableChangeStream()
+   * );
+   * }
+ * + * @see UpdateTableRequest for available options. + */ + public Table updateTable(UpdateTableRequest request) { + return ApiExceptions.callAndTranslateApiException(updateTableAsync(request)); + } + + /** + * Asynchronously update a table with the specified configuration. + * + *

Sample code: + * + *

{@code
+   * // Update table to 1 day change stream retention.
+   * ApiFuture
tableFuture = client.createTableAsync( + * UpdateTableRequest.of("my-table") + * .addChangeStreamRetention(Duration.ofHours(24)) + * ); + * + * ApiFutures.addCallback( + * tableFuture, + * new ApiFutureCallback
() { + * public void onSuccess(Table table) { + * System.out.println("Updated table: " + table.getTableName()); + * } + * + * public void onFailure(Throwable t) { + * t.printStackTrace(); + * } + * }, + * MoreExecutors.directExecutor() + * ); + * } + * + * @see UpdateTableRequest for available options. + */ + public ApiFuture
updateTableAsync(UpdateTableRequest request) { + return ApiFutures.transform( + stub.updateTableOperationCallable().futureCall(request.toProto(projectId, instanceId)), + new ApiFunction() { + @Override + public Table apply(com.google.bigtable.admin.v2.Table tableProto) { + return Table.fromProto(tableProto); + } + }, + MoreExecutors.directExecutor()); + } + /** * Creates, updates and drops column families as specified in the request. * diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/CreateTableRequest.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/CreateTableRequest.java index 03022b876..6b315c3f5 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/CreateTableRequest.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/CreateTableRequest.java @@ -16,6 +16,7 @@ package com.google.cloud.bigtable.admin.v2.models; import com.google.api.core.InternalApi; +import com.google.bigtable.admin.v2.ChangeStreamConfig; import com.google.bigtable.admin.v2.ColumnFamily; import com.google.cloud.bigtable.admin.v2.internal.NameUtil; import com.google.cloud.bigtable.admin.v2.models.GCRules.GCRule; @@ -23,6 +24,7 @@ import com.google.common.base.Preconditions; import com.google.protobuf.ByteString; import javax.annotation.Nonnull; +import org.threeten.bp.Duration; /** * Fluent wrapper for {@link com.google.bigtable.admin.v2.CreateTableRequest} @@ -76,6 +78,22 @@ public CreateTableRequest addSplit(ByteString key) { return this; } + /** Add change stream retention period between 1 day and 7 days */ + public CreateTableRequest addChangeStreamRetention(Duration retention) { + Preconditions.checkNotNull(retention); + requestBuilder + .getTableBuilder() + .setChangeStreamConfig( + ChangeStreamConfig.newBuilder() + .setRetentionPeriod( + com.google.protobuf.Duration.newBuilder() + .setSeconds(retention.getSeconds()) + .setNanos(retention.getNano()) + .build()) + .build()); + return this; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/Table.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/Table.java index bb852b25a..31aa612f1 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/Table.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/Table.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.Map.Entry; import javax.annotation.Nonnull; +import org.threeten.bp.Duration; /** Wrapper for {@link Table} protocol buffer object */ public final class Table { @@ -103,6 +104,8 @@ public com.google.bigtable.admin.v2.Table.ClusterState.ReplicationState toProto( private final Map replicationStatesByClusterId; private final List columnFamilies; + private final Duration changeStreamRetention; + @InternalApi public static Table fromProto(@Nonnull com.google.bigtable.admin.v2.Table proto) { ImmutableMap.Builder replicationStates = ImmutableMap.builder(); @@ -120,18 +123,31 @@ public static Table fromProto(@Nonnull com.google.bigtable.admin.v2.Table proto) columnFamilies.add(ColumnFamily.fromProto(entry.getKey(), entry.getValue())); } + Duration changeStreamConfig = null; + if (proto.hasChangeStreamConfig()) { + changeStreamConfig = + Duration.ofSeconds( + proto.getChangeStreamConfig().getRetentionPeriod().getSeconds(), + proto.getChangeStreamConfig().getRetentionPeriod().getNanos()); + } + return new Table( - TableName.parse(proto.getName()), replicationStates.build(), columnFamilies.build()); + TableName.parse(proto.getName()), + replicationStates.build(), + columnFamilies.build(), + changeStreamConfig); } private Table( TableName tableName, Map replicationStatesByClusterId, - List columnFamilies) { + List columnFamilies, + Duration changeStreamRetention) { this.instanceId = tableName.getInstance(); this.id = tableName.getTable(); this.replicationStatesByClusterId = replicationStatesByClusterId; this.columnFamilies = columnFamilies; + this.changeStreamRetention = changeStreamRetention; } /** Gets the table's id. */ @@ -152,6 +168,10 @@ public List getColumnFamilies() { return columnFamilies; } + public Duration getChangeStreamRetention() { + return changeStreamRetention; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -164,11 +184,13 @@ public boolean equals(Object o) { return Objects.equal(id, table.id) && Objects.equal(instanceId, table.instanceId) && Objects.equal(replicationStatesByClusterId, table.replicationStatesByClusterId) - && Objects.equal(columnFamilies, table.columnFamilies); + && Objects.equal(columnFamilies, table.columnFamilies) + && Objects.equal(changeStreamRetention, table.changeStreamRetention); } @Override public int hashCode() { - return Objects.hashCode(id, instanceId, replicationStatesByClusterId, columnFamilies); + return Objects.hashCode( + id, instanceId, replicationStatesByClusterId, columnFamilies, changeStreamRetention); } } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/UpdateTableRequest.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/UpdateTableRequest.java new file mode 100644 index 000000000..034736aa5 --- /dev/null +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/UpdateTableRequest.java @@ -0,0 +1,98 @@ +/* + * Copyright 2023 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.bigtable.admin.v2.ChangeStreamConfig; +import com.google.cloud.bigtable.admin.v2.internal.NameUtil; +import com.google.common.base.Preconditions; +import java.util.Objects; +import org.threeten.bp.Duration; + +/** + * Wrapper for {@link com.google.bigtable.admin.v2.UpdateTableRequest} + * + *

Allows for updating table: + * + *

    + *
  • Change stream retention period. + *
+ */ +public class UpdateTableRequest { + + private final String tableId; + + private final com.google.bigtable.admin.v2.UpdateTableRequest.Builder requestBuilder = + com.google.bigtable.admin.v2.UpdateTableRequest.newBuilder(); + + public static UpdateTableRequest of(String tableId) { + return new UpdateTableRequest(tableId); + } + + private UpdateTableRequest(String tableId) { + this.tableId = tableId; + } + + /** Update change stream retention period between 1 day and 7 days. */ + public UpdateTableRequest addChangeStreamRetention(Duration retention) { + Preconditions.checkNotNull(retention); + if (!retention.isZero()) { + requestBuilder + .getTableBuilder() + .setChangeStreamConfig( + ChangeStreamConfig.newBuilder() + .setRetentionPeriod( + com.google.protobuf.Duration.newBuilder() + .setSeconds(retention.getSeconds()) + .setNanos(retention.getNano()) + .build()) + .build()); + requestBuilder.getUpdateMaskBuilder().addPaths("change_stream_config.retention_period"); + } else { + requestBuilder.getTableBuilder().clearChangeStreamConfig(); + requestBuilder.getUpdateMaskBuilder().addPaths("change_stream_config"); + } + return this; + } + + /** Disable change stream for table */ + public UpdateTableRequest disableChangeStreamRetention() { + return addChangeStreamRetention(Duration.ZERO); + } + + @InternalApi + public com.google.bigtable.admin.v2.UpdateTableRequest toProto( + String projectId, String instanceId) { + requestBuilder + .getTableBuilder() + .setName(NameUtil.formatTableName(projectId, instanceId, tableId)); + return requestBuilder.build(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof UpdateTableRequest)) return false; + UpdateTableRequest that = (UpdateTableRequest) o; + return Objects.equals(requestBuilder, that.requestBuilder); + } + + @Override + public int hashCode() { + return Objects.hash(requestBuilder); + } +} diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClientTests.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClientTests.java index a5ada34be..17a2aa4a5 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClientTests.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClientTests.java @@ -29,6 +29,7 @@ import com.google.api.gax.rpc.testing.FakeOperationSnapshot; import com.google.bigtable.admin.v2.Backup.State; import com.google.bigtable.admin.v2.BackupInfo; +import com.google.bigtable.admin.v2.ChangeStreamConfig; import com.google.bigtable.admin.v2.ColumnFamily; import com.google.bigtable.admin.v2.CreateBackupMetadata; import com.google.bigtable.admin.v2.DeleteBackupRequest; @@ -45,6 +46,7 @@ import com.google.bigtable.admin.v2.Table.ClusterState; import com.google.bigtable.admin.v2.Table.View; import com.google.bigtable.admin.v2.TableName; +import com.google.bigtable.admin.v2.UpdateTableMetadata; import com.google.cloud.Identity; import com.google.cloud.Policy; import com.google.cloud.Role; @@ -68,6 +70,7 @@ import com.google.common.io.BaseEncoding; import com.google.longrunning.Operation; import com.google.protobuf.ByteString; +import com.google.protobuf.Duration; import com.google.protobuf.Empty; import com.google.protobuf.Timestamp; import com.google.protobuf.util.Timestamps; @@ -117,6 +120,13 @@ public class BigtableTableAdminClientTests { com.google.bigtable.admin.v2.CreateTableRequest, com.google.bigtable.admin.v2.Table> mockCreateTableCallable; + @Mock + private OperationCallable< + com.google.bigtable.admin.v2.UpdateTableRequest, + com.google.bigtable.admin.v2.Table, + UpdateTableMetadata> + mockUpdateTableOperationCallable; + @Mock private UnaryCallable< com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest, @@ -204,6 +214,40 @@ public void testCreateTable() { assertThat(result).isEqualTo(Table.fromProto(expectedResponse)); } + @Test + public void testUpdateTable() { + // Setup + Mockito.when(mockStub.updateTableOperationCallable()) + .thenReturn(mockUpdateTableOperationCallable); + + com.google.cloud.bigtable.admin.v2.models.UpdateTableRequest request = + com.google.cloud.bigtable.admin.v2.models.UpdateTableRequest.of(TABLE_ID) + .addChangeStreamRetention(org.threeten.bp.Duration.ofHours(24)); + + com.google.bigtable.admin.v2.Table expectedResponse = + com.google.bigtable.admin.v2.Table.newBuilder() + .setName(TABLE_NAME) + .setChangeStreamConfig( + ChangeStreamConfig.newBuilder() + .setRetentionPeriod(Duration.newBuilder().setSeconds(86400).build()) + .build()) + .build(); + + mockOperationResult( + mockUpdateTableOperationCallable, + request.toProto(PROJECT_ID, INSTANCE_ID), + expectedResponse, + UpdateTableMetadata.newBuilder().setName(TABLE_NAME).build()); + + // Execute + Table actualResult = adminClient.updateTable(request); + + // Verify + assertThat(actualResult.getId()).isEqualTo(TABLE_ID); + assertThat(actualResult.getChangeStreamRetention()) + .isEqualTo(org.threeten.bp.Duration.ofHours(24)); + } + @Test public void testModifyFamilies() { // Setup diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/it/BigtableTableAdminClientIT.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/it/BigtableTableAdminClientIT.java index 65035c118..a1b5c97e3 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/it/BigtableTableAdminClientIT.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/it/BigtableTableAdminClientIT.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import com.google.api.gax.rpc.NotFoundException; @@ -34,6 +35,7 @@ import com.google.cloud.bigtable.admin.v2.models.GCRules.VersionRule; import com.google.cloud.bigtable.admin.v2.models.ModifyColumnFamiliesRequest; import com.google.cloud.bigtable.admin.v2.models.Table; +import com.google.cloud.bigtable.admin.v2.models.UpdateTableRequest; import com.google.cloud.bigtable.test_helpers.env.EmulatorEnv; import com.google.cloud.bigtable.test_helpers.env.PrefixGenerator; import com.google.cloud.bigtable.test_helpers.env.TestEnvRule; @@ -85,7 +87,8 @@ public void createTable() { .addFamily("cf1") .addFamily("cf2", GCRULES.maxVersions(10)) .addSplit(ByteString.copyFromUtf8("b")) - .addSplit(ByteString.copyFromUtf8("q")); + .addSplit(ByteString.copyFromUtf8("q")) + .addChangeStreamRetention(Duration.ofDays(2)); Table tableResponse = tableAdmin.createTable(createTableReq); assertEquals(tableId, tableResponse.getId()); @@ -98,6 +101,39 @@ public void createTable() { assertFalse(columnFamilyById.get("cf1").hasGCRule()); assertTrue(columnFamilyById.get("cf2").hasGCRule()); assertEquals(10, ((VersionRule) columnFamilyById.get("cf2").getGCRule()).getMaxVersions()); + assertEquals(Duration.ofDays(2), tableResponse.getChangeStreamRetention()); + + // Disable change stream so the table can be deleted. + UpdateTableRequest updateTableRequest = + UpdateTableRequest.of(tableId).disableChangeStreamRetention(); + tableAdmin.updateTable(updateTableRequest); + } + + @Test + public void updateTable() { + assume() + .withMessage("Emulator doesn't return proper responses for CreateTable") + .that(testEnvRule.env()) + .isNotInstanceOf(EmulatorEnv.class); + + CreateTableRequest createTableReq = + CreateTableRequest.of(tableId) + .addFamily("cf1") + .addChangeStreamRetention(Duration.ofDays(2)); + Table tableResponse = tableAdmin.createTable(createTableReq); + assertEquals(tableId, tableResponse.getId()); + assertEquals(Duration.ofDays(2), tableResponse.getChangeStreamRetention()); + + UpdateTableRequest updateTableRequest = + UpdateTableRequest.of(tableId).addChangeStreamRetention(Duration.ofDays(4)); + tableResponse = tableAdmin.updateTable(updateTableRequest); + assertEquals(tableId, tableResponse.getId()); + assertEquals(Duration.ofDays(4), tableResponse.getChangeStreamRetention()); + + updateTableRequest = UpdateTableRequest.of(tableId).disableChangeStreamRetention(); + tableResponse = tableAdmin.updateTable(updateTableRequest); + assertEquals(tableId, tableResponse.getId()); + assertNull(tableResponse.getChangeStreamRetention()); } @Test diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/models/CreateTableRequestTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/models/CreateTableRequestTest.java index b12b3f24b..5379b700e 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/models/CreateTableRequestTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/models/CreateTableRequestTest.java @@ -18,6 +18,7 @@ import static com.google.cloud.bigtable.admin.v2.models.GCRules.GCRULES; import static com.google.common.truth.Truth.assertThat; +import com.google.bigtable.admin.v2.ChangeStreamConfig; import com.google.bigtable.admin.v2.ColumnFamily; import com.google.bigtable.admin.v2.GcRule; import com.google.bigtable.admin.v2.Table; @@ -46,7 +47,8 @@ public void testToProto() { .addFamily("family-id") .addFamily("another-family", GCRULES.maxAge(100, TimeUnit.HOURS)) .addSplit(splitKey) - .addSplit(secondSplitKey); + .addSplit(secondSplitKey) + .addChangeStreamRetention(Duration.ofHours(24)); com.google.bigtable.admin.v2.CreateTableRequest requestProto = com.google.bigtable.admin.v2.CreateTableRequest.newBuilder() @@ -63,6 +65,11 @@ public void testToProto() { com.google.protobuf.Duration.newBuilder() .setSeconds(100 * 60 * 60)) .build()) + .build()) + .setChangeStreamConfig( + ChangeStreamConfig.newBuilder() + .setRetentionPeriod( + com.google.protobuf.Duration.newBuilder().setSeconds(86400)) .build())) .setParent(NameUtil.formatInstanceName(PROJECT_ID, INSTANCE_ID)) .addInitialSplits( diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/models/UpdateTableRequestTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/models/UpdateTableRequestTest.java new file mode 100644 index 000000000..fabebdccb --- /dev/null +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/models/UpdateTableRequestTest.java @@ -0,0 +1,84 @@ +/* + * Copyright 2023 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 static com.google.common.truth.Truth.assertThat; + +import com.google.bigtable.admin.v2.ChangeStreamConfig; +import com.google.bigtable.admin.v2.Table; +import com.google.cloud.bigtable.admin.v2.internal.NameUtil; +import com.google.protobuf.FieldMask; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.threeten.bp.Duration; + +@RunWith(JUnit4.class) +public class UpdateTableRequestTest { + private static final String TABLE_ID = "my-table"; + private static final String PROJECT_ID = "my-project"; + private static final String INSTANCE_ID = "my-instance"; + + @Test + public void testEnableChangeStreamToProto() { + UpdateTableRequest request = + UpdateTableRequest.of(TABLE_ID).addChangeStreamRetention(Duration.ofHours(24)); + + com.google.bigtable.admin.v2.UpdateTableRequest requestProto = + com.google.bigtable.admin.v2.UpdateTableRequest.newBuilder() + .setTable( + Table.newBuilder() + .setName(NameUtil.formatTableName(PROJECT_ID, INSTANCE_ID, TABLE_ID)) + .setChangeStreamConfig( + ChangeStreamConfig.newBuilder() + .setRetentionPeriod( + com.google.protobuf.Duration.newBuilder().setSeconds(86400)) + .build())) + .setUpdateMask( + FieldMask.newBuilder().addPaths("change_stream_config.retention_period").build()) + .build(); + assertThat(request.toProto(PROJECT_ID, INSTANCE_ID)).isEqualTo(requestProto); + } + + @Test + public void testDisableChangeStreamToProto() { + UpdateTableRequest request = + UpdateTableRequest.of(TABLE_ID).addChangeStreamRetention(Duration.ofHours(0)); + + com.google.bigtable.admin.v2.UpdateTableRequest requestProto = + com.google.bigtable.admin.v2.UpdateTableRequest.newBuilder() + .setTable( + Table.newBuilder() + .setName(NameUtil.formatTableName(PROJECT_ID, INSTANCE_ID, TABLE_ID))) + .setUpdateMask(FieldMask.newBuilder().addPaths("change_stream_config").build()) + .build(); + assertThat(request.toProto(PROJECT_ID, INSTANCE_ID)).isEqualTo(requestProto); + } + + @Test + public void testNoChangeChangeStreamToProto() { + UpdateTableRequest request = UpdateTableRequest.of(TABLE_ID); + + com.google.bigtable.admin.v2.UpdateTableRequest requestProto = + com.google.bigtable.admin.v2.UpdateTableRequest.newBuilder() + .setTable( + Table.newBuilder() + .setName(NameUtil.formatTableName(PROJECT_ID, INSTANCE_ID, TABLE_ID))) + .build(); + assertThat(request.toProto(PROJECT_ID, INSTANCE_ID)).isEqualTo(requestProto); + } +}