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

add metadata update to example and fix builder user-settable fields #58

Merged
merged 5 commits into from
May 14, 2015
Merged
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
177 changes: 154 additions & 23 deletions src/main/java/com/google/gcloud/examples/StorageExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
/**
* An example of using the Google Cloud Storage.
* <p>
* This example demonstrates a simple/typical usage.
* This example demonstrates a simple/typical storage usage.
* <p>
* Steps needed for running the example:
* <ol>
Expand All @@ -57,9 +57,14 @@
* -Dexec.args="[<project_id>] list [<bucket>]| info [<bucket> [<file>]]|
* download <bucket> <path> [local_file]| upload <local_file> <bucket> [<path>]|
* delete <bucket> <path>+| cp <from_bucket> <from_path> <to_bucket> <to_path>|
* compose <bucket> <from_path>+ <to_path>"}
* compose <bucket> <from_path>+ <to_path>| update_metadata <bucket> <file> [key=value]*"}
* </li>
* </ol>
*
* The first parameter is an optional project_id (logged-in project will be used if not supplied).
* Second parameter is a Storage operation (list, delete, compose,...) to demonstrate the its
* usage. Any other arguments are specific to the operation.
* See each action's run method for the specific Storage interaction.
*/
public class StorageExample {

Expand Down Expand Up @@ -112,24 +117,36 @@ public String params() {
}
}

/**
* This class demonstrates how to retrieve Bucket or Blob metadata.
* If more than one blob is supplied a Batch operation would be used to get all blobs metadata
* in a single RPC.
*
* @see <a href="https://cloud.google.com/storage/docs/json_api/v1/objects/get">Objects: get</a>
*/
private static class InfoAction extends BlobsAction {
@Override
public void run(StorageService storage, Blob... blobs) {


if (blobs.length == 1) {
if (blobs[0].name().isEmpty()) {
System.out.println(storage.get(blobs[0].bucket()));
// get Bucket
Bucket bucket = storage.get(blobs[0].bucket());
System.out.println("Bucket info: " + bucket);
} else {
System.out.println(storage.get(blobs[0].bucket(), blobs[0].name()));
// get Blob
Blob blob = storage.get(blobs[0].bucket(), blobs[0].name());
System.out.println("Blob info: " + blob);
}
} else {
// use batch to get multiple blobs.
BatchRequest.Builder batch = BatchRequest.builder();
for (Blob blob : blobs) {
batch.get(blob.bucket(), blob.name());
}
BatchResponse response = storage.apply(batch.build());
System.out.println(response.gets());
for (BatchResponse.Result<Blob> result : response.gets()) {
System.out.println(result.get());
}
}
}

Expand All @@ -147,22 +164,45 @@ public String params() {
}
}

/**
* This class demonstrates how to delete a blob.
* If more than one blob is supplied a Batch operation would be used to delete all requested
* blobs in a single RPC.
*
* @see <a href="https://cloud.google.com/storage/docs/json_api/v1/objects/delete">Objects: delete</a>
*/
private static class DeleteAction extends BlobsAction {
@Override
public void run(StorageService storage, Blob... blobs) {
if (blobs.length == 1) {
System.out.println(storage.delete(blobs[0].bucket(), blobs[0].name()));
boolean wasDeleted = storage.delete(blobs[0].bucket(), blobs[0].name());
if (wasDeleted) {
System.out.println("Blob " + blobs[0] + " was deleted");
}
} else {
// use batch operation
BatchRequest.Builder batch = BatchRequest.builder();
for (Blob blob : blobs) {
batch.delete(blob.bucket(), blob.name());
}
int index = 0;
BatchResponse response = storage.apply(batch.build());
System.out.println(response.deletes());
for (BatchResponse.Result<Boolean> result : response.deletes()) {
if (result.get()) {
// request order is maintained
System.out.println("Blob " + blobs[index] + " was deleted");
}
index++;
}
}
}
}

