Skip to content

Commit

Permalink
Merge pull request #251 from mziccard/add-blob-id
Browse files Browse the repository at this point in the history
Add BlobId class to identify a storage object
  • Loading branch information
aozarov committed Oct 14, 2015
2 parents 52e60ee + 41da3aa commit 5e1d71b
Show file tree
Hide file tree
Showing 21 changed files with 519 additions and 253 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ CopyRequest parse(Storage storage, String... args) {
if (args.length != 4) {
throw new IllegalArgumentException();
}
return CopyRequest.of(args[0], args[1], BlobInfo.of(args[2], args[3]));
return CopyRequest.of(args[0], args[1], BlobInfo.builder(args[2], args[3]).build());
}

@Override
Expand All @@ -420,7 +420,7 @@ ComposeRequest parse(Storage storage, String... args) {
throw new IllegalArgumentException();
}
ComposeRequest.Builder request = ComposeRequest.builder();
request.target(BlobInfo.of(args[0], args[args.length - 1]));
request.target(BlobInfo.builder(args[0], args[args.length - 1]).build());
for (int i = 1; i < args.length - 1; i++) {
request.addSource(args[i]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,31 @@ public final class BatchRequest implements Serializable {

private static final long serialVersionUID = -1527992265939800345L;

private final Map<BlobInfo, Iterable<BlobSourceOption>> toDelete;
private final Map<BlobId, Iterable<BlobSourceOption>> toDelete;
private final Map<BlobInfo, Iterable<BlobTargetOption>> toUpdate;
private final Map<BlobInfo, Iterable<BlobSourceOption>> toGet;
private final Map<BlobId, Iterable<BlobSourceOption>> toGet;

public static class Builder {

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

private Builder() {}

/**
* Delete the given blob.
*/
public Builder delete(String bucket, String blob, BlobSourceOption... options) {
toDelete.put(BlobInfo.of(bucket, blob), Lists.newArrayList(options));
toDelete.put(BlobId.of(bucket, blob), Lists.newArrayList(options));
return this;
}

/**
* Delete the given blob.
*/
public Builder delete(BlobId blob, BlobSourceOption... options) {
toDelete.put(blob, Lists.newArrayList(options));
return this;
}

Expand All @@ -65,7 +73,15 @@ public Builder update(BlobInfo blobInfo, BlobTargetOption... options) {
* Retrieve metadata for the given blob.
*/
public Builder get(String bucket, String blob, BlobSourceOption... options) {
toGet.put(BlobInfo.of(bucket, blob), Lists.newArrayList(options));
toGet.put(BlobId.of(bucket, blob), Lists.newArrayList(options));
return this;
}

/**
* Retrieve metadata for the given blob.
*/
public Builder get(BlobId blob, BlobSourceOption... options) {
toGet.put(blob, Lists.newArrayList(options));
return this;
}

Expand Down Expand Up @@ -96,15 +112,15 @@ public boolean equals(Object obj) {
&& Objects.equals(toGet, other.toGet);
}

public Map<BlobInfo, Iterable<BlobSourceOption>> toDelete() {
public Map<BlobId, Iterable<BlobSourceOption>> toDelete() {
return toDelete;
}

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

public Map<BlobInfo, Iterable<BlobSourceOption>> toGet() {
public Map<BlobId, Iterable<BlobSourceOption>> toGet() {
return toGet;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import com.google.gcloud.storage.Storage.SignUrlOption;

import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -119,7 +118,19 @@ public Blob(Storage storage, BlobInfo info) {
*/
public Blob(Storage storage, String bucket, String blob) {
this.storage = checkNotNull(storage);
this.info = BlobInfo.of(checkNotNull(bucket), checkNotNull(blob));
this.info = BlobInfo.builder(BlobId.of(bucket, blob)).build();
}

/**
* Constructs a {@code Blob} object for the provided {@code BlobId}. The storage service is used
* to issue requests.
*
* @param storage the storage service used for issuing requests
* @param blobId blob's identifier
*/
public Blob(Storage storage, BlobId blobId) {
this.storage = checkNotNull(storage);
this.info = BlobInfo.builder(blobId).build();
}

/**
Expand All @@ -129,14 +140,21 @@ public BlobInfo info() {
return info;
}

/**
* Returns the blob's id.
*/
public BlobId id() {
return info.blobId();
}

/**
* Checks if this blob exists.
*
* @return true if this blob exists, false otherwise
* @throws StorageException upon failure
*/
public boolean exists() {
return storage.get(info.bucket(), info.name()) != null;
return storage.get(info.blobId()) != null;
}

/**
Expand All @@ -146,7 +164,7 @@ public boolean exists() {
* @throws StorageException upon failure
*/
public byte[] content(Storage.BlobSourceOption... options) {
return storage.readAllBytes(info.bucket(), info.name(), options);
return storage.readAllBytes(info.blobId(), options);
}

/**
Expand All @@ -157,7 +175,7 @@ public byte[] content(Storage.BlobSourceOption... options) {
* @throws StorageException upon failure
*/
public Blob reload(BlobSourceOption... options) {
return new Blob(storage, storage.get(info.bucket(), info.name(), convert(info, options)));
return new Blob(storage, storage.get(info.blobId(), convert(info, options)));
}

/**
Expand All @@ -179,6 +197,23 @@ public Blob update(BlobInfo blobInfo, BlobTargetOption... options) {
return new Blob(storage, storage.update(blobInfo, options));
}

/**
* Copies this blob to the specified target. Possibly copying also some of the metadata
* (e.g. content-type).
*
* @param targetBlob target blob's id
* @param options source blob options
* @return the copied blob
* @throws StorageException upon failure
*/
public Blob copyTo(BlobId targetBlob, BlobSourceOption... options) {
BlobInfo updatedInfo = info.toBuilder().blobId(targetBlob).build();
CopyRequest copyRequest =
CopyRequest.builder().source(info.bucket(), info.name())
.sourceOptions(convert(info, options)).target(updatedInfo).build();
return new Blob(storage, storage.copy(copyRequest));
}

/**
* Deletes this blob.
*
Expand All @@ -187,7 +222,7 @@ public Blob update(BlobInfo blobInfo, BlobTargetOption... options) {
* @throws StorageException upon failure
*/
public boolean delete(BlobSourceOption... options) {
return storage.delete(info.bucket(), info.name(), convert(info, options));
return storage.delete(info.blobId(), convert(info, options));
}

/**
Expand All @@ -214,7 +249,7 @@ public Blob copyTo(String targetBucket, BlobSourceOption... options) {
* @throws StorageException upon failure
*/
public Blob copyTo(String targetBucket, String targetBlob, BlobSourceOption... options) {
BlobInfo updatedInfo = info.toBuilder().bucket(targetBucket).name(targetBlob).build();
BlobInfo updatedInfo = info.toBuilder().blobId(BlobId.of(targetBucket, targetBlob)).build();
CopyRequest copyRequest =
CopyRequest.builder().source(info.bucket(), info.name())
.sourceOptions(convert(info, options)).target(updatedInfo).build();
Expand All @@ -228,7 +263,7 @@ public Blob copyTo(String targetBucket, String targetBlob, BlobSourceOption... o
* @throws StorageException upon failure
*/
public BlobReadChannel reader(BlobSourceOption... options) {
return storage.reader(info.bucket(), info.name(), convert(info, options));
return storage.reader(info.blobId(), convert(info, options));
}

/**
Expand Down Expand Up @@ -270,18 +305,18 @@ public Storage storage() {
* {@code infos.length > 1} a batch request is used to fetch blobs.
*
* @param storage the storage service used to issue the request
* @param infos the blobs to get
* @param blobs the blobs to get
* @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
*/
public static List<Blob> get(final Storage storage, BlobInfo... infos) {
public static List<Blob> get(final Storage storage, BlobId... blobs) {
checkNotNull(storage);
checkNotNull(infos);
if (infos.length == 0) {
checkNotNull(blobs);
if (blobs.length == 0) {
return Collections.emptyList();
}
return Collections.unmodifiableList(Lists.transform(storage.get(infos),
return Collections.unmodifiableList(Lists.transform(storage.get(blobs),
new Function<BlobInfo, Blob>() {
@Override
public Blob apply(BlobInfo f) {
Expand Down Expand Up @@ -320,18 +355,18 @@ public Blob apply(BlobInfo f) {
* {@code infos.length > 1} a batch request is used to delete blobs.
*
* @param storage the storage service used to issue the request
* @param infos the blobs to delete
* @param blobs the blobs to delete
* @return an immutable list of booleans. If a blob has been deleted the corresponding item in the
* list is {@code true}. If deletion failed or access to the resource was denied the item is
* {@code false}.
* @throws StorageException upon failure
*/
public static List<Boolean> delete(Storage storage, BlobInfo... infos) {
public static List<Boolean> delete(Storage storage, BlobId... blobs) {
checkNotNull(storage);
checkNotNull(infos);
if (infos.length == 0) {
checkNotNull(blobs);
if (blobs.length == 0) {
return Collections.emptyList();
}
return storage.delete(infos);
return storage.delete(blobs);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.gcloud.storage;

import com.google.api.services.storage.model.StorageObject;
import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.MoreObjects;

import java.io.Serializable;
import java.util.Objects;

/**
* Google Storage object identifier.
*/
public final class BlobId implements Serializable {

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

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

public String bucket() {
return bucket;
}

public String name() {
return name;
}

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

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

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

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

public static BlobId of(String bucket, String name) {
return new BlobId(checkNotNull(bucket), checkNotNull(name));
}

static BlobId fromPb(StorageObject storageObject) {
return BlobId.of(storageObject.getBucket(), storageObject.getName());
}
}
Loading

0 comments on commit 5e1d71b

Please sign in to comment.