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: delete bucket OLM rules #352

Merged
merged 11 commits into from Jun 16, 2020
7 changes: 6 additions & 1 deletion google-cloud-storage/clirr-ignored-differences.xml
Expand Up @@ -21,4 +21,9 @@
<method>com.google.cloud.storage.PostPolicyV4 generateSignedPostPolicyV4(com.google.cloud.storage.BlobInfo, long, java.util.concurrent.TimeUnit, com.google.cloud.storage.Storage$PostPolicyV4Option[])</method>
<differenceType>7012</differenceType>
</difference>
</differences>
<difference>
<className>com/google/cloud/storage/Storage</className>
<method>java.util.List deleteLifecycleRules(java.lang.String, com.google.cloud.storage.BucketInfo$LifecycleRule[])</method>
<differenceType>7012</differenceType>
</difference>
</differences>
Expand Up @@ -1114,6 +1114,45 @@ public boolean deleteDefaultAcl(Entity entity) {
return storage.deleteDefaultAcl(getName(), entity);
}

/**
* Deletes the lifecycle rules of this bucket.
*
* <p>Example of deleting the lifecycle rules of this bucket:
*
* <pre>{@code
* String bucketName = "my-unique-bucket";
* LifecycleRule lifecycleRule_1 =
* new LifecycleRule(
* LifecycleAction.newSetStorageClassAction(StorageClass.COLDLINE),
* LifecycleCondition.newBuilder()
* .setAge(1)
* .setNumberOfNewerVersions(3)
* .setIsLive(false)
* .setMatchesStorageClass(ImmutableList.of(StorageClass.COLDLINE))
* .build());
* LifecycleRule lifecycleRule_2 =
* new LifecycleRule(
* LifecycleAction.newDeleteAction(), LifecycleCondition.newBuilder().setAge(1).build());
* ImmutableList<LifecycleRule> lifecycleRules =
* ImmutableList.of(lifecycleRule_1, lifecycleRule_2);
* Bucket bucket =
* storage.create(
* BucketInfo.newBuilder(bucketName)
* .setLocation("us")
* .setLifecycleRules(lifecycleRules)
* .build());
* Map<LifecycleRule, Boolean> results = storage.deleteLifecycleRules(lifecycleTestBucket, lifecycleRule_1);
* }</pre>
*
* @param rulesToDelete the set of lifecycle rules to delete
* @return the lists of deleted lifecycle rules of bucket, an empty list if the requested
* lifecycle rules was not found
* @throws StorageException upon failure
*/
public List<LifecycleRule> deleteLifecycleRules(LifecycleRule... rulesToDelete) {
return storage.deleteLifecycleRules(getName(), rulesToDelete);
}

/**
* Creates a new default blob ACL entry on this bucket.
*
Expand Down
Expand Up @@ -1181,13 +1181,15 @@ public Builder setNotFoundPage(String notFoundPage) {
@Override
@Deprecated
public Builder setDeleteRules(Iterable<? extends DeleteRule> rules) {
this.deleteRules = rules != null ? ImmutableList.copyOf(rules) : null;
this.deleteRules =
rules != null ? ImmutableList.copyOf(rules) : ImmutableList.<DeleteRule>of();
athakor marked this conversation as resolved.
Show resolved Hide resolved
return this;
}

@Override
public Builder setLifecycleRules(Iterable<? extends LifecycleRule> rules) {
this.lifecycleRules = rules != null ? ImmutableList.copyOf(rules) : null;
this.lifecycleRules =
rules != null ? ImmutableList.copyOf(rules) : ImmutableList.<LifecycleRule>of();
athakor marked this conversation as resolved.
Show resolved Hide resolved
return this;
}

Expand Down Expand Up @@ -1430,11 +1432,11 @@ public String getNotFoundPage() {
*/
@Deprecated
public List<? extends DeleteRule> getDeleteRules() {
return deleteRules;
return deleteRules != null ? deleteRules : ImmutableList.<DeleteRule>of();
athakor marked this conversation as resolved.
Show resolved Hide resolved
}

