Skip to content

Commit

Permalink
Merge pull request #366 from mziccard/add-generation-blob-id
Browse files Browse the repository at this point in the history
Move generation from BlobInfo to BlobId
  • Loading branch information
aozarov committed Nov 14, 2015
2 parents 29d8ec3 + 3311969 commit 315a0eb
Show file tree
Hide file tree
Showing 9 changed files with 318 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ private Storage.Objects.Get getRequest(StorageObject object, Map<Option, ?> opti
throws IOException {
return storage.objects()
.get(object.getBucket(), object.getName())
.setGeneration(object.getGeneration())
.setProjection(DEFAULT_PROJECTION)
.setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options))
.setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options))
Expand Down Expand Up @@ -289,6 +290,7 @@ private Storage.Objects.Delete deleteRequest(StorageObject blob, Map<Option, ?>
throws IOException {
return storage.objects()
.delete(blob.getBucket(), blob.getName())
.setGeneration(blob.getGeneration())
.setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options))
.setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options))
.setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options))
Expand Down Expand Up @@ -333,6 +335,7 @@ public byte[] load(StorageObject from, Map<Option, ?> options)
try {
Storage.Objects.Get getRequest = storage.objects()
.get(from.getBucket(), from.getName())
.setGeneration(from.getGeneration())
.setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options))
.setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options))
.setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options))
Expand Down Expand Up @@ -410,8 +413,10 @@ public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
public byte[] read(StorageObject from, Map<Option, ?> options, long position, int bytes)
throws StorageException {
try {
Get req = storage.objects().get(from.getBucket(), from.getName());
req.setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options))
Get req = storage.objects()
.get(from.getBucket(), from.getName())
.setGeneration(from.getGeneration())
.setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options))
.setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options))
.setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options))
.setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options));
Expand Down Expand Up @@ -522,6 +527,7 @@ private RewriteResponse rewrite(RewriteRequest req, String token) throws Storage
com.google.api.services.storage.model.RewriteResponse rewriteReponse = storage.objects()
.rewrite(req.source.getBucket(), req.source.getName(), req.target.getBucket(),
req.target.getName(), req.target.getContentType() != null ? req.target : null)
.setSourceGeneration(req.source.getGeneration())
.setRewriteToken(token)
.setMaxBytesRewrittenPerCall(maxBytesRewrittenPerCall)
.setProjection(DEFAULT_PROJECTION)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,21 @@
import java.util.Objects;

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

private static final long serialVersionUID = -6156002883225601925L;
private final String bucket;
private final String name;
private final Long generation;

