From 6f4585eb6706390865cf5fb565fa8062d0071045 Mon Sep 17 00:00:00 2001 From: Ajit Thakor <49403056+athakor@users.noreply.github.com> Date: Fri, 28 Aug 2020 04:28:34 +0530 Subject: [PATCH] feat: add support of customTime metadata (#413) * feat: support customTime metadata * feat: add javaDoc * feat: address few nits * feat: fix the api breaking change * Add exception to avoid breaking change * Add exception to avoid breaking change Co-authored-by: Jesse Lovelace --- .../java/com/google/cloud/storage/Blob.java | 6 +++ .../com/google/cloud/storage/BlobInfo.java | 41 +++++++++++++++++++ .../google/cloud/storage/BlobInfoTest.java | 6 +++ .../com/google/cloud/storage/BlobTest.java | 5 +++ .../cloud/storage/it/ITStorageTest.java | 4 +- 5 files changed, 61 insertions(+), 1 deletion(-) diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/Blob.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/Blob.java index 679b410a6..398eb3166 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/Blob.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/Blob.java @@ -434,6 +434,12 @@ Builder setCreateTime(Long createTime) { return this; } + @Override + public Builder setCustomTime(Long customTime) { + infoBuilder.setCustomTime(customTime); + return this; + } + @Override Builder setIsDirectory(boolean isDirectory) { infoBuilder.setIsDirectory(isDirectory); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobInfo.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobInfo.java index ef38ba033..67256d1c7 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobInfo.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobInfo.java @@ -84,6 +84,7 @@ public StorageObject apply(BlobInfo blobInfo) { private final String etag; private final String md5; private final String crc32c; + private final Long customTime; private final String mediaLink; private final Map metadata; private final Long metageneration; @@ -260,6 +261,26 @@ public abstract static class Builder { */ public abstract Builder setCrc32c(String crc32c); + /** + * Sets the custom time for an object. Once set it can't be unset and only changed to a custom + * datetime in the future. To unset the custom time, you must either perform a rewrite operation + * or upload the data again. + * + *

Example of setting the custom time. + * + *

{@code
+     * String bucketName = "my-unique-bucket";
+     * String blobName = "my-blob-name";
+     * long customTime = 1598423868301L;
+     * BlobInfo blob = BlobInfo.newBuilder(bucketName, blobName).setCustomTime(customTime).build();
+     * }
+ */ + public Builder setCustomTime(Long customTime) { + throw new UnsupportedOperationException( + "Override setCustomTime with your own implementation," + + " or use com.google.cloud.storage.Blob."); + } + /** * Sets the CRC32C checksum of blob's data as described in RFC 4960, Appendix B; from hex @@ -325,6 +346,7 @@ static final class BuilderImpl extends Builder { private String selfLink; private String md5; private String crc32c; + private Long customTime; private String mediaLink; private Map metadata; private Long metageneration; @@ -360,6 +382,7 @@ static final class BuilderImpl extends Builder { selfLink = blobInfo.selfLink; md5 = blobInfo.md5; crc32c = blobInfo.crc32c; + customTime = blobInfo.customTime; mediaLink = blobInfo.mediaLink; metadata = blobInfo.metadata; metageneration = blobInfo.metageneration; @@ -488,6 +511,12 @@ public Builder setCrc32c(String crc32c) { return this; } + @Override + public Builder setCustomTime(Long customTime) { + this.customTime = customTime; + return this; + } + @Override public Builder setCrc32cFromHexString(String crc32cHexString) { if (crc32cHexString == null) { @@ -619,6 +648,7 @@ public BlobInfo build() { selfLink = builder.selfLink; md5 = builder.md5; crc32c = builder.crc32c; + customTime = builder.customTime; mediaLink = builder.mediaLink; metadata = builder.metadata; metageneration = builder.metageneration; @@ -857,6 +887,11 @@ public Long getCreateTime() { return createTime; } + /** Returns the custom time specified by the user for an object. */ + public Long getCustomTime() { + return customTime; + } + /** * Returns {@code true} if the current blob represents a directory. This can only happen if the * blob is returned by {@link Storage#list(String, Storage.BlobListOption...)} when the {@link @@ -1002,6 +1037,9 @@ public ObjectAccessControl apply(Acl acl) { if (createTime != null) { storageObject.setTimeCreated(new DateTime(createTime)); } + if (customTime != null) { + storageObject.setCustomTime(new DateTime(customTime)); + } if (size != null) { storageObject.setSize(BigInteger.valueOf(size)); } @@ -1125,6 +1163,9 @@ static BlobInfo fromPb(StorageObject storageObject) { if (storageObject.getTimeCreated() != null) { builder.setCreateTime(storageObject.getTimeCreated().getValue()); } + if (storageObject.getCustomTime() != null) { + builder.setCustomTime(storageObject.getCustomTime().getValue()); + } if (storageObject.getSize() != null) { builder.setSize(storageObject.getSize().longValue()); } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java index ea4f6dbda..d4119971f 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java @@ -67,6 +67,7 @@ public class BlobInfoTest { private static final Long SIZE = 1024L; private static final Long UPDATE_TIME = DELETE_TIME - 1L; private static final Long CREATE_TIME = UPDATE_TIME - 1L; + private static final Long CUSTOM_TIME = CREATE_TIME - 1L; private static final String ENCRYPTION_ALGORITHM = "AES256"; private static final String KEY_SHA256 = "keySha"; private static final CustomerEncryption CUSTOMER_ENCRYPTION = @@ -101,6 +102,7 @@ public class BlobInfoTest { .setSize(SIZE) .setUpdateTime(UPDATE_TIME) .setCreateTime(CREATE_TIME) + .setCustomTime(CUSTOM_TIME) .setStorageClass(STORAGE_CLASS) .setKmsKeyName(KMS_KEY_NAME) .setEventBasedHold(EVENT_BASED_HOLD) @@ -195,6 +197,7 @@ public void testBuilder() { assertEquals(SIZE, BLOB_INFO.getSize()); assertEquals(UPDATE_TIME, BLOB_INFO.getUpdateTime()); assertEquals(CREATE_TIME, BLOB_INFO.getCreateTime()); + assertEquals(CUSTOM_TIME, BLOB_INFO.getCustomTime()); assertEquals(STORAGE_CLASS, BLOB_INFO.getStorageClass()); assertEquals(KMS_KEY_NAME, BLOB_INFO.getKmsKeyName()); assertEquals(EVENT_BASED_HOLD, BLOB_INFO.getEventBasedHold()); @@ -214,6 +217,7 @@ public void testBuilder() { assertNull(DIRECTORY_INFO.getCrc32c()); assertNull(DIRECTORY_INFO.getCrc32cToHexString()); assertNull(DIRECTORY_INFO.getCreateTime()); + assertNull(DIRECTORY_INFO.getCustomTime()); assertNull(DIRECTORY_INFO.getDeleteTime()); assertNull(DIRECTORY_INFO.getEtag()); assertNull(DIRECTORY_INFO.getGeneration()); @@ -257,6 +261,7 @@ private void compareBlobs(BlobInfo expected, BlobInfo value) { assertEquals(expected.getOwner(), value.getOwner()); assertEquals(expected.getSelfLink(), value.getSelfLink()); assertEquals(expected.getSize(), value.getSize()); + assertEquals(expected.getCustomTime(), value.getCustomTime()); assertEquals(expected.getUpdateTime(), value.getUpdateTime()); assertEquals(expected.getStorageClass(), value.getStorageClass()); assertEquals(expected.getKmsKeyName(), value.getKmsKeyName()); @@ -299,6 +304,7 @@ public void testToPbAndFromPb() { assertNull(blobInfo.getCrc32c()); assertNull(blobInfo.getCrc32cToHexString()); assertNull(blobInfo.getCreateTime()); + assertNull(blobInfo.getCustomTime()); assertNull(blobInfo.getDeleteTime()); assertNull(blobInfo.getEtag()); assertNull(blobInfo.getGeneration()); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/BlobTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/BlobTest.java index 7ff384fb9..2ff21b712 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/BlobTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/BlobTest.java @@ -91,6 +91,7 @@ public class BlobTest { private static final Long SIZE = 1024L; private static final Long UPDATE_TIME = DELETE_TIME - 1L; private static final Long CREATE_TIME = UPDATE_TIME - 1L; + private static final Long CUSTOM_TIME = CREATE_TIME - 1L; private static final String ENCRYPTION_ALGORITHM = "AES256"; private static final String KEY_SHA256 = "keySha"; private static final BlobInfo.CustomerEncryption CUSTOMER_ENCRYPTION = @@ -122,6 +123,7 @@ public class BlobTest { .setSize(SIZE) .setUpdateTime(UPDATE_TIME) .setCreateTime(CREATE_TIME) + .setCustomTime(CUSTOM_TIME) .setCustomerEncryption(CUSTOMER_ENCRYPTION) .setKmsKeyName(KMS_KEY_NAME) .setEventBasedHold(EVENT_BASED_HOLD) @@ -510,6 +512,7 @@ public void testBuilder() { .setContentLanguage(CONTENT_LANGUAGE) .setCrc32c(CRC32) .setCreateTime(CREATE_TIME) + .setCustomTime(CUSTOM_TIME) .setCustomerEncryption(CUSTOMER_ENCRYPTION) .setKmsKeyName(KMS_KEY_NAME) .setEventBasedHold(EVENT_BASED_HOLD) @@ -539,6 +542,7 @@ public void testBuilder() { assertEquals(CRC32, blob.getCrc32c()); assertEquals(CRC32_HEX_STRING, blob.getCrc32cToHexString()); assertEquals(CREATE_TIME, blob.getCreateTime()); + assertEquals(CUSTOM_TIME, blob.getCustomTime()); assertEquals(CUSTOMER_ENCRYPTION, blob.getCustomerEncryption()); assertEquals(KMS_KEY_NAME, blob.getKmsKeyName()); assertEquals(EVENT_BASED_HOLD, blob.getEventBasedHold()); @@ -589,6 +593,7 @@ public void testBuilder() { assertNull(blob.getSelfLink()); assertEquals(0L, (long) blob.getSize()); assertNull(blob.getUpdateTime()); + assertNull(blob.getCustomTime()); assertTrue(blob.isDirectory()); } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java index 52947795b..925e3d6d1 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java @@ -527,9 +527,11 @@ public void testUpdateBucketDefaultKmsKeyName() throws ExecutionException, Inter @Test public void testCreateBlob() { String blobName = "test-create-blob"; - BlobInfo blob = BlobInfo.newBuilder(BUCKET, blobName).build(); + BlobInfo blob = + BlobInfo.newBuilder(BUCKET, blobName).setCustomTime(System.currentTimeMillis()).build(); Blob remoteBlob = storage.create(blob, BLOB_BYTE_CONTENT); assertNotNull(remoteBlob); + assertNotNull(remoteBlob.getCustomTime()); assertEquals(blob.getBucket(), remoteBlob.getBucket()); assertEquals(blob.getName(), remoteBlob.getName()); byte[] readBytes = storage.readAllBytes(BUCKET, blobName);