Skip to content

Commit

Permalink
feat: add Autoclass support and sample (#1697)
Browse files Browse the repository at this point in the history
* Add Autoclass support and sample

* fix import

* Apply suggestions from code review

Co-authored-by: BenWhitehead <[email protected]>

* fix clirr, enforce builder

* format

Co-authored-by: BenWhitehead <[email protected]>
  • Loading branch information
JesseLovelace and BenWhitehead authored Nov 7, 2022
1 parent 7e3175a commit 82aacd7
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 0 deletions.
6 changes: 6 additions & 0 deletions google-cloud-storage/clirr-ignored-differences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
<method>* setCustomPlacementConfig(com.google.cloud.storage.BucketInfo$CustomPlacementConfig)</method>
</difference>

<difference>
<className>com/google/cloud/storage/BucketInfo*</className>
<differenceType>7013</differenceType>
<method>* setAutoclass(com.google.cloud.storage.BucketInfo$Autoclass)</method>
</difference>

<difference>
<differenceType>7002</differenceType>
<className>com/google/cloud/storage/HmacKey$HmacKeyMetadata</className>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import com.google.cloud.storage.Acl.Role;
import com.google.cloud.storage.Acl.User;
import com.google.cloud.storage.BlobInfo.CustomerEncryption;
import com.google.cloud.storage.BucketInfo.Autoclass;
import com.google.cloud.storage.BucketInfo.CustomPlacementConfig;
import com.google.cloud.storage.BucketInfo.IamConfiguration;
import com.google.cloud.storage.BucketInfo.LifecycleRule;
Expand Down Expand Up @@ -101,6 +102,8 @@ final class ApiaryConversions {
Codec.of(this::loggingEncode, this::loggingDecode);
private final Codec<IamConfiguration, Bucket.IamConfiguration> iamConfigurationCodec =
Codec.of(this::iamConfigEncode, this::iamConfigDecode);
private final Codec<Autoclass, Bucket.Autoclass> autoclassCodec =
Codec.of(this::autoclassEncode, this::autoclassDecode);
private final Codec<LifecycleRule, Rule> lifecycleRuleCodec =
Codec.of(this::lifecycleRuleEncode, this::lifecycleRuleDecode);
private final Codec<LifecycleCondition, Condition> lifecycleConditionCodec =
Expand Down Expand Up @@ -386,6 +389,7 @@ private Bucket bucketInfoEncode(BucketInfo from) {
to.setRetentionPolicy(retentionPolicy);
}
ifNonNull(from.getIamConfiguration(), this::iamConfigEncode, to::setIamConfiguration);
ifNonNull(from.getAutoclass(), this::autoclassEncode, to::setAutoclass);
ifNonNull(from.getLogging(), this::loggingEncode, to::setLogging);
ifNonNull(
from.getCustomPlacementConfig(),
Expand Down Expand Up @@ -438,6 +442,7 @@ private BucketInfo bucketInfoDecode(com.google.api.services.storage.model.Bucket
ifNonNull(retentionPolicy, RetentionPolicy::getIsLocked, to::setRetentionPolicyIsLocked);
ifNonNull(retentionPolicy, RetentionPolicy::getRetentionPeriod, to::setRetentionPeriod);
ifNonNull(from.getIamConfiguration(), this::iamConfigDecode, to::setIamConfiguration);
ifNonNull(from.getAutoclass(), this::autoclassDecode, to::setAutoclass);
ifNonNull(from.getLogging(), this::loggingDecode, to::setLogging);
ifNonNull(
from.getCustomPlacementConfig(),
Expand Down Expand Up @@ -473,6 +478,20 @@ private IamConfiguration iamConfigDecode(Bucket.IamConfiguration from) {
return to.build();
}

private Bucket.Autoclass autoclassEncode(Autoclass from) {
Bucket.Autoclass to = new Bucket.Autoclass();
ifNonNull(from.getEnabled(), to::setEnabled);
ifNonNull(from.getToggleTime(), dateTimeCodec::encode, to::setToggleTime);
return to;
}

private Autoclass autoclassDecode(Bucket.Autoclass from) {
Autoclass.Builder to = Autoclass.newBuilder();
to.setEnabled(from.getEnabled());
ifNonNull(from.getToggleTime(), dateTimeCodec::decode, to::setToggleTime);
return to.build();
}

private UniformBucketLevelAccess ublaEncode(IamConfiguration from) {
UniformBucketLevelAccess to = new UniformBucketLevelAccess();
to.setEnabled(from.isUniformBucketLevelAccessEnabled());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,12 @@ public Builder setIamConfiguration(IamConfiguration iamConfiguration) {
return this;
}

@Override
public Builder setAutoclass(Autoclass autoclass) {
infoBuilder.setAutoclass(autoclass);
return this;
}

@Override
public Builder setLogging(Logging logging) {
infoBuilder.setLogging(logging);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ public class BucketInfo implements Serializable {
private final Boolean retentionPolicyIsLocked;
private final Duration retentionPeriod;
private final IamConfiguration iamConfiguration;
private final Autoclass autoclass;
private final String locationType;
private final Logging logging;
private final CustomPlacementConfig customPlacementConfig;
Expand Down Expand Up @@ -340,6 +341,89 @@ public String toString() {
}
}

public static final class Autoclass implements Serializable {

private static final long serialVersionUID = -2378172222188072439L;
private Boolean enabled;
private OffsetDateTime toggleTime;

public Boolean getEnabled() {
return enabled;
}

public OffsetDateTime getToggleTime() {
return toggleTime;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Autoclass)) {
return false;
}
Autoclass that = (Autoclass) o;
return Objects.equals(enabled, that.enabled) && Objects.equals(toggleTime, that.toggleTime);
}

@Override
public int hashCode() {
return Objects.hash(enabled, toggleTime);
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("enabled", enabled)
.add("toggleTime", toggleTime)
.toString();
}

private Autoclass() {}

private Autoclass(Builder builder) {
this.enabled = builder.enabled;
this.toggleTime = builder.toggleTime;
}

public static Builder newBuilder() {
return new Builder();
}

public Builder toBuilder() {
return newBuilder().setEnabled(enabled).setToggleTime(toggleTime);
}

public static final class Builder {
private Boolean enabled;
private OffsetDateTime toggleTime;

/**
* Sets whether Autoclass is enabled for this bucket. Currently, autoclass can only be enabled
* at bucket create time. Any calls to update an existing Autoclass configuration must be to
* disable it, calls to enable Autoclass on an existing bucket will fail.
*/
public Builder setEnabled(Boolean enabled) {
this.enabled = enabled;
return this;
}

/**
* Sets the last time autoclass was toggled on or off. Set to package private because this
* should only be set by the backend.
*/
Builder setToggleTime(OffsetDateTime toggleTime) {
this.toggleTime = toggleTime;
return this;
}

public Autoclass build() {
return new Autoclass(this);
}
}
}

/**
* The bucket's custom placement configuration for Custom Dual Regions. If using `location` is
* also required.
Expand Down Expand Up @@ -1443,6 +1527,8 @@ public Builder setRetentionPeriodDuration(Duration retentionPeriod) {
@BetaApi
public abstract Builder setIamConfiguration(IamConfiguration iamConfiguration);

public abstract Builder setAutoclass(Autoclass autoclass);

public abstract Builder setLogging(Logging logging);

public abstract Builder setCustomPlacementConfig(CustomPlacementConfig customPlacementConfig);
Expand Down Expand Up @@ -1540,6 +1626,7 @@ static final class BuilderImpl extends Builder {
private Boolean retentionPolicyIsLocked;
private Duration retentionPeriod;
private IamConfiguration iamConfiguration;
private Autoclass autoclass;
private String locationType;
private Logging logging;
private CustomPlacementConfig customPlacementConfig;
Expand Down Expand Up @@ -1577,6 +1664,7 @@ static final class BuilderImpl extends Builder {
retentionPolicyIsLocked = bucketInfo.retentionPolicyIsLocked;
retentionPeriod = bucketInfo.retentionPeriod;
iamConfiguration = bucketInfo.iamConfiguration;
autoclass = bucketInfo.autoclass;
locationType = bucketInfo.locationType;
logging = bucketInfo.logging;
customPlacementConfig = bucketInfo.customPlacementConfig;
Expand Down Expand Up @@ -1910,6 +1998,15 @@ public Builder setIamConfiguration(IamConfiguration iamConfiguration) {
return this;
}

@Override
public Builder setAutoclass(Autoclass autoclass) {
if (!Objects.equals(this.autoclass, autoclass)) {
modifiedFields.add(BucketField.AUTOCLASS);
}
this.autoclass = autoclass;
return this;
}

@Override
public Builder setLogging(Logging logging) {
Logging tmp = logging != null ? logging : Logging.newBuilder().build();
Expand Down Expand Up @@ -2165,6 +2262,7 @@ private Builder clearDeleteLifecycleRules() {
retentionPolicyIsLocked = builder.retentionPolicyIsLocked;
retentionPeriod = builder.retentionPeriod;
iamConfiguration = builder.iamConfiguration;
autoclass = builder.autoclass;
locationType = builder.locationType;
logging = builder.logging;
customPlacementConfig = builder.customPlacementConfig;
Expand Down Expand Up @@ -2487,6 +2585,11 @@ public IamConfiguration getIamConfiguration() {
return iamConfiguration;
}

/** Returns the Autoclass configuration */
public Autoclass getAutoclass() {
return autoclass;
}

/** Returns the Logging */
public Logging getLogging() {
return logging;
Expand Down Expand Up @@ -2531,6 +2634,7 @@ public int hashCode() {
retentionPolicyIsLocked,
retentionPeriod,
iamConfiguration,
autoclass,
locationType,
logging);
}
Expand Down Expand Up @@ -2570,6 +2674,7 @@ public boolean equals(Object o) {
&& Objects.equals(retentionPolicyIsLocked, that.retentionPolicyIsLocked)
&& Objects.equals(retentionPeriod, that.retentionPeriod)
&& Objects.equals(iamConfiguration, that.iamConfiguration)
&& Objects.equals(autoclass, that.autoclass)
&& Objects.equals(locationType, that.locationType)
&& Objects.equals(logging, that.logging);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ final class GrpcConversions {
Codec.of(this::loggingEncode, this::loggingDecode);
private final Codec<BucketInfo.IamConfiguration, Bucket.IamConfig> iamConfigurationCodec =
Codec.of(this::iamConfigEncode, this::iamConfigDecode);
private final Codec<BucketInfo.Autoclass, Bucket.Autoclass> autoclassCodec =
Codec.of(this::autoclassEncode, this::autoclassDecode);
private final Codec<BucketInfo.LifecycleRule, Bucket.Lifecycle.Rule> lifecycleRuleCodec =
Codec.of(this::lifecycleRuleEncode, this::lifecycleRuleDecode);
private final Codec<BucketInfo, Bucket> bucketInfoCodec =
Expand Down Expand Up @@ -276,6 +278,9 @@ private BucketInfo bucketInfoDecode(Bucket from) {
if (from.hasIamConfig()) {
to.setIamConfiguration(iamConfigurationCodec.decode(from.getIamConfig()));
}
if (from.hasAutoclass()) {
to.setAutoclass(autoclassCodec.decode(from.getAutoclass()));
}
if (from.hasCustomPlacementConfig()) {
Bucket.CustomPlacementConfig customPlacementConfig = from.getCustomPlacementConfig();
to.setCustomPlacementConfig(
Expand Down Expand Up @@ -364,6 +369,7 @@ private Bucket bucketInfoEncode(BucketInfo from) {
to::addAllDefaultObjectAcl);
ifNonNull(from.getAcl(), toImmutableListOf(bucketAclCodec::encode), to::addAllAcl);
ifNonNull(from.getIamConfiguration(), iamConfigurationCodec::encode, to::setIamConfig);
ifNonNull(from.getAutoclass(), autoclassCodec::encode, to::setAutoclass);
CustomPlacementConfig customPlacementConfig = from.getCustomPlacementConfig();
if (customPlacementConfig != null && customPlacementConfig.getDataLocations() != null) {
to.setCustomPlacementConfig(
Expand Down Expand Up @@ -516,6 +522,20 @@ private Bucket.IamConfig.UniformBucketLevelAccess ublaEncode(BucketInfo.IamConfi
return to.build();
}

private BucketInfo.Autoclass autoclassDecode(Bucket.Autoclass from) {
BucketInfo.Autoclass.Builder to = BucketInfo.Autoclass.newBuilder();
to.setEnabled(from.getEnabled());
ifNonNull(from.getToggleTime(), timestampCodec::decode, to::setToggleTime);
return to.build();
}

private Bucket.Autoclass autoclassEncode(BucketInfo.Autoclass from) {
Bucket.Autoclass.Builder to = Bucket.Autoclass.newBuilder();
ifNonNull(from.getEnabled(), to::setEnabled);
ifNonNull(from.getToggleTime(), timestampCodec::encode, to::setToggleTime);
return to.build();
}

private Bucket.IamConfig iamConfigEncode(BucketInfo.IamConfiguration from) {
Bucket.IamConfig.Builder to = Bucket.IamConfig.newBuilder();
to.setUniformBucketLevelAccess(ublaEncode(from));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
Expand All @@ -31,6 +32,7 @@
import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.BucketFixture;
import com.google.cloud.storage.BucketInfo;
import com.google.cloud.storage.BucketInfo.Autoclass;
import com.google.cloud.storage.BucketInfo.CustomPlacementConfig;
import com.google.cloud.storage.Cors;
import com.google.cloud.storage.HttpMethod;
Expand All @@ -44,6 +46,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.time.Duration;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -495,6 +498,40 @@ public void testEnableDisableBucketDefaultEventBasedHold()
}
}

@Test
public void testCreateBucketWithAutoclass() throws ExecutionException, InterruptedException {
String bucketName = bucketFixture.newBucketName();
storageFixtureHttp
.getInstance()
.create(
BucketInfo.newBuilder(bucketName)
.setAutoclass(Autoclass.newBuilder().setEnabled(true).build())
.build());
try {
Bucket remoteBucket = storageFixture.getInstance().get(bucketName);

assertNotNull(remoteBucket.getAutoclass());
assertTrue(remoteBucket.getAutoclass().getEnabled());
OffsetDateTime time = remoteBucket.getAutoclass().getToggleTime();
assertNotNull(time);

remoteBucket
.toBuilder()
.setAutoclass(Autoclass.newBuilder().setEnabled(false).build())
.build()
.update();

remoteBucket = storageFixture.getInstance().get(bucketName);
assertNotNull(remoteBucket.getAutoclass());
assertFalse(remoteBucket.getAutoclass().getEnabled());
assertNotNull(remoteBucket.getAutoclass().getToggleTime());
assertNotEquals(time, remoteBucket.getAutoclass().getToggleTime());
} finally {
RemoteStorageHelper.forceDelete(
storageFixtureHttp.getInstance(), bucketName, 5, TimeUnit.SECONDS);
}
}

private void unsetRequesterPays() {
Bucket remoteBucket =
storageFixture
Expand Down
Loading

0 comments on commit 82aacd7

Please sign in to comment.