From 9eceabcecc303cbfa369573b22781dc3bc5d1455 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 20 Oct 2015 14:37:22 +0200 Subject: [PATCH] Remove md5 and crc32c options from StorageRpc - BlobWriteOption extends Serializable instead of Option - add BlobTargetObject.convert to convert BlobWriteOption and possibly mask md5 and crc32c fields - add private Storage.create(blobInfo, inputStream, blobTargetOption) --- .../google/gcloud/spi/DefaultStorageRpc.java | 13 --- .../com/google/gcloud/spi/StorageRpc.java | 2 - .../com/google/gcloud/storage/Storage.java | 89 ++++++++++++++----- .../google/gcloud/storage/StorageImpl.java | 21 +++-- 4 files changed, 79 insertions(+), 46 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java index f7c29e561835..52820171cf29 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java @@ -23,8 +23,6 @@ import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_GENERATION_NOT_MATCH; import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_MATCH; import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_NOT_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_MD5_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_CRC32C_MATCH; import static com.google.gcloud.spi.StorageRpc.Option.MAX_RESULTS; import static com.google.gcloud.spi.StorageRpc.Option.PAGE_TOKEN; import static com.google.gcloud.spi.StorageRpc.Option.PREDEFINED_ACL; @@ -108,15 +106,6 @@ private static StorageException translate(GoogleJsonError exception) { return new StorageException(exception.getCode(), exception.getMessage(), retryable); } - private static void applyOptions(StorageObject storageObject, Map options) { - if (IF_MD5_MATCH.getBoolean(options) == null) { - storageObject.setMd5Hash(null); - } - if (IF_CRC32C_MATCH.getBoolean(options) == null) { - storageObject.setCrc32c(null); - } - } - @Override public Bucket create(Bucket bucket, Map options) throws StorageException { try { @@ -134,7 +123,6 @@ public Bucket create(Bucket bucket, Map options) throws StorageExcept @Override public StorageObject create(StorageObject storageObject, final InputStream content, Map options) throws StorageException { - applyOptions(storageObject, options); try { Storage.Objects.Insert insert = storage.objects() .insert(storageObject.getBucket(), storageObject, @@ -503,7 +491,6 @@ public void write(String uploadId, byte[] toWrite, int toWriteOffset, StorageObj @Override public String open(StorageObject object, Map options) throws StorageException { - applyOptions(object, options); try { Insert req = storage.objects().insert(object.getBucket(), object); GenericUrl url = req.buildHttpRequest().getUrl(); diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java index 95341ba1e21e..b7ac99bf909e 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java @@ -42,8 +42,6 @@ enum Option { IF_SOURCE_METAGENERATION_NOT_MATCH("ifSourceMetagenerationNotMatch"), IF_SOURCE_GENERATION_MATCH("ifSourceGenerationMatch"), IF_SOURCE_GENERATION_NOT_MATCH("ifSourceGenerationNotMatch"), - IF_MD5_MATCH("md5Hash"), - IF_CRC32C_MATCH("crc32c"), PREFIX("prefix"), MAX_RESULTS("maxResults"), PAGE_TOKEN("pageToken"), diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 9e292f05c5fa..ed5939a061f8 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -21,9 +21,11 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.gcloud.Service; import com.google.gcloud.spi.StorageRpc; +import com.google.gcloud.spi.StorageRpc.Tuple; import java.io.InputStream; import java.io.Serializable; @@ -33,6 +35,7 @@ import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -146,65 +149,103 @@ public static BlobTargetOption metagenerationNotMatch() { return new BlobTargetOption(StorageRpc.Option.IF_METAGENERATION_NOT_MATCH); } - static BlobWriteOption[] convert(BlobTargetOption[] options, BlobWriteOption... optionsToAdd) { - BlobWriteOption[] writeOptions = new BlobWriteOption[options.length + optionsToAdd.length]; - int index = 0; - for (BlobTargetOption option : options) { - writeOptions[index++] = new BlobWriteOption(option); - } - for (BlobWriteOption option : optionsToAdd) { - writeOptions[index++] = option; + static Tuple convert(BlobInfo info, BlobWriteOption... options) { + BlobInfo.Builder infoBuilder = info.toBuilder().crc32c(null).md5(null); + List targetOptions = Lists.newArrayListWithCapacity(options.length); + for (BlobWriteOption option : options) { + switch (option.option) { + case IF_CRC32C_MATCH: + infoBuilder.crc32c(info.crc32c()); + break; + case IF_MD5_MATCH: + infoBuilder.md5(info.md5()); + break; + default: + targetOptions.add(option.toTargetOption()); + break; + } } - return writeOptions; + return Tuple.of(infoBuilder.build(), + targetOptions.toArray(new BlobTargetOption[targetOptions.size()])); } } - class BlobWriteOption extends Option { + class BlobWriteOption implements Serializable { private static final long serialVersionUID = -3880421670966224580L; - BlobWriteOption(BlobTargetOption option) { - super(option.rpcOption(), option.value()); + private final Option option; + private final Object value; + + enum Option { + PREDEFINED_ACL, IF_GENERATION_MATCH, IF_GENERATION_NOT_MATCH, IF_METAGENERATION_MATCH, + IF_METAGENERATION_NOT_MATCH, IF_MD5_MATCH, IF_CRC32C_MATCH; + + StorageRpc.Option toRpcOption() { + return StorageRpc.Option.valueOf(this.name()); + } } - private BlobWriteOption(StorageRpc.Option rpcOption, Object value) { - super(rpcOption, value); + BlobTargetOption toTargetOption() { + return new BlobTargetOption(this.option.toRpcOption(), this.value); } - private BlobWriteOption(StorageRpc.Option rpcOption) { - this(rpcOption, null); + private BlobWriteOption(Option option, Object value) { + this.option = option; + this.value = value; + } + + private BlobWriteOption(Option option) { + this(option, null); + } + + @Override + public int hashCode() { + return Objects.hash(option, value); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof BlobWriteOption)) { + return false; + } + final BlobWriteOption other = (BlobWriteOption) obj; + return this.option == other.option && Objects.equals(this.value, other.value); } public static BlobWriteOption predefinedAcl(PredefinedAcl acl) { - return new BlobWriteOption(StorageRpc.Option.PREDEFINED_ACL, acl.entry()); + return new BlobWriteOption(Option.PREDEFINED_ACL, acl.entry()); } public static BlobWriteOption doesNotExist() { - return new BlobWriteOption(StorageRpc.Option.IF_GENERATION_MATCH, 0L); + return new BlobWriteOption(Option.IF_GENERATION_MATCH, 0L); } public static BlobWriteOption generationMatch() { - return new BlobWriteOption(StorageRpc.Option.IF_GENERATION_MATCH); + return new BlobWriteOption(Option.IF_GENERATION_MATCH); } public static BlobWriteOption generationNotMatch() { - return new BlobWriteOption(StorageRpc.Option.IF_GENERATION_NOT_MATCH); + return new BlobWriteOption(Option.IF_GENERATION_NOT_MATCH); } public static BlobWriteOption metagenerationMatch() { - return new BlobWriteOption(StorageRpc.Option.IF_METAGENERATION_MATCH); + return new BlobWriteOption(Option.IF_METAGENERATION_MATCH); } public static BlobWriteOption metagenerationNotMatch() { - return new BlobWriteOption(StorageRpc.Option.IF_METAGENERATION_NOT_MATCH); + return new BlobWriteOption(Option.IF_METAGENERATION_NOT_MATCH); } public static BlobWriteOption md5Match() { - return new BlobWriteOption(StorageRpc.Option.IF_MD5_MATCH, true); + return new BlobWriteOption(Option.IF_MD5_MATCH, true); } public static BlobWriteOption crc32cMatch() { - return new BlobWriteOption(StorageRpc.Option.IF_CRC32C_MATCH, true); + return new BlobWriteOption(Option.IF_CRC32C_MATCH, true); } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java index 8b8438397942..421786c783cb 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java @@ -129,9 +129,7 @@ public BlobInfo create(BlobInfo blobInfo, BlobTargetOption... options) { .md5(EMPTY_BYTE_ARRAY_MD5) .crc32c(EMPTY_BYTE_ARRAY_CRC32C) .build(); - return create(updatedInfo, new ByteArrayInputStream(EMPTY_BYTE_ARRAY), - BlobTargetOption.convert( - options, BlobWriteOption.md5Match(), BlobWriteOption.crc32cMatch())); + return create(updatedInfo, new ByteArrayInputStream(EMPTY_BYTE_ARRAY), options); } @Override @@ -142,14 +140,18 @@ public BlobInfo create(BlobInfo blobInfo, byte[] content, BlobTargetOption... op .crc32c(BaseEncoding.base64().encode( Ints.toByteArray(Hashing.crc32c().hashBytes(content).asInt()))) .build(); - return create(updatedInfo, new ByteArrayInputStream(content), BlobTargetOption.convert( - options, BlobWriteOption.md5Match(), BlobWriteOption.crc32cMatch())); + return create(updatedInfo, new ByteArrayInputStream(content), options); } @Override public BlobInfo create(BlobInfo blobInfo, final InputStream content, BlobWriteOption... options) { - final StorageObject blobPb = blobInfo.toPb(); - final Map optionsMap = optionMap(blobInfo, options); + Tuple targetOptions = BlobTargetOption.convert(blobInfo, options); + return create(targetOptions.x(), content, targetOptions.y()); + } + + private BlobInfo create(BlobInfo info, final InputStream content, BlobTargetOption... options) { + final StorageObject blobPb = info.toPb(); + final Map optionsMap = optionMap(info, options); try { return BlobInfo.fromPb(runWithRetries(new Callable() { @Override @@ -558,6 +560,11 @@ public BlobReadChannel reader(BlobId blob, BlobSourceOption... options) { @Override public BlobWriteChannel writer(BlobInfo blobInfo, BlobWriteOption... options) { + Tuple targetOptions = BlobTargetOption.convert(blobInfo, options); + return writer(targetOptions.x(), targetOptions.y()); + } + + private BlobWriteChannel writer(BlobInfo blobInfo, BlobTargetOption... options) { final Map optionsMap = optionMap(blobInfo, options); return new BlobWriteChannelImpl(options(), blobInfo, optionsMap); }