public List<? extends LifecycleRule> getLifecycleRules() {
return lifecycleRules;
return lifecycleRules != null ? lifecycleRules : ImmutableList.<LifecycleRule>of();
}

/**
Expand Down Expand Up @@ -1711,7 +1713,7 @@ public Rule apply(LifecycleRule lifecycleRule) {
}
}));
}
if (!rules.isEmpty()) {
if (rules != null) {
Lifecycle lifecycle = new Lifecycle();
lifecycle.setRule(ImmutableList.copyOf(rules));
bucketPb.setLifecycle(lifecycle);
Expand Down
Expand Up @@ -31,6 +31,7 @@
import com.google.cloud.Tuple;
import com.google.cloud.WriteChannel;
import com.google.cloud.storage.Acl.Entity;
import com.google.cloud.storage.BucketInfo.LifecycleRule;
import com.google.cloud.storage.HmacKey.HmacKeyMetadata;
import com.google.cloud.storage.PostPolicyV4.PostConditionsV4;
import com.google.cloud.storage.PostPolicyV4.PostFieldsV4;
Expand Down Expand Up @@ -1999,7 +2000,6 @@ Blob create(
* only if supplied Decrpytion Key decrypts the blob successfully, otherwise a {@link
* StorageException} is thrown. For more information review
*
* @throws StorageException upon failure
athakor marked this conversation as resolved.
Show resolved Hide resolved
* @see <a
* href="https://cloud.google.com/storage/docs/encryption/customer-supplied-keys#encrypted-elements">Encrypted
* Elements</a>
Expand Down Expand Up @@ -3076,6 +3076,44 @@ PostPolicyV4 generateSignedPostPolicyV4(
*/
boolean deleteDefaultAcl(String bucket, Entity entity);

/**
* Deletes the lifecycle rules of the requested bucket.
*
* <p>Example of deleting the lifecycle rules of the requested bucket:
*
* <pre>{@code
* String bucketName = "my-unique-bucket";
* LifecycleRule lifecycleRule_1 =
* new LifecycleRule(
* LifecycleAction.newSetStorageClassAction(StorageClass.COLDLINE),
* LifecycleCondition.newBuilder()
* .setAge(1)
* .setNumberOfNewerVersions(3)
* .setIsLive(false)
* .setMatchesStorageClass(ImmutableList.of(StorageClass.COLDLINE))
* .build());
* LifecycleRule lifecycleRule_2 =
* new LifecycleRule(
* LifecycleAction.newDeleteAction(), LifecycleCondition.newBuilder().setAge(1).build());
* ImmutableList<LifecycleRule> lifecycleRules =
* ImmutableList.of(lifecycleRule_1, lifecycleRule_2);
* Bucket bucket =
* storage.create(
* BucketInfo.newBuilder(bucketName)
* .setLocation("us")
* .setLifecycleRules(lifecycleRules)
* .build());
* Map<LifecycleRule, Boolean> results = storage.deleteLifecycleRules(lifecycleTestBucket, lifecycleRule_1);
* }</pre>
*
* @param bucket name of the bucket
* @param rulesToDelete the set of lifecycle rules to delete
* @return the lists of deleted lifecycle rules of bucket, an empty list if the requested
* lifecycle rules was not found
* @throws StorageException upon failure
*/
List<LifecycleRule> deleteLifecycleRules(String bucket, LifecycleRule... rulesToDelete);

