Skip to content

Commit 6f9dfdf

Browse files
JesseLovelaceBenWhiteheadgcf-owl-bot[bot]
authored
feat: Add RPO metadata settings (#1105)
* (feat) Add RPO metadata settings * Add javadoc * Apply suggestions from code review Co-authored-by: BenWhitehead <[email protected]> * typo * 🦉 Updates from OwlBot See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * fix clirr Co-authored-by: BenWhitehead <[email protected]> Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
1 parent ece0fe5 commit 6f9dfdf

File tree

5 files changed

+146
-0
lines changed

5 files changed

+146
-0
lines changed

google-cloud-storage/clirr-ignored-differences.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!-- see https://www.mojohaus.org/clirr-maven-plugin/examples/ignored-differences.html -->
33
<differences>
4+
<difference>
5+
<className>com/google/cloud/storage/BucketInfo$Builder</className>
6+
<method>com.google.cloud.storage.BucketInfo$Builder setRpo(com.google.cloud.storage.Rpo)</method>
7+
<differenceType>7013</differenceType>
8+
</difference>
49
<difference>
510
<className>com/google/cloud/storage/BucketInfo$LifecycleRule$LifecycleAction</className>
611
<method>BucketInfo$LifecycleRule$LifecycleAction()</method>

google-cloud-storage/src/main/java/com/google/cloud/storage/Bucket.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,12 @@ public Builder deleteLifecycleRules() {
577577
return this;
578578
}
579579

580+
@Override
581+
public Builder setRpo(Rpo rpo) {
582+
infoBuilder.setRpo(rpo);
583+
return this;
584+
}
585+
580586
@Override
581587
public Builder setStorageClass(StorageClass storageClass) {
582588
infoBuilder.setStorageClass(storageClass);

google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ public com.google.api.services.storage.model.Bucket apply(BucketInfo bucketInfo)
9292
private final List<Acl> acl;
9393
private final List<Acl> defaultAcl;
9494
private final String location;
95+
private final Rpo rpo;
9596
private final StorageClass storageClass;
9697
private final Map<String, String> labels;
9798
private final String defaultKmsKeyName;
@@ -1205,6 +1206,15 @@ public abstract static class Builder {
12051206
/** Deletes the lifecycle rules of this bucket. */
12061207
public abstract Builder deleteLifecycleRules();
12071208

1209+
/**
1210+
* Sets the bucket's Recovery Point Objective (RPO). This can only be set for a dual-region
1211+
* bucket, and determines the speed at which data will be replicated between regions. See the
1212+
* {@code Rpo} class for supported values, and <a
1213+
* href="https://cloud.google.com/storage/docs/turbo-replication">here</a> for additional
1214+
* details.
1215+
*/
1216+
public abstract Builder setRpo(Rpo rpo);
1217+
12081218
/**
12091219
* Sets the bucket's storage class. This defines how blobs in the bucket are stored and
12101220
* determines the SLA and the cost of storage. A list of supported values is available <a
@@ -1306,6 +1316,7 @@ static final class BuilderImpl extends Builder {
13061316
private String notFoundPage;
13071317
private List<DeleteRule> deleteRules;
13081318
private List<LifecycleRule> lifecycleRules;
1319+
private Rpo rpo;
13091320
private StorageClass storageClass;
13101321
private String location;
13111322
private String etag;
@@ -1337,6 +1348,7 @@ static final class BuilderImpl extends Builder {
13371348
updateTime = bucketInfo.updateTime;
13381349
metageneration = bucketInfo.metageneration;
13391350
location = bucketInfo.location;
1351+
rpo = bucketInfo.rpo;
13401352
storageClass = bucketInfo.storageClass;
13411353
cors = bucketInfo.cors;
13421354
acl = bucketInfo.acl;
@@ -1430,6 +1442,12 @@ public Builder deleteLifecycleRules() {
14301442
return this;
14311443
}
14321444

1445+
@Override
1446+
public Builder setRpo(Rpo rpo) {
1447+
this.rpo = rpo;
1448+
return this;
1449+
}
1450+
14331451
@Override
14341452
public Builder setStorageClass(StorageClass storageClass) {
14351453
this.storageClass = storageClass;
@@ -1568,6 +1586,7 @@ public BucketInfo build() {
15681586
updateTime = builder.updateTime;
15691587
metageneration = builder.metageneration;
15701588
location = builder.location;
1589+
rpo = builder.rpo;
15711590
storageClass = builder.storageClass;
15721591
cors = builder.cors;
15731592
acl = builder.acl;
@@ -1729,6 +1748,16 @@ public String getLocationType() {
17291748
return locationType;
17301749
}
17311750

1751+
/**
1752+
* Returns the bucket's recovery point objective (RPO). This defines how quickly data is
1753+
* replicated between regions in a dual-region bucket. Not defined for single-region buckets.
1754+
*
1755+
* @see <a href="https://cloud.google.com/storage/docs/turbo-replication"Turbo Replication"</a>
1756+
*/
1757+
public Rpo getRpo() {
1758+
return rpo;
1759+
}
1760+
17321761
/**
17331762
* Returns the bucket's storage class. This defines how blobs in the bucket are stored and
17341763
* determines the SLA and the cost of storage.
@@ -1899,6 +1928,9 @@ com.google.api.services.storage.model.Bucket toPb() {
18991928
if (locationType != null) {
19001929
bucketPb.setLocationType(locationType);
19011930
}
1931+
if (rpo != null) {
1932+
bucketPb.setRpo(rpo.toString());
1933+
}
19021934
if (storageClass != null) {
19031935
bucketPb.setStorageClass(storageClass.toString());
19041936
}
@@ -2062,6 +2094,9 @@ static BucketInfo fromPb(com.google.api.services.storage.model.Bucket bucketPb)
20622094
if (bucketPb.getLocation() != null) {
20632095
builder.setLocation(bucketPb.getLocation());
20642096
}
2097+
if (bucketPb.getRpo() != null) {
2098+
builder.setRpo(Rpo.valueOf(bucketPb.getRpo()));
2099+
}
20652100
if (bucketPb.getStorageClass() != null) {
20662101
builder.setStorageClass(StorageClass.valueOf(bucketPb.getStorageClass()));
20672102
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright 2021 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+
package com.google.cloud.storage;
17+
18+
import com.google.api.core.ApiFunction;
19+
import com.google.cloud.StringEnumType;
20+
import com.google.cloud.StringEnumValue;
21+
22+
/**
23+
* Enums for the Recovery Point Objective (RPO) of dual-region buckets, which determines how fast
24+
* data is replicated between regions.
25+
*
26+
* @see <a
27+
* href="https://cloud.google.com/storage/docs/turbo-replication">https://cloud.google.com/storage/docs/turbo-replication</a>
28+
*/
29+
public final class Rpo extends StringEnumValue {
30+
31+
private static final long serialVersionUID = -3954216195295821508L;
32+
33+
private Rpo(String constant) {
34+
super(constant);
35+
}
36+
37+
private static final ApiFunction<String, Rpo> CONSTRUCTOR = Rpo::new;
38+
39+
private static final StringEnumType<Rpo> type = new StringEnumType<>(Rpo.class, CONSTRUCTOR);
40+
41+
/**
42+
* Default recovery point objective. With this setting, there is no guarantee on the amount of
43+
* time it takes for data to replicate between regions.
44+
*/
45+
public static final Rpo DEFAULT = type.createAndRegister("DEFAULT");
46+
47+
/**
48+
* Turbo recovery point objective. With this setting, data in a dual-region bucket will replicate
49+
* between regions within 15 minutes.
50+
*/
51+
public static final Rpo ASYNC_TURBO = type.createAndRegister("ASYNC_TURBO");
52+
53+
/**
54+
* Get the Rpo for the given String constant, and throw an exception if the constant is not
55+
* recognized.
56+
*/
57+
public static Rpo valueOfStrict(String constant) {
58+
return type.valueOfStrict(constant);
59+
}
60+
61+
/** Get the Rpo for the given String constant, and allow unrecognized values. */
62+
public static Rpo valueOf(String constant) {
63+
return type.valueOf(constant);
64+
}
65+
66+
/** Return the known values for Rpo. */
67+
public static Rpo[] values() {
68+
return type.values();
69+
}
70+
}

google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import com.google.cloud.storage.HttpMethod;
7474
import com.google.cloud.storage.PostPolicyV4;
7575
import com.google.cloud.storage.PostPolicyV4.PostFieldsV4;
76+
import com.google.cloud.storage.Rpo;
7677
import com.google.cloud.storage.ServiceAccount;
7778
import com.google.cloud.storage.Storage;
7879
import com.google.cloud.storage.Storage.BlobField;
@@ -3951,4 +3952,33 @@ protected Object handleInvocation(
39513952
blobGen2.downloadTo(actualData);
39523953
assertEquals(contentGen2Expected, ByteBuffer.wrap(actualData.toByteArray()));
39533954
}
3955+
3956+
@Test
3957+
public void testRpoConfig() {
3958+
String rpoBucket = RemoteStorageHelper.generateBucketName();
3959+
try {
3960+
Bucket bucket =
3961+
storage.create(
3962+
BucketInfo.newBuilder(rpoBucket).setLocation("NAM4").setRpo(Rpo.ASYNC_TURBO).build());
3963+
assertEquals("ASYNC_TURBO", bucket.getRpo().toString());
3964+
3965+
bucket.toBuilder().setRpo(Rpo.DEFAULT).build().update();
3966+
3967+
assertEquals("DEFAULT", storage.get(rpoBucket).getRpo().toString());
3968+
} finally {
3969+
storage.delete(rpoBucket);
3970+
}
3971+
}
3972+
3973+
private static String randString(Random rand, int length) {
3974+
final StringBuilder sb = new StringBuilder();
3975+
while (sb.length() < length) {
3976+
int i = rand.nextInt('z');
3977+
char c = (char) i;
3978+
if (Character.isLetter(c) || Character.isDigit(c)) {
3979+
sb.append(c);
3980+
}
3981+
}
3982+
return sb.toString();
3983+
}
39543984
}

0 commit comments

Comments
 (0)