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