diff --git a/google-cloud-storage/clirr-ignored-differences.xml b/google-cloud-storage/clirr-ignored-differences.xml
index 8aabcf10b..f160493af 100644
--- a/google-cloud-storage/clirr-ignored-differences.xml
+++ b/google-cloud-storage/clirr-ignored-differences.xml
@@ -2,13 +2,8 @@
- com/google/cloud/storage/Storage*
- 7012
- * downloadTo(com.google.cloud.storage.BlobId, java.io.OutputStream, com.google.cloud.storage.Storage$BlobSourceOption[])
-
-
- com/google/cloud/storage/Storage*
- 7012
- * downloadTo(com.google.cloud.storage.BlobId, java.nio.file.Path, com.google.cloud.storage.Storage$BlobSourceOption[])
+ com/google/cloud/storage/BucketInfo*
+ 7013
+ * setCustomPlacementConfig(com.google.cloud.storage.BucketInfo$CustomPlacementConfig)
diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/Bucket.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/Bucket.java
index 95acd19d6..20a6d8ad9 100644
--- a/google-cloud-storage/src/main/java/com/google/cloud/storage/Bucket.java
+++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/Bucket.java
@@ -691,6 +691,12 @@ Builder setLocationType(String locationType) {
return this;
}
+ @Override
+ public Builder setCustomPlacementConfig(CustomPlacementConfig customPlacementConfig) {
+ infoBuilder.setCustomPlacementConfig(customPlacementConfig);
+ return this;
+ }
+
@Override
public Bucket build() {
return new Bucket(storage, infoBuilder);
diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java
index 029906806..70a9817c8 100644
--- a/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java
+++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java
@@ -103,6 +103,7 @@ public com.google.api.services.storage.model.Bucket apply(BucketInfo bucketInfo)
private final IamConfiguration iamConfiguration;
private final String locationType;
private final Logging logging;
+ private final CustomPlacementConfig customPlacementConfig;
private static final Logger log = Logger.getLogger(BucketInfo.class.getName());
@@ -328,6 +329,76 @@ public IamConfiguration build() {
}
}
+ /**
+ * The bucket's custom placement configuration for Custom Dual Regions. If using `location` is
+ * also required.
+ */
+ public static class CustomPlacementConfig implements Serializable {
+
+ private static final long serialVersionUID = -3172255903331692127L;
+ private List dataLocations;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ CustomPlacementConfig other = (CustomPlacementConfig) o;
+ return Objects.equals(toPb(), other.toPb());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(dataLocations);
+ }
+
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
+ public Builder toBuilder() {
+ Builder builder = new Builder();
+ builder.dataLocations = dataLocations;
+ return builder;
+ }
+
+ public List getDataLocations() {
+ return dataLocations;
+ }
+
+ Bucket.CustomPlacementConfig toPb() {
+ Bucket.CustomPlacementConfig customPlacementConfig = null;
+ if (dataLocations != null) {
+ customPlacementConfig = new Bucket.CustomPlacementConfig();
+ customPlacementConfig.setDataLocations(dataLocations);
+ }
+ return customPlacementConfig;
+ }
+
+ static CustomPlacementConfig fromPb(Bucket.CustomPlacementConfig customPlacementConfig) {
+ return newBuilder().setDataLocations(customPlacementConfig.getDataLocations()).build();
+ }
+
+ private CustomPlacementConfig(Builder builder) {
+ this.dataLocations = builder.dataLocations;
+ }
+
+ public static class Builder {
+ private List dataLocations;
+
+ /** A list of regions for custom placement configurations. */
+ public Builder setDataLocations(List dataLocations) {
+ this.dataLocations = dataLocations != null ? ImmutableList.copyOf(dataLocations) : null;
+ return this;
+ }
+
+ public CustomPlacementConfig build() {
+ return new CustomPlacementConfig(this);
+ }
+ }
+ }
+
/**
* The bucket's logging configuration, which defines the destination bucket and optional name
* prefix for the current bucket's logs.
@@ -1361,6 +1432,8 @@ public abstract static class Builder {
public abstract Builder setLogging(Logging logging);
+ public abstract Builder setCustomPlacementConfig(CustomPlacementConfig customPlacementConfig);
+
/** Creates a {@code BucketInfo} object. */
public abstract BucketInfo build();
}
@@ -1396,6 +1469,7 @@ static final class BuilderImpl extends Builder {
private IamConfiguration iamConfiguration;
private String locationType;
private Logging logging;
+ private CustomPlacementConfig customPlacementConfig;
BuilderImpl(String name) {
this.name = name;
@@ -1431,6 +1505,7 @@ static final class BuilderImpl extends Builder {
iamConfiguration = bucketInfo.iamConfiguration;
locationType = bucketInfo.locationType;
logging = bucketInfo.logging;
+ customPlacementConfig = bucketInfo.customPlacementConfig;
}
@Override
@@ -1626,6 +1701,12 @@ public Builder setLogging(Logging logging) {
return this;
}
+ @Override
+ public Builder setCustomPlacementConfig(CustomPlacementConfig customPlacementConfig) {
+ this.customPlacementConfig = customPlacementConfig != null ? customPlacementConfig : null;
+ return this;
+ }
+
@Override
Builder setLocationType(String locationType) {
this.locationType = locationType;
@@ -1669,6 +1750,7 @@ public BucketInfo build() {
iamConfiguration = builder.iamConfiguration;
locationType = builder.locationType;
logging = builder.logging;
+ customPlacementConfig = builder.customPlacementConfig;
}
/** Returns the service-generated id for the bucket. */
@@ -1792,7 +1874,8 @@ public Long getMetageneration() {
/**
* Returns the bucket's location. Data for blobs in the bucket resides in physical storage within
- * this region or regions.
+ * this region or regions. If specifying more than one region `customPlacementConfig` should be
+ * set in conjunction.
*
* @see Bucket Locations
*/
@@ -1945,6 +2028,11 @@ public Logging getLogging() {
return logging;
}
+ /** Returns the Custom Placement Configuration */
+ public CustomPlacementConfig getCustomPlacementConfig() {
+ return customPlacementConfig;
+ }
+
/** Returns a builder for the current bucket. */
public Builder toBuilder() {
return new BuilderImpl(this);
@@ -2118,6 +2206,9 @@ public Rule apply(LifecycleRule lifecycleRule) {
if (logging != null) {
bucketPb.setLogging(logging.toPb());
}
+ if (customPlacementConfig != null) {
+ bucketPb.setCustomPlacementConfig(customPlacementConfig.toPb());
+ }
return bucketPb;
}
@@ -2258,6 +2349,10 @@ public DeleteRule apply(Rule rule) {
if (logging != null) {
builder.setLogging(Logging.fromPb(logging));
}
+ Bucket.CustomPlacementConfig customPlacementConfig = bucketPb.getCustomPlacementConfig();
+ if (customPlacementConfig != null) {
+ builder.setCustomPlacementConfig(CustomPlacementConfig.fromPb(customPlacementConfig));
+ }
return builder.build();
}
}
diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java
index 462b4bbde..fd0cc6e52 100644
--- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java
+++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java
@@ -65,6 +65,7 @@
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.BucketInfo;
+import com.google.cloud.storage.BucketInfo.CustomPlacementConfig;
import com.google.cloud.storage.BucketInfo.LifecycleRule;
import com.google.cloud.storage.BucketInfo.LifecycleRule.AbortIncompleteMPUAction;
import com.google.cloud.storage.BucketInfo.LifecycleRule.LifecycleAction;
@@ -3552,13 +3553,22 @@ public void testBucketLocationType() throws ExecutionException, InterruptedExcep
}
@Test
- public void testBucketLocationDualRegion() {
+ public void testBucketCustomPlacmentConfigDualRegion() {
String bucketName = RemoteStorageHelper.generateBucketName();
- String dualRegionLocation = "US-EAST1+US-WEST1";
+ List locations = new ArrayList<>();
+ locations.add("US-EAST1");
+ locations.add("US-WEST1");
+ CustomPlacementConfig customPlacementConfig =
+ CustomPlacementConfig.newBuilder().setDataLocations(locations).build();
Bucket bucket =
- storage.create(BucketInfo.newBuilder(bucketName).setLocation(dualRegionLocation).build());
- assertEquals(bucket.getLocation(), dualRegionLocation);
- assertEquals(bucket.getLocationType(), "dual-region");
+ storage.create(
+ BucketInfo.newBuilder(bucketName)
+ .setCustomPlacementConfig(customPlacementConfig)
+ .setLocation("us")
+ .build());
+ assertTrue(bucket.getCustomPlacementConfig().getDataLocations().contains("US-EAST1"));
+ assertTrue(bucket.getCustomPlacementConfig().getDataLocations().contains("US-WEST1"));
+ assertTrue(bucket.getLocation().equalsIgnoreCase("us"));
}
@Test