Skip to content

Commit 315a0eb

Browse files
committed
Merge pull request #366 from mziccard/add-generation-blob-id
Move generation from BlobInfo to BlobId
2 parents 29d8ec3 + 3311969 commit 315a0eb

9 files changed

Lines changed: 318 additions & 81 deletions

File tree

gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ private Storage.Objects.Get getRequest(StorageObject object, Map<Option, ?> opti
208208
throws IOException {
209209
return storage.objects()
210210
.get(object.getBucket(), object.getName())
211+
.setGeneration(object.getGeneration())
211212
.setProjection(DEFAULT_PROJECTION)
212213
.setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options))
213214
.setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options))
@@ -289,6 +290,7 @@ private Storage.Objects.Delete deleteRequest(StorageObject blob, Map<Option, ?>
289290
throws IOException {
290291
return storage.objects()
291292
.delete(blob.getBucket(), blob.getName())
293+
.setGeneration(blob.getGeneration())
292294
.setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options))
293295
.setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options))
294296
.setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options))
@@ -333,6 +335,7 @@ public byte[] load(StorageObject from, Map<Option, ?> options)
333335
try {
334336
Storage.Objects.Get getRequest = storage.objects()
335337
.get(from.getBucket(), from.getName())
338+
.setGeneration(from.getGeneration())
336339
.setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options))
337340
.setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options))
338341
.setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options))
@@ -410,8 +413,10 @@ public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
410413
public byte[] read(StorageObject from, Map<Option, ?> options, long position, int bytes)
411414
throws StorageException {
412415
try {
413-
Get req = storage.objects().get(from.getBucket(), from.getName());
414-
req.setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options))
416+
Get req = storage.objects()
417+
.get(from.getBucket(), from.getName())
418+
.setGeneration(from.getGeneration())
419+
.setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options))
415420
.setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options))
416421
.setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options))
417422
.setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options));
@@ -522,6 +527,7 @@ private RewriteResponse rewrite(RewriteRequest req, String token) throws Storage
522527
com.google.api.services.storage.model.RewriteResponse rewriteReponse = storage.objects()
523528
.rewrite(req.source.getBucket(), req.source.getName(), req.target.getBucket(),
524529
req.target.getName(), req.target.getContentType() != null ? req.target : null)
530+
.setSourceGeneration(req.source.getGeneration())
525531
.setRewriteToken(token)
526532
.setMaxBytesRewrittenPerCall(maxBytesRewrittenPerCall)
527533
.setProjection(DEFAULT_PROJECTION)

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: 40 additions & 4 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
}
@@ -517,7 +535,7 @@ class BlobGetOption extends Option {
517535

518536
private static final long serialVersionUID = 803817709703661480L;
519537

520-
private BlobGetOption(StorageRpc.Option rpcOption, long value) {
538+
private BlobGetOption(StorageRpc.Option rpcOption, Long value) {
521539
super(rpcOption, value);
522540
}
523541

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

528546
/**
529547
* 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.
548+
* fail if blob's generation does not match. The generation value to compare with the actual
549+
* blob's generation is taken from a source {@link BlobId} object. When this option is passed
550+
* to a {@link Storage} method and {@link BlobId#generation()} is {@code null} or no
551+
* {@link BlobId} is provided an exception is thrown.
531552
*/
553+
public static BlobGetOption generationMatch() {
554+
return new BlobGetOption(StorageRpc.Option.IF_GENERATION_MATCH, (Long) null);
555+
}
556+
557+
/**
558+
* Returns an option for blob's data generation mismatch. If this option is used the request
559+
* will fail if blob's generation matches. The generation value to compare with the actual
560+
* blob's generation is taken from a source {@link BlobId} object. When this option is passed
561+
* to a {@link Storage} method and {@link BlobId#generation()} is {@code null} or no
562+
* {@link BlobId} is provided an exception is thrown.
563+
*/
564+
public static BlobGetOption generationNotMatch() {
565+
return new BlobGetOption(StorageRpc.Option.IF_GENERATION_NOT_MATCH, (Long) null);
566+
}
567+
532568
public static BlobGetOption generationMatch(long generation) {
533569
return new BlobGetOption(StorageRpc.Option.IF_GENERATION_MATCH, generation);
534570
}

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

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ 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 = optionMap(blob, options);
203203
try {
204204
StorageObject storageObject = runWithRetries(new Callable<StorageObject>() {
205205
@Override
@@ -405,7 +405,7 @@ public boolean delete(String bucket, String blob, BlobSourceOption... options) {
405405
@Override
406406
public boolean delete(BlobId blob, BlobSourceOption... options) {
407407
final StorageObject storageObject = blob.toPb();
408-
final Map<StorageRpc.Option, ?> optionsMap = optionMap(options);
408+
final Map<StorageRpc.Option, ?> optionsMap = optionMap(blob, options);
409409
try {
410410
return runWithRetries(new Callable<Boolean>() {
411411
@Override
@@ -428,8 +428,9 @@ public BlobInfo compose(final ComposeRequest composeRequest) {
428428
final List<StorageObject> sources =
429429
Lists.newArrayListWithCapacity(composeRequest.sourceBlobs().size());
430430
for (ComposeRequest.SourceBlob sourceBlob : composeRequest.sourceBlobs()) {
431-
sources.add(BlobInfo.builder(composeRequest.target().bucket(), sourceBlob.name())
432-
.generation(sourceBlob.generation()).build().toPb());
431+
sources.add(BlobInfo.builder(
432+
BlobId.of(composeRequest.target().bucket(), sourceBlob.name(), sourceBlob.generation()))
433+
.build().toPb());
433434
}
434435
final StorageObject target = composeRequest.target().toPb();
435436
final Map<StorageRpc.Option, ?> targetOptions = optionMap(composeRequest.target().generation(),
@@ -450,7 +451,7 @@ public StorageObject call() {
450451
public CopyWriter copy(final CopyRequest copyRequest) {
451452
final StorageObject source = copyRequest.source().toPb();
452453
final Map<StorageRpc.Option, ?> sourceOptions =
453-
optionMap(null, null, copyRequest.sourceOptions(), true);
454+
optionMap(copyRequest.source().generation(), null, copyRequest.sourceOptions(), true);
454455
final StorageObject target = copyRequest.target().toPb();
455456
final Map<StorageRpc.Option, ?> targetOptions = optionMap(copyRequest.target().generation(),
456457
copyRequest.target().metageneration(), copyRequest.targetOptions());
@@ -476,7 +477,7 @@ public byte[] readAllBytes(String bucket, String blob, BlobSourceOption... optio
476477
@Override
477478
public byte[] readAllBytes(BlobId blob, BlobSourceOption... options) {
478479
final StorageObject storageObject = blob.toPb();
479-
final Map<StorageRpc.Option, ?> optionsMap = optionMap(options);
480+
final Map<StorageRpc.Option, ?> optionsMap = optionMap(blob, options);
480481
try {
481482
return runWithRetries(new Callable<byte[]>() {
482483
@Override
@@ -495,7 +496,7 @@ public BatchResponse apply(BatchRequest batchRequest) {
495496
Lists.newArrayListWithCapacity(batchRequest.toDelete().size());
496497
for (Map.Entry<BlobId, Iterable<BlobSourceOption>> entry : batchRequest.toDelete().entrySet()) {
497498
BlobId blob = entry.getKey();
498-
Map<StorageRpc.Option, ?> optionsMap = optionMap(null, null, entry.getValue());
499+
Map<StorageRpc.Option, ?> optionsMap = optionMap(blob.generation(), null, entry.getValue());
499500
StorageObject storageObject = blob.toPb();
500501
toDelete.add(Tuple.<StorageObject, Map<StorageRpc.Option, ?>>of(storageObject, optionsMap));
501502
}
@@ -512,7 +513,7 @@ public BatchResponse apply(BatchRequest batchRequest) {
512513
Lists.newArrayListWithCapacity(batchRequest.toGet().size());
513514
for (Map.Entry<BlobId, Iterable<BlobGetOption>> entry : batchRequest.toGet().entrySet()) {
514515
BlobId blob = entry.getKey();
515-
Map<StorageRpc.Option, ?> optionsMap = optionMap(null, null, entry.getValue());
516+
Map<StorageRpc.Option, ?> optionsMap = optionMap(blob.generation(), null, entry.getValue());
516517
toGet.add(Tuple.<StorageObject, Map<StorageRpc.Option, ?>>of(blob.toPb(), optionsMap));
517518
}
518519
StorageRpc.BatchResponse response =
@@ -557,7 +558,7 @@ public BlobReadChannel reader(String bucket, String blob, BlobSourceOption... op
557558

558559
@Override
559560
public BlobReadChannel reader(BlobId blob, BlobSourceOption... options) {
560-
Map<StorageRpc.Option, ?> optionsMap = optionMap(options);
561+
Map<StorageRpc.Option, ?> optionsMap = optionMap(blob, options);
561562
return new BlobReadChannelImpl(options(), blob, optionsMap);
562563
}
563564

@@ -741,4 +742,8 @@ private static <T> void addToOptionMap(StorageRpc.Option getOption, StorageRpc.O
741742
private Map<StorageRpc.Option, ?> optionMap(BlobInfo blobInfo, Option... options) {
742743
return optionMap(blobInfo.generation(), blobInfo.metageneration(), options);
743744
}
745+
746+
private Map<StorageRpc.Option, ?> optionMap(BlobId blobId, Option... options) {
747+
return optionMap(blobId.generation(), null, options);
748+
}
744749
}

0 commit comments

Comments
 (0)