Skip to content

Commit 316f971

Browse files
docs: add Multi Region Encryption samples (#3524)
* docs: add Multi Region Encryption samples * add create backup sample * chore: generate libraries at Wed Dec 4 08:33:54 UTC 2024 * add sample for CopyBackup with multi region encryption keys * add restore backup sample * fix sample * chore: generate libraries at Wed Dec 4 09:25:28 UTC 2024 --------- Co-authored-by: cloud-java-bot <[email protected]>
1 parent e6884d9 commit 316f971

5 files changed

+456
-0
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -505,9 +505,12 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-spanner/tree/
505505
| Batch Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/BatchSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/BatchSample.java) |
506506
| Batch Write At Least Once Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/BatchWriteAtLeastOnceSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/BatchWriteAtLeastOnceSample.java) |
507507
| Copy Backup Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CopyBackupSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CopyBackupSample.java) |
508+
| Copy Backup With Multi Region Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CopyBackupWithMultiRegionEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CopyBackupWithMultiRegionEncryptionKey.java) |
508509
| Create Backup With Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateBackupWithEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateBackupWithEncryptionKey.java) |
510+
| Create Backup With Multi Region Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateBackupWithMultiRegionEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateBackupWithMultiRegionEncryptionKey.java) |
509511
| Create Database With Default Leader Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithDefaultLeaderSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithDefaultLeaderSample.java) |
510512
| Create Database With Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithEncryptionKey.java) |
513+
| Create Database With Multi Region Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithMultiRegionEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithMultiRegionEncryptionKey.java) |
511514
| Create Database With Version Retention Period Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithVersionRetentionPeriodSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithVersionRetentionPeriodSample.java) |
512515
| Create Full Backup Schedule Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateFullBackupScheduleSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateFullBackupScheduleSample.java) |
513516
| Create Incremental Backup Schedule Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateIncrementalBackupScheduleSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateIncrementalBackupScheduleSample.java) |
@@ -560,6 +563,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-spanner/tree/
560563
| Quickstart Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/QuickstartSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/QuickstartSample.java) |
561564
| Read Data With Database Role | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/ReadDataWithDatabaseRole.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/ReadDataWithDatabaseRole.java) |
562565
| Restore Backup With Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/RestoreBackupWithEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/RestoreBackupWithEncryptionKey.java) |
566+
| Restore Backup With Multi Region Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/RestoreBackupWithMultiRegionEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/RestoreBackupWithMultiRegionEncryptionKey.java) |
563567
| Set Max Commit Delay Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/SetMaxCommitDelaySample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/SetMaxCommitDelaySample.java) |
564568
| Singer Proto | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/SingerProto.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/SingerProto.java) |
565569
| Spanner Graph Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java) |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* Copyright 2024 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.spanner;
18+
19+
// [START spanner_copy_backup_with_MR_CMEK]
20+
21+
import com.google.cloud.Timestamp;
22+
import com.google.cloud.spanner.Spanner;
23+
import com.google.cloud.spanner.SpannerException;
24+
import com.google.cloud.spanner.SpannerExceptionFactory;
25+
import com.google.cloud.spanner.SpannerOptions;
26+
import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient;
27+
import com.google.common.collect.ImmutableList;
28+
import com.google.spanner.admin.database.v1.Backup;
29+
import com.google.spanner.admin.database.v1.BackupName;
30+
import com.google.spanner.admin.database.v1.CopyBackupEncryptionConfig;
31+
import com.google.spanner.admin.database.v1.CopyBackupEncryptionConfig.EncryptionType;
32+
import com.google.spanner.admin.database.v1.CopyBackupRequest;
33+
import com.google.spanner.admin.database.v1.InstanceName;
34+
import java.time.Instant;
35+
import java.time.OffsetDateTime;
36+
import java.time.ZoneId;
37+
import java.util.concurrent.ExecutionException;
38+
import java.util.concurrent.TimeUnit;
39+
40+
public class CopyBackupWithMultiRegionEncryptionKey {
41+
42+
static void copyBackupWithMultiRegionEncryptionKey() {
43+
// TODO(developer): Replace these variables before running the sample.
44+
String projectId = "my-project";
45+
String instanceId = "my-instance";
46+
String sourceBackupId = "my-backup";
47+
String destinationBackupId = "my-destination-backup";
48+
String[] kmsKeyNames =
49+
new String[] {
50+
"projects/" + projectId + "/locations/<location1>/keyRings/<keyRing>/cryptoKeys/<keyId>",
51+
"projects/" + projectId + "/locations/<location2>/keyRings/<keyRing>/cryptoKeys/<keyId>",
52+
"projects/" + projectId + "/locations/<location3>/keyRings/<keyRing>/cryptoKeys/<keyId>"
53+
};
54+
55+
try (Spanner spanner =
56+
SpannerOptions.newBuilder().setProjectId(projectId).build().getService();
57+
DatabaseAdminClient databaseAdminClient = spanner.createDatabaseAdminClient()) {
58+
copyBackupWithMultiRegionEncryptionKey(
59+
databaseAdminClient,
60+
projectId,
61+
instanceId,
62+
sourceBackupId,
63+
destinationBackupId,
64+
kmsKeyNames);
65+
}
66+
}
67+
68+
static void copyBackupWithMultiRegionEncryptionKey(
69+
DatabaseAdminClient databaseAdminClient,
70+
String projectId,
71+
String instanceId,
72+
String sourceBackupId,
73+
String destinationBackupId,
74+
String[] kmsKeyNames) {
75+
76+
Timestamp expireTime =
77+
Timestamp.ofTimeMicroseconds(
78+
TimeUnit.MICROSECONDS.convert(
79+
System.currentTimeMillis() + TimeUnit.DAYS.toMillis(14), TimeUnit.MILLISECONDS));
80+
81+
// Initiate the request which returns an OperationFuture.
82+
System.out.println("Copying backup [" + destinationBackupId + "]...");
83+
CopyBackupRequest request =
84+
CopyBackupRequest.newBuilder()
85+
.setParent(InstanceName.of(projectId, instanceId).toString())
86+
.setBackupId(destinationBackupId)
87+
.setSourceBackup(BackupName.of(projectId, instanceId, sourceBackupId).toString())
88+
.setExpireTime(expireTime.toProto())
89+
.setEncryptionConfig(
90+
CopyBackupEncryptionConfig.newBuilder()
91+
.setEncryptionType(EncryptionType.CUSTOMER_MANAGED_ENCRYPTION)
92+
.addAllKmsKeyNames(ImmutableList.copyOf(kmsKeyNames))
93+
.build())
94+
.build();
95+
Backup destinationBackup;
96+
try {
97+
// Creates a copy of an existing backup.
98+
// Wait for the backup operation to complete.
99+
destinationBackup = databaseAdminClient.copyBackupAsync(request).get();
100+
System.out.println("Copied backup [" + destinationBackup.getName() + "]");
101+
} catch (ExecutionException e) {
102+
throw (SpannerException) e.getCause();
103+
} catch (InterruptedException e) {
104+
throw SpannerExceptionFactory.propagateInterrupt(e);
105+
}
106+
// Load the metadata of the new backup from the server.
107+
destinationBackup = databaseAdminClient.getBackup(destinationBackup.getName());
108+
System.out.println(
109+
String.format(
110+
"Backup %s of size %d bytes was copied at %s for version of database at %s",
111+
destinationBackup.getName(),
112+
destinationBackup.getSizeBytes(),
113+
OffsetDateTime.ofInstant(
114+
Instant.ofEpochSecond(
115+
destinationBackup.getCreateTime().getSeconds(),
116+
destinationBackup.getCreateTime().getNanos()),
117+
ZoneId.systemDefault()),
118+
OffsetDateTime.ofInstant(
119+
Instant.ofEpochSecond(
120+
destinationBackup.getVersionTime().getSeconds(),
121+
destinationBackup.getVersionTime().getNanos()),
122+
ZoneId.systemDefault())));
123+
}
124+
}
125+
// [END spanner_copy_backup_with_MR_CMEK]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.spanner;
18+
19+
// [START spanner_create_backup_with_MR_CMEK]
20+
21+
import com.google.cloud.spanner.Spanner;
22+
import com.google.cloud.spanner.SpannerExceptionFactory;
23+
import com.google.cloud.spanner.SpannerOptions;
24+
import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient;
25+
import com.google.common.collect.ImmutableList;
26+
import com.google.protobuf.Timestamp;
27+
import com.google.spanner.admin.database.v1.Backup;
28+
import com.google.spanner.admin.database.v1.BackupName;
29+
import com.google.spanner.admin.database.v1.CreateBackupEncryptionConfig;
30+
import com.google.spanner.admin.database.v1.CreateBackupEncryptionConfig.EncryptionType;
31+
import com.google.spanner.admin.database.v1.CreateBackupRequest;
32+
import com.google.spanner.admin.database.v1.DatabaseName;
33+
import com.google.spanner.admin.database.v1.InstanceName;
34+
import java.util.concurrent.ExecutionException;
35+
import java.util.concurrent.TimeUnit;
36+
import java.util.concurrent.TimeoutException;
37+
import org.threeten.bp.LocalDateTime;
38+
import org.threeten.bp.OffsetDateTime;
39+
40+
public class CreateBackupWithMultiRegionEncryptionKey {
41+
42+
static void createBackupWithMultiRegionEncryptionKey() {
43+
// TODO(developer): Replace these variables before running the sample.
44+
String projectId = "my-project";
45+
String instanceId = "my-instance";
46+
String databaseId = "my-database";
47+
String backupId = "my-backup";
48+
String[] kmsKeyNames =
49+
new String[] {
50+
"projects/" + projectId + "/locations/<location1>/keyRings/<keyRing>/cryptoKeys/<keyId>",
51+
"projects/" + projectId + "/locations/<location2>/keyRings/<keyRing>/cryptoKeys/<keyId>",
52+
"projects/" + projectId + "/locations/<location3>/keyRings/<keyRing>/cryptoKeys/<keyId>"
53+
};
54+
55+
try (Spanner spanner =
56+
SpannerOptions.newBuilder().setProjectId(projectId).build().getService();
57+
DatabaseAdminClient adminClient = spanner.createDatabaseAdminClient()) {
58+
createBackupWithMultiRegionEncryptionKey(
59+
adminClient, projectId, instanceId, databaseId, backupId, kmsKeyNames);
60+
}
61+
}
62+
63+
static Void createBackupWithMultiRegionEncryptionKey(
64+
DatabaseAdminClient adminClient,
65+
String projectId,
66+
String instanceId,
67+
String databaseId,
68+
String backupId,
69+
String[] kmsKeyNames) {
70+
// Set expire time to 14 days from now.
71+
final Timestamp expireTime =
72+
Timestamp.newBuilder()
73+
.setSeconds(
74+
TimeUnit.MILLISECONDS.toSeconds(
75+
(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(14))))
76+
.build();
77+
final BackupName backupName = BackupName.of(projectId, instanceId, backupId);
78+
Backup backup =
79+
Backup.newBuilder()
80+
.setName(backupName.toString())
81+
.setDatabase(DatabaseName.of(projectId, instanceId, databaseId).toString())
82+
.setExpireTime(expireTime)
83+
.build();
84+
85+
final CreateBackupRequest request =
86+
CreateBackupRequest.newBuilder()
87+
.setParent(InstanceName.of(projectId, instanceId).toString())
88+
.setBackupId(backupId)
89+
.setBackup(backup)
90+
.setEncryptionConfig(
91+
CreateBackupEncryptionConfig.newBuilder()
92+
.setEncryptionType(EncryptionType.CUSTOMER_MANAGED_ENCRYPTION)
93+
.addAllKmsKeyNames(ImmutableList.copyOf(kmsKeyNames))
94+
.build())
95+
.build();
96+
try {
97+
System.out.println("Waiting for operation to complete...");
98+
backup = adminClient.createBackupAsync(request).get(1200, TimeUnit.SECONDS);
99+
} catch (ExecutionException e) {
100+
// If the operation failed during execution, expose the cause.
101+
throw SpannerExceptionFactory.asSpannerException(e.getCause());
102+
} catch (InterruptedException e) {
103+
// Throw when a thread is waiting, sleeping, or otherwise occupied,
104+
// and the thread is interrupted, either before or during the activity.
105+
throw SpannerExceptionFactory.propagateInterrupt(e);
106+
} catch (TimeoutException e) {
107+
// If the operation timed out propagates the timeout
108+
throw SpannerExceptionFactory.propagateTimeout(e);
109+
}
110+
System.out.printf(
111+
"Backup %s of size %d bytes was created at %s using encryption keys %s%n",
112+
backup.getName(),
113+
backup.getSizeBytes(),
114+
LocalDateTime.ofEpochSecond(
115+
backup.getCreateTime().getSeconds(),
116+
backup.getCreateTime().getNanos(),
117+
OffsetDateTime.now().getOffset()),
118+
ImmutableList.copyOf(kmsKeyNames));
119+
120+
return null;
121+
}
122+
}
123+
// [END spanner_create_backup_with_MR_CMEK]

0 commit comments

Comments
 (0)