From f201a7a034a5a4c44e1c1469d89e4c83389a5ad1 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 18 Aug 2016 17:40:01 +0200 Subject: [PATCH] Add snippets to Bucket's javadoc, BucketSnippets class and tests --- .../storage/snippets/BucketSnippets.java | 227 ++++++++++++++++++ .../storage/snippets/ITBucketSnippets.java | 108 +++++++++ .../java/com/google/cloud/storage/Bucket.java | 108 ++++++++- 3 files changed, 442 insertions(+), 1 deletion(-) create mode 100644 gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/BucketSnippets.java create mode 100644 gcloud-java-examples/src/test/java/com/google/cloud/examples/storage/snippets/ITBucketSnippets.java diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/BucketSnippets.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/BucketSnippets.java new file mode 100644 index 000000000000..df6c0d68d742 --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/BucketSnippets.java @@ -0,0 +1,227 @@ +/* + * Copyright 2016 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. + */ + +/* + * EDITING INSTRUCTIONS + * This file is referenced in Bucket's javadoc. Any change to this file should be reflected in + * Bucket's javadoc. + */ + +package com.google.cloud.examples.storage.snippets; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.google.cloud.storage.Blob; +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.Bucket.BucketSourceOption; +import com.google.cloud.storage.Storage.BlobGetOption; +import com.google.cloud.storage.StorageException; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/** + * This class contains a number of snippets for the {@link Bucket} class. + */ +public class BucketSnippets { + + private final Bucket bucket; + + public BucketSnippets(Bucket bucket) { + this.bucket = bucket; + } + + /** + * Example of checking if the bucket exists. + */ + // [TARGET exists(BucketSourceOption...)] + public boolean exists() { + // [START exists] + boolean exists = bucket.exists(); + if (exists) { + // the bucket exists + } else { + // the bucket was not found + } + // [END exists] + return exists; + } + + /** + * Example of getting the bucket's latest information, if its generation does not match the + * {@link Bucket#metageneration()} value, otherwise a {@link StorageException} is thrown. + */ + // [TARGET reload(BucketSourceOption...)] + public Bucket reload() { + // [START reload] + Bucket latestBucket = bucket.reload(BucketSourceOption.metagenerationMatch()); + if (latestBucket == null) { + // the bucket was not found + } + // [END reload] + return bucket; + } + + /** + * Example of updating the bucket's information. + */ + // [TARGET update(BucketTargetOption...)] + public Bucket update() { + // [START update] + Bucket updatedBucket = bucket.toBuilder().versioningEnabled(true).build().update(); + // [END update] + return updatedBucket; + } + + /** + * Example of deleting the bucket, if its metageneration matches the + * {@link Bucket#metageneration()} value, otherwise a {@link StorageException} is thrown. + */ + // [TARGET delete(BucketSourceOption...)] + public boolean delete() { + // [START delete] + boolean deleted = bucket.delete(BucketSourceOption.metagenerationMatch()); + if (deleted) { + // the bucket was deleted + } else { + // the bucket was not found + } + // [END delete] + return deleted; + } + + /** + * Example of listing the blobs in the bucket. + */ + // [TARGET list(BlobListOption...)] + public Iterator listBlobs() { + // [START listBlobs] + Iterator blobIterator = bucket.list().iterateAll(); + while (blobIterator.hasNext()) { + Blob blob = blobIterator.next(); + // do something with the blob + } + // [END listBlobs] + return blobIterator; + } + + /** + * Example of getting a blob in the bucket, only if its metageneration matches a value, otherwise + * a {@link StorageException} is thrown. + */ + // [TARGET get(String, BlobGetOption...)] + // [VARIABLE "my_blob_name"] + // [VARIABLE 42] + public Blob getBlob(String blobName, long generation) { + // [START getBlob] + Blob blob = bucket.get(blobName, BlobGetOption.generationMatch(generation)); + // [END getBlob] + return blob; + } + + + /** + * Example of getting some blobs in the bucket, using a batch request. + */ + // [TARGET get(String, String, String...)] + // [VARIABLE "my_blob_name1"] + // [VARIABLE "my_blob_name2"] + public List getBlobFromStrings(String blobName1, String blobName2) { + // [START getBlobFromStrings] + List blobs = bucket.get(blobName1, blobName2); + for (Blob blob : blobs) { + if (blob == null) { + // the blob was not found + } + } + // [END getBlobFromStrings] + return blobs; + } + + /** + * Example of getting some blobs in the bucket, using a batch request. + */ + // [TARGET get(Iterable)] + // [VARIABLE "my_blob_name1"] + // [VARIABLE "my_blob_name2"] + public List getBlobFromStringIterable(String blobName1, String blobName2) { + // [START getBlobFromStringIterable] + List blobNames = new LinkedList<>(); + blobNames.add(blobName1); + blobNames.add(blobName2); + List blobs = bucket.get(blobNames); + for (Blob blob : blobs) { + if (blob == null) { + // the blob was not found + } + } + // [END getBlobFromStringIterable] + return blobs; + } + + /** + * Example of creating a blob in the bucket from a byte array. + */ + // [TARGET create(String, byte[], BlobTargetOption...)] + // [VARIABLE "my_blob_name"] + public Blob createBlobFromByteArray(String blobName) { + // [START createBlobFromByteArray] + Blob blob = bucket.create(blobName, "Hello, World!".getBytes(UTF_8)); + // [END createBlobFromByteArray] + return blob; + } + + /** + * Example of creating a blob in the bucket from an input stream. + */ + // [TARGET create(String, InputStream, BlobWriteOption...)] + // [VARIABLE "my_blob_name"] + public Blob createBlobFromInputStream(String blobName) { + // [START createBlobFromInputStream] + InputStream content = new ByteArrayInputStream("Hello, World!".getBytes(UTF_8)); + Blob blob = bucket.create(blobName, content); + // [END createBlobFromInputStream] + return blob; + } + + /** + * Example of creating a blob in the bucket from a byte array with a content type. + */ + // [TARGET create(String, byte[], String, BlobTargetOption...)] + // [VARIABLE "my_blob_name"] + public Blob createBlobFromByteArrayWithContentType(String blobName) { + // [START createBlobFromByteArrayWithContentType] + Blob blob = bucket.create(blobName, "Hello, World!".getBytes(UTF_8), "text/plain"); + // [END createBlobFromByteArrayWithContentType] + return blob; + } + + /** + * Example of creating a blob in the bucket from an input stream with a content type. + */ + // [TARGET create(String, InputStream, String, BlobWriteOption...)] + // [VARIABLE "my_blob_name"] + public Blob createBlobFromInputStreamWithContentType(String blobName) { + // [START createBlobFromInputStreamWithContentType] + InputStream content = new ByteArrayInputStream("Hello, World!".getBytes(UTF_8)); + Blob blob = bucket.create(blobName, content, "text/plain"); + // [END createBlobFromInputStreamWithContentType] + return blob; + } +} diff --git a/gcloud-java-examples/src/test/java/com/google/cloud/examples/storage/snippets/ITBucketSnippets.java b/gcloud-java-examples/src/test/java/com/google/cloud/examples/storage/snippets/ITBucketSnippets.java new file mode 100644 index 000000000000..95549af2b732 --- /dev/null +++ b/gcloud-java-examples/src/test/java/com/google/cloud/examples/storage/snippets/ITBucketSnippets.java @@ -0,0 +1,108 @@ +/* + * Copyright 2016 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.cloud.examples.storage.snippets; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import com.google.cloud.storage.Blob; +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.BucketInfo; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageException; +import com.google.cloud.storage.testing.RemoteStorageHelper; +import com.google.common.collect.ImmutableSet; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ITBucketSnippets { + + private static final Logger log = Logger.getLogger(ITBucketSnippets.class.getName()); + private static final String BUCKET = RemoteStorageHelper.generateBucketName(); + private static final String BLOB1 = "blob1"; + private static final String BLOB2 = "blob2"; + private static final String BLOB3 = "blob3"; + private static final String BLOB4 = "blob4"; + private static final Set BLOBS = ImmutableSet.of(BLOB1, BLOB2, BLOB3, BLOB4); + + private static Storage storage; + private static BucketSnippets bucketSnippets; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @BeforeClass + public static void beforeClass() { + RemoteStorageHelper helper = RemoteStorageHelper.create(); + storage = helper.options().service(); + bucketSnippets = new BucketSnippets(storage.create(BucketInfo.of(BUCKET))); + } + + @AfterClass + public static void afterClass() throws ExecutionException, InterruptedException { + if (storage != null) { + boolean wasDeleted = RemoteStorageHelper.forceDelete(storage, BUCKET, 5, TimeUnit.SECONDS); + if (!wasDeleted && log.isLoggable(Level.WARNING)) { + log.log(Level.WARNING, "Deletion of bucket {0} timed out, bucket is not empty", BUCKET); + } + } + } + + @Test + public void testBucket() { + assertTrue(bucketSnippets.exists()); + Bucket bucket = bucketSnippets.reload(); + assertNotNull(bucket); + Bucket updatedBucket = bucketSnippets.update(); + assertTrue(updatedBucket.versioningEnabled()); + Blob blob1 = bucketSnippets.createBlobFromByteArray(BLOB1); + assertNotNull(blob1); + Blob blob2 = bucketSnippets.createBlobFromByteArrayWithContentType(BLOB2); + assertNotNull(blob2); + Blob blob3 = bucketSnippets.createBlobFromInputStream(BLOB3); + assertNotNull(blob3); + Blob blob4 = bucketSnippets.createBlobFromInputStreamWithContentType(BLOB4); + assertNotNull(blob4); + Iterator blobIterator = bucketSnippets.listBlobs(); + while (blobIterator.hasNext()) { + assertTrue(BLOBS.contains(blobIterator.next().name())); + } + blob1 = bucketSnippets.getBlob(BLOB1, blob1.generation()); + assertEquals(BLOB1, blob1.name()); + List blobs = bucketSnippets.getBlobFromStrings(BLOB2, BLOB3); + assertEquals(BLOB2, blobs.get(0).name()); + assertEquals(BLOB3, blobs.get(1).name()); + blobs = bucketSnippets.getBlobFromStringIterable(BLOB3, BLOB4); + assertEquals(BLOB3, blobs.get(0).name()); + assertEquals(BLOB4, blobs.get(1).name()); + thrown.expect(StorageException.class); + assertTrue(bucketSnippets.delete()); + } +} diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java index ebb6835eba4b..d342eb92146c 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java @@ -23,6 +23,7 @@ import com.google.cloud.Page; import com.google.cloud.storage.Storage.BlobGetOption; +import com.google.cloud.storage.Storage.BlobListOption; import com.google.cloud.storage.Storage.BucketTargetOption; import com.google.cloud.storage.spi.StorageRpc; import com.google.common.base.Function; @@ -530,6 +531,16 @@ public Bucket build() { /** * Checks if this bucket exists. * + *

Example of checking if the bucket exists. + *

 {@code
+   * boolean exists = bucket.exists();
+   * if (exists) {
+   *   // the bucket exists
+   * } else {
+   *   // the bucket was not found
+   * }
+   * }
+ * * @return true if this bucket exists, false otherwise * @throws StorageException upon failure */ @@ -543,6 +554,15 @@ public boolean exists(BucketSourceOption... options) { /** * Fetches current bucket's latest information. Returns {@code null} if the bucket does not exist. * + *

Example of getting the bucket's latest information, if its generation does not match the + * {@link Bucket#metageneration()} value, otherwise a {@link StorageException} is thrown. + *

 {@code
+   * Bucket latestBucket = bucket.reload(BucketSourceOption.metagenerationMatch());
+   * if (latestBucket == null) {
+   *   // the bucket was not found
+   * }
+   * }
+ * * @param options bucket read options * @return a {@code Bucket} object with latest information or {@code null} if not found * @throws StorageException upon failure @@ -558,6 +578,11 @@ public Bucket reload(BucketSourceOption... options) { * version use the {@code metagenerationMatch} option: * {@code bucket.update(BucketTargetOption.metagenerationMatch())} * + *

Example of updating the bucket's information. + *

 {@code
+   * Bucket updatedBucket = bucket.toBuilder().versioningEnabled(true).build().update();
+   * }
+ * * @param options update options * @return a {@code Bucket} object with updated information * @throws StorageException upon failure @@ -569,6 +594,17 @@ public Bucket update(BucketTargetOption... options) { /** * Deletes this bucket. * + *

Example of deleting the bucket, if its metageneration matches the + * {@link Bucket#metageneration()} value, otherwise a {@link StorageException} is thrown. + *

 {@code
+   * boolean deleted = bucket.delete(BucketSourceOption.metagenerationMatch());
+   * if (deleted) {
+   *   // the bucket was deleted
+   * } else {
+   *   // the bucket was not found
+   * }
+   * }
+ * * @param options bucket delete options * @return {@code true} if bucket was deleted, {@code false} if it was not found * @throws StorageException upon failure @@ -580,16 +616,33 @@ public boolean delete(BucketSourceOption... options) { /** * Returns the paginated list of {@code Blob} in this bucket. * + *

Example of listing the blobs in the bucket. + *

 {@code
+   * Iterator blobIterator = bucket.list().iterateAll();
+   * while (blobIterator.hasNext()) {
+   *   Blob blob = blobIterator.next();
+   *   // do something with the blob
+   * }
+   * }
+ * * @param options options for listing blobs * @throws StorageException upon failure */ - public Page list(Storage.BlobListOption... options) { + public Page list(BlobListOption... options) { return storage.list(name(), options); } /** * Returns the requested blob in this bucket or {@code null} if not found. * + *

Example of getting a blob in the bucket, only if its metageneration matches a value, otherwise + * a {@link StorageException} is thrown. + *

 {@code
+   * String blobName = "my_blob_name";
+   * long generation = 42;
+   * Blob blob = bucket.get(blobName, BlobGetOption.generationMatch(generation));
+   * }
+ * * @param blob name of the requested blob * @param options blob search options * @throws StorageException upon failure @@ -601,6 +654,18 @@ public Blob get(String blob, BlobGetOption... options) { /** * Returns a list of requested blobs in this bucket. Blobs that do not exist are null. * + *

Example of getting some blobs in the bucket, using a batch request. + *

 {@code
+   * String blobName1 = "my_blob_name1";
+   * String blobName2 = "my_blob_name2";
+   * List blobs = bucket.get(blobName1, blobName2);
+   * for (Blob blob : blobs) {
+   *   if (blob == null) {
+   *     // the blob was not found
+   *   }
+   * }
+   * }
+ * * @param blobName1 first blob to get * @param blobName2 second blob to get * @param blobNames other blobs to get @@ -620,6 +685,21 @@ public List get(String blobName1, String blobName2, String... blobNames) { /** * Returns a list of requested blobs in this bucket. Blobs that do not exist are null. * + *

Example of getting some blobs in the bucket, using a batch request. + *

 {@code
+   * String blobName1 = "my_blob_name1";
+   * String blobName2 = "my_blob_name2";
+   * List blobNames = new LinkedList<>();
+   * blobNames.add(blobName1);
+   * blobNames.add(blobName2);
+   * List blobs = bucket.get(blobNames);
+   * for (Blob blob : blobs) {
+   *   if (blob == null) {
+   *     // the blob was not found
+   *   }
+   * }
+   * }
+ * * @param blobNames blobs to get * @return an immutable list of {@code Blob} objects * @throws StorageException upon failure @@ -638,6 +718,12 @@ public List get(Iterable blobNames) { * is recommended as it uses resumable upload. MD5 and CRC32C hashes of {@code content} are * computed and used for validating transferred data. * + *

Example of creating a blob in the bucket from a byte array with a content type. + *

 {@code
+   * String blobName = "my_blob_name";
+   * Blob blob = bucket.create(blobName, "Hello, World!".getBytes(UTF_8), "text/plain");
+   * }
+ * * @param blob a blob name * @param content the blob content * @param contentType the blob content type @@ -657,6 +743,13 @@ public Blob create(String blob, byte[] content, String contentType, BlobTargetOp * For large content, {@link Blob#writer(com.google.cloud.storage.Storage.BlobWriteOption...)} * is recommended as it uses resumable upload. * + *

Example of creating a blob in the bucket from an input stream with a content type. + *

 {@code
+   * String blobName = "my_blob_name";
+   * InputStream content = new ByteArrayInputStream("Hello, World!".getBytes(UTF_8));
+   * Blob blob = bucket.create(blobName, content, "text/plain");
+   * }
+ * * @param blob a blob name * @param content the blob content as a stream * @param contentType the blob content type @@ -678,6 +771,12 @@ public Blob create(String blob, InputStream content, String contentType, * is recommended as it uses resumable upload. MD5 and CRC32C hashes of {@code content} are * computed and used for validating transferred data. * + *

Example of creating a blob in the bucket from a byte array. + *

 {@code
+   * String blobName = "my_blob_name";
+   * Blob blob = bucket.create(blobName, "Hello, World!".getBytes(UTF_8));
+   * }
+ * * @param blob a blob name * @param content the blob content * @param options options for blob creation @@ -696,6 +795,13 @@ public Blob create(String blob, byte[] content, BlobTargetOption... options) { * For large content, {@link Blob#writer(com.google.cloud.storage.Storage.BlobWriteOption...)} * is recommended as it uses resumable upload. * + *

Example of creating a blob in the bucket from an input stream. + *

 {@code
+   * String blobName = "my_blob_name";
+   * InputStream content = new ByteArrayInputStream("Hello, World!".getBytes(UTF_8));
+   * Blob blob = bucket.create(blobName, content);
+   * }
+ * * @param blob a blob name * @param content the blob content as a stream * @param options options for blob creation