Skip to content

Commit

Permalink
Move generation from BlobInfo to BlobId
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
mziccard committed Nov 12, 2015
1 parent e4471f9 commit 1326f35
Show file tree
Hide file tree
Showing 9 changed files with 337 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public Builder delete(String bucket, String blob, BlobSourceOption... options) {
* Delete the given blob.
*/
public Builder delete(BlobId blob, BlobSourceOption... options) {
toDelete.put(blob, Lists.newArrayList(options));
toDelete.put(blob, Lists.newArrayList(BlobSourceOption.setGeneration(blob, options)));
return this;
}

Expand All @@ -82,7 +82,7 @@ public Builder get(String bucket, String blob, BlobGetOption... options) {
* Retrieve metadata for the given blob.
*/
public Builder get(BlobId blob, BlobGetOption... options) {
toGet.put(blob, Lists.newArrayList(options));
toGet.put(blob, Lists.newArrayList(BlobGetOption.setGeneration(blob, options)));
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,51 +32,87 @@ 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;
}

/**
* Returns the name of the containing bucket.
*/
public String bucket() {
return bucket;
}

/**
* Returns the blob's name.
*/
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 {@code BlobId} object. Generation is set to {@code null}.
*
* @param bucket name of the containing bucket
* @param name blob's name
*/
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
*/
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 @@ -209,11 +207,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 @@ -253,7 +246,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 @@ -336,7 +328,7 @@ public Map<String, String> metadata() {
}

public Long generation() {
return generation;
return blobId().generation();
}

public Long metageneration() {
Expand All @@ -355,7 +347,6 @@ public Builder toBuilder() {
return new Builder()
.blobId(blobId)
.id(id)
.generation(generation)
.cacheControl(cacheControl)
.contentEncoding(contentEncoding)
.contentType(contentType)
Expand All @@ -381,6 +372,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 @@ -431,7 +423,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 All @@ -452,6 +443,20 @@ public static Builder builder(String bucket, String name) {
return new Builder().blobId(BlobId.of(bucket, name));
}

/**
* 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 @@ -470,9 +475,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 @@ -373,10 +373,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 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 All @@ -392,20 +414,62 @@ public static BlobSourceOption metagenerationMatch(long metageneration) {
public static BlobSourceOption metagenerationNotMatch(long metageneration) {
return new BlobSourceOption(StorageRpc.Option.IF_METAGENERATION_NOT_MATCH, metageneration);
}

static BlobSourceOption[] setGeneration(BlobId blobId, Iterable<BlobSourceOption> options) {
return setGeneration(blobId, Iterables.toArray(options, BlobSourceOption.class));
}

static BlobSourceOption[] setGeneration(BlobId blobId, BlobSourceOption... options) {
BlobSourceOption[] updatedOptions = new BlobSourceOption[options.length];
int index = 0;
for (BlobSourceOption option : options) {
if ((option.rpcOption() == StorageRpc.Option.IF_GENERATION_MATCH
|| option.rpcOption() == StorageRpc.Option.IF_GENERATION_NOT_MATCH)
&& option.value() == null) {
updatedOptions[index] = new BlobSourceOption(option.rpcOption(), blobId.generation());
} else {
updatedOptions[index] = option;
}
index++;
}
return updatedOptions;
}
}

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);
}

private BlobGetOption(StorageRpc.Option rpcOption, String 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 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 All @@ -431,6 +495,22 @@ public static BlobGetOption metagenerationNotMatch(long metageneration) {
public static BlobGetOption fields(BlobField... fields) {
return new BlobGetOption(StorageRpc.Option.FIELDS, BlobField.selector(fields));
}

static BlobGetOption[] setGeneration(BlobId blobId, BlobGetOption... options) {
BlobGetOption[] updatedOptions = new BlobGetOption[options.length];
int index = 0;
for (BlobGetOption option : options) {
if ((option.rpcOption() == StorageRpc.Option.IF_GENERATION_MATCH
|| option.rpcOption() == StorageRpc.Option.IF_GENERATION_NOT_MATCH)
&& option.value() == null) {
updatedOptions[index] = new BlobGetOption(option.rpcOption(), blobId.generation());
} else {
updatedOptions[index] = option;
}
index++;
}
return updatedOptions;
}
}

class BucketListOption extends Option {
Expand Down Expand Up @@ -797,7 +877,8 @@ public CopyRequest build() {

private CopyRequest(Builder builder) {
source = checkNotNull(builder.source);
sourceOptions = ImmutableList.copyOf(builder.sourceOptions);
sourceOptions = ImmutableList.copyOf(
BlobSourceOption.setGeneration(source, builder.sourceOptions));
target = checkNotNull(builder.target);
targetOptions = ImmutableList.copyOf(builder.targetOptions);
megabytesCopiedPerChunk = builder.megabytesCopiedPerChunk;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ 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(BlobGetOption.setGeneration(blob, options));
try {
StorageObject storageObject = runWithRetries(new Callable<StorageObject>() {
@Override
Expand Down Expand Up @@ -405,7 +406,8 @@ 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(BlobSourceOption.setGeneration(blob, options));
try {
return runWithRetries(new Callable<Boolean>() {
@Override
Expand All @@ -428,8 +430,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 Down Expand Up @@ -476,7 +479,8 @@ 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(BlobSourceOption.setGeneration(blob, options));
try {
return runWithRetries(new Callable<byte[]>() {
@Override
Expand Down Expand Up @@ -557,7 +561,8 @@ 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(BlobSourceOption.setGeneration(blob, options));
return new BlobReadChannelImpl(options(), blob, optionsMap);
}

Expand Down
Loading

0 comments on commit 1326f35

Please sign in to comment.