Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Autoclass v2.1 support #2258

Merged
merged 1 commit into from Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -484,13 +484,23 @@ private Bucket.Autoclass autoclassEncode(Autoclass from) {
Bucket.Autoclass to = new Bucket.Autoclass();
ifNonNull(from.getEnabled(), to::setEnabled);
ifNonNull(from.getToggleTime(), dateTimeCodec::encode, to::setToggleTime);
ifNonNull(from.getTerminalStorageClass(), StorageClass::toString, to::setTerminalStorageClass);
ifNonNull(
from.getTerminalStorageClassUpdateTime(),
dateTimeCodec::encode,
to::setTerminalStorageClassUpdateTime);
return to;
}

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

Expand Down
Expand Up @@ -344,11 +344,26 @@ public String toString() {
}
}

/**
* Configuration for the Autoclass settings of a bucket.
*
* @see <a
* href="https://cloud.google.com/storage/docs/autoclass">https://cloud.google.com/storage/docs/autoclass</a>
*/
public static final class Autoclass implements Serializable {

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

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

public Boolean getEnabled() {
return enabled;
Expand All @@ -358,6 +373,14 @@ public OffsetDateTime getToggleTime() {
return toggleTime;
}

public StorageClass getTerminalStorageClass() {
return terminalStorageClass;
}

public OffsetDateTime getTerminalStorageClassUpdateTime() {
return terminalStorageClassUpdateTime;
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand All @@ -366,41 +389,47 @@ public boolean equals(Object o) {
if (!(o instanceof Autoclass)) {
return false;
}
Autoclass that = (Autoclass) o;
return Objects.equals(enabled, that.enabled) && Objects.equals(toggleTime, that.toggleTime);
Autoclass autoclass = (Autoclass) o;
return Objects.equals(enabled, autoclass.enabled)
&& Objects.equals(toggleTime, autoclass.toggleTime)
&& Objects.equals(terminalStorageClass, autoclass.terminalStorageClass)
&& Objects.equals(
terminalStorageClassUpdateTime, autoclass.terminalStorageClassUpdateTime);
}

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

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("enabled", enabled)
.add("toggleTime", toggleTime)
.add("terminalStorageClass", terminalStorageClass)
.add("terminalStorageClassUpdateTime", terminalStorageClassUpdateTime)
.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);
return newBuilder()
.setEnabled(enabled)
.setToggleTime(toggleTime)
.setTerminalStorageClass(terminalStorageClass)
.setTerminalStorageClassUpdateTime(terminalStorageClassUpdateTime);
}

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

/**
* Sets whether Autoclass is enabled for this bucket. Currently, autoclass can only be enabled
Expand All @@ -421,6 +450,30 @@ Builder setToggleTime(OffsetDateTime toggleTime) {
return this;
}

/**
* When set to {@link StorageClass#NEARLINE}, Autoclass restricts transitions between Standard
* and Nearline storage classes only.
*
* <p>When set to {@link StorageClass#ARCHIVE}, Autoclass allows transitions to Coldline and
* Archive as well.
*
* <p>Only valid values are {@code NEARLINE} and {@code ARCHIVE}.
*/
public Builder setTerminalStorageClass(StorageClass terminalStorageClass) {
this.terminalStorageClass = terminalStorageClass;
return this;
}

/**
* The time at which Autoclass terminal storage class was last updated for this bucket.
*
* <p>This is auto populated when the feature is enabled.
*/
Builder setTerminalStorageClassUpdateTime(OffsetDateTime terminalStorageClassUpdateTime) {
this.terminalStorageClassUpdateTime = terminalStorageClassUpdateTime;
return this;
}

public Autoclass build() {
return new Autoclass(this);
}
Expand Down
Expand Up @@ -565,13 +565,27 @@ 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);

String terminalStorageClass = from.getTerminalStorageClass();
if (!terminalStorageClass.isEmpty()) {
to.setTerminalStorageClass(StorageClass.valueOf(terminalStorageClass));
}
ifNonNull(
from.getTerminalStorageClassUpdateTime(),
timestampCodec::decode,
to::setTerminalStorageClassUpdateTime);
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);
ifNonNull(from.getTerminalStorageClass(), StorageClass::toString, to::setTerminalStorageClass);
ifNonNull(
from.getTerminalStorageClassUpdateTime(),
timestampCodec::encode,
to::setTerminalStorageClassUpdateTime);
return to.build();
}

Expand Down
Expand Up @@ -42,6 +42,7 @@
import com.google.cloud.storage.Storage.BucketGetOption;
import com.google.cloud.storage.Storage.BucketListOption;
import com.google.cloud.storage.Storage.BucketTargetOption;
import com.google.cloud.storage.StorageClass;
import com.google.cloud.storage.TransportCompatibility.Transport;
import com.google.cloud.storage.it.runner.StorageITRunner;
import com.google.cloud.storage.it.runner.annotations.Backend;
Expand All @@ -58,6 +59,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.StreamSupport;
import org.junit.Ignore;
import org.junit.Test;
Expand Down Expand Up @@ -417,6 +419,51 @@ public void testCreateBucketWithAutoclass() {
}
}

@Test
public void testCreateBucketWithAutoclass_ARCHIVE() throws Exception {
String bucketName = generator.randomBucketName();
Autoclass autoclass =
Autoclass.newBuilder()
.setEnabled(true)
.setTerminalStorageClass(StorageClass.ARCHIVE)
.build();
BucketInfo info = BucketInfo.newBuilder(bucketName).setAutoclass(autoclass).build();
try (TemporaryBucket tmpb =
TemporaryBucket.newBuilder().setStorage(storage).setBucketInfo(info).build()) {
BucketInfo remoteBucket = tmpb.getBucket();

Autoclass remoteBucketAutoclass = remoteBucket.getAutoclass();
assertThat(remoteBucketAutoclass).isNotNull();
assertThat(remoteBucketAutoclass.getEnabled()).isTrue();
assertThat(remoteBucketAutoclass.getToggleTime()).isNotNull();
assertThat(remoteBucketAutoclass.getTerminalStorageClassUpdateTime()).isNotNull();
assertThat(remoteBucketAutoclass.getTerminalStorageClass()).isEqualTo(StorageClass.ARCHIVE);

Page<Bucket> bucketPage = storage.list(BucketListOption.prefix(bucketName));
ImmutableList<Bucket> buckets = ImmutableList.copyOf(bucketPage.iterateAll());

Optional<Bucket> first =
buckets.stream().filter(b -> bucketName.equals(b.getName())).findFirst();

assertThat(first.isPresent()).isTrue();
assertThat(first.get().getAutoclass().getTerminalStorageClass())
.isEqualTo(StorageClass.ARCHIVE);

BucketInfo disabled =
remoteBucket
.toBuilder()
.setAutoclass(Autoclass.newBuilder().setEnabled(false).build())
.build();
Bucket updated = storage.update(disabled, BucketTargetOption.metagenerationMatch());

Autoclass updatedAutoclass = updated.getAutoclass();
assertThat(updatedAutoclass.getEnabled()).isFalse();
assertThat(updatedAutoclass.getTerminalStorageClass()).isNull();

assertThat(updatedAutoclass).isNotEqualTo(remoteBucketAutoclass);
}
}

@Test
public void testUpdateBucket_noModification() throws Exception {
String bucketName = generator.randomBucketName();
Expand Down