/**
* Creates a new default blob ACL entry on the specified bucket.
*
Expand Down
Expand Up @@ -49,6 +49,7 @@
import com.google.cloud.RetryHelper.RetryHelperException;
import com.google.cloud.Tuple;
import com.google.cloud.storage.Acl.Entity;
import com.google.cloud.storage.BucketInfo.LifecycleRule;
import com.google.cloud.storage.HmacKey.HmacKeyMetadata;
import com.google.cloud.storage.PostPolicyV4.ConditionV4Type;
import com.google.cloud.storage.PostPolicyV4.PostConditionsV4;
Expand Down Expand Up @@ -77,10 +78,12 @@
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -1279,6 +1282,37 @@ public Boolean call() {
}
}

@Override
public List<LifecycleRule> deleteLifecycleRules(String bucket, LifecycleRule... rulesToDelete) {
final Storage storage = getOptions().getService();
final List<LifecycleRule> results = Lists.newArrayList();
try {
Bucket remoteBucket =
storage.get(bucket, Storage.BucketGetOption.fields(Storage.BucketField.LIFECYCLE));
List<LifecycleRule> lifecycleRules = new ArrayList(remoteBucket.getLifecycleRules());
for (Iterator<LifecycleRule> iterator = lifecycleRules.iterator(); iterator.hasNext(); ) {
LifecycleRule lifecycleRule = iterator.next();
for (LifecycleRule ruleToDelete : rulesToDelete) {
if (lifecycleRule.equals(ruleToDelete)) {
iterator.remove();
results.add(ruleToDelete);
}
}
}
if (results.size() > 0) {
storage
.get(bucket, Storage.BucketGetOption.fields())
.toBuilder()
.setLifecycleRules(lifecycleRules)
.build()
.update();
}
return Collections.unmodifiableList(results);
} catch (StorageException ex) {
throw ex;
}
}

@Override
public Acl createDefaultAcl(String bucket, Acl acl) {
final ObjectAccessControl aclPb = acl.toObjectPb().setBucket(bucket);
Expand Down
Expand Up @@ -17,6 +17,7 @@
package com.google.cloud.storage;

import static com.google.cloud.storage.Acl.Role.WRITER;
import static com.google.common.truth.Truth.assertThat;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.createStrictMock;
import static org.easymock.EasyMock.expect;
Expand Down Expand Up @@ -649,6 +650,35 @@ public void testDeleteAcl() throws Exception {
assertTrue(bucket.deleteAcl(User.ofAllAuthenticatedUsers()));
}

@Test
public void testDeleteLifecycleRules() {
List<LifecycleRule> expectedResults = ImmutableList.of(LIFECYCLE_RULES.get(0));
expect(storage.getOptions()).andReturn(mockOptions).times(1);
expect(storage.deleteLifecycleRules(FULL_BUCKET_INFO.getName(), LIFECYCLE_RULES.get(0)))
.andReturn(expectedResults);
replay(storage);
initializeBucket();
List<LifecycleRule> actualResults = bucket.deleteLifecycleRules(LIFECYCLE_RULES.get(0));
assertThat(actualResults).hasSize(1);
assertThat(actualResults.get(0)).isEqualTo(LIFECYCLE_RULES.get(0));
}

@Test
public void testDeleteNonExistingLifecycleRule() {
List<LifecycleRule> expectedResults = ImmutableList.of();
LifecycleRule nonExistingLifecycleRule =
new LifecycleRule(
LifecycleAction.newSetStorageClassAction(StorageClass.ARCHIVE),
LifecycleCondition.newBuilder().setAge(10).build());
expect(storage.getOptions()).andReturn(mockOptions).times(1);
expect(storage.deleteLifecycleRules(FULL_BUCKET_INFO.getName(), nonExistingLifecycleRule))
.andReturn(expectedResults);
replay(storage);
initializeBucket();
List<LifecycleRule> actualResults = bucket.deleteLifecycleRules(nonExistingLifecycleRule);
assertThat(actualResults).isEmpty();
}

@Test
public void testCreateAcl() throws Exception {
initializeExpectedBucket(4);
Expand Down
Expand Up @@ -181,6 +181,20 @@ public class ITStorageTest {
&& System.getenv("GOOGLE_CLOUD_TESTS_IN_VPCSC").equalsIgnoreCase("true");
private static final List<String> LOCATION_TYPES =
ImmutableList.of("multi-region", "region", "dual-region");
private static final LifecycleRule LIFECYCLE_RULE_1 =
new LifecycleRule(
LifecycleAction.newSetStorageClassAction(StorageClass.COLDLINE),
LifecycleCondition.newBuilder()
.setAge(1)
.setNumberOfNewerVersions(3)
.setIsLive(false)
.setMatchesStorageClass(ImmutableList.of(StorageClass.COLDLINE))
.build());
private static final LifecycleRule LIFECYCLE_RULE_2 =
new LifecycleRule(
LifecycleAction.newDeleteAction(), LifecycleCondition.newBuilder().setAge(1).build());
private static final ImmutableList<LifecycleRule> LIFECYCLE_RULES =
ImmutableList.of(LIFECYCLE_RULE_1, LIFECYCLE_RULE_2);

@BeforeClass
public static void beforeClass() throws IOException {
Expand Down Expand Up @@ -3273,4 +3287,70 @@ public void testBlobReload() throws Exception {
updated.delete();
assertNull(updated.reload());
}

@Test
public void testDeleteIndividualLifecycleRules() throws ExecutionException, InterruptedException {
String bucketName = RemoteStorageHelper.generateBucketName();
Bucket bucket =
storage.create(
BucketInfo.newBuilder(bucketName)
.setLocation("us")
.setLifecycleRules(LIFECYCLE_RULES)
.build());
assertThat(bucket.getName()).isEqualTo(bucketName);
assertThat(bucket.getLifecycleRules()).hasSize(2);
try {
List<LifecycleRule> results = storage.deleteLifecycleRules(bucketName, LIFECYCLE_RULE_1);
assertThat(results).hasSize(1);
assertThat(results.get(0)).isEqualTo(LIFECYCLE_RULE_1);
} finally {
RemoteStorageHelper.forceDelete(storage, bucketName, 5, TimeUnit.SECONDS);
}
}

@Test
public void testDeleteAllLifecycleRules() throws ExecutionException, InterruptedException {
String bucketName = RemoteStorageHelper.generateBucketName();
Bucket bucket =
storage.create(
BucketInfo.newBuilder(bucketName)
.setLocation("us")
.setLifecycleRules(LIFECYCLE_RULES)
.build());
assertThat(bucket.getName()).isEqualTo(bucketName);
assertThat(bucket.getLifecycleRules()).hasSize(2);
try {
List<LifecycleRule> results =
storage.deleteLifecycleRules(bucketName, LIFECYCLE_RULE_1, LIFECYCLE_RULE_2);
assertThat(results).hasSize(2);
assertThat(results).contains(LIFECYCLE_RULE_1);
assertThat(results).contains(LIFECYCLE_RULE_2);
} finally {
RemoteStorageHelper.forceDelete(storage, bucketName, 5, TimeUnit.SECONDS);
}
}

@Test
public void testDeleteNonExistingLifecycleRule() throws ExecutionException, InterruptedException {
String bucketName = RemoteStorageHelper.generateBucketName();
LifecycleRule nonExistingLifecycleRule =
new LifecycleRule(
LifecycleAction.newSetStorageClassAction(StorageClass.ARCHIVE),
LifecycleCondition.newBuilder().setAge(10).build());
Bucket bucket =
storage.create(
BucketInfo.newBuilder(bucketName)
.setLocation("us")
.setLifecycleRules(LIFECYCLE_RULES)
.build());
assertThat(bucket.getName()).isEqualTo(bucketName);
assertThat(bucket.getLifecycleRules()).hasSize(2);
try {
List<LifecycleRule> results =
storage.deleteLifecycleRules(bucketName, nonExistingLifecycleRule);
assertThat(results).isEmpty();
} finally {
RemoteStorageHelper.forceDelete(storage, bucketName, 5, TimeUnit.SECONDS);
}
}
athakor marked this conversation as resolved.
Show resolved Hide resolved
}