Skip to content

Commit 2ffac2d

Browse files
committed
Move generation from BlobInfo to BlobId
- Add generation to BlobId and remove from BlobInfo, update tests - Add generationMatch() and generationNotMatch() methods to (BlobSource/BlobGet)Option - Add setGeneration method to set generation value in empty generation options from BlobId - Add support for empty generation options in storage.get - Add support for empty generation options in storage.readAllBytes - Add support for empty generation options in storage.reader - Add support for empty generation options in storage.delete - Add support for empty generation options in BatchRequest - Add support for empty generation options in CopyRequest - Update/and unit and integration tests
1 parent ea56c11 commit 2ffac2d

File tree

9 files changed

+322
-75
lines changed

9 files changed

+322
-75
lines changed

gcloud-java-storage/src/main/java/com/google/gcloud/storage/BatchRequest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public Builder delete(String bucket, String blob, BlobSourceOption... options) {
5858
* Delete the given blob.
5959
*/
6060
public Builder delete(BlobId blob, BlobSourceOption... options) {
61-
toDelete.put(blob, Lists.newArrayList(options));
61+
toDelete.put(blob, Lists.newArrayList(BlobSourceOption.setGeneration(blob, options)));
6262
return this;
6363
}
6464

@@ -82,7 +82,7 @@ public Builder get(String bucket, String blob, BlobGetOption... options) {
8282
* Retrieve metadata for the given blob.
8383
*/
8484
public Builder get(BlobId blob, BlobGetOption... options) {
85-
toGet.put(blob, Lists.newArrayList(options));
85+
toGet.put(blob, Lists.newArrayList(BlobGetOption.setGeneration(blob, options)));
8686
return this;
8787
}
8888

gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobId.java

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,21 @@
2525
import java.util.Objects;
2626

2727
/**
28-
* Google Storage object identifier.
28+
* Google Storage Object identifier. A {@code BlobId} object includes the name of the containing
29+
* bucket, the blob's name and possibly the blob's generation. If {@link #generation()} is
30+
* {@code null} the identifier refers to the latest blob's generation.
2931
*/
3032
public final class BlobId implements Serializable {
3133

3234
private static final long serialVersionUID = -6156002883225601925L;
3335
private final String bucket;
3436
private final String name;
37+
private final Long generation;
3538

36-
private BlobId(String bucket, String name) {
39+
private BlobId(String bucket, String name, Long generation) {
3740
this.bucket = bucket;
3841
this.name = name;
42+
this.generation = generation;
3943
}
4044

4145
/**
@@ -52,43 +56,66 @@ public String name() {
5256
return name;
5357
}
5458

59+
/**
60+
* Returns blob's data generation. Used for versioning.
61+
*/
62+
public Long generation() {
63+
return generation;
64+
}
65+
5566
@Override
5667
public String toString() {
5768
return MoreObjects.toStringHelper(this)
5869
.add("bucket", bucket())
5970
.add("name", name())
71+
.add("generation", generation())
6072
.toString();
6173
}
6274

6375
@Override
6476
public int hashCode() {
65-
return Objects.hash(bucket, name);
77+
return Objects.hash(bucket, name, generation);
6678
}
6779

6880
@Override
6981
public boolean equals(Object obj) {
7082
return obj instanceof BlobId && Objects.equals(bucket, ((BlobId) obj).bucket)
71-
&& Objects.equals(name, ((BlobId) obj).name);
83+
&& Objects.equals(name, ((BlobId) obj).name)
84+
&& Objects.equals(generation, ((BlobId) obj).generation);
7285
}
7386

7487
StorageObject toPb() {
7588
StorageObject storageObject = new StorageObject();
7689
storageObject.setBucket(bucket);
7790
storageObject.setName(name);
91+
storageObject.setGeneration(generation);
7892
return storageObject;
7993
}
8094

8195
/**
82-
* Creates a blob identifier.
96+
* Creates a blob identifier. Generation is set to {@code null}.
8397
*
8498
* @param bucket the name of the bucket that contains the blob
8599
* @param name the name of the blob
86100
*/
87101
public static BlobId of(String bucket, String name) {
88-
return new BlobId(checkNotNull(bucket), checkNotNull(name));
102+
return new BlobId(checkNotNull(bucket), checkNotNull(name), null);
103+
}
104+
105+
/**
106+
* Creates a {@code BlobId} object.
107+
*
108+
* @param bucket name of the containing bucket
109+
* @param name blob's name
110+
* @param generation blob's data generation, used for versioning. If {@code null} the identifier
111+
* refers to the latest blob's generation
112+
*/
113+
public static BlobId of(String bucket, String name, Long generation) {
114+
return new BlobId(checkNotNull(bucket), checkNotNull(name), generation);
89115
}
90116

91117
static BlobId fromPb(StorageObject storageObject) {
92-
return BlobId.of(storageObject.getBucket(), storageObject.getName());
118+
return BlobId.of(storageObject.getBucket(), storageObject.getName(),
119+
storageObject.getGeneration());
93120
}
94121
}

gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ public StorageObject apply(BlobInfo blobInfo) {
7676
private final String crc32c;
7777
private final String mediaLink;
7878
private final Map<String, String> metadata;
79-
private final Long generation;
8079
private final Long metageneration;
8180
private final Long deleteTime;
8281
private final Long updateTime;
@@ -116,7 +115,6 @@ public static final class Builder {
116115
private String crc32c;
117116
private String mediaLink;
118117
private Map<String, String> metadata;
119-
private Long generation;
120118
private Long metageneration;
121119
private Long deleteTime;
122120
private Long updateTime;
@@ -260,11 +258,6 @@ public Builder metadata(Map<String, String> metadata) {
260258
return this;
261259
}
262260

263-
Builder generation(Long generation) {
264-
this.generation = generation;
265-
return this;
266-
}
267-
268261
Builder metageneration(Long metageneration) {
269262
this.metageneration = metageneration;
270263
return this;
@@ -307,7 +300,6 @@ private BlobInfo(Builder builder) {
307300
crc32c = builder.crc32c;
308301
mediaLink = builder.mediaLink;
309302
metadata = builder.metadata;
310-
generation = builder.generation;
311303
metageneration = builder.metageneration;
312304
deleteTime = builder.deleteTime;
313305
updateTime = builder.updateTime;
@@ -481,7 +473,7 @@ public Map<String, String> metadata() {
481473
* Returns blob's data generation. Used for blob versioning.
482474
*/
483475
public Long generation() {
484-
return generation;
476+
return blobId().generation();
485477
}
486478

487479
/**
@@ -514,7 +506,6 @@ public Builder toBuilder() {
514506
return new Builder()
515507
.blobId(blobId)
516508
.id(id)
517-
.generation(generation)
518509
.cacheControl(cacheControl)
519510
.contentEncoding(contentEncoding)
520511
.contentType(contentType)
@@ -540,6 +531,7 @@ public String toString() {
540531
return MoreObjects.toStringHelper(this)
541532
.add("bucket", bucket())
542533
.add("name", name())
534+
.add("generation", generation())
543535
.add("size", size())
544536
.add("content-type", contentType())
545537
.add("metadata", metadata())
@@ -590,7 +582,6 @@ public ObjectAccessControl apply(Acl acl) {
590582
storageObject.setContentEncoding(contentEncoding);
591583
storageObject.setCrc32c(crc32c);
592584
storageObject.setContentType(contentType);
593-
storageObject.setGeneration(generation);
594585
storageObject.setMd5Hash(md5);
595586
storageObject.setMediaLink(mediaLink);
596587
storageObject.setMetageneration(metageneration);
@@ -618,8 +609,19 @@ public static Builder builder(String bucket, String name) {
618609
}
619610

620611
/**
621-
* Returns a {@code BlobInfo} builder where blob identity is set to the provided value.
612+
* Returns a {@code BlobInfo} builder where blob identity is set using the provided values.
613+
*/
614+
public static Builder builder(BucketInfo bucketInfo, String name, Long generation) {
615+
return builder(bucketInfo.name(), name, generation);
616+
}
617+
618+
/**
619+
* Returns a {@code BlobInfo} builder where blob identity is set using the provided values.
622620
*/
621+
public static Builder builder(String bucket, String name, Long generation) {
622+
return new Builder().blobId(BlobId.of(bucket, name, generation));
623+
}
624+
623625
public static Builder builder(BlobId blobId) {
624626
return new Builder().blobId(blobId);
625627
}
@@ -638,9 +640,6 @@ static BlobInfo fromPb(StorageObject storageObject) {
638640
if (storageObject.getContentType() != null) {
639641
builder.contentType(storageObject.getContentType());
640642
}
641-
if (storageObject.getGeneration() != null) {
642-
builder.generation(storageObject.getGeneration());
643-
}
644643
if (storageObject.getMd5Hash() != null) {
645644
builder.md5(storageObject.getMd5Hash());
646645
}

gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -473,14 +473,32 @@ class BlobSourceOption extends Option {
473473

474474
private static final long serialVersionUID = -3712768261070182991L;
475475

476-
private BlobSourceOption(StorageRpc.Option rpcOption, long value) {
476+
private BlobSourceOption(StorageRpc.Option rpcOption, Long value) {
477477
super(rpcOption, value);
478478
}
479479

480480
/**
481481
* Returns an option for blob's data generation match. If this option is used the request will
482-
* fail if blob's generation does not match the provided value.
482+
* fail if blob's generation does not match. The generation value to compare with the actual
483+
* blob's generation is taken from a source {@link BlobId} object. When this option is passed
484+
* to a {@link Storage} method and {@link BlobId#generation()} is {@code null} or no
485+
* {@link BlobId} is provided an exception is thrown.
483486
*/
487+
public static BlobSourceOption generationMatch() {
488+
return new BlobSourceOption(StorageRpc.Option.IF_GENERATION_MATCH, null);
489+
}
490+
491+
/**
492+
* Returns an option for blob's data generation mismatch. If this option is used the request
493+
* will fail if blob's generation matches. The generation value to compare with the actual
494+
* blob's generation is taken from a source {@link BlobId} object. When this option is passed
495+
* to a {@link Storage} method and {@link BlobId#generation()} is {@code null} or no
496+
* {@link BlobId} is provided an exception is thrown.
497+
*/
498+
public static BlobSourceOption generationNotMatch() {
499+
return new BlobSourceOption(StorageRpc.Option.IF_GENERATION_NOT_MATCH, null);
500+
}
501+
484502
public static BlobSourceOption generationMatch(long generation) {
485503
return new BlobSourceOption(StorageRpc.Option.IF_GENERATION_MATCH, generation);
486504
}
@@ -508,6 +526,26 @@ public static BlobSourceOption metagenerationMatch(long metageneration) {
508526
public static BlobSourceOption metagenerationNotMatch(long metageneration) {
509527
return new BlobSourceOption(StorageRpc.Option.IF_METAGENERATION_NOT_MATCH, metageneration);
510528
}
529+
530+
static BlobSourceOption[] setGeneration(BlobId blobId, Iterable<BlobSourceOption> options) {
531+
return setGeneration(blobId, Iterables.toArray(options, BlobSourceOption.class));
532+
}
533+
534+
static BlobSourceOption[] setGeneration(BlobId blobId, BlobSourceOption... options) {
535+
BlobSourceOption[] updatedOptions = new BlobSourceOption[options.length];
536+
int index = 0;
537+
for (BlobSourceOption option : options) {
538+
if ((option.rpcOption() == StorageRpc.Option.IF_GENERATION_MATCH
539+
|| option.rpcOption() == StorageRpc.Option.IF_GENERATION_NOT_MATCH)
540+
&& option.value() == null) {
541+
updatedOptions[index] = new BlobSourceOption(option.rpcOption(), blobId.generation());
542+
} else {
543+
updatedOptions[index] = option;
544+
}
545+
index++;
546+
}
547+
return updatedOptions;
548+
}
511549
}
512550

513551
/**
@@ -517,7 +555,7 @@ class BlobGetOption extends Option {
517555

518556
private static final long serialVersionUID = 803817709703661480L;
519557

520-
private BlobGetOption(StorageRpc.Option rpcOption, long value) {
558+
private BlobGetOption(StorageRpc.Option rpcOption, Long value) {
521559
super(rpcOption, value);
522560
}
523561

@@ -527,8 +565,26 @@ private BlobGetOption(StorageRpc.Option rpcOption, String value) {
527565

528566
/**
529567
* Returns an option for blob's data generation match. If this option is used the request will
530-
* fail if blob's generation does not match the provided value.
568+
* fail if blob's generation does not match. The generation value to compare with the actual
569+
* blob's generation is taken from a source {@link BlobId} object. When this option is passed
570+
* to a {@link Storage} method and {@link BlobId#generation()} is {@code null} or no
571+
* {@link BlobId} is provided an exception is thrown.
572+
*/
573+
public static BlobGetOption generationMatch() {
574+
return new BlobGetOption(StorageRpc.Option.IF_GENERATION_MATCH, (Long) null);
575+
}
576+
577+
/**
578+
* Returns an option for blob's data generation mismatch. If this option is used the request
579+
* will fail if blob's generation matches. The generation value to compare with the actual
580+
* blob's generation is taken from a source {@link BlobId} object. When this option is passed
581+
* to a {@link Storage} method and {@link BlobId#generation()} is {@code null} or no
582+
* {@link BlobId} is provided an exception is thrown.
531583
*/
584+
public static BlobGetOption generationNotMatch() {
585+
return new BlobGetOption(StorageRpc.Option.IF_GENERATION_NOT_MATCH, (Long) null);
586+
}
587+
532588
public static BlobGetOption generationMatch(long generation) {
533589
return new BlobGetOption(StorageRpc.Option.IF_GENERATION_MATCH, generation);
534590
}
@@ -566,6 +622,22 @@ public static BlobGetOption metagenerationNotMatch(long metageneration) {
566622
public static BlobGetOption fields(BlobField... fields) {
567623
return new BlobGetOption(StorageRpc.Option.FIELDS, BlobField.selector(fields));
568624
}
625+
626+
static BlobGetOption[] setGeneration(BlobId blobId, BlobGetOption... options) {
627+
BlobGetOption[] updatedOptions = new BlobGetOption[options.length];
628+
int index = 0;
629+
for (BlobGetOption option : options) {
630+
if ((option.rpcOption() == StorageRpc.Option.IF_GENERATION_MATCH
631+
|| option.rpcOption() == StorageRpc.Option.IF_GENERATION_NOT_MATCH)
632+
&& option.value() == null) {
633+
updatedOptions[index] = new BlobGetOption(option.rpcOption(), blobId.generation());
634+
} else {
635+
updatedOptions[index] = option;
636+
}
637+
index++;
638+
}
639+
return updatedOptions;
640+
}
569641
}
570642

571643
/**
@@ -1019,7 +1091,8 @@ public CopyRequest build() {
10191091

10201092
private CopyRequest(Builder builder) {
10211093
source = checkNotNull(builder.source);
1022-
sourceOptions = ImmutableList.copyOf(builder.sourceOptions);
1094+
sourceOptions = ImmutableList.copyOf(
1095+
BlobSourceOption.setGeneration(source, builder.sourceOptions));
10231096
target = checkNotNull(builder.target);
10241097
targetOptions = ImmutableList.copyOf(builder.targetOptions);
10251098
megabytesCopiedPerChunk = builder.megabytesCopiedPerChunk;

gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,8 @@ public BlobInfo get(String bucket, String blob, BlobGetOption... options) {
199199
@Override
200200
public BlobInfo get(BlobId blob, BlobGetOption... options) {
201201
final StorageObject storedObject = blob.toPb();
202-
final Map<StorageRpc.Option, ?> optionsMap = optionMap(options);
202+
final Map<StorageRpc.Option, ?> optionsMap =
203+
optionMap(BlobGetOption.setGeneration(blob, options));
203204
try {
204205
StorageObject storageObject = runWithRetries(new Callable<StorageObject>() {
205206
@Override
@@ -405,7 +406,8 @@ public boolean delete(String bucket, String blob, BlobSourceOption... options) {
405406
@Override
406407
public boolean delete(BlobId blob, BlobSourceOption... options) {
407408
final StorageObject storageObject = blob.toPb();
408-
final Map<StorageRpc.Option, ?> optionsMap = optionMap(options);
409+
final Map<StorageRpc.Option, ?> optionsMap =
410+
optionMap(BlobSourceOption.setGeneration(blob, options));
409411
try {
410412
return runWithRetries(new Callable<Boolean>() {
411413
@Override
@@ -428,8 +430,9 @@ public BlobInfo compose(final ComposeRequest composeRequest) {
428430
final List<StorageObject> sources =
429431
Lists.newArrayListWithCapacity(composeRequest.sourceBlobs().size());
430432
for (ComposeRequest.SourceBlob sourceBlob : composeRequest.sourceBlobs()) {
431-
sources.add(BlobInfo.builder(composeRequest.target().bucket(), sourceBlob.name())
432-
.generation(sourceBlob.generation()).build().toPb());
433+
sources.add(BlobInfo.builder(
434+
BlobId.of(composeRequest.target().bucket(), sourceBlob.name(), sourceBlob.generation()))
435+
.build().toPb());
433436
}
434437
final StorageObject target = composeRequest.target().toPb();
435438
final Map<StorageRpc.Option, ?> targetOptions = optionMap(composeRequest.target().generation(),
@@ -476,7 +479,8 @@ public byte[] readAllBytes(String bucket, String blob, BlobSourceOption... optio
476479
@Override
477480
public byte[] readAllBytes(BlobId blob, BlobSourceOption... options) {
478481
final StorageObject storageObject = blob.toPb();
479-
final Map<StorageRpc.Option, ?> optionsMap = optionMap(options);
482+
final Map<StorageRpc.Option, ?> optionsMap =
483+
optionMap(BlobSourceOption.setGeneration(blob, options));
480484
try {
481485
return runWithRetries(new Callable<byte[]>() {
482486
@Override
@@ -557,7 +561,8 @@ public BlobReadChannel reader(String bucket, String blob, BlobSourceOption... op
557561

558562
@Override
559563
public BlobReadChannel reader(BlobId blob, BlobSourceOption... options) {
560-
Map<StorageRpc.Option, ?> optionsMap = optionMap(options);
564+
Map<StorageRpc.Option, ?> optionsMap =
565+
optionMap(BlobSourceOption.setGeneration(blob, options));
561566
return new BlobReadChannelImpl(options(), blob, optionsMap);
562567
}
563568

0 commit comments

Comments
 (0)