private BlobId(String bucket, String name) {
private BlobId(String bucket, String name, Long generation) {
this.bucket = bucket;
this.name = name;
this.generation = generation;
}

/**
Expand All @@ -52,43 +56,66 @@ public String name() {
return name;
}

/**
* Returns blob's data generation. Used for versioning.
*/
public Long generation() {
return generation;
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("bucket", bucket())
.add("name", name())
.add("generation", generation())
.toString();
}

@Override
public int hashCode() {
return Objects.hash(bucket, name);
return Objects.hash(bucket, name, generation);
}

@Override
public boolean equals(Object obj) {
return obj instanceof BlobId && Objects.equals(bucket, ((BlobId) obj).bucket)
&& Objects.equals(name, ((BlobId) obj).name);
&& Objects.equals(name, ((BlobId) obj).name)
&& Objects.equals(generation, ((BlobId) obj).generation);
}

StorageObject toPb() {
StorageObject storageObject = new StorageObject();
storageObject.setBucket(bucket);
storageObject.setName(name);
storageObject.setGeneration(generation);
return storageObject;
}

/**
* Creates a blob identifier.
* Creates a blob identifier. Generation is set to {@code null}.
*
* @param bucket the name of the bucket that contains the blob
* @param name the name of the blob
*/
public static BlobId of(String bucket, String name) {
return new BlobId(checkNotNull(bucket), checkNotNull(name));
return new BlobId(checkNotNull(bucket), checkNotNull(name), null);
}

/**
* Creates a {@code BlobId} object.
*
* @param bucket name of the containing bucket
* @param name blob's name
* @param generation blob's data generation, used for versioning. If {@code null} the identifier
* refers to the latest blob's generation
*/
public static BlobId of(String bucket, String name, Long generation) {
return new BlobId(checkNotNull(bucket), checkNotNull(name), generation);
}

static BlobId fromPb(StorageObject storageObject) {
return BlobId.of(storageObject.getBucket(), storageObject.getName());
return BlobId.of(storageObject.getBucket(), storageObject.getName(),
storageObject.getGeneration());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ public StorageObject apply(BlobInfo blobInfo) {
private final String crc32c;
private final String mediaLink;
private final Map<String, String> metadata;
private final Long generation;
private final Long metageneration;
private final Long deleteTime;
private final Long updateTime;
Expand Down Expand Up @@ -116,7 +115,6 @@ public static final class Builder {
private String crc32c;
private String mediaLink;
private Map<String, String> metadata;
private Long generation;
private Long metageneration;
private Long deleteTime;
private Long updateTime;
Expand Down Expand Up @@ -260,11 +258,6 @@ public Builder metadata(Map<String, String> metadata) {
return this;
}

Builder generation(Long generation) {
this.generation = generation;
return this;
}

Builder metageneration(Long metageneration) {
this.metageneration = metageneration;
return this;
Expand Down Expand Up @@ -307,7 +300,6 @@ private BlobInfo(Builder builder) {
crc32c = builder.crc32c;
mediaLink = builder.mediaLink;
metadata = builder.metadata;
generation = builder.generation;
metageneration = builder.metageneration;
deleteTime = builder.deleteTime;
updateTime = builder.updateTime;
Expand Down Expand Up @@ -481,7 +473,7 @@ public Map<String, String> metadata() {
* Returns blob's data generation. Used for blob versioning.
*/
public Long generation() {
return generation;
return blobId().generation();
}

/**
Expand Down Expand Up @@ -514,7 +506,6 @@ public Builder toBuilder() {
return new Builder()
.blobId(blobId)
.id(id)
.generation(generation)
.cacheControl(cacheControl)
.contentEncoding(contentEncoding)
.contentType(contentType)
Expand All @@ -540,6 +531,7 @@ public String toString() {
return MoreObjects.toStringHelper(this)
.add("bucket", bucket())
.add("name", name())
.add("generation", generation())
.add("size", size())
.add("content-type", contentType())
.add("metadata", metadata())
Expand Down Expand Up @@ -590,7 +582,6 @@ public ObjectAccessControl apply(Acl acl) {
storageObject.setContentEncoding(contentEncoding);
storageObject.setCrc32c(crc32c);
storageObject.setContentType(contentType);
storageObject.setGeneration(generation);
storageObject.setMd5Hash(md5);
storageObject.setMediaLink(mediaLink);
storageObject.setMetageneration(metageneration);
Expand Down Expand Up @@ -618,8 +609,19 @@ public static Builder builder(String bucket, String name) {
}

/**
* Returns a {@code BlobInfo} builder where blob identity is set to the provided value.
* Returns a {@code BlobInfo} builder where blob identity is set using the provided values.
*/
public static Builder builder(BucketInfo bucketInfo, String name, Long generation) {
return builder(bucketInfo.name(), name, generation);
}

/**
* Returns a {@code BlobInfo} builder where blob identity is set using the provided values.
*/
public static Builder builder(String bucket, String name, Long generation) {
return new Builder().blobId(BlobId.of(bucket, name, generation));
}

public static Builder builder(BlobId blobId) {
return new Builder().blobId(blobId);
}
Expand All @@ -638,9 +640,6 @@ static BlobInfo fromPb(StorageObject storageObject) {
if (storageObject.getContentType() != null) {
builder.contentType(storageObject.getContentType());
}
if (storageObject.getGeneration() != null) {
builder.generation(storageObject.getGeneration());
}
if (storageObject.getMd5Hash() != null) {
builder.md5(storageObject.getMd5Hash());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -473,14 +473,32 @@ class BlobSourceOption extends Option {

private static final long serialVersionUID = -3712768261070182991L;

private BlobSourceOption(StorageRpc.Option rpcOption, long value) {
private BlobSourceOption(StorageRpc.Option rpcOption, Long value) {
super(rpcOption, value);
}

/**
* Returns an option for blob's data generation match. If this option is used the request will
* fail if blob's generation does not match the provided value.
* fail if blob's generation does not match. The generation value to compare with the actual
* blob's generation is taken from a source {@link BlobId} object. When this option is passed
* to a {@link Storage} method and {@link BlobId#generation()} is {@code null} or no
* {@link BlobId} is provided an exception is thrown.
*/
public static BlobSourceOption generationMatch() {
return new BlobSourceOption(StorageRpc.Option.IF_GENERATION_MATCH, null);
}

/**
* Returns an option for blob's data generation mismatch. If this option is used the request
* will fail if blob's generation matches. The generation value to compare with the actual
* blob's generation is taken from a source {@link BlobId} object. When this option is passed
* to a {@link Storage} method and {@link BlobId#generation()} is {@code null} or no
* {@link BlobId} is provided an exception is thrown.
*/
public static BlobSourceOption generationNotMatch() {
return new BlobSourceOption(StorageRpc.Option.IF_GENERATION_NOT_MATCH, null);
}

public static BlobSourceOption generationMatch(long generation) {
return new BlobSourceOption(StorageRpc.Option.IF_GENERATION_MATCH, generation);
}
Expand Down Expand Up @@ -517,7 +535,7 @@ class BlobGetOption extends Option {

private static final long serialVersionUID = 803817709703661480L;

private BlobGetOption(StorageRpc.Option rpcOption, long value) {
private BlobGetOption(StorageRpc.Option rpcOption, Long value) {
super(rpcOption, value);
}

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

/**
* Returns an option for blob's data generation match. If this option is used the request will
* fail if blob's generation does not match the provided value.
* fail if blob's generation does not match. The generation value to compare with the actual
* blob's generation is taken from a source {@link BlobId} object. When this option is passed
* to a {@link Storage} method and {@link BlobId#generation()} is {@code null} or no
* {@link BlobId} is provided an exception is thrown.
*/
public static BlobGetOption generationMatch() {
return new BlobGetOption(StorageRpc.Option.IF_GENERATION_MATCH, (Long) null);
}

/**
* Returns an option for blob's data generation mismatch. If this option is used the request
* will fail if blob's generation matches. The generation value to compare with the actual
* blob's generation is taken from a source {@link BlobId} object. When this option is passed
* to a {@link Storage} method and {@link BlobId#generation()} is {@code null} or no
* {@link BlobId} is provided an exception is thrown.
*/
public static BlobGetOption generationNotMatch() {
return new BlobGetOption(StorageRpc.Option.IF_GENERATION_NOT_MATCH, (Long) null);
}

public static BlobGetOption generationMatch(long generation) {
return new BlobGetOption(StorageRpc.Option.IF_GENERATION_MATCH, generation);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public BlobInfo get(String bucket, String blob, BlobGetOption... options) {
@Override
public BlobInfo get(BlobId blob, BlobGetOption... options) {
final StorageObject storedObject = blob.toPb();
final Map<StorageRpc.Option, ?> optionsMap = optionMap(options);
final Map<StorageRpc.Option, ?> optionsMap = optionMap(blob, options);
try {
StorageObject storageObject = runWithRetries(new Callable<StorageObject>() {
@Override
Expand Down Expand Up @@ -405,7 +405,7 @@ public boolean delete(String bucket, String blob, BlobSourceOption... options) {
@Override
public boolean delete(BlobId blob, BlobSourceOption... options) {
final StorageObject storageObject = blob.toPb();
final Map<StorageRpc.Option, ?> optionsMap = optionMap(options);
final Map<StorageRpc.Option, ?> optionsMap = optionMap(blob, options);
try {
return runWithRetries(new Callable<Boolean>() {
@Override
Expand All @@ -428,8 +428,9 @@ public BlobInfo compose(final ComposeRequest composeRequest) {
final List<StorageObject> sources =
Lists.newArrayListWithCapacity(composeRequest.sourceBlobs().size());
for (ComposeRequest.SourceBlob sourceBlob : composeRequest.sourceBlobs()) {
sources.add(BlobInfo.builder(composeRequest.target().bucket(), sourceBlob.name())
.generation(sourceBlob.generation()).build().toPb());
sources.add(BlobInfo.builder(
BlobId.of(composeRequest.target().bucket(), sourceBlob.name(), sourceBlob.generation()))
.build().toPb());
}
final StorageObject target = composeRequest.target().toPb();
final Map<StorageRpc.Option, ?> targetOptions = optionMap(composeRequest.target().generation(),
Expand All @@ -450,7 +451,7 @@ public StorageObject call() {
public CopyWriter copy(final CopyRequest copyRequest) {
final StorageObject source = copyRequest.source().toPb();
final Map<StorageRpc.Option, ?> sourceOptions =
optionMap(null, null, copyRequest.sourceOptions(), true);
optionMap(copyRequest.source().generation(), null, copyRequest.sourceOptions(), true);
final StorageObject target = copyRequest.target().toPb();
final Map<StorageRpc.Option, ?> targetOptions = optionMap(copyRequest.target().generation(),
copyRequest.target().metageneration(), copyRequest.targetOptions());
Expand All @@ -476,7 +477,7 @@ public byte[] readAllBytes(String bucket, String blob, BlobSourceOption... optio
@Override
public byte[] readAllBytes(BlobId blob, BlobSourceOption... options) {
final StorageObject storageObject = blob.toPb();
final Map<StorageRpc.Option, ?> optionsMap = optionMap(options);
final Map<StorageRpc.Option, ?> optionsMap = optionMap(blob, options);
try {
return runWithRetries(new Callable<byte[]>() {
@Override
Expand All @@ -495,7 +496,7 @@ public BatchResponse apply(BatchRequest batchRequest) {
Lists.newArrayListWithCapacity(batchRequest.toDelete().size());
for (Map.Entry<BlobId, Iterable<BlobSourceOption>> entry : batchRequest.toDelete().entrySet()) {
BlobId blob = entry.getKey();
Map<StorageRpc.Option, ?> optionsMap = optionMap(null, null, entry.getValue());
Map<StorageRpc.Option, ?> optionsMap = optionMap(blob.generation(), null, entry.getValue());
StorageObject storageObject = blob.toPb();
toDelete.add(Tuple.<StorageObject, Map<StorageRpc.Option, ?>>of(storageObject, optionsMap));
}
Expand All @@ -512,7 +513,7 @@ public BatchResponse apply(BatchRequest batchRequest) {
Lists.newArrayListWithCapacity(batchRequest.toGet().size());
for (Map.Entry<BlobId, Iterable<BlobGetOption>> entry : batchRequest.toGet().entrySet()) {
BlobId blob = entry.getKey();
Map<StorageRpc.Option, ?> optionsMap = optionMap(null, null, entry.getValue());
Map<StorageRpc.Option, ?> optionsMap = optionMap(blob.generation(), null, entry.getValue());
toGet.add(Tuple.<StorageObject, Map<StorageRpc.Option, ?>>of(blob.toPb(), optionsMap));
}
StorageRpc.BatchResponse response =
Expand Down Expand Up @@ -557,7 +558,7 @@ public BlobReadChannel reader(String bucket, String blob, BlobSourceOption... op

@Override
public BlobReadChannel reader(BlobId blob, BlobSourceOption... options) {
Map<StorageRpc.Option, ?> optionsMap = optionMap(options);
Map<StorageRpc.Option, ?> optionsMap = optionMap(blob, options);
return new BlobReadChannelImpl(options(), blob, optionsMap);
}

Expand Down Expand Up @@ -741,4 +742,8 @@ private static <T> void addToOptionMap(StorageRpc.Option getOption, StorageRpc.O
private Map<StorageRpc.Option, ?> optionMap(BlobInfo blobInfo, Option... options) {
return optionMap(blobInfo.generation(), blobInfo.metageneration(), options);
}

private Map<StorageRpc.Option, ?> optionMap(BlobId blobId, Option... options) {
return optionMap(blobId.generation(), null, options);
}
}
Loading

0 comments on commit 315a0eb

Please sign in to comment.