Skip to content

feat: Spanner copy backup ct #1718

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

Closed
wants to merge 18 commits into from

Conversation

ansh0l
Copy link
Contributor

@ansh0l ansh0l commented Feb 28, 2022

Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly:

  • Make sure to open an issue as a bug/issue before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea
  • Ensure the tests and linter pass
  • Code coverage does not decrease (if any source code was changed)
  • Appropriate docs were updated (if necessary)

Fixes #<issue_number_goes_here> ☕️

@ansh0l ansh0l requested review from a team as code owners February 28, 2022 03:40
@product-auto-label product-auto-label bot added the api: spanner Issues related to the googleapis/java-spanner API. label Feb 28, 2022
@generated-files-bot
Copy link

Warning: This pull request is touching the following templated files:

  • google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClient.java
  • google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminSettings.java
  • google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/gapic_metadata.json
  • google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStub.java
  • google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java
  • google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/GrpcDatabaseAdminStub.java
  • google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientTest.java
  • google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/MockDatabaseAdminImpl.java
  • grpc-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/DatabaseAdminGrpc.java
  • proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Backup.java
  • proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupOrBuilder.java
  • proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupProto.java
  • proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/SpannerDatabaseAdminProto.java
  • proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/backup.proto
  • proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/spanner_database_admin.proto
  • proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/Instance.java
  • proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceOrBuilder.java
  • proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/SpannerInstanceAdminProto.java
  • proto-google-cloud-spanner-admin-instance-v1/src/main/proto/google/spanner/admin/instance/v1/spanner_instance_admin.proto
  • proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CreateSessionRequest.java
  • proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/CreateSessionRequestOrBuilder.java
  • proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequest.java
  • proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Mutation.java
  • proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/MutationProto.java
  • proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerProto.java
  • proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/mutation.proto
  • proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/spanner.proto

@snippet-bot
Copy link

snippet-bot bot commented Feb 28, 2022

Here is the summary of changes.

You are about to add 1 region tag.

This comment is generated by snippet-bot.
If you find problems with this result, please file an issue at:
https://github.com/googleapis/repo-automation-bots/issues.
To update this comment, add snippet-bot:force-run label or use the checkbox below:

  • Refresh this comment

@ansh0l ansh0l added the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Feb 28, 2022
@ansh0l ansh0l changed the title Spanner copy backup ct feat: Spanner copy backup ct Feb 28, 2022
* OperationFuture<Backup, CopyBackupMetadata> op = dbAdminClient
* .copyBackup(
* instanceId,
* sourceBackup,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: sourceBackupId

* "projects/my-project/locations/some-location/keyRings/my-keyring/cryptoKeys/my-key"));
*
* Backup backupToCopy = dbAdminClient
* .newBackupBuilder(destinationBackupId)
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't we need a sourceBackupId?

