Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Automated backups are supported in the admin client #2472

Merged
merged 19 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,14 @@ public CreateTableRequest addFamily(
return this;
}

/** Adds split at the specified key to the configuration */
/** Adds split at the specified key to the configuration. */
public CreateTableRequest addSplit(ByteString key) {
Preconditions.checkNotNull(key);
requestBuilder.addInitialSplitsBuilder().setKey(key);
return this;
}

/** Add change stream retention period between 1 day and 7 days */
/** Add change stream retention period between 1 day and 7 days. */
public CreateTableRequest addChangeStreamRetention(Duration retention) {
Preconditions.checkNotNull(retention);
requestBuilder
Expand All @@ -129,6 +129,26 @@ public CreateTableRequest setDeletionProtection(boolean deletionProtection) {
return this;
}

/** Set an automated backup policy for the table. */
public CreateTableRequest setAutomatedBackup(Duration retentionPeriod, Duration frequency) {
com.google.bigtable.admin.v2.Table.AutomatedBackupPolicy policy =
com.google.bigtable.admin.v2.Table.AutomatedBackupPolicy.newBuilder()
.setRetentionPeriod(
com.google.protobuf.Duration.newBuilder()
.setSeconds(retentionPeriod.getSeconds())
.setNanos(retentionPeriod.getNano())
.build())
.setFrequency(
com.google.protobuf.Duration.newBuilder()
.setSeconds(frequency.getSeconds())
.setNanos(frequency.getNano())
.build())
.build();

requestBuilder.getTableBuilder().setAutomatedBackupPolicy(policy);
return this;
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* 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;
Expand Down Expand Up @@ -58,7 +59,7 @@ public enum ReplicationState {

/**
* The table is fully created and ready for use after a restore, and is being optimized for
* performance. When optimizations are complete, the table will transition to `READY` state.
* performance. When optimizations are complete, the table will transition to`READY` state.
*/
READY_OPTIMIZING(
com.google.bigtable.admin.v2.Table.ClusterState.ReplicationState.READY_OPTIMIZING),
Expand Down Expand Up @@ -99,13 +100,47 @@ public com.google.bigtable.admin.v2.Table.ClusterState.ReplicationState toProto(
}
}

public static class AutomatedBackupPolicy {
private final com.google.bigtable.admin.v2.Table.AutomatedBackupPolicy proto;

/**
* Wraps the protobuf. This method is considered an internal implementation detail and not meant
* to be used by applications.
*/
@InternalApi
public static AutomatedBackupPolicy fromProto(
com.google.bigtable.admin.v2.Table.AutomatedBackupPolicy proto) {
return new AutomatedBackupPolicy(proto);
}

AutomatedBackupPolicy(@Nonnull com.google.bigtable.admin.v2.Table.AutomatedBackupPolicy proto) {
this.proto = proto;
}

/**
* Creates the request protobuf. This method is considered an internal implementation detail and
* not meant to be used by applications.
*/
@InternalApi
public com.google.bigtable.admin.v2.Table.AutomatedBackupPolicy toProto() {
return proto;
}

/** Returns policy config contents as a string. */
public String viewConfig() {
AutomatedBackupPolicy config = fromProto(proto);
return config.proto.getAllFields().toString();
}
}

private final String id;
private final String instanceId;
private final Map<String, ReplicationState> replicationStatesByClusterId;
private final List<ColumnFamily> columnFamilies;

private final Duration changeStreamRetention;
private final boolean deletionProtection;
private static AutomatedBackupPolicy automatedBackupPolicy;

@InternalApi
public static Table fromProto(@Nonnull com.google.bigtable.admin.v2.Table proto) {
Expand All @@ -132,26 +167,35 @@ public static Table fromProto(@Nonnull com.google.bigtable.admin.v2.Table proto)
proto.getChangeStreamConfig().getRetentionPeriod().getNanos());
}

if (proto.hasAutomatedBackupPolicy()) {
automatedBackupPolicy = AutomatedBackupPolicy.fromProto(proto.getAutomatedBackupPolicy());
} else {
automatedBackupPolicy = null;
}

return new Table(
TableName.parse(proto.getName()),
replicationStates.build(),
columnFamilies.build(),
changeStreamConfig,
proto.getDeletionProtection());
proto.getDeletionProtection(),
automatedBackupPolicy);
}

private Table(
TableName tableName,
Map<String, ReplicationState> replicationStatesByClusterId,
List<ColumnFamily> columnFamilies,
Duration changeStreamRetention,
boolean deletionProtection) {
boolean deletionProtection,
AutomatedBackupPolicy automatedBackupPolicy) {
this.instanceId = tableName.getInstance();
this.id = tableName.getTable();
this.replicationStatesByClusterId = replicationStatesByClusterId;
this.columnFamilies = columnFamilies;
this.changeStreamRetention = changeStreamRetention;
this.deletionProtection = deletionProtection;
Table.automatedBackupPolicy = automatedBackupPolicy;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be: this.automatedBackupPolicy = automatedBackupPolicy;?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So because it's a static field, I need to set it in a static way.

Here's the error I get if I try to replace Table with this:

The static field Table.automatedBackupPolicy should be accessed in a static wayJava(570425420)

}

/** Gets the table's id. */
Expand Down Expand Up @@ -181,6 +225,16 @@ public boolean isDeletionProtected() {
return deletionProtection;
}

/** Returns whether this table has automated backups enabled. */
public boolean isAutomatedBackupEnabled() {
return automatedBackupPolicy == null ? false : true;
}

/** Returns the automated backup policy config. */
public AutomatedBackupPolicy getAutomatedBackupPolicy() {
return automatedBackupPolicy;
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand All @@ -195,7 +249,8 @@ public boolean equals(Object o) {
&& Objects.equal(replicationStatesByClusterId, table.replicationStatesByClusterId)
&& Objects.equal(columnFamilies, table.columnFamilies)
&& Objects.equal(changeStreamRetention, table.changeStreamRetention)
&& Objects.equal(deletionProtection, table.deletionProtection);
&& Objects.equal(deletionProtection, table.deletionProtection)
&& Objects.equal(automatedBackupPolicy, Table.automatedBackupPolicy);
}

@Override
Expand All @@ -206,6 +261,7 @@ public int hashCode() {
replicationStatesByClusterId,
columnFamilies,
changeStreamRetention,
deletionProtection);
deletionProtection,
automatedBackupPolicy);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public class UpdateTableRequest {
private final com.google.bigtable.admin.v2.UpdateTableRequest.Builder requestBuilder =
com.google.bigtable.admin.v2.UpdateTableRequest.newBuilder();

private final com.google.bigtable.admin.v2.Table.AutomatedBackupPolicy.Builder
automatedPolicyBuilder =
com.google.bigtable.admin.v2.Table.AutomatedBackupPolicy.newBuilder();

public static UpdateTableRequest of(String tableId) {
return new UpdateTableRequest(tableId);
}
Expand Down Expand Up @@ -69,7 +73,7 @@ public UpdateTableRequest addChangeStreamRetention(Duration retention) {
return this;
}

/** Disable change stream for table */
/** Disable change stream for table. */
public UpdateTableRequest disableChangeStreamRetention() {
return addChangeStreamRetention(Duration.ZERO);
}
Expand All @@ -81,6 +85,66 @@ public UpdateTableRequest setDeletionProtection(boolean deletionProtection) {
return this;
}

/** Disables table automated backup policy. */
public UpdateTableRequest disableAutomatedBackup() {
requestBuilder.getTableBuilder().setAutomatedBackupPolicy(automatedPolicyBuilder.build());
requestBuilder.getUpdateMaskBuilder().addPaths("automated_backup_policy");
return this;
}

/** Set an automated backup policy for the table. */
public UpdateTableRequest setAutomatedBackup(Duration retentionPeriod, Duration frequency) {
com.google.bigtable.admin.v2.Table.AutomatedBackupPolicy policy =
com.google.bigtable.admin.v2.Table.AutomatedBackupPolicy.newBuilder()
.setRetentionPeriod(
com.google.protobuf.Duration.newBuilder()
.setSeconds(retentionPeriod.getSeconds())
.setNanos(retentionPeriod.getNano())
.build())
.setFrequency(
com.google.protobuf.Duration.newBuilder()
.setSeconds(frequency.getSeconds())
.setNanos(frequency.getNano())
.build())
.build();

requestBuilder.getTableBuilder().setAutomatedBackupPolicy(policy);
requestBuilder.getUpdateMaskBuilder().addPaths("automated_backup_policy");
return this;
}

/** Updates table automated backup policy retention period. */
public UpdateTableRequest setAutomatedBackupRetentionPeriod(Duration retention) {
requestBuilder
.getTableBuilder()
.setAutomatedBackupPolicy(
automatedPolicyBuilder
.setRetentionPeriod(
com.google.protobuf.Duration.newBuilder()
.setSeconds(retention.getSeconds())
.setNanos(retention.getNano())
.build())
.build());
requestBuilder.getUpdateMaskBuilder().addPaths("automated_backup_policy.retention_period");
return this;
}

/** Updates table automated backup policy frequency. */
public UpdateTableRequest setAutomatedBackupFrequency(Duration frequency) {
requestBuilder
.getTableBuilder()
.setAutomatedBackupPolicy(
automatedPolicyBuilder
.setFrequency(
com.google.protobuf.Duration.newBuilder()
.setSeconds(frequency.getSeconds())
.setNanos(frequency.getNano())
.build())
.build());
requestBuilder.getUpdateMaskBuilder().addPaths("automated_backup_policy.frequency");
return this;
}

@InternalApi
public com.google.bigtable.admin.v2.UpdateTableRequest toProto(
String projectId, String instanceId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ public void testToProto() {
.addSplit(splitKey)
.addSplit(secondSplitKey)
.addChangeStreamRetention(Duration.ofHours(24))
.setDeletionProtection(true);
.setDeletionProtection(true)
.setAutomatedBackup(Duration.ofHours(24), Duration.ofHours(24));

com.google.bigtable.admin.v2.CreateTableRequest requestProto =
com.google.bigtable.admin.v2.CreateTableRequest.newBuilder()
Expand All @@ -72,6 +73,17 @@ public void testToProto() {
.setRetentionPeriod(
com.google.protobuf.Duration.newBuilder().setSeconds(86400))
.build())
.setAutomatedBackupPolicy(
com.google.bigtable.admin.v2.Table.AutomatedBackupPolicy.newBuilder()
.setRetentionPeriod(
com.google.protobuf.Duration.newBuilder()
.setSeconds(86400)
.setNanos(0))
.setFrequency(
com.google.protobuf.Duration.newBuilder()
.setSeconds(86400)
.setNanos(0))
.build())
.setDeletionProtection(true))
.setParent(NameUtil.formatInstanceName(PROJECT_ID, INSTANCE_ID))
.addInitialSplits(
Expand Down Expand Up @@ -136,20 +148,23 @@ public void testEquality() {
CreateTableRequest.of(TABLE_ID)
.addFamily("family-id")
.addFamily("another-family", GCRULES.maxAge(100, TimeUnit.HOURS))
.setAutomatedBackup(Duration.ofHours(100), Duration.ofHours(100))
.addSplit(splitKey);

assertThat(request)
.isEqualTo(
CreateTableRequest.of(TABLE_ID)
.addFamily("family-id")
.addFamily("another-family", GCRULES.maxAge(Duration.ofHours(100)))
.setAutomatedBackup(Duration.ofHours(100), Duration.ofHours(100))
.addSplit(splitKey));

assertThat(request)
.isNotEqualTo(
CreateTableRequest.of(TABLE_ID)
.addFamily("family-id")
.addFamily("another-family")
.setAutomatedBackup(Duration.ofHours(100), Duration.ofHours(10))
.addSplit(splitKey));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.google.cloud.bigtable.admin.v2.models;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;

import com.google.bigtable.admin.v2.ColumnFamily;
import com.google.bigtable.admin.v2.GcRule;
Expand Down Expand Up @@ -67,6 +68,13 @@ public void testFromProto() {
.setSeconds(1)
.setNanos(99)))
.build())
.setAutomatedBackupPolicy(
com.google.bigtable.admin.v2.Table.AutomatedBackupPolicy.newBuilder()
.setRetentionPeriod(
com.google.protobuf.Duration.newBuilder().setSeconds(1).setNanos(99))
.setFrequency(
com.google.protobuf.Duration.newBuilder().setSeconds(1).setNanos(99))
.build())
.setDeletionProtection(true)
.build();

Expand All @@ -79,6 +87,18 @@ public void testFromProto() {
"cluster1", Table.ReplicationState.READY,
"cluster2", Table.ReplicationState.INITIALIZING);
assertThat(result.getColumnFamilies()).hasSize(3);
assertThat(result.isAutomatedBackupEnabled()).isTrue();
assertEquals(
result.getAutomatedBackupPolicy().viewConfig(),
"{google.bigtable.admin.v2.Table.AutomatedBackupPolicy.retention_period=seconds: 1\n"
+ //
"nanos: 99\n"
+ //
", google.bigtable.admin.v2.Table.AutomatedBackupPolicy.frequency=seconds: 1\n"
+ //
"nanos: 99\n"
+ //
"}");
assertThat(result.isDeletionProtected()).isTrue();

for (Entry<String, ColumnFamily> entry : proto.getColumnFamiliesMap().entrySet()) {
Expand Down
Loading
Loading