/**
* This class demonstrates how to list buckets or a bucket's blobs.
*
* @see <a href="https://cloud.google.com/storage/docs/json_api/v1/objects/list">Objects: list</a>
*/
private static class ListAction extends StorageAction<String> {

@Override
Expand All @@ -179,10 +219,12 @@ String parse(String... args) {
@Override
public void run(StorageService storage, String bucket) {
if (bucket == null) {
// list buckets
for (Bucket b : storage.list()) {
System.out.println(b);
}
} else {
// list a bucket's blobs
for (Blob b : storage.list(bucket)) {
System.out.println(b);
}
Expand All @@ -195,13 +237,24 @@ public String params() {
}
}

/**
* This class demonstrates how to create a new Blob or to update its content.
*
* @see <a href="https://cloud.google.com/storage/docs/json_api/v1/objects/insert">Objects: insert</a>
*/
private static class UploadAction extends StorageAction<Tuple<Path, Blob>> {
@Override
public void run(StorageService storage, Tuple<Path, Blob> tuple) throws Exception {
if (Files.size(tuple.x()) > 1024) {
try (BlobWriteChannel writer = storage.writer(tuple.y())) {
run(storage, tuple.x(), tuple.y());
}

private void run(StorageService storage, Path uploadFrom, Blob blob) throws IOException {
if (Files.size(uploadFrom) > 1_000_000) {
// When content is not available or large (1MB or more) it is recommended
// to write it in chunks via the blob's channel writer.
try (BlobWriteChannel writer = storage.writer(blob)) {
byte[] buffer = new byte[1024];
try (InputStream input = Files.newInputStream(tuple.x())) {
try (InputStream input = Files.newInputStream(uploadFrom)) {
int limit;
while ((limit = input.read(buffer)) >= 0) {
try {
Expand All @@ -213,9 +266,11 @@ public void run(StorageService storage, Tuple<Path, Blob> tuple) throws Exceptio
}
}
} else {
byte[] bytes = Files.readAllBytes(tuple.x());
System.out.println(storage.create(tuple.y(), bytes));
byte[] bytes = Files.readAllBytes(uploadFrom);
// create the blob in one request.
storage.create(blob, bytes);
}
System.out.println("Blob was created");
}

@Override
Expand All @@ -235,22 +290,37 @@ public String params() {
}
}

/**
* This class demonstrates how read a blob's content.
* The example will dump the content to a local file if one was given or write
* it to stdout otherwise.
*
* @see <a href="https://cloud.google.com/storage/docs/json_api/v1/objects/get">Objects: get</a>
*/
private static class DownloadAction extends StorageAction<Tuple<Blob, Path>> {

@Override
public void run(StorageService storage, Tuple<Blob, Path> tuple) throws IOException {
Blob blob = storage.get(tuple.x().bucket(), tuple.x().name());
run(storage, tuple.x().bucket(), tuple.x().name(), tuple.y());
}

private void run(StorageService storage, String bucket, String blobName, Path downloadTo)
throws IOException {
Blob blob = storage.get(bucket, blobName);
if (blob == null) {
System.out.println("No such object");
return;
}
PrintStream writeTo = System.out;
if (tuple.y() != null) {
writeTo = new PrintStream(new FileOutputStream(tuple.y().toFile()));
if (downloadTo != null) {
writeTo = new PrintStream(new FileOutputStream(downloadTo.toFile()));
}
if (blob.size() < 1024) {
writeTo.write(storage.load(blob.bucket(), blob.name()));
if (blob.size() < 1_000_000) {
// Blob is small read all its content in one request
byte[] content = storage.load(blob.bucket(), blob.name());
writeTo.write(content);
} else {
// When Blob size is big or unknown use the blob's channel reader.
try (BlobReadChannel reader = storage.reader(blob.bucket(), blob.name())) {
WritableByteChannel channel = Channels.newChannel(writeTo);
ByteBuffer bytes = ByteBuffer.allocate(64 * 1024);
Expand All @@ -261,7 +331,7 @@ public void run(StorageService storage, Tuple<Blob, Path> tuple) throws IOExcept
}
}
}
if (tuple.y() == null) {
if (downloadTo == null) {
writeTo.println();
} else {
writeTo.close();
Expand Down Expand Up @@ -291,10 +361,16 @@ public String params() {
}
}

/**
* This class demonstrates how to use the copy command.
*
* @see <a href="https://cloud.google.com/storage/docs/json_api/v1/objects/copy">Objects: copy</a>
*/
private static class CopyAction extends StorageAction<CopyRequest> {
@Override
public void run(StorageService storage, CopyRequest request) {
System.out.println(storage.copy(request));
Blob copiedBlob = storage.copy(request);
System.out.println("Copied " + copiedBlob);
}

@Override
Expand All @@ -311,10 +387,16 @@ public String params() {
}
}

/**
* This class demonstrates how to use the compose command.
*
* @see <a href="https://cloud.google.com/storage/docs/json_api/v1/objects/compose">Objects: compose</a>
*/
private static class ComposeAction extends StorageAction<ComposeRequest> {
@Override
public void run(StorageService storage, ComposeRequest request) {
System.out.println(storage.compose(request));
Blob composedBlob = storage.compose(request);
System.out.println("Composed " + composedBlob);
}

@Override
Expand All @@ -336,6 +418,54 @@ public String params() {
}
}

/**
* This class demonstrates how to update a blob's metadata.
*
* @see <a href="https://cloud.google.com/storage/docs/json_api/v1/objects/update">Objects: update</a>
*/
private static class UpdateMetadata extends StorageAction<Tuple<Blob, Map<String, String>>> {

This comment was marked as spam.

This comment was marked as spam.


@Override
public void run(StorageService storage, Tuple<Blob, Map<String, String>> tuple)
throws IOException {
run(storage, tuple.x().bucket(), tuple.x().name(), tuple.y());
}

private void run(StorageService storage, String bucket, String blobName,
Map<String, String> metadata) {
Blob blob = storage.get(bucket, blobName);
if (blob == null) {
System.out.println("No such object");
return;
}
blob = storage.update(blob.toBuilder().metadata(metadata).build());
System.out.println("Updated " + blob);
}

@Override
Tuple<Blob, Map<String, String>> parse(String... args) {
if (args.length < 2) {
throw new IllegalArgumentException();
}
Blob blob = Blob.of(args[0], args[1]);
Map<String, String> metadata = new HashMap<>();
for (int i = 2; i < args.length; i++) {
int idx = args[i].indexOf('=');
if (idx < 0) {
metadata.put(args[i], "");
} else {
metadata.put(args[i].substring(0, idx), args[i].substring(idx + 1));
}
}
return Tuple.of(blob, metadata);
}

@Override
public String params() {
return "<bucket> <path> [local_file]";
}
}

static {
ACTIONS.put("info", new InfoAction());
ACTIONS.put("delete", new DeleteAction());
Expand All @@ -344,6 +474,7 @@ public String params() {
ACTIONS.put("download", new DownloadAction());
ACTIONS.put("cp", new CopyAction());
ACTIONS.put("compose", new ComposeAction());
ACTIONS.put("update_metadata", new UpdateMetadata());
}

public static void printUsage() {
Expand Down Expand Up @@ -378,7 +509,7 @@ public static void main(String... args) throws Exception {
args = Arrays.copyOfRange(args, 1, args.length);
}
if (action == null) {
System.out.println("Unrecognized action '" + args[1] + "'");
System.out.println("Unrecognized action.");
printUsage();
return;
}
Expand Down
Loading