public OperationFuture<Backup, CopyBackupMetadata> copyBackup(Backup backupInfo)
throws SpannerException {
Preconditions.checkArgument(
backupInfo.getId() != null, "Cannot create a backup without a source backup");
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't the id the destination backup? (from your javadocs?)

Copy link
Contributor

Choose a reason for hiding this comment

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

We should also check for the destination backup id as you are doing here

@@ -0,0 +1,42 @@
diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml
index f5d1351a..9ede6f23 100644
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need this file?

@@ -44,8 +44,14 @@
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-spanner</artifactId>
<version>6.19.1-SNAPSHOT</version>
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we added this for testing, but forgot to remove it?

</dependency>
<!-- [END spanner_install_with_bom] -->
<dependency>
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here

OperationFuture<Backup, CopyBackupMetadata> op = dbAdminClient.copyBackup(backup);
try {
// Wait for the backup operation to complete.
backup = op.get();
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add a timeout here (it could be a long one).

.getProgress()
.getStartTime();
} catch (InvalidProtocolBufferException e) {
return null;
Copy link
Contributor

Choose a reason for hiding this comment

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

returning null makes me worried. Should we throw a RuntimeException?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is OK in this case. We use this to order operations by start time, and this just ensures that if the listBackupOperations happens to return an operation without a start time (or some other invalid operation) that we just ignore it.

// any referencing backup prevents the backup from being deleted. When the
// copy operation is done (either successfully completed or cancelled or the
// destination backup is deleted), the reference to the backup is removed.
repeated string referencing_backups = 11 [
Copy link
Contributor

Choose a reason for hiding this comment

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

Did we expose this?

Copy link
Contributor

Choose a reason for hiding this comment

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

We need to expose this in the BackupInfo and when reading the response proto we need to map this.

// multiple APIs: CreateBackup, UpdateBackup, CopyBackup. When updating or
// copying an existing backup, the expiration time specified must be
// less than `Backup.max_expire_time`.
google.protobuf.Timestamp max_expire_time = 12 [(google.api.field_behavior) = OUTPUT_ONLY];
Copy link
Contributor

Choose a reason for hiding this comment

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

Did we expose this?

Copy link
Contributor

Choose a reason for hiding this comment

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

We need to expose this in the BackupInfo and when reading the response proto we need to map this.

message CopyBackupRequest {
// Required. The name of the destination instance that will contain the backup copy.
// Values are of the form: `projects/<project>/instances/<instance>`.
string parent = 1 [
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems we need to populate this, did we?

// any referencing backup prevents the backup from being deleted. When the
// copy operation is done (either successfully completed or cancelled or the
// destination backup is deleted), the reference to the backup is removed.
repeated string referencing_backups = 11 [
Copy link
Contributor

Choose a reason for hiding this comment

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

We need to expose this in the BackupInfo and when reading the response proto we need to map this.

// multiple APIs: CreateBackup, UpdateBackup, CopyBackup. When updating or
// copying an existing backup, the expiration time specified must be
// less than `Backup.max_expire_time`.
google.protobuf.Timestamp max_expire_time = 12 [(google.api.field_behavior) = OUTPUT_ONLY];
Copy link
Contributor

Choose a reason for hiding this comment

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

We need to expose this in the BackupInfo and when reading the response proto we need to map this.

public OperationFuture<Backup, CopyBackupMetadata> copyBackup(Backup backupInfo)
throws SpannerException {
Preconditions.checkArgument(
backupInfo.getId() != null, "Cannot create a backup without a source backup");
Copy link
Contributor

Choose a reason for hiding this comment

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

We should also check for the destination backup id as you are doing here

CopyBackupRequest.newBuilder()
.setParent(instanceName)
.setBackupId(backupId)
.setSourceBackup(backupId)
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be sourceBackupId

.setSourceBackup(sourceBackupId)
.build();

Timestamp expireTime = Timestamp.ofTimeMicroseconds(TimeUnit.MICROSECONDS.convert(
Copy link
Contributor

Choose a reason for hiding this comment

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

Use the expireTime in the backup to be copied

System.currentTimeMillis() + TimeUnit.DAYS.toMillis(14), TimeUnit.MILLISECONDS));

// Initiate the requefst which returns an OperationFuture.
System.out.println("Copying backup [" + backup.getId() + "]...");
Copy link
Contributor

Choose a reason for hiding this comment

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

This is the destination backup id, let's print the source backup

@@ -1840,6 +1887,9 @@ static void updateBackup(DatabaseAdminClient dbAdminClient, BackupId backupId) {
TimeUnit.SECONDS.toMicros(backup.getExpireTime().getSeconds())
+ TimeUnit.NANOSECONDS.toMicros(backup.getExpireTime().getNanos())
+ TimeUnit.DAYS.toMicros(30L));
int timeDiff = expireTime.compareTo(backup.getExpireTime());
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be removed for now

*
* @param sourceInstanceId the id of the instance where the database to backup is located and
* where the backup will be created.
* @param sourceBackup the source backup id.
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: here also sourceBackupId to be consistent

final String instanceName = backupInfo.getInstanceId().getName();
final String databaseName = backupInfo.getDatabase().getName();
final String backupId = backupInfo.getId().getBackup();
final Backup.Builder backupBuilder =
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think we are actually using this builder anywhere. Could we remove it?

.getProgress()
.getStartTime();
} catch (InvalidProtocolBufferException e) {
return null;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is OK in this case. We use this to order operations by start time, and this just ensures that if the listBackupOperations happens to return an operation without a start time (or some other invalid operation) that we just ignore it.

OperationFuture<Backup, CopyBackupMetadata> copyBackUp(
com.google.cloud.spanner.Backup backupInfo) throws SpannerException;


Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: remove extra empty line

.setEncryptionInfo(ENCRYPTION_INFO)
.setState(com.google.spanner.admin.database.v1.Backup.State.CREATING)
.build();
com.google.spanner.admin.database.v1.Backup.newBuilder()
Copy link
Collaborator

Choose a reason for hiding this comment

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

More of a question than an action item, but: Do you know why the formatter is changing the indentation here? Are you just using the normal mvn com.coveo:fmt-maven-plugin:format command, or is this a new format plugin?

@ansh0l
Copy link
Contributor Author

ansh0l commented Mar 25, 2022

Closing this PR in the interest of https://github.com/googleapis/java-spanner/pull/1778/files (which contains fixes by @asthamohta and removes autogenerated code)

@ansh0l ansh0l closed this Mar 25, 2022
gcf-owl-bot bot added a commit that referenced this pull request Nov 29, 2022
chore: upgrade native image checks to graalvm-22.3.0
Source-Link: googleapis/synthtool@5e52896
Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-java:latest@sha256:27b1b1884dce60460d7521b23c2a73376cba90c0ef3d9f0d32e4bdb786959cfd
mpeddada1 pushed a commit that referenced this pull request Dec 5, 2022
chore: upgrade native image checks to graalvm-22.3.0
Source-Link: googleapis/synthtool@5e52896
Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-java:latest@sha256:27b1b1884dce60460d7521b23c2a73376cba90c0ef3d9f0d32e4bdb786959cfd

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: spanner Issues related to the googleapis/java-spanner API. do not merge Indicates a pull request not ready for merge, due to either quality or timing.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants