Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make storage.update use normal update and add storage.patch #276

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,27 @@ public Bucket patch(Bucket bucket, Map<Option, ?> options) {
}
}

@Override
public StorageObject update(StorageObject storageObject, Map<Option, ?> options) {
try {
return updateRequest(storageObject, options).execute();
} catch (IOException ex) {
throw translate(ex);
}
}

private Storage.Objects.Update updateRequest(StorageObject storageObject, Map<Option, ?> options)
throws IOException {
return storage.objects()
.update(storageObject.getBucket(), storageObject.getName(), storageObject)
.setProjection(DEFAULT_PROJECTION)
.setPredefinedAcl(PREDEFINED_ACL.getString(options))
.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));
}

@Override
public StorageObject patch(StorageObject storageObject, Map<Option, ?> options) {
try {
Expand Down Expand Up @@ -374,6 +395,8 @@ public BatchResponse batch(BatchRequest request) throws StorageException {
Maps.newConcurrentMap();
final Map<StorageObject, Tuple<StorageObject, StorageException>> gets =
Maps.newConcurrentMap();
final Map<StorageObject, Tuple<StorageObject, StorageException>> patches =
Maps.newConcurrentMap();
try {
for (final Tuple<StorageObject, Map<Option, ?>> tuple : request.toDelete) {
deleteRequest(tuple.x(), tuple.y()).queue(batch, new JsonBatchCallback<Void>() {
Expand All @@ -389,7 +412,7 @@ public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
});
}
for (final Tuple<StorageObject, Map<Option, ?>> tuple : request.toUpdate) {
patchRequest(tuple.x(), tuple.y()).queue(batch, new JsonBatchCallback<StorageObject>() {
updateRequest(tuple.x(), tuple.y()).queue(batch, new JsonBatchCallback<StorageObject>() {
@Override
public void onSuccess(StorageObject storageObject, HttpHeaders responseHeaders) {
updates.put(tuple.x(),
Expand All @@ -403,6 +426,21 @@ public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
}
});
}
for (final Tuple<StorageObject, Map<Option, ?>> tuple : request.toPatch) {
patchRequest(tuple.x(), tuple.y()).queue(batch, new JsonBatchCallback<StorageObject>() {
@Override
public void onSuccess(StorageObject storageObject, HttpHeaders responseHeaders) {
patches.put(tuple.x(),
Tuple.<StorageObject, StorageException>of(storageObject, null));
}

@Override
public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
patches.put(tuple.x(),
Tuple.<StorageObject, StorageException>of(null, translate(e)));
}
});
}
for (final Tuple<StorageObject, Map<Option, ?>> tuple : request.toGet) {
getRequest(tuple.x(), tuple.y()).queue(batch, new JsonBatchCallback<StorageObject>() {
@Override
Expand All @@ -422,7 +460,7 @@ public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
} catch (IOException ex) {
throw translate(ex);
}
return new BatchResponse(deletes, updates, gets);
return new BatchResponse(deletes, updates, gets, patches);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,20 @@ class BatchRequest {
public final List<Tuple<StorageObject, Map<Option, ?>>> toDelete;
public final List<Tuple<StorageObject, Map<Option, ?>>> toUpdate;
public final List<Tuple<StorageObject, Map<Option, ?>>> toGet;
public final List<Tuple<StorageObject, Map<Option, ?>>> toPatch;

public BatchRequest(Iterable<Tuple<StorageObject, Map<Option, ?>>> toDelete,
Iterable<Tuple<StorageObject, Map<Option, ?>>> toUpdate,
Iterable<Tuple<StorageObject, Map<Option, ?>>> toGet) {
Iterable<Tuple<StorageObject, Map<Option, ?>>> toGet,
Iterable<Tuple<StorageObject, Map<Option, ?>>> toPatch) {
this.toDelete = ImmutableList.copyOf(
firstNonNull(toDelete, ImmutableList.<Tuple<StorageObject, Map<Option, ?>>>of()));
this.toUpdate = ImmutableList.copyOf(
firstNonNull(toUpdate, ImmutableList.<Tuple<StorageObject, Map<Option, ?>>>of()));
this.toGet = ImmutableList.copyOf(
firstNonNull(toGet, ImmutableList.<Tuple<StorageObject, Map<Option, ?>>>of()));
this.toPatch = ImmutableList.copyOf(
firstNonNull(toPatch, ImmutableList.<Tuple<StorageObject, Map<Option, ?>>>of()));
}
}

Expand All @@ -122,13 +126,16 @@ class BatchResponse {
public final Map<StorageObject, Tuple<Boolean, StorageException>> deletes;
public final Map<StorageObject, Tuple<StorageObject, StorageException>> updates;
public final Map<StorageObject, Tuple<StorageObject, StorageException>> gets;
public final Map<StorageObject, Tuple<StorageObject, StorageException>> patches;

public BatchResponse(Map<StorageObject, Tuple<Boolean, StorageException>> deletes,
Map<StorageObject, Tuple<StorageObject, StorageException>> updates,
Map<StorageObject, Tuple<StorageObject, StorageException>> gets) {
Map<StorageObject, Tuple<StorageObject, StorageException>> gets,
Map<StorageObject, Tuple<StorageObject, StorageException>> patches) {
this.deletes = ImmutableMap.copyOf(deletes);
this.updates = ImmutableMap.copyOf(updates);
this.gets = ImmutableMap.copyOf(gets);
this.patches = ImmutableMap.copyOf(patches);
}
}

Expand All @@ -144,13 +151,13 @@ Tuple<String, Iterable<StorageObject>> list(String bucket, Map<Option, ?> option

Bucket get(Bucket bucket, Map<Option, ?> options) throws StorageException;

StorageObject get(StorageObject object, Map<Option, ?> options)
throws StorageException;
StorageObject get(StorageObject object, Map<Option, ?> options) throws StorageException;

Bucket patch(Bucket bucket, Map<Option, ?> options) throws StorageException;

StorageObject patch(StorageObject storageObject, Map<Option, ?> options)
throws StorageException;
StorageObject update(StorageObject storageObject, Map<Option, ?> options) throws StorageException;

StorageObject patch(StorageObject storageObject, Map<Option, ?> options) throws StorageException;

boolean delete(Bucket bucket, Map<Option, ?> options) throws StorageException;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@ public final class BatchRequest implements Serializable {
private final Map<BlobId, Iterable<BlobSourceOption>> toDelete;
private final Map<BlobInfo, Iterable<BlobTargetOption>> toUpdate;
private final Map<BlobId, Iterable<BlobSourceOption>> toGet;
private final Map<BlobInfo, Iterable<BlobTargetOption>> toPatch;

public static class Builder {

private Map<BlobId, Iterable<BlobSourceOption>> toDelete = new LinkedHashMap<>();
private Map<BlobInfo, Iterable<BlobTargetOption>> toUpdate = new LinkedHashMap<>();
private Map<BlobId, Iterable<BlobSourceOption>> toGet = new LinkedHashMap<>();
private Map<BlobInfo, Iterable<BlobTargetOption>> toPatch = new LinkedHashMap<>();

private Builder() {}

Expand Down Expand Up @@ -85,6 +87,14 @@ public Builder get(BlobId blob, BlobSourceOption... options) {
return this;
}

/**
* Patch the given blob.
*/
public Builder patch(BlobInfo blobInfo, BlobTargetOption... options) {
toPatch.put(blobInfo, Lists.newArrayList(options));
return this;
}

public BatchRequest build() {
return new BatchRequest(this);
}
Expand All @@ -94,11 +104,12 @@ private BatchRequest(Builder builder) {
toDelete = ImmutableMap.copyOf(builder.toDelete);
toUpdate = ImmutableMap.copyOf(builder.toUpdate);
toGet = ImmutableMap.copyOf(builder.toGet);
toPatch = ImmutableMap.copyOf(builder.toPatch);
}

@Override
public int hashCode() {
return Objects.hash(toDelete, toUpdate, toGet);
return Objects.hash(toDelete, toUpdate, toGet, toPatch);
}

@Override
Expand All @@ -109,7 +120,8 @@ public boolean equals(Object obj) {
BatchRequest other = (BatchRequest) obj;
return Objects.equals(toDelete, other.toDelete)
&& Objects.equals(toUpdate, other.toUpdate)
&& Objects.equals(toGet, other.toGet);
&& Objects.equals(toGet, other.toGet)
&& Objects.equals(toPatch, other.toPatch);
}

public Map<BlobId, Iterable<BlobSourceOption>> toDelete() {
Expand All @@ -124,6 +136,10 @@ public Map<BlobId, Iterable<BlobSourceOption>> toGet() {
return toGet;
}

public Map<BlobInfo, Iterable<BlobTargetOption>> toPatch() {
return toPatch;
}

public static Builder builder() {
return new Builder();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public final class BatchResponse implements Serializable {
private final List<Result<Boolean>> deleteResult;
private final List<Result<BlobInfo>> updateResult;
private final List<Result<BlobInfo>> getResult;
private final List<Result<BlobInfo>> patchResult;

public static class Result<T extends Serializable> implements Serializable {

Expand Down Expand Up @@ -114,15 +115,16 @@ static <T extends Serializable> Result<T> empty() {
}

public BatchResponse(List<Result<Boolean>> deleteResult, List<Result<BlobInfo>> updateResult,
List<Result<BlobInfo>> getResult) {
List<Result<BlobInfo>> getResult, List<Result<BlobInfo>> patchResult) {
this.deleteResult = ImmutableList.copyOf(deleteResult);
this.updateResult = ImmutableList.copyOf(updateResult);
this.getResult = ImmutableList.copyOf(getResult);
this.patchResult = ImmutableList.copyOf(patchResult);
}

@Override
public int hashCode() {
return Objects.hash(deleteResult, updateResult, getResult);
return Objects.hash(deleteResult, updateResult, getResult, patchResult);
}

@Override
Expand All @@ -133,7 +135,8 @@ public boolean equals(Object obj) {
BatchResponse other = (BatchResponse) obj;
return Objects.equals(deleteResult, other.deleteResult)
&& Objects.equals(updateResult, other.updateResult)
&& Objects.equals(updateResult, other.updateResult);
&& Objects.equals(getResult, other.getResult)
&& Objects.equals(patchResult, other.patchResult);
}

/**
Expand All @@ -156,4 +159,11 @@ public List<Result<BlobInfo>> updates() {
public List<Result<BlobInfo>> gets() {
return getResult;
}

/**
* Returns the results for the patch operations using the request order.
*/
public List<Result<BlobInfo>> patches() {
return patchResult;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,14 @@ public Blob reload(BlobSourceOption... options) {
}

/**
* Updates the blob's information. Bucket or blob's name cannot be changed by this method. If you
* want to rename the blob or move it to a different bucket use the {@link #copyTo} and
* {@link #delete} operations. A new {@code Blob} object is returned. By default no checks are
* made on the metadata generation of the current blob. If you want to update the information only
* if the current blob metadata are at their latest version use the {@code metagenerationMatch}
* option: {@code blob.update(newInfo, BlobTargetOption.metagenerationMatch())}.
* Updates the blob's information, metadata are replaced. Bucket or blob's name cannot be changed
* by this method. If you want to rename the blob or move it to a different bucket use the
* {@link #copyTo} and {@link #delete} operations. A new {@code Blob} object is returned. By
* default no checks are made on the metadata generation of the current blob. If you want to
* update the information only if the current blob metadata are at their latest version use the
* {@code metagenerationMatch} option:
* {@code blob.update(newInfo, BlobTargetOption.metagenerationMatch())}.
* Update will fail if an incomplete {@code blobInfo} is provided.
*
* @param blobInfo new blob's information. Bucket and blob names must match the current ones
* @param options update options
Expand All @@ -202,6 +204,32 @@ public Blob update(BlobInfo blobInfo, BlobTargetOption... options) {
return new Blob(storage, storage.update(blobInfo, options));
}

/**
* Updates the blob's information according to patch semantics. Original metadata are merged with
* metadata in the provided {@code blobInfo}. To replace metadata use
* {@link #update(com.google.gcloud.storage.BlobInfo,
* com.google.gcloud.storage.Storage.BlobTargetOption...)} instead. Bucket or blob's name cannot
* be changed by this method. If you want to rename the blob or move it to a different bucket use
* the {@link #copyTo} and {@link #delete} operations. A new {@code Blob} object is returned.
*
* By default no checks are made on the metadata generation of the current blob. If you want to
* update the information only if the current blob metadata are at their latest version use the
* {@code metagenerationMatch} option:
* {@code blob.patch(newInfo, BlobTargetOption.metagenerationMatch())}.
*
* @param blobInfo updated blob's information. Bucket and blob names must match the current ones
* @param options update options
* @return a {@code Blob} object with patched information
* @throws StorageException upon failure
* @see <a href="https://cloud.google.com/storage/docs/json_api/v1/how-tos/performance#patch">
* Patch (partial update)</a>
*/
public Blob patch(BlobInfo blobInfo, BlobTargetOption... options) {
checkArgument(Objects.equals(blobInfo.bucket(), info.bucket()), "Bucket name must match");
checkArgument(Objects.equals(blobInfo.name(), info.name()), "Blob name must match");
return new Blob(storage, storage.patch(blobInfo, options));
}

/**
* Copies this blob to the specified target. Possibly copying also some of the metadata
* (e.g. content-type).
Expand Down Expand Up @@ -306,8 +334,7 @@ public Storage storage() {
}

/**
* Gets the requested blobs. If {@code infos.length == 0} an empty list is returned. If
* {@code infos.length > 1} a batch request is used to fetch blobs.
* Gets the requested blobs. A batch request is used to get blobs.
*
* @param storage the storage service used to issue the request
* @param blobs the blobs to get
Expand All @@ -331,13 +358,14 @@ public Blob apply(BlobInfo f) {
}

/**
* Updates the requested blobs. If {@code infos.length == 0} an empty list is returned. If
* {@code infos.length > 1} a batch request is used to update blobs.
* Updates the requested blobs using a batch request. Blobs metadata will be replaced using values
* from the given {@code BlobInfo} objects.
*
* @param storage the storage service used to issue the request
* @param infos the blobs to update
* @return an immutable list of {@code Blob} objects. If a blob does not exist or access to it has
* been denied the corresponding item in the list is {@code null}.
* @return an immutable list of {@code Blob} objects. If an incomplete {@code blobInfo} is
* provided, the blob does not exist or access to it has been denied the corresponding item in
* the list is {@code null}.
* @throws StorageException upon failure
*/
public static List<Blob> update(final Storage storage, BlobInfo... infos) {
Expand All @@ -356,8 +384,7 @@ public Blob apply(BlobInfo f) {
}

/**
* Deletes the requested blobs. If {@code infos.length == 0} an empty list is returned. If
* {@code infos.length > 1} a batch request is used to delete blobs.
* Deletes the requested blobs using a batch request.
*
* @param storage the storage service used to issue the request
* @param blobs the blobs to delete
Expand All @@ -374,4 +401,33 @@ public static List<Boolean> delete(Storage storage, BlobId... blobs) {
}
return storage.delete(blobs);
}

/**
* Updates the requested blobs according to the patch semantics. Original metadata are merged with
* metadata in the provided {@code BlobInfo} objects. To replace metadata use {@link
* #update(com.google.gcloud.storage.Storage, com.google.gcloud.storage.BlobInfo...)} instead.
* A batch request is used to perform this call.
*
* @param storage the storage service used to issue the request
* @param infos the blobs to update
* @return an immutable list of {@code Blob} objects. If a blob does not exist or access to it has
* been denied the corresponding item in the list is {@code null}.
* @throws StorageException upon failure
* @see <a href="https://cloud.google.com/storage/docs/json_api/v1/how-tos/performance#patch">
* Patch (partial update)</a>
*/
public static List<Blob> patch(final Storage storage, BlobInfo... infos) {
checkNotNull(storage);
checkNotNull(infos);
if (infos.length == 0) {
return Collections.emptyList();
}
return Collections.unmodifiableList(Lists.transform(storage.patch(infos),
new Function<BlobInfo, Blob>() {
@Override
public Blob apply(BlobInfo f) {
return f != null ? new Blob(storage, f) : null;
}
}));
}
}
Loading