Skip to content

Commit 65357aa

Browse files
author
Frank Natividad
committed
Add support for blob temporary holds
1 parent 23c27bc commit 65357aa

6 files changed

Lines changed: 80 additions & 5 deletions

File tree

google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/Blob.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,12 @@ public Builder setEventBasedHold(Boolean eventBasedHold) {
415415
return this;
416416
}
417417

418+
@Override
419+
public Builder setTemporaryHold(Boolean temporaryHold) {
420+
infoBuilder.setTemporaryHold(temporaryHold);
421+
return this;
422+
}
423+
418424
@Override
419425
public Blob build() {
420426
return new Blob(storage, infoBuilder);

google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobInfo.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public StorageObject apply(BlobInfo blobInfo) {
8686
private final CustomerEncryption customerEncryption;
8787
private final String kmsKeyName;
8888
private final Boolean eventBasedHold;
89+
private final Boolean temporaryHold;
8990

9091
/**
9192
* This class is meant for internal use only. Users are discouraged from using this class.
@@ -281,6 +282,10 @@ public abstract static class Builder {
281282
*/
282283
public abstract Builder setEventBasedHold(Boolean eventBasedHold);
283284

285+
/**
286+
* Sets the blob's temporaryHold.
287+
*/
288+
public abstract Builder setTemporaryHold(Boolean temporaryHold);
284289

285290
/**
286291
* Creates a {@code BlobInfo} object.
@@ -316,6 +321,7 @@ static final class BuilderImpl extends Builder {
316321
private StorageClass storageClass;
317322
private String kmsKeyName;
318323
private Boolean eventBasedHold;
324+
private Boolean temporaryHold;
319325

320326
BuilderImpl(BlobId blobId) {
321327
this.blobId = blobId;
@@ -348,6 +354,7 @@ static final class BuilderImpl extends Builder {
348354
storageClass = blobInfo.storageClass;
349355
kmsKeyName = blobInfo.kmsKeyName;
350356
eventBasedHold = blobInfo.eventBasedHold;
357+
temporaryHold = blobInfo.temporaryHold;
351358
}
352359

353360
@Override
@@ -508,6 +515,12 @@ public Builder setEventBasedHold(Boolean eventBasedHold) {
508515
return this;
509516
}
510517

518+
@Override
519+
public Builder setTemporaryHold(Boolean temporaryHold) {
520+
this.temporaryHold = temporaryHold;
521+
return this;
522+
}
523+
511524
@Override
512525
public BlobInfo build() {
513526
checkNotNull(blobId);
@@ -542,6 +555,7 @@ public BlobInfo build() {
542555
storageClass = builder.storageClass;
543556
kmsKeyName = builder.kmsKeyName;
544557
eventBasedHold = builder.eventBasedHold;
558+
temporaryHold = builder.temporaryHold;
545559
}
546560

547561
/**
@@ -780,8 +794,16 @@ public String getKmsKeyName() {
780794
return kmsKeyName;
781795
}
782796

797+
/**
798+
* Returns the Event Based Hold status of the blob, if any.
799+
*/
783800
public Boolean getEventBasedHold() { return eventBasedHold; }
784801

802+
/**
803+
* Returns the Temporary Hold status of the blob, if any.
804+
*/
805+
public Boolean getTemporaryHold() { return temporaryHold; }
806+
785807
/**
786808
* Returns a builder for the current blob.
787809
*/
@@ -857,6 +879,7 @@ public ObjectAccessControl apply(Acl acl) {
857879

858880
storageObject.setKmsKeyName(kmsKeyName);
859881
storageObject.setEventBasedHold(eventBasedHold);
882+
storageObject.setTemporaryHold(temporaryHold);
860883
storageObject.setMetadata(pbMetadata);
861884
storageObject.setCacheControl(cacheControl);
862885
storageObject.setContentEncoding(contentEncoding);
@@ -993,6 +1016,9 @@ public Acl apply(ObjectAccessControl objectAccessControl) {
9931016
if (storageObject.getEventBasedHold() != null) {
9941017
builder.setEventBasedHold(storageObject.getEventBasedHold());
9951018
}
1019+
if (storageObject.getTemporaryHold() != null) {
1020+
builder.setTemporaryHold(storageObject.getTemporaryHold());
1021+
}
9961022
return builder.build();
9971023
}
9981024
}

google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ enum BlobField implements FieldSelector {
140140
@GcpLaunchStage.Beta
141141
KMS_KEY_NAME("kmsKeyName"),
142142
EVENT_BASED_HOLD("eventBasedHold"),
143+
TEMPORARY_HOLD("temporaryHold"),
143144
UPDATED("updated");
144145

145146
static final List<? extends FieldSelector> REQUIRED_FIELDS = ImmutableList.of(BUCKET, NAME);

google-cloud-clients/google-cloud-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public class BlobInfoTest {
6969
private static final String KMS_KEY_NAME = "projects/p/locations/kr-loc/keyRings/kr/cryptoKeys/key";
7070
private static final StorageClass STORAGE_CLASS = StorageClass.COLDLINE;
7171
private static final Boolean EVENT_BASED_HOLD = true;
72+
private static final Boolean TEMPORARY_HOLD = true;
7273

7374
private static final BlobInfo BLOB_INFO = BlobInfo.newBuilder("b", "n", GENERATION)
7475
.setAcl(ACL)
@@ -95,6 +96,7 @@ public class BlobInfoTest {
9596
.setStorageClass(STORAGE_CLASS)
9697
.setKmsKeyName(KMS_KEY_NAME)
9798
.setEventBasedHold(EVENT_BASED_HOLD)
99+
.setTemporaryHold(TEMPORARY_HOLD)
98100
.build();
99101
private static final BlobInfo DIRECTORY_INFO = BlobInfo.newBuilder("b", "n/")
100102
.setSize(0L)
@@ -159,6 +161,7 @@ public void testBuilder() {
159161
assertEquals(STORAGE_CLASS, BLOB_INFO.getStorageClass());
160162
assertEquals(KMS_KEY_NAME, BLOB_INFO.getKmsKeyName());
161163
assertEquals(EVENT_BASED_HOLD, BLOB_INFO.getEventBasedHold());
164+
assertEquals(TEMPORARY_HOLD, BLOB_INFO.getTemporaryHold());
162165
assertFalse(BLOB_INFO.isDirectory());
163166
assertEquals("b", DIRECTORY_INFO.getBucket());
164167
assertEquals("n/", DIRECTORY_INFO.getName());
@@ -216,6 +219,7 @@ private void compareBlobs(BlobInfo expected, BlobInfo value) {
216219
assertEquals(expected.getStorageClass(), value.getStorageClass());
217220
assertEquals(expected.getKmsKeyName(), value.getKmsKeyName());
218221
assertEquals(expected.getEventBasedHold(), value.getEventBasedHold());
222+
assertEquals(expected.getTemporaryHold(), value.getTemporaryHold());
219223
}
220224

221225
private void compareCustomerEncryptions(CustomerEncryption expected, CustomerEncryption value) {
@@ -265,6 +269,7 @@ public void testToPbAndFromPb() {
265269
assertNull(blobInfo.getStorageClass());
266270
assertNull(blobInfo.getKmsKeyName());
267271
assertNull(blobInfo.getEventBasedHold());
272+
assertNull(blobInfo.getTemporaryHold());
268273
assertTrue(blobInfo.isDirectory());
269274
}
270275

google-cloud-clients/google-cloud-storage/src/test/java/com/google/cloud/storage/BlobTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public class BlobTest {
9393
new BlobInfo.CustomerEncryption(ENCRYPTION_ALGORITHM, KEY_SHA256);
9494
private static final String KMS_KEY_NAME = "projects/p/locations/kr-loc/keyRings/kr/cryptoKeys/key";
9595
private static final Boolean EVENT_BASED_HOLD = true;
96+
private static final Boolean TEMPORARY_HOLD = true;
9697
private static final BlobInfo FULL_BLOB_INFO = BlobInfo.newBuilder("b", "n", GENERATION)
9798
.setAcl(ACLS)
9899
.setComponentCount(COMPONENT_COUNT)
@@ -117,6 +118,7 @@ public class BlobTest {
117118
.setCustomerEncryption(CUSTOMER_ENCRYPTION)
118119
.setKmsKeyName(KMS_KEY_NAME)
119120
.setEventBasedHold(EVENT_BASED_HOLD)
121+
.setTemporaryHold(TEMPORARY_HOLD)
120122
.build();
121123
private static final BlobInfo BLOB_INFO = BlobInfo.newBuilder("b", "n")
122124
.setMetageneration(42L)
@@ -475,6 +477,7 @@ public void testBuilder() {
475477
.setCustomerEncryption(CUSTOMER_ENCRYPTION)
476478
.setKmsKeyName(KMS_KEY_NAME)
477479
.setEventBasedHold(EVENT_BASED_HOLD)
480+
.setTemporaryHold(TEMPORARY_HOLD)
478481
.setDeleteTime(DELETE_TIME)
479482
.setEtag(ETAG)
480483
.setGeneratedId(GENERATED_ID)
@@ -501,6 +504,7 @@ public void testBuilder() {
501504
assertEquals(CUSTOMER_ENCRYPTION, blob.getCustomerEncryption());
502505
assertEquals(KMS_KEY_NAME, blob.getKmsKeyName());
503506
assertEquals(EVENT_BASED_HOLD, blob.getEventBasedHold());
507+
assertEquals(TEMPORARY_HOLD, blob.getTemporaryHold());
504508
assertEquals(DELETE_TIME, blob.getDeleteTime());
505509
assertEquals(ETAG, blob.getEtag());
506510
assertEquals(GENERATED_ID, blob.getGeneratedId());
@@ -533,6 +537,7 @@ public void testBuilder() {
533537
assertNull(blob.getCustomerEncryption());
534538
assertNull(blob.getKmsKeyName());
535539
assertNull(blob.getEventBasedHold());
540+
assertNull(blob.getTemporaryHold());
536541
assertNull(blob.getDeleteTime());
537542
assertNull(blob.getEtag());
538543
assertNull(blob.getGeneratedId());

google-cloud-clients/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -223,18 +223,34 @@ public void testCreateDefaultEventBasedHoldBucket() throws ExecutionException, I
223223

224224
@Test
225225
public void testEnableDisableBucketDefaultEventBasedHold() {
226-
Bucket remoteBucket = storage.get(BUCKET, Storage.BucketGetOption.fields(BucketField.DEFAULT_EVENT_BASED_HOLD, BucketField.BILLING));
226+
Bucket remoteBucket = storage.get(BUCKET, Storage.BucketGetOption.fields(BucketField.DEFAULT_EVENT_BASED_HOLD));
227227
assertNull(remoteBucket.getDefaultEventBasedHold());
228-
Bucket updatedBucket = remoteBucket.toBuilder().setDefaultEventBasedHold(true).build().update();
229-
assertTrue(updatedBucket.getDefaultEventBasedHold());
228+
remoteBucket = remoteBucket.toBuilder().setDefaultEventBasedHold(true).build().update();
229+
assertTrue(remoteBucket.getDefaultEventBasedHold());
230+
remoteBucket = storage.get(BUCKET, Storage.BucketGetOption.fields(BucketField.DEFAULT_EVENT_BASED_HOLD));
231+
assertTrue(remoteBucket.getDefaultEventBasedHold());
230232
String blobName = "test-create-with-event-based-hold";
231233
BlobInfo blobInfo = BlobInfo.newBuilder(BUCKET, blobName).build();
232234
Blob remoteBlob = storage.create(blobInfo);
233235
assertTrue(remoteBlob.getEventBasedHold());
236+
remoteBlob = storage.get(blobInfo.getBlobId(), Storage.BlobGetOption.fields(BlobField.EVENT_BASED_HOLD));
237+
assertTrue(remoteBlob.getEventBasedHold());
234238
remoteBlob = remoteBlob.toBuilder().setEventBasedHold(false).build().update();
235239
assertFalse(remoteBlob.getEventBasedHold());
236-
updatedBucket = remoteBucket.toBuilder().setDefaultEventBasedHold(false).build().update().reload();
237-
assertFalse(updatedBucket.getDefaultEventBasedHold());
240+
remoteBucket = remoteBucket.toBuilder().setDefaultEventBasedHold(false).build().update();
241+
assertFalse(remoteBucket.getDefaultEventBasedHold());
242+
}
243+
244+
@Test
245+
public void testEnableDisableTemporaryHold() {
246+
String blobName = "test-create-with-event-based-hold";
247+
BlobInfo blobInfo = BlobInfo.newBuilder(BUCKET, blobName).setTemporaryHold(true).build();
248+
Blob remoteBlob = storage.create(blobInfo);
249+
assertTrue(remoteBlob.getTemporaryHold());
250+
remoteBlob = storage.get(remoteBlob.getBlobId(), Storage.BlobGetOption.fields(BlobField.TEMPORARY_HOLD));
251+
assertTrue(remoteBlob.getTemporaryHold());
252+
remoteBlob = remoteBlob.toBuilder().setTemporaryHold(false).build().update();
253+
assertFalse(remoteBlob.getTemporaryHold());
238254
}
239255

240256
@Test
@@ -251,6 +267,22 @@ public void testAttemptDeletionObjectEventBasedHold() {
251267
}
252268
}
253269

270+
@Test
271+
public void testAttemptDeletionObjectTemporaryHold() {
272+
String blobName = "test-create-with-temporary-hold";
273+
BlobInfo blobInfo = BlobInfo.newBuilder(BUCKET, blobName).setTemporaryHold(true).build();
274+
Blob remoteBlob = storage.create(blobInfo);
275+
assertTrue(remoteBlob.getTemporaryHold());
276+
remoteBlob = storage.get(remoteBlob.getBlobId(), Storage.BlobGetOption.fields(BlobField.TEMPORARY_HOLD));
277+
assertTrue(remoteBlob.getTemporaryHold());
278+
try {
279+
remoteBlob.delete();
280+
fail("Expected failure on delete from temporaryHold");
281+
} catch (StorageException ex) {
282+
// expected
283+
}
284+
}
285+
254286
@Test
255287
public void testCreateBlob() {
256288
String blobName = "test-create-blob";

0 commit comments

Comments
 (0)