Skip to content

Commit

Permalink
feat: add support of customTime metadata (#413)
Browse files Browse the repository at this point in the history
* 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 <jesselovelace@google.com>
  • Loading branch information
athakor and JesseLovelace committed Aug 27, 2020
1 parent 1af8288 commit 6f4585e
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 1 deletion.
Expand Up @@ -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);
Expand Down
Expand Up @@ -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<String, String> metadata;
private final Long metageneration;
Expand Down Expand Up @@ -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.
*
* <p>Example of setting the custom time.
*
* <pre>{@code
* String bucketName = "my-unique-bucket";
* String blobName = "my-blob-name";
* long customTime = 1598423868301L;
* BlobInfo blob = BlobInfo.newBuilder(bucketName, blobName).setCustomTime(customTime).build();
* }</pre>
*/
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 <a
* href="http://tools.ietf.org/html/rfc4960#appendix-B">RFC 4960, Appendix B;</a> from hex
Expand Down Expand Up @@ -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<String, String> metadata;
private Long metageneration;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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));
}
Expand Down Expand Up @@ -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());
}
Expand Down
Expand Up @@ -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 =
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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());
Expand All @@ -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());
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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());
Expand Down
Expand Up @@ -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 =
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -589,6 +593,7 @@ public void testBuilder() {
assertNull(blob.getSelfLink());
assertEquals(0L, (long) blob.getSize());
assertNull(blob.getUpdateTime());
assertNull(blob.getCustomTime());
assertTrue(blob.isDirectory());
}

Expand Down
Expand Up @@ -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);
Expand Down

0 comments on commit 6f4585e

Please sign in to comment.