Skip to content

Commit

Permalink
feat: add soft delete feature (#2403)
Browse files Browse the repository at this point in the history
* feat: add soft delete feature

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* add softDeleteTime and hardDeleteTime object fields

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* add new fields to field tests

* clirr ignore

* remove debug comments

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* add softdeletetime and harddeletetime to grpc codec

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* fix read mask test

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* fix style issues

* updates to apiary library

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* fix read mask test

* fix typo

---------

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
  • Loading branch information
JesseLovelace and gcf-owl-bot[bot] authored Mar 14, 2024
1 parent 8074fff commit 989f36f
Show file tree
Hide file tree
Showing 22 changed files with 654 additions and 11 deletions.
18 changes: 18 additions & 0 deletions google-cloud-storage/clirr-ignored-differences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,24 @@
<method>com.google.cloud.storage.BlobInfo$Builder setRetention(com.google.cloud.storage.BlobInfo$Retention)</method>
</difference>

<difference>
<differenceType>7013</differenceType>
<className>com/google/cloud/storage/BucketInfo$Builder</className>
<method>com.google.cloud.storage.BucketInfo$Builder setSoftDeletePolicy(com.google.cloud.storage.BucketInfo$SoftDeletePolicy)</method>
</difference>

<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/storage/Storage</className>
<method>com.google.cloud.storage.Blob restore(com.google.cloud.storage.BlobId, com.google.cloud.storage.Storage$BlobRestoreOption[])</method>
</difference>

<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/storage/spi/v1/StorageRpc</className>
<method>com.google.api.services.storage.model.StorageObject restore(com.google.api.services.storage.model.StorageObject, java.util.Map)</method>
</difference>

<!-- @BetaApi members -->
<difference>
<differenceType>7009</differenceType>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,18 @@ Builder setRetentionExpirationTimeOffsetDateTime(OffsetDateTime retentionExpirat
return this;
}

@Override
Builder setSoftDeleteTime(OffsetDateTime softDeleteTime) {
infoBuilder.setSoftDeleteTime(softDeleteTime);
return this;
}

@Override
Builder setHardDeleteTime(OffsetDateTime hardDeleteTime) {
infoBuilder.setHardDeleteTime(hardDeleteTime);
return this;
}

@Override
public Builder setRetention(Retention retention) {
infoBuilder.setRetention(retention);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ public class BlobInfo implements Serializable {
private final Boolean temporaryHold;
private final OffsetDateTime retentionExpirationTime;
private final Retention retention;
private final OffsetDateTime softDeleteTime;
private final OffsetDateTime hardDeleteTime;
private final transient ImmutableSet<NamedField> modifiedFields;

/** This class is meant for internal use only. Users are discouraged from using this class. */
Expand Down Expand Up @@ -525,6 +527,10 @@ Builder setRetentionExpirationTimeOffsetDateTime(OffsetDateTime retentionExpirat
return setRetentionExpirationTime(millisOffsetDateTimeCodec.decode(retentionExpirationTime));
}

abstract Builder setSoftDeleteTime(OffsetDateTime offsetDateTime);

abstract Builder setHardDeleteTime(OffsetDateTime hardDeleteTIme);

public abstract Builder setRetention(Retention retention);

/** Creates a {@code BlobInfo} object. */
Expand Down Expand Up @@ -626,6 +632,8 @@ static final class BuilderImpl extends Builder {
private Boolean temporaryHold;
private OffsetDateTime retentionExpirationTime;
private Retention retention;
private OffsetDateTime softDeleteTime;
private OffsetDateTime hardDeleteTime;
private final ImmutableSet.Builder<NamedField> modifiedFields = ImmutableSet.builder();

BuilderImpl(BlobId blobId) {
Expand Down Expand Up @@ -664,6 +672,8 @@ static final class BuilderImpl extends Builder {
temporaryHold = blobInfo.temporaryHold;
retentionExpirationTime = blobInfo.retentionExpirationTime;
retention = blobInfo.retention;
softDeleteTime = blobInfo.softDeleteTime;
hardDeleteTime = blobInfo.hardDeleteTime;
}

@Override
Expand Down Expand Up @@ -1037,6 +1047,24 @@ Builder setRetentionExpirationTimeOffsetDateTime(OffsetDateTime retentionExpirat
return this;
}

@Override
Builder setSoftDeleteTime(OffsetDateTime softDeleteTime) {
if (!Objects.equals(this.softDeleteTime, softDeleteTime)) {
modifiedFields.add(BlobField.SOFT_DELETE_TIME);
}
this.softDeleteTime = softDeleteTime;
return this;
}

@Override
Builder setHardDeleteTime(OffsetDateTime hardDeleteTime) {
if (!Objects.equals(this.hardDeleteTime, hardDeleteTime)) {
modifiedFields.add(BlobField.HARD_DELETE_TIME);
}
this.hardDeleteTime = hardDeleteTime;
return this;
}

@Override
public Builder setRetention(Retention retention) {
// todo: b/308194853
Expand Down Expand Up @@ -1269,6 +1297,8 @@ Builder clearRetentionExpirationTime() {
temporaryHold = builder.temporaryHold;
retentionExpirationTime = builder.retentionExpirationTime;
retention = builder.retention;
softDeleteTime = builder.softDeleteTime;
hardDeleteTime = builder.hardDeleteTime;
modifiedFields = builder.modifiedFields.build();
}

Expand Down Expand Up @@ -1662,6 +1692,18 @@ public OffsetDateTime getRetentionExpirationTimeOffsetDateTime() {
return retentionExpirationTime;
}

/** If this object has been soft-deleted, returns the time it was soft-deleted. */
public OffsetDateTime getSoftDeleteTime() {
return softDeleteTime;
}

/**
* If this object has been soft-deleted, returns the time at which it will be permanently deleted.
*/
public OffsetDateTime getHardDeleteTime() {
return hardDeleteTime;
}

/** Returns the object's Retention policy. */
public Retention getRetention() {
return retention;
Expand Down Expand Up @@ -1717,7 +1759,9 @@ public int hashCode() {
eventBasedHold,
temporaryHold,
retention,
retentionExpirationTime);
retentionExpirationTime,
softDeleteTime,
hardDeleteTime);
}

@Override
Expand Down Expand Up @@ -1759,7 +1803,9 @@ public boolean equals(Object o) {
&& Objects.equals(eventBasedHold, blobInfo.eventBasedHold)
&& Objects.equals(temporaryHold, blobInfo.temporaryHold)
&& Objects.equals(retentionExpirationTime, blobInfo.retentionExpirationTime)
&& Objects.equals(retention, blobInfo.retention);
&& Objects.equals(retention, blobInfo.retention)
&& Objects.equals(softDeleteTime, blobInfo.softDeleteTime)
&& Objects.equals(hardDeleteTime, blobInfo.hardDeleteTime);
}

ImmutableSet<NamedField> getModifiedFields() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,12 @@ Builder setObjectRetention(ObjectRetention objectRetention) {
return this;
}

@Override
public Builder setSoftDeletePolicy(SoftDeletePolicy softDeletePolicy) {
infoBuilder.setSoftDeletePolicy(softDeletePolicy);
return this;
}

@Override
public Builder setHierarchicalNamespace(HierarchicalNamespace hierarchicalNamespace) {
infoBuilder.setHierarchicalNamespace(hierarchicalNamespace);
Expand Down Expand Up @@ -1089,6 +1095,28 @@ public Blob get(String blob, BlobGetOption... options) {
return storage.get(BlobId.of(getName(), blob), options);
}

/**
* Returns the requested blob in this bucket of a specific generation or {@code null} if not
* found.
*
* <p>Example of getting a blob of a specific in the bucket.
*
* <pre>{@code
* String blobName = "my_blob_name";
* long generation = 42;
* Blob blob = bucket.get(blobName, generation);
* }</pre>
*
* @param blob name of the requested blob
* @param generation the generation to get
* @param options blob search options
* @throws StorageException upon failure
*/
@TransportCompatibility({Transport.HTTP, Transport.GRPC})
public Blob get(String blob, Long generation, BlobGetOption... options) {
return storage.get(BlobId.of(getName(), blob, generation), options);
}

/**
* Returns a list of requested blobs in this bucket. Blobs that do not exist are null.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ public class BucketInfo implements Serializable {
private final ObjectRetention objectRetention;
private final HierarchicalNamespace hierarchicalNamespace;

private final SoftDeletePolicy softDeletePolicy;

private final transient ImmutableSet<NamedField> modifiedFields;

/**
Expand Down Expand Up @@ -350,6 +352,90 @@ public String toString() {
}
}

/**
* The bucket's soft delete policy. If this policy is set, any deleted objects will be
* soft-deleted according to the time specified in the policy
*/
public static class SoftDeletePolicy implements Serializable {

private static final long serialVersionUID = -8100190443052242908L;
private Duration retentionDuration;
private OffsetDateTime effectiveTime;

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

@Override
public int hashCode() {
return Objects.hash(retentionDuration, effectiveTime);
}

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

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

public Builder toBuilder() {
return new Builder().setRetentionDuration(retentionDuration).setEffectiveTime(effectiveTime);
}

private SoftDeletePolicy() {}

public SoftDeletePolicy(Builder builder) {
this.retentionDuration = builder.retentionDuration;
this.effectiveTime = builder.effectiveTime;
}

public Duration getRetentionDuration() {
return retentionDuration;
}

public OffsetDateTime getEffectiveTime() {
return effectiveTime;
}

public static final class Builder {
private Duration retentionDuration;
private OffsetDateTime effectiveTime;

/** Sets the length of time to retain soft-deleted objects for, expressed as a Duration */
public Builder setRetentionDuration(Duration retentionDuration) {
this.retentionDuration = retentionDuration;
return this;
}

/**
* Sets the time from which this soft-delete policy is effective. This is package-private
* because it can only be set by the backend.
*/
Builder setEffectiveTime(OffsetDateTime effectiveTime) {
this.effectiveTime = effectiveTime;
return this;
}

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

/**
* Configuration for the Autoclass settings of a bucket.
*
Expand Down Expand Up @@ -1753,6 +1839,8 @@ public Builder setRetentionPeriodDuration(Duration retentionPeriod) {

abstract Builder setObjectRetention(ObjectRetention objectRetention);

public abstract Builder setSoftDeletePolicy(SoftDeletePolicy softDeletePolicy);

/** Creates a {@code BucketInfo} object. */
public abstract BucketInfo build();

Expand Down Expand Up @@ -1851,6 +1939,8 @@ static final class BuilderImpl extends Builder {
private Logging logging;
private CustomPlacementConfig customPlacementConfig;
private ObjectRetention objectRetention;

private SoftDeletePolicy softDeletePolicy;
private HierarchicalNamespace hierarchicalNamespace;
private final ImmutableSet.Builder<NamedField> modifiedFields = ImmutableSet.builder();

Expand Down Expand Up @@ -1891,6 +1981,7 @@ static final class BuilderImpl extends Builder {
logging = bucketInfo.logging;
customPlacementConfig = bucketInfo.customPlacementConfig;
objectRetention = bucketInfo.objectRetention;
softDeletePolicy = bucketInfo.softDeletePolicy;
hierarchicalNamespace = bucketInfo.hierarchicalNamespace;
}

Expand Down Expand Up @@ -2257,6 +2348,15 @@ Builder setObjectRetention(ObjectRetention objectRetention) {
return this;
}

@Override
public Builder setSoftDeletePolicy(SoftDeletePolicy softDeletePolicy) {
if (!Objects.equals(this.softDeletePolicy, softDeletePolicy)) {
modifiedFields.add(BucketField.SOFT_DELETE_POLICY);
}
this.softDeletePolicy = softDeletePolicy;
return this;
}

@Override
public Builder setHierarchicalNamespace(HierarchicalNamespace hierarchicalNamespace) {
if (!Objects.equals(this.hierarchicalNamespace, hierarchicalNamespace)) {
Expand Down Expand Up @@ -2507,6 +2607,7 @@ private Builder clearDeleteLifecycleRules() {
logging = builder.logging;
customPlacementConfig = builder.customPlacementConfig;
objectRetention = builder.objectRetention;
softDeletePolicy = builder.softDeletePolicy;
hierarchicalNamespace = builder.hierarchicalNamespace;
modifiedFields = builder.modifiedFields.build();
}
Expand Down Expand Up @@ -2848,6 +2949,11 @@ public ObjectRetention getObjectRetention() {
return objectRetention;
}

/** returns the Soft Delete policy */
public SoftDeletePolicy getSoftDeletePolicy() {
return softDeletePolicy;
}

/** Returns the Hierarchical Namespace (Folders) Configuration */
public HierarchicalNamespace getHierarchicalNamespace() {
return hierarchicalNamespace;
Expand Down Expand Up @@ -2890,6 +2996,7 @@ public int hashCode() {
autoclass,
locationType,
objectRetention,
softDeletePolicy,
hierarchicalNamespace,
logging);
}
Expand Down Expand Up @@ -2932,6 +3039,7 @@ public boolean equals(Object o) {
&& Objects.equals(autoclass, that.autoclass)
&& Objects.equals(locationType, that.locationType)
&& Objects.equals(objectRetention, that.objectRetention)
&& Objects.equals(softDeletePolicy, that.softDeletePolicy)
&& Objects.equals(hierarchicalNamespace, that.hierarchicalNamespace)
&& Objects.equals(logging, that.logging);
}
Expand Down
Loading

0 comments on commit 989f36f

Please sign in to comment.