diff --git a/README.md b/README.md index 1113ce2fb25f..207009ee6475 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ Java idiomatic client for [Google Cloud Platform][cloud-platform] services. [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java.svg) +[![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs) @@ -42,17 +43,17 @@ libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.3" Example Applications -------------------- -- [`BigQueryExample`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-examples/src/main/java/com/google/gcloud/examples/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality +- [`BigQueryExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/BigQueryExample.html). - [`Bookshelf`](https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/bookshelf) - An App Engine app that manages a virtual bookshelf. - This app uses `gcloud-java` to interface with Cloud Datastore and Cloud Storage. It also uses Cloud SQL, another Google Cloud Platform service. -- [`DatastoreExample`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-examples/src/main/java/com/google/gcloud/examples/DatastoreExample.java) - A simple command line interface for the Cloud Datastore +- [`DatastoreExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java) - A simple command line interface for the Cloud Datastore - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/DatastoreExample.html). -- [`ResourceManagerExample`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-examples/src/main/java/com/google/gcloud/examples/ResourceManagerExample.java) - A simple command line interface providing some of Cloud Resource Manager's functionality +- [`ResourceManagerExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java) - A simple command line interface providing some of Cloud Resource Manager's functionality - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/ResourceManagerExample.html). -- [`SparkDemo`](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/managedvms/sparkjava) - An example of using gcloud-java-datastore from within the SparkJava and App Engine Managed VM frameworks. - - Read about how it works on the example's [README page](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/managedvms/sparkjava#how-does-it-work). -- [`StorageExample`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java) - A simple command line interface providing some of Cloud Storage's functionality +- [`SparkDemo`](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/managed_vms/sparkjava) - An example of using gcloud-java-datastore from within the SparkJava and App Engine Managed VM frameworks. + - Read about how it works on the example's [README page](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/managed_vms/sparkjava#how-does-it-work). +- [`StorageExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java) - A simple command line interface providing some of Cloud Storage's functionality - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/StorageExample.html). Specifying a Project ID @@ -123,15 +124,15 @@ Google Cloud BigQuery (Alpha) Here is a code snippet showing a simple usage example from within Compute/App Engine. Note that you must [supply credentials](#authentication) and a project ID if running this snippet elsewhere. +Complete source code can be found at +[CreateTableAndLoadData.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/CreateTableAndLoadData.java). ```java import com.google.gcloud.bigquery.BigQuery; import com.google.gcloud.bigquery.BigQueryOptions; import com.google.gcloud.bigquery.Field; +import com.google.gcloud.bigquery.FormatOptions; import com.google.gcloud.bigquery.Job; -import com.google.gcloud.bigquery.JobStatus; -import com.google.gcloud.bigquery.JobInfo; -import com.google.gcloud.bigquery.LoadJobConfiguration; import com.google.gcloud.bigquery.Schema; import com.google.gcloud.bigquery.StandardTableDefinition; import com.google.gcloud.bigquery.Table; @@ -145,19 +146,17 @@ if (table == null) { System.out.println("Creating table " + tableId); Field integerField = Field.of("fieldName", Field.Type.integer()); Schema schema = Schema.of(integerField); - bigquery.create(TableInfo.of(tableId, StandardTableDefinition.of(schema))); + table = bigquery.create(TableInfo.of(tableId, StandardTableDefinition.of(schema))); +} +System.out.println("Loading data into table " + tableId); +Job loadJob = table.load(FormatOptions.csv(), "gs://bucket/path"); +while (!loadJob.isDone()) { + Thread.sleep(1000L); +} +if (loadJob.status().error() != null) { + System.out.println("Job completed with errors"); } else { - System.out.println("Loading data into table " + tableId); - LoadJobConfiguration configuration = LoadJobConfiguration.of(tableId, "gs://bucket/path"); - Job loadJob = bigquery.create(JobInfo.of(configuration)); - while (!loadJob.isDone()) { - Thread.sleep(1000L); - } - if (loadJob.status().error() != null) { - System.out.println("Job completed with errors"); - } else { - System.out.println("Job succeeded"); - } + System.out.println("Job succeeded"); } ``` @@ -171,8 +170,32 @@ Google Cloud Datastore #### Preview -Here is a code snippet showing a simple usage example from within Compute/App Engine. Note that you must [supply credentials](#authentication) and a project ID if running this snippet elsewhere. +Here are two code snippets showing simple usage examples from within Compute/App Engine. Note that you must [supply credentials](#authentication) and a project ID if running this snippet elsewhere. + +The first snippet shows how to create a Datastore entity. Complete source code can be found at +[CreateEntity.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/CreateEntity.java). + +```java +import com.google.gcloud.datastore.Datastore; +import com.google.gcloud.datastore.DatastoreOptions; +import com.google.gcloud.datastore.DateTime; +import com.google.gcloud.datastore.Entity; +import com.google.gcloud.datastore.Key; +import com.google.gcloud.datastore.KeyFactory; +Datastore datastore = DatastoreOptions.defaultInstance().service(); +KeyFactory keyFactory = datastore.newKeyFactory().kind("keyKind"); +Key key = keyFactory.newKey("keyName"); +Entity entity = Entity.builder(key) + .set("name", "John Doe") + .set("age", 30) + .set("access_time", DateTime.now()) + .build(); +datastore.put(entity); +``` +The second snippet shows how to update a Datastore entity if it exists. Complete source code can be +found at +[UpdateEntity.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/UpdateEntity.java). ```java import com.google.gcloud.datastore.Datastore; import com.google.gcloud.datastore.DatastoreOptions; @@ -182,17 +205,10 @@ import com.google.gcloud.datastore.Key; import com.google.gcloud.datastore.KeyFactory; Datastore datastore = DatastoreOptions.defaultInstance().service(); -KeyFactory keyFactory = datastore.newKeyFactory().kind(KIND); -Key key = keyFactory.newKey(keyName); +KeyFactory keyFactory = datastore.newKeyFactory().kind("keyKind"); +Key key = keyFactory.newKey("keyName"); Entity entity = datastore.get(key); -if (entity == null) { - entity = Entity.builder(key) - .set("name", "John Do") - .set("age", 30) - .set("access_time", DateTime.now()) - .build(); - datastore.put(entity); -} else { +if (entity != null) { System.out.println("Updating access_time for " + entity.getString("name")); entity = Entity.builder(entity) .set("access_time", DateTime.now()) @@ -210,7 +226,8 @@ Google Cloud Resource Manager (Alpha) #### Preview Here is a code snippet showing a simple usage example. Note that you must supply Google SDK credentials for this service, not other forms of authentication listed in the [Authentication section](#authentication). - +Complete source code can be found at +[UpdateAndListProjects.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/UpdateAndListProjects.java). ```java import com.google.gcloud.resourcemanager.Project; import com.google.gcloud.resourcemanager.ResourceManager; @@ -219,14 +236,15 @@ import com.google.gcloud.resourcemanager.ResourceManagerOptions; import java.util.Iterator; ResourceManager resourceManager = ResourceManagerOptions.defaultInstance().service(); -Project myProject = resourceManager.get("some-project-id"); // Use an existing project's ID -Project newProject = myProject.toBuilder() - .addLabel("launch-status", "in-development") - .build() - .replace(); -System.out.println("Updated the labels of project " + newProject.projectId() - + " to be " + newProject.labels()); -// List all the projects you have permission to view. +Project project = resourceManager.get("some-project-id"); // Use an existing project's ID +if (project != null) { + Project newProject = project.toBuilder() + .addLabel("launch-status", "in-development") + .build() + .replace(); + System.out.println("Updated the labels of project " + newProject.projectId() + + " to be " + newProject.labels()); +} Iterator projectIterator = resourceManager.list().iterateAll(); System.out.println("Projects I can view:"); while (projectIterator.hasNext()) { @@ -244,8 +262,28 @@ Google Cloud Storage #### Preview -Here is a code snippet showing a simple usage example from within Compute/App Engine. Note that you must [supply credentials](#authentication) and a project ID if running this snippet elsewhere. +Here are two code snippets showing simple usage examples from within Compute/App Engine. Note that you must [supply credentials](#authentication) and a project ID if running this snippet elsewhere. + +The first snippet shows how to create a Storage blob. Complete source code can be found at +[CreateBlob.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateBlob.java). + +```java +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.google.gcloud.storage.Blob; +import com.google.gcloud.storage.BlobId; +import com.google.gcloud.storage.BlobInfo; +import com.google.gcloud.storage.Storage; +import com.google.gcloud.storage.StorageOptions; +Storage storage = StorageOptions.defaultInstance().service(); +BlobId blobId = BlobId.of("bucket", "blob_name"); +BlobInfo blobInfo = BlobInfo.builder(blobId).contentType("text/plain").build(); +Blob blob = storage.create(blobInfo, "Hello, Cloud Storage!".getBytes(UTF_8)); +``` +The second snippet shows how to update a Storage blob if it exists. Complete source code can be +found at +[UpdateBlob.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/UpdateBlob.java). ```java import static java.nio.charset.StandardCharsets.UTF_8; @@ -259,12 +297,8 @@ import java.nio.channels.WritableByteChannel; Storage storage = StorageOptions.defaultInstance().service(); BlobId blobId = BlobId.of("bucket", "blob_name"); -Blob blob = Blob.get(storage, blobId); -if (blob == null) { - BlobInfo blobInfo = BlobInfo.builder(blobId).contentType("text/plain").build(); - storage.create(blobInfo, "Hello, Cloud Storage!".getBytes(UTF_8)); -} else { - System.out.println("Updating content for " + blobId.name()); +Blob blob = storage.get(blobId); +if (blob != null) { byte[] prevContent = blob.content(); System.out.println(new String(prevContent, UTF_8)); WritableByteChannel channel = blob.writer(); diff --git a/codacy-conf.json b/codacy-conf.json new file mode 100644 index 000000000000..61328436cba3 --- /dev/null +++ b/codacy-conf.json @@ -0,0 +1 @@ +{"patterns":[{"patternId":"Custom_Javascript_Scopes","enabled":true},{"patternId":"Custom_Javascript_EvalWith","enabled":true},{"patternId":"Custom_Javascript_TryCatch","enabled":true},{"patternId":"Custom_Scala_NonFatal","enabled":true},{"patternId":"bitwise","enabled":true},{"patternId":"maxparams","enabled":true},{"patternId":"CSSLint_universal_selector","enabled":true},{"patternId":"CSSLint_unqualified_attributes","enabled":true},{"patternId":"CSSLint_zero_units","enabled":true},{"patternId":"CSSLint_overqualified_elements","enabled":true},{"patternId":"CSSLint_shorthand","enabled":true},{"patternId":"CSSLint_duplicate_background_images","enabled":true},{"patternId":"CSSLint_box_model","enabled":true},{"patternId":"CSSLint_compatible_vendor_prefixes","enabled":true},{"patternId":"CSSLint_display_property_grouping","enabled":true},{"patternId":"CSSLint_duplicate_properties","enabled":true},{"patternId":"CSSLint_empty_rules","enabled":true},{"patternId":"CSSLint_errors","enabled":true},{"patternId":"CSSLint_gradients","enabled":true},{"patternId":"CSSLint_important","enabled":true},{"patternId":"CSSLint_known_properties","enabled":true},{"patternId":"CSSLint_text_indent","enabled":true},{"patternId":"CSSLint_unique_headings","enabled":true},{"patternId":"PyLint_E0100","enabled":true},{"patternId":"PyLint_E0101","enabled":true},{"patternId":"PyLint_E0102","enabled":true},{"patternId":"PyLint_E0103","enabled":true},{"patternId":"PyLint_E0104","enabled":true},{"patternId":"PyLint_E0105","enabled":true},{"patternId":"PyLint_E0106","enabled":true},{"patternId":"PyLint_E0107","enabled":true},{"patternId":"PyLint_E0108","enabled":true},{"patternId":"PyLint_E0202","enabled":true},{"patternId":"PyLint_E0203","enabled":true},{"patternId":"PyLint_E0211","enabled":true},{"patternId":"PyLint_E0601","enabled":true},{"patternId":"PyLint_E0603","enabled":true},{"patternId":"PyLint_E0604","enabled":true},{"patternId":"PyLint_E0701","enabled":true},{"patternId":"PyLint_E0702","enabled":true},{"patternId":"PyLint_E0710","enabled":true},{"patternId":"PyLint_E0711","enabled":true},{"patternId":"PyLint_E0712","enabled":true},{"patternId":"PyLint_E1003","enabled":true},{"patternId":"PyLint_E1102","enabled":true},{"patternId":"PyLint_E1111","enabled":true},{"patternId":"PyLint_E1120","enabled":true},{"patternId":"PyLint_E1121","enabled":true},{"patternId":"PyLint_E1123","enabled":true},{"patternId":"PyLint_E1124","enabled":true},{"patternId":"PyLint_E1200","enabled":true},{"patternId":"PyLint_E1201","enabled":true},{"patternId":"PyLint_E1205","enabled":true},{"patternId":"PyLint_E1206","enabled":true},{"patternId":"PyLint_E1300","enabled":true},{"patternId":"PyLint_E1301","enabled":true},{"patternId":"PyLint_E1302","enabled":true},{"patternId":"PyLint_E1303","enabled":true},{"patternId":"PyLint_E1304","enabled":true},{"patternId":"PyLint_E1305","enabled":true},{"patternId":"PyLint_E1306","enabled":true},{"patternId":"rulesets-codesize.xml-CyclomaticComplexity","enabled":true},{"patternId":"rulesets-codesize.xml-NPathComplexity","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveMethodLength","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveClassLength","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveParameterList","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessivePublicCount","enabled":true},{"patternId":"rulesets-codesize.xml-TooManyFields","enabled":true},{"patternId":"rulesets-codesize.xml-TooManyMethods","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveClassComplexity","enabled":true},{"patternId":"rulesets-controversial.xml-Superglobals","enabled":true},{"patternId":"rulesets-design.xml-ExitExpression","enabled":true},{"patternId":"rulesets-design.xml-EvalExpression","enabled":true},{"patternId":"rulesets-design.xml-GotoStatement","enabled":true},{"patternId":"rulesets-design.xml-NumberOfChildren","enabled":true},{"patternId":"rulesets-design.xml-DepthOfInheritance","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedPrivateField","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedLocalVariable","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedPrivateMethod","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedFormalParameter","enabled":true},{"patternId":"PyLint_C0303","enabled":true},{"patternId":"PyLint_C1001","enabled":true},{"patternId":"rulesets-naming.xml-ShortVariable","enabled":true},{"patternId":"rulesets-naming.xml-LongVariable","enabled":true},{"patternId":"rulesets-naming.xml-ShortMethodName","enabled":true},{"patternId":"rulesets-naming.xml-ConstantNamingConventions","enabled":true},{"patternId":"rulesets-naming.xml-BooleanGetMethodName","enabled":true},{"patternId":"PyLint_W0101","enabled":true},{"patternId":"PyLint_W0102","enabled":true},{"patternId":"PyLint_W0104","enabled":true},{"patternId":"PyLint_W0105","enabled":true},{"patternId":"Custom_Scala_GetCalls","enabled":true},{"patternId":"ScalaStyle_EqualsHashCodeChecker","enabled":true},{"patternId":"ScalaStyle_ParameterNumberChecker","enabled":true},{"patternId":"ScalaStyle_ReturnChecker","enabled":true},{"patternId":"ScalaStyle_NullChecker","enabled":true},{"patternId":"ScalaStyle_NoCloneChecker","enabled":true},{"patternId":"ScalaStyle_NoFinalizeChecker","enabled":true},{"patternId":"ScalaStyle_CovariantEqualsChecker","enabled":true},{"patternId":"ScalaStyle_StructuralTypeChecker","enabled":true},{"patternId":"ScalaStyle_MethodLengthChecker","enabled":true},{"patternId":"ScalaStyle_NumberOfMethodsInTypeChecker","enabled":true},{"patternId":"ScalaStyle_WhileChecker","enabled":true},{"patternId":"ScalaStyle_VarFieldChecker","enabled":true},{"patternId":"ScalaStyle_VarLocalChecker","enabled":true},{"patternId":"ScalaStyle_RedundantIfChecker","enabled":true},{"patternId":"ScalaStyle_DeprecatedJavaChecker","enabled":true},{"patternId":"ScalaStyle_EmptyClassChecker","enabled":true},{"patternId":"ScalaStyle_NotImplementedErrorUsage","enabled":true},{"patternId":"Custom_Scala_GroupImports","enabled":true},{"patternId":"Custom_Scala_ReservedKeywords","enabled":true},{"patternId":"Custom_Scala_ElseIf","enabled":true},{"patternId":"Custom_Scala_CallByNameAsLastArguments","enabled":true},{"patternId":"Custom_Scala_WildcardImportOnMany","enabled":true},{"patternId":"Custom_Scala_UtilTryForTryCatch","enabled":true},{"patternId":"Custom_Scala_ProhibitObjectName","enabled":true},{"patternId":"Custom_Scala_ImportsAtBeginningOfPackage","enabled":true},{"patternId":"Custom_Scala_NameResultsAndParameters","enabled":true},{"patternId":"Custom_Scala_IncompletePatternMatching","enabled":true},{"patternId":"Custom_Scala_UsefulTypeAlias","enabled":true},{"patternId":"Custom_Scala_JavaThreads","enabled":true},{"patternId":"Custom_Scala_DirectPromiseCreation","enabled":true},{"patternId":"Custom_Scala_StructuralTypes","enabled":true},{"patternId":"Custom_Scala_CollectionLastHead","enabled":true},{"patternId":"PyLint_W0106","enabled":true},{"patternId":"PyLint_W0107","enabled":true},{"patternId":"PyLint_W0108","enabled":true},{"patternId":"PyLint_W0109","enabled":true},{"patternId":"PyLint_W0110","enabled":true},{"patternId":"PyLint_W0120","enabled":true},{"patternId":"PyLint_W0122","enabled":true},{"patternId":"PyLint_W0150","enabled":true},{"patternId":"PyLint_W0199","enabled":true},{"patternId":"rulesets-cleancode.xml-ElseExpression","enabled":true},{"patternId":"rulesets-cleancode.xml-StaticAccess","enabled":true},{"patternId":"ScalaStyle_NonASCIICharacterChecker","enabled":true},{"patternId":"ScalaStyle_FieldNamesChecker","enabled":true},{"patternId":"Custom_Scala_WithNameCalls","enabled":true},{"patternId":"braces_IfElseStmtsMustUseBraces","enabled":true},{"patternId":"basic_AvoidDecimalLiteralsInBigDecimalConstructor","enabled":true},{"patternId":"basic_CheckSkipResult","enabled":true},{"patternId":"design_AvoidInstanceofChecksInCatchClause","enabled":true},{"patternId":"j2ee_DoNotCallSystemExit","enabled":true},{"patternId":"unusedcode_UnusedLocalVariable","enabled":true},{"patternId":"basic_DontUseFloatTypeForLoopIndices","enabled":true},{"patternId":"basic_AvoidBranchingStatementAsLastInLoop","enabled":true},{"patternId":"empty_EmptyFinallyBlock","enabled":true},{"patternId":"design_CompareObjectsWithEquals","enabled":true},{"patternId":"junit_UnnecessaryBooleanAssertion","enabled":true},{"patternId":"design_SimplifyBooleanExpressions","enabled":true},{"patternId":"basic_JumbledIncrementer","enabled":true},{"patternId":"design_SwitchStmtsShouldHaveDefault","enabled":true},{"patternId":"strictexception_AvoidThrowingRawExceptionTypes","enabled":true},{"patternId":"design_SimplifyBooleanReturns","enabled":true},{"patternId":"empty_EmptyInitializer","enabled":true},{"patternId":"design_FieldDeclarationsShouldBeAtStartOfClass","enabled":true},{"patternId":"naming_PackageCase","enabled":true},{"patternId":"controversial_UnnecessaryConstructor","enabled":true},{"patternId":"naming_MethodNamingConventions","enabled":true},{"patternId":"basic_UnconditionalIfStatement","enabled":true},{"patternId":"design_SingularField","enabled":true},{"patternId":"design_AssignmentToNonFinalStatic","enabled":true},{"patternId":"strings_UseStringBufferLength","enabled":true},{"patternId":"finalizers_AvoidCallingFinalize","enabled":true},{"patternId":"naming_ClassNamingConventions","enabled":true},{"patternId":"imports_UnnecessaryFullyQualifiedName","enabled":true},{"patternId":"unusedcode_UnusedPrivateField","enabled":true},{"patternId":"strings_UnnecessaryCaseChange","enabled":true},{"patternId":"design_NonStaticInitializer","enabled":true},{"patternId":"design_MissingBreakInSwitch","enabled":true},{"patternId":"design_AvoidReassigningParameters","enabled":true},{"patternId":"basic_AvoidThreadGroup","enabled":true},{"patternId":"codesize_ExcessiveParameterList","parameters":{"minimum":"8","violationSuppressRegex":"\"\"","violationSuppressXPath":"\"\""},"enabled":true},{"patternId":"design_UncommentedEmptyMethodBody","enabled":true},{"patternId":"basic_BrokenNullCheck","enabled":true},{"patternId":"strings_StringInstantiation","enabled":true},{"patternId":"design_EqualsNull","enabled":true},{"patternId":"basic_OverrideBothEqualsAndHashcode","enabled":true},{"patternId":"basic_BooleanInstantiation","enabled":true},{"patternId":"basic_ReturnFromFinallyBlock","enabled":true},{"patternId":"empty_EmptyTryBlock","enabled":true},{"patternId":"basic_ExtendsObject","enabled":true},{"patternId":"strictexception_AvoidThrowingNullPointerException","enabled":true},{"patternId":"empty_EmptySwitchStatements","enabled":true},{"patternId":"basic_MisplacedNullCheck","enabled":true},{"patternId":"strings_StringToString","enabled":true},{"patternId":"naming_MethodWithSameNameAsEnclosingClass","enabled":true},{"patternId":"imports_UnusedImports","enabled":true},{"patternId":"basic_AvoidMultipleUnaryOperators","enabled":true},{"patternId":"junit_SimplifyBooleanAssertion","enabled":true},{"patternId":"braces_IfStmtsMustUseBraces","enabled":true},{"patternId":"naming_NoPackage","enabled":true},{"patternId":"unusedcode_UnusedFormalParameter","enabled":true},{"patternId":"empty_EmptyStatementNotInLoop","enabled":true},{"patternId":"naming_GenericsNaming","enabled":true},{"patternId":"strings_UseEqualsToCompareStrings","enabled":true},{"patternId":"empty_EmptyStaticInitializer","enabled":true},{"patternId":"empty_EmptyStatementBlock","enabled":true},{"patternId":"basic_CollapsibleIfStatements","enabled":true},{"patternId":"design_ImmutableField","enabled":true},{"patternId":"controversial_OneDeclarationPerLine","enabled":true},{"patternId":"unnecessary_UnnecessaryReturn","enabled":true},{"patternId":"codesize_NPathComplexity","enabled":true},{"patternId":"imports_DontImportJavaLang","enabled":true},{"patternId":"empty_EmptySynchronizedBlock","enabled":true},{"patternId":"unnecessary_UselessOperationOnImmutable","enabled":true},{"patternId":"design_PositionLiteralsFirstInComparisons","enabled":true},{"patternId":"junit_JUnitSpelling","enabled":true},{"patternId":"finalizers_EmptyFinalizer","enabled":true},{"patternId":"design_NonCaseLabelInSwitchStatement","enabled":true},{"patternId":"android_DoNotHardCodeSDCard","enabled":true},{"patternId":"design_LogicInversion","enabled":true},{"patternId":"unusedcode_UnusedPrivateMethod","enabled":true},{"patternId":"basic_CheckResultSet","enabled":true},{"patternId":"controversial_AvoidPrefixingMethodParameters","enabled":true},{"patternId":"empty_EmptyIfStmt","enabled":true},{"patternId":"basic_DontCallThreadRun","enabled":true},{"patternId":"junit_JUnitStaticSuite","enabled":true},{"patternId":"codesize_ExcessiveMethodLength","enabled":true},{"patternId":"design_MissingStaticMethodInNonInstantiatableClass","enabled":true},{"patternId":"Style_MethodName","enabled":true},{"patternId":"Metrics_CyclomaticComplexity","enabled":true},{"patternId":"Lint_DuplicateMethods","enabled":true},{"patternId":"Style_Lambda","enabled":true},{"patternId":"Lint_UselessSetterCall","enabled":true},{"patternId":"Style_VariableName","enabled":true},{"patternId":"Lint_AmbiguousOperator","enabled":true},{"patternId":"Style_LeadingCommentSpace","enabled":true},{"patternId":"Style_CaseEquality","enabled":true},{"patternId":"Lint_StringConversionInInterpolation","enabled":true},{"patternId":"Performance_ReverseEach","enabled":true},{"patternId":"Lint_LiteralInCondition","enabled":true},{"patternId":"Performance_Sample","enabled":true},{"patternId":"Style_NonNilCheck","enabled":true},{"patternId":"Lint_RescueException","enabled":true},{"patternId":"Lint_UselessElseWithoutRescue","enabled":true},{"patternId":"Style_ConstantName","enabled":true},{"patternId":"Lint_LiteralInInterpolation","enabled":true},{"patternId":"Lint_NestedMethodDefinition","enabled":true},{"patternId":"Style_DoubleNegation","enabled":true},{"patternId":"Lint_SpaceBeforeFirstArg","enabled":true},{"patternId":"Lint_Debugger","enabled":true},{"patternId":"Style_ClassVars","enabled":true},{"patternId":"Lint_EmptyEnsure","enabled":true},{"patternId":"Style_MultilineBlockLayout","enabled":true},{"patternId":"Lint_UnusedBlockArgument","enabled":true},{"patternId":"Lint_UselessAccessModifier","enabled":true},{"patternId":"Performance_Size","enabled":true},{"patternId":"Lint_EachWithObjectArgument","enabled":true},{"patternId":"Style_Alias","enabled":true},{"patternId":"Lint_Loop","enabled":true},{"patternId":"Style_NegatedWhile","enabled":true},{"patternId":"Style_ColonMethodCall","enabled":true},{"patternId":"Lint_AmbiguousRegexpLiteral","enabled":true},{"patternId":"Lint_UnusedMethodArgument","enabled":true},{"patternId":"Style_MultilineIfThen","enabled":true},{"patternId":"Lint_EnsureReturn","enabled":true},{"patternId":"Style_NegatedIf","enabled":true},{"patternId":"Lint_Eval","enabled":true},{"patternId":"Style_NilComparison","enabled":true},{"patternId":"Style_ArrayJoin","enabled":true},{"patternId":"Lint_ConditionPosition","enabled":true},{"patternId":"Lint_UnreachableCode","enabled":true},{"patternId":"Performance_Count","enabled":true},{"patternId":"Lint_EmptyInterpolation","enabled":true},{"patternId":"Style_LambdaCall","enabled":true},{"patternId":"Lint_HandleExceptions","enabled":true},{"patternId":"Lint_ShadowingOuterLocalVariable","enabled":true},{"patternId":"Lint_EndAlignment","enabled":true},{"patternId":"Style_MultilineTernaryOperator","enabled":true},{"patternId":"Style_AutoResourceCleanup","enabled":true},{"patternId":"Lint_ElseLayout","enabled":true},{"patternId":"Style_NestedTernaryOperator","enabled":true},{"patternId":"Style_OneLineConditional","enabled":true},{"patternId":"Style_EmptyElse","enabled":true},{"patternId":"Lint_UselessComparison","enabled":true},{"patternId":"Metrics_PerceivedComplexity","enabled":true},{"patternId":"Style_InfiniteLoop","enabled":true},{"patternId":"Rails_Date","enabled":true},{"patternId":"Style_EvenOdd","enabled":true},{"patternId":"Style_IndentationConsistency","enabled":true},{"patternId":"Style_ModuleFunction","enabled":true},{"patternId":"Lint_UselessAssignment","enabled":true},{"patternId":"Style_EachWithObject","enabled":true},{"patternId":"Performance_Detect","enabled":true},{"patternId":"duplicate_key","enabled":true},{"patternId":"no_interpolation_in_single_quotes","enabled":true},{"patternId":"no_backticks","enabled":true},{"patternId":"no_unnecessary_fat_arrows","enabled":true},{"patternId":"indentation","enabled":true},{"patternId":"ensure_comprehensions","enabled":true},{"patternId":"no_stand_alone_at","enabled":true},{"patternId":"cyclomatic_complexity","enabled":true},{"patternId":"Deserialize","enabled":true},{"patternId":"SymbolDoS","enabled":true},{"patternId":"SkipBeforeFilter","enabled":true},{"patternId":"SanitizeMethods","enabled":true},{"patternId":"SelectTag","enabled":true},{"patternId":"XMLDoS","enabled":true},{"patternId":"SimpleFormat","enabled":true},{"patternId":"Evaluation","enabled":true},{"patternId":"BasicAuth","enabled":true},{"patternId":"JRubyXML","enabled":true},{"patternId":"RenderInline","enabled":true},{"patternId":"YAMLParsing","enabled":true},{"patternId":"Redirect","enabled":true},{"patternId":"UnsafeReflection","enabled":true},{"patternId":"SSLVerify","enabled":true},{"patternId":"HeaderDoS","enabled":true},{"patternId":"TranslateBug","enabled":true},{"patternId":"Execute","enabled":true},{"patternId":"JSONParsing","enabled":true},{"patternId":"LinkTo","enabled":true},{"patternId":"FileDisclosure","enabled":true},{"patternId":"SafeBufferManipulation","enabled":true},{"patternId":"ModelAttributes","enabled":true},{"patternId":"ResponseSplitting","enabled":true},{"patternId":"DigestDoS","enabled":true},{"patternId":"Send","enabled":true},{"patternId":"MailTo","enabled":true},{"patternId":"SymbolDoSCVE","enabled":true},{"patternId":"StripTags","enabled":true},{"patternId":"MassAssignment","enabled":true},{"patternId":"RegexDoS","enabled":true},{"patternId":"SelectVulnerability","enabled":true},{"patternId":"FileAccess","enabled":true},{"patternId":"ContentTag","enabled":true},{"patternId":"SessionSettings","enabled":true},{"patternId":"FilterSkipping","enabled":true},{"patternId":"CreateWith","enabled":true},{"patternId":"JSONEncoding","enabled":true},{"patternId":"SQLCVEs","enabled":true},{"patternId":"ForgerySetting","enabled":true},{"patternId":"QuoteTableName","enabled":true},{"patternId":"I18nXSS","enabled":true},{"patternId":"WithoutProtection","enabled":true},{"patternId":"CrossSiteScripting","enabled":true},{"patternId":"SingleQuotes","enabled":true},{"patternId":"NestedAttributes","enabled":true},{"patternId":"DetailedExceptions","enabled":true},{"patternId":"LinkToHref","enabled":true},{"patternId":"RenderDoS","enabled":true},{"patternId":"ModelSerialize","enabled":true},{"patternId":"SQL","enabled":true},{"patternId":"Render","enabled":true},{"patternId":"UnscopedFind","enabled":true},{"patternId":"ValidationRegex","enabled":true},{"patternId":"EscapeFunction","enabled":true},{"patternId":"Custom_Scala_FieldNamesChecker","enabled":true},{"patternId":"Custom_Scala_ObjDeserialization","enabled":true},{"patternId":"Custom_Scala_RSAPadding","enabled":true},{"patternId":"ESLint_no-extra-boolean-cast","enabled":true},{"patternId":"ESLint_no-iterator","enabled":true},{"patternId":"ESLint_no-invalid-regexp","enabled":true},{"patternId":"ESLint_no-obj-calls","enabled":true},{"patternId":"ESLint_no-sparse-arrays","enabled":true},{"patternId":"ESLint_no-unreachable","enabled":true},{"patternId":"ESLint_no-dupe-keys","enabled":true},{"patternId":"ESLint_no-multi-str","enabled":true},{"patternId":"ESLint_no-extend-native","enabled":true},{"patternId":"ESLint_guard-for-in","enabled":true},{"patternId":"ESLint_no-func-assign","enabled":true},{"patternId":"ESLint_no-extra-semi","enabled":true},{"patternId":"ESLint_camelcase","enabled":true},{"patternId":"ESLint_no-mixed-spaces-and-tabs","enabled":true},{"patternId":"ESLint_no-undef","enabled":true},{"patternId":"ESLint_semi","enabled":true},{"patternId":"ESLint_no-empty-character-class","enabled":true},{"patternId":"ESLint_complexity","enabled":true},{"patternId":"ESLint_no-dupe-class-members","enabled":true},{"patternId":"ESLint_no-debugger","enabled":true},{"patternId":"ESLint_block-scoped-var","enabled":true},{"patternId":"ESLint_no-loop-func","enabled":true},{"patternId":"ESLint_no-use-before-define","enabled":true},{"patternId":"ESLint_no-console","enabled":true},{"patternId":"ESLint_require-yield","enabled":true},{"patternId":"ESLint_no-redeclare","enabled":true},{"patternId":"ESLint_no-undefined","enabled":true},{"patternId":"ESLint_use-isnan","enabled":true},{"patternId":"ESLint_no-control-regex","enabled":true},{"patternId":"ESLint_no-const-assign","enabled":true},{"patternId":"ESLint_no-new","enabled":true},{"patternId":"ESLint_new-cap","enabled":true},{"patternId":"ESLint_no-irregular-whitespace","enabled":true},{"patternId":"ESLint_object-shorthand","enabled":true},{"patternId":"ESLint_no-ex-assign","enabled":true},{"patternId":"ESLint_wrap-iife","enabled":true},{"patternId":"ESLint_arrow-parens","enabled":true},{"patternId":"ESLint_no-constant-condition","enabled":true},{"patternId":"ESLint_no-octal","enabled":true},{"patternId":"ESLint_no-dupe-args","enabled":true},{"patternId":"ESLint_quotes","enabled":true},{"patternId":"ESLint_no-fallthrough","enabled":true},{"patternId":"ESLint_no-delete-var","enabled":true},{"patternId":"ESLint_no-caller","enabled":true},{"patternId":"ESLint_no-cond-assign","enabled":true},{"patternId":"ESLint_no-this-before-super","enabled":true},{"patternId":"ESLint_no-negated-in-lhs","enabled":true},{"patternId":"ESLint_no-inner-declarations","enabled":true},{"patternId":"ESLint_eqeqeq","enabled":true},{"patternId":"ESLint_curly","enabled":true},{"patternId":"ESLint_arrow-spacing","enabled":true},{"patternId":"ESLint_no-empty","enabled":true},{"patternId":"ESLint_no-unused-vars","enabled":true},{"patternId":"ESLint_generator-star-spacing","enabled":true},{"patternId":"ESLint_no-duplicate-case","enabled":true},{"patternId":"ESLint_valid-typeof","enabled":true},{"patternId":"ESLint_no-regex-spaces","enabled":true},{"patternId":"ESLint_no-class-assign","enabled":true},{"patternId":"PyLint_W0221","enabled":true},{"patternId":"PyLint_E0117","enabled":true},{"patternId":"PyLint_E0001","enabled":true},{"patternId":"PyLint_E0241","enabled":true},{"patternId":"PyLint_W0404","enabled":true},{"patternId":"PyLint_E0704","enabled":true},{"patternId":"PyLint_E0703","enabled":true},{"patternId":"PyLint_E0302","enabled":true},{"patternId":"PyLint_W1301","enabled":true},{"patternId":"PyLint_R0201","enabled":true},{"patternId":"PyLint_E0113","enabled":true},{"patternId":"PyLint_W0410","enabled":true},{"patternId":"PyLint_C0123","enabled":true},{"patternId":"PyLint_E0115","enabled":true},{"patternId":"PyLint_E0114","enabled":true},{"patternId":"PyLint_E1126","enabled":true},{"patternId":"PyLint_W0702","enabled":true},{"patternId":"PyLint_W1303","enabled":true},{"patternId":"PyLint_W0622","enabled":true},{"patternId":"PyLint_W0222","enabled":true},{"patternId":"PyLint_W0233","enabled":true},{"patternId":"PyLint_W1305","enabled":true},{"patternId":"PyLint_E1127","enabled":true},{"patternId":"PyLint_E0112","enabled":true},{"patternId":"PyLint_W0611","enabled":true},{"patternId":"PyLint_W0601","enabled":true},{"patternId":"PyLint_W1300","enabled":true},{"patternId":"PyLint_W0124","enabled":true},{"patternId":"PyLint_R0203","enabled":true},{"patternId":"PyLint_E0236","enabled":true},{"patternId":"PyLint_W0612","enabled":true},{"patternId":"PyLint_W0604","enabled":true},{"patternId":"PyLint_W0705","enabled":true},{"patternId":"PyLint_E0238","enabled":true},{"patternId":"PyLint_W0602","enabled":true},{"patternId":"PyLint_R0102","enabled":true},{"patternId":"PyLint_R0202","enabled":true},{"patternId":"PyLint_E0240","enabled":true},{"patternId":"PyLint_W0623","enabled":true},{"patternId":"PyLint_W0711","enabled":true},{"patternId":"PyLint_E0116","enabled":true},{"patternId":"PyLint_E0239","enabled":true},{"patternId":"PyLint_E1132","enabled":true},{"patternId":"PyLint_W1307","enabled":true},{"patternId":"PyLint_C0200","enabled":true},{"patternId":"PyLint_E0301","enabled":true},{"patternId":"PyLint_W1306","enabled":true},{"patternId":"PyLint_W1302","enabled":true},{"patternId":"PyLint_E0110","enabled":true},{"patternId":"PyLint_E1125","enabled":true}]} \ No newline at end of file diff --git a/gcloud-java-bigquery/README.md b/gcloud-java-bigquery/README.md index 1a4e48dfd4fd..df1058dec024 100644 --- a/gcloud-java-bigquery/README.md +++ b/gcloud-java-bigquery/README.md @@ -6,6 +6,7 @@ Java idiomatic client for [Google Cloud BigQuery] (https://cloud.google.com/bigq [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-bigquery.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-bigquery.svg) +[![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/bigquery/package-summary.html) @@ -34,7 +35,7 @@ libraryDependencies += "com.google.gcloud" % "gcloud-java-bigquery" % "0.1.3" Example Application ------------------- -- [`BigQueryExample`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-examples/src/main/java/com/google/gcloud/examples/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality. +- [`BigQueryExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality. Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/BigQueryExample.html). Authentication @@ -200,91 +201,13 @@ while (rowIterator.hasNext()) { ``` #### Complete source code -Here we put together all the code shown above into one program. This program assumes that you are -running on Compute Engine or from your own desktop. To run this example on App Engine, simply move +In +[InsertDataAndQueryTable.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/InsertDataAndQueryTable.java) +we put together all the code shown above into one program. The program assumes that you are +running on Compute Engine or from your own desktop. To run the example on App Engine, simply move the code from the main method to your application's servlet class and change the print statements to display on your webpage. -```java -import com.google.gcloud.bigquery.BigQuery; -import com.google.gcloud.bigquery.BigQueryOptions; -import com.google.gcloud.bigquery.DatasetInfo; -import com.google.gcloud.bigquery.Field; -import com.google.gcloud.bigquery.FieldValue; -import com.google.gcloud.bigquery.InsertAllRequest; -import com.google.gcloud.bigquery.InsertAllResponse; -import com.google.gcloud.bigquery.QueryRequest; -import com.google.gcloud.bigquery.QueryResponse; -import com.google.gcloud.bigquery.Schema; -import com.google.gcloud.bigquery.StandardTableDefinition; -import com.google.gcloud.bigquery.Table; -import com.google.gcloud.bigquery.TableId; -import com.google.gcloud.bigquery.TableInfo; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -public class GcloudBigQueryExample { - - public static void main(String[] args) throws InterruptedException { - - // Create a service instance - BigQuery bigquery = BigQueryOptions.defaultInstance().service(); - - // Create a dataset - String datasetId = "my_dataset_id"; - bigquery.create(DatasetInfo.builder(datasetId).build()); - - TableId tableId = TableId.of(datasetId, "my_table_id"); - // Table field definition - Field stringField = Field.of("StringField", Field.Type.string()); - // Table schema definition - Schema schema = Schema.of(stringField); - // Create a table - StandardTableDefinition tableDefinition = StandardTableDefinition.of(schema); - Table createdTable = bigquery.create(TableInfo.of(tableId, tableDefinition)); - - // Define rows to insert - Map firstRow = new HashMap<>(); - Map secondRow = new HashMap<>(); - firstRow.put("StringField", "value1"); - secondRow.put("StringField", "value2"); - // Create an insert request - InsertAllRequest insertRequest = InsertAllRequest.builder(tableId) - .addRow(firstRow) - .addRow(secondRow) - .build(); - // Insert rows - InsertAllResponse insertResponse = bigquery.insertAll(insertRequest); - // Check if errors occurred - if (insertResponse.hasErrors()) { - System.out.println("Errors occurred while inserting rows"); - } - - // Create a query request - QueryRequest queryRequest = - QueryRequest.builder("SELECT * FROM my_dataset_id.my_table_id") - .maxWaitTime(60000L) - .maxResults(1000L) - .build(); - // Request query to be executed and wait for results - QueryResponse queryResponse = bigquery.query(queryRequest); - while (!queryResponse.jobCompleted()) { - Thread.sleep(1000L); - queryResponse = bigquery.getQueryResults(queryResponse.jobId()); - } - // Read rows - Iterator> rowIterator = queryResponse.result().iterateAll(); - System.out.println("Table rows:"); - while (rowIterator.hasNext()) { - System.out.println(rowIterator.next()); - } - } -} -``` - Troubleshooting --------------- diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/DatasetInfo.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/DatasetInfo.java index dad5f715ee5f..aa767b97631b 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/DatasetInfo.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/DatasetInfo.java @@ -396,7 +396,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj.getClass().equals(DatasetInfo.class) + return obj != null + && obj.getClass().equals(DatasetInfo.class) && Objects.equals(toPb(), ((DatasetInfo) obj).toPb()); } diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ExternalTableDefinition.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ExternalTableDefinition.java index 882b1eb7065f..5f396d948f5a 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ExternalTableDefinition.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ExternalTableDefinition.java @@ -28,8 +28,8 @@ import java.util.Objects; /** - * Google BigQuery external table type. BigQuery's external tables are tables whose data reside - * outside of BigQuery but can be queried as normal BigQuery tables. External tables are + * Google BigQuery external table definition. BigQuery's external tables are tables whose data + * reside outside of BigQuery but can be queried as normal BigQuery tables. External tables are * experimental and might be subject to change or removed. * * @see Federated Data Sources diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobInfo.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobInfo.java index 2f27895e216b..1adf7fabafc1 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobInfo.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobInfo.java @@ -319,7 +319,9 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj.getClass().equals(JobInfo.class) && Objects.equals(toPb(), ((JobInfo) obj).toPb()); + return obj != null + && obj.getClass().equals(JobInfo.class) + && Objects.equals(toPb(), ((JobInfo) obj).toPb()); } JobInfo setProjectId(String projectId) { diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/StandardTableDefinition.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/StandardTableDefinition.java index d6e8f0176609..d0e49157a99c 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/StandardTableDefinition.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/StandardTableDefinition.java @@ -26,10 +26,11 @@ import java.util.Objects; /** - * A Google BigQuery default table type. This type is used for standard, two-dimensional tables with - * individual records organized in rows, and a data type assigned to each column (also called a - * field). Individual fields within a record may contain nested and repeated children fields. Every - * table is described by a schema that describes field names, types, and other information. + * A Google BigQuery default table definition. This definition is used for standard, two-dimensional + * tables with individual records organized in rows, and a data type assigned to each column (also + * called a field). Individual fields within a record may contain nested and repeated children + * fields. Every table is described by a schema that describes field names, types, and other + * information. * * @see Managing Tables */ @@ -218,14 +219,14 @@ public StreamingBuffer streamingBuffer() { } /** - * Returns a builder for a BigQuery default table type. + * Returns a builder for a BigQuery standard table definition. */ public static Builder builder() { return new Builder(); } /** - * Creates a BigQuery default table type given its schema. + * Creates a BigQuery standard table definition given its schema. * * @param schema the schema of the table */ diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java index de32baa82dab..3f902d2ff242 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java @@ -213,7 +213,8 @@ public InsertAllResponse insert(Iterable rows, * @param options table data list options * @throws BigQueryException upon failure */ - public Page> list(BigQuery.TableDataListOption... options) throws BigQueryException { + public Page> list(BigQuery.TableDataListOption... options) + throws BigQueryException { return bigquery.listTableData(tableId(), options); } diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableDefinition.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableDefinition.java index de858f54ac43..26e7bcc76f55 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableDefinition.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableDefinition.java @@ -25,7 +25,7 @@ import java.util.Objects; /** - * Base class for a Google BigQuery table type. + * Base class for a Google BigQuery table definition. */ public abstract class TableDefinition implements Serializable { @@ -63,10 +63,10 @@ public enum Type { } /** - * Base builder for table types. + * Base builder for table definitions. * - * @param the table type class - * @param the table type builder + * @param the table definition class + * @param the table definition builder */ public abstract static class Builder> { @@ -152,8 +152,8 @@ final int baseHashCode() { return Objects.hash(type); } - final boolean baseEquals(TableDefinition jobConfiguration) { - return Objects.equals(toPb(), jobConfiguration.toPb()); + final boolean baseEquals(TableDefinition tableDefinition) { + return Objects.equals(toPb(), tableDefinition.toPb()); } Table toPb() { diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableInfo.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableInfo.java index 64bcf8db7f83..de331350e978 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableInfo.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableInfo.java @@ -339,7 +339,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj.getClass().equals(TableInfo.class) + return obj != null + && obj.getClass().equals(TableInfo.class) && Objects.equals(toPb(), ((TableInfo) obj).toPb()); } diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ViewDefinition.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ViewDefinition.java index 7065bcc155d2..796dd411b4a1 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ViewDefinition.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ViewDefinition.java @@ -27,8 +27,9 @@ import java.util.Objects; /** - * Google BigQuery view table type. BigQuery's views are logical views, not materialized views, - * which means that the query that defines the view is re-executed every time the view is queried. + * Google BigQuery view table definition. BigQuery's views are logical views, not materialized + * views, which means that the query that defines the view is re-executed every time the view is + * queried. * * @see Views */ @@ -168,7 +169,7 @@ Table toPb() { } /** - * Returns a builder for a BigQuery view type. + * Returns a builder for a BigQuery view definition. * * @param query the query used to generate the view */ @@ -177,7 +178,7 @@ public static Builder builder(String query) { } /** - * Returns a builder for a BigQuery view type. + * Returns a builder for a BigQuery view definition. * * @param query the query used to generate the table * @param functions user-defined functions that can be used by the query @@ -187,7 +188,7 @@ public static Builder builder(String query, List functions) } /** - * Returns a builder for a BigQuery view type. + * Returns a builder for a BigQuery view definition. * * @param query the query used to generate the table * @param functions user-defined functions that can be used by the query @@ -197,7 +198,7 @@ public static Builder builder(String query, UserDefinedFunction... functions) { } /** - * Creates a BigQuery view type given the query used to generate the table. + * Creates a BigQuery view definition given the query used to generate the table. * * @param query the query used to generate the table */ @@ -206,7 +207,7 @@ public static ViewDefinition of(String query) { } /** - * Creates a BigQuery view type given a query and some user-defined functions. + * Creates a BigQuery view definition given a query and some user-defined functions. * * @param query the query used to generate the table * @param functions user-defined functions that can be used by the query @@ -216,7 +217,7 @@ public static ViewDefinition of(String query, List function } /** - * Creates a BigQuery view type given a query and some user-defined functions. + * Creates a BigQuery view definition given a query and some user-defined functions. * * @param query the query used to generate the table * @param functions user-defined functions that can be used by the query diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/package-info.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/package-info.java index 6a54a183eaec..db5e956e0a12 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/package-info.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/package-info.java @@ -17,7 +17,10 @@ /** * A client to Google Cloud BigQuery. * - *

A simple usage example: + *

A simple usage example showing how to create a table if it does not exist and load data into + * it. For the complete source code see + * + * CreateTableAndLoadData.java. *

 {@code
  * BigQuery bigquery = BigQueryOptions.defaultInstance().service();
  * TableId tableId = TableId.of("dataset", "table");
@@ -26,19 +29,17 @@
  *   System.out.println("Creating table " + tableId);
  *   Field integerField = Field.of("fieldName", Field.Type.integer());
  *   Schema schema = Schema.of(integerField);
- *   bigquery.create(TableInfo.of(tableId, StandardTableDefinition.of(schema)));
+ *   table = bigquery.create(TableInfo.of(tableId, StandardTableDefinition.of(schema)));
+ * }
+ * System.out.println("Loading data into table " + tableId);
+ * Job loadJob = table.load(FormatOptions.csv(), "gs://bucket/path");
+ * while (!loadJob.isDone()) {
+ *   Thread.sleep(1000L);
+ * }
+ * if (loadJob.status().error() != null) {
+ *   System.out.println("Job completed with errors");
  * } else {
- *   System.out.println("Loading data into table " + tableId);
- *   LoadJobConfiguration configuration = LoadJobConfiguration.of(tableId, "gs://bucket/path");
- *   Job loadJob = bigquery.create(JobInfo.of(configuration));
- *   while (!loadJob.isDone()) {
- *     Thread.sleep(1000L);
- *   }
- *   if (loadJob.status().error() != null) {
- *     System.out.println("Job completed with errors");
- *   } else {
- *     System.out.println("Job succeeded");
- *   }
+ *   System.out.println("Job succeeded");
  * }}
* * @see Google Cloud BigQuery diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ITBigQueryTest.java index dbd8cda02b9f..8021809be6b2 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ITBigQueryTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ITBigQueryTest.java @@ -654,9 +654,10 @@ public void testQuery() throws InterruptedException { rowCount++; } assertEquals(2, rowCount); - Job queryJob = bigquery.getJob(response.jobId()); - JobStatistics.QueryStatistics statistics = queryJob.statistics(); - assertNotNull(statistics.queryPlan()); + // todo(mziccard) uncomment as soon as #624 is closed + // Job queryJob = bigquery.getJob(response.jobId()); + // JobStatistics.QueryStatistics statistics = queryJob.statistics(); + // assertNotNull(statistics.queryPlan()); } @Test @@ -821,9 +822,10 @@ public void testQueryJob() throws InterruptedException { } assertEquals(2, rowCount); assertTrue(bigquery.delete(DATASET, tableName)); - Job queryJob = bigquery.getJob(remoteJob.jobId()); - JobStatistics.QueryStatistics statistics = queryJob.statistics(); - assertNotNull(statistics.queryPlan()); + // todo(mziccard) uncomment as soon as #624 is closed + // Job queryJob = bigquery.getJob(remoteJob.jobId()); + // JobStatistics.QueryStatistics statistics = queryJob.statistics(); + // assertNotNull(statistics.queryPlan()); } @Test diff --git a/gcloud-java-core/README.md b/gcloud-java-core/README.md index 9063bebebbef..8b91e49f3860 100644 --- a/gcloud-java-core/README.md +++ b/gcloud-java-core/README.md @@ -6,6 +6,7 @@ This module provides common functionality required by service-specific modules o [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-core.svg)](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-core.svg) +[![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/package-summary.html) diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md index 7eae00f2ad3f..8c0ae1950e77 100644 --- a/gcloud-java-datastore/README.md +++ b/gcloud-java-datastore/README.md @@ -6,6 +6,7 @@ Java idiomatic client for [Google Cloud Datastore] (https://cloud.google.com/dat [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-datastore.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-datastore.svg) +[![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/datastore/package-summary.html) @@ -34,7 +35,7 @@ libraryDependencies += "com.google.gcloud" % "gcloud-java-datastore" % "0.1.3" Example Application -------------------- -[`DatastoreExample`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-examples/src/main/java/com/google/gcloud/examples/DatastoreExample.java) is a simple command line interface for the Cloud Datastore. Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/DatastoreExample.html). +[`DatastoreExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java) is a simple command line interface for the Cloud Datastore. Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/DatastoreExample.html). Authentication -------------- @@ -134,67 +135,12 @@ Cloud Datastore relies on indexing to run queries. Indexing is turned on by defa #### Complete source code -Here we put together all the code shown above into one program. This program assumes that you are running on Compute Engine or from your own desktop. To run this example on App Engine, move this code to your application's servlet class and print the query output to the webpage instead of `System.out`. - -```java -import com.google.gcloud.datastore.Datastore; -import com.google.gcloud.datastore.DatastoreOptions; -import com.google.gcloud.datastore.Entity; -import com.google.gcloud.datastore.Key; -import com.google.gcloud.datastore.KeyFactory; -import com.google.gcloud.datastore.Query; -import com.google.gcloud.datastore.QueryResults; -import com.google.gcloud.datastore.StructuredQuery; -import com.google.gcloud.datastore.StructuredQuery.PropertyFilter; - -public class GcloudDatastoreExample { - - public static void main(String[] args) { - // Create datastore service object. - // By default, credentials are inferred from the runtime environment. - Datastore datastore = DatastoreOptions.defaultInstance().service(); - - // Add an entity to Datastore - KeyFactory keyFactory = datastore.newKeyFactory().kind("Person"); - Key key = keyFactory.newKey("john.doe@gmail.com"); - Entity entity = Entity.builder(key) - .set("name", "John Doe") - .set("age", 51) - .set("favorite_food", "pizza") - .build(); - datastore.put(entity); - - // Get an entity from Datastore - Entity johnEntity = datastore.get(key); - - // Add a couple more entities to make the query results more interesting - Key janeKey = keyFactory.newKey("jane.doe@gmail.com"); - Entity janeEntity = Entity.builder(janeKey) - .set("name", "Jane Doe") - .set("age", 44) - .set("favorite_food", "pizza") - .build(); - Key joeKey = keyFactory.newKey("joe.shmoe@gmail.com"); - Entity joeEntity = Entity.builder(joeKey) - .set("name", "Joe Shmoe") - .set("age", 27) - .set("favorite_food", "sushi") - .build(); - datastore.put(janeEntity, joeEntity); - - // Run a query - Query query = Query.entityQueryBuilder() - .kind("Person") - .filter(PropertyFilter.eq("favorite_food", "pizza")) - .build(); - QueryResults results = datastore.run(query); - while (results.hasNext()) { - Entity currentEntity = results.next(); - System.out.println(currentEntity.getString("name") + ", you're invited to a pizza party!"); - } - } -} -``` +In +[AddEntitiesAndRunQuery.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java) +we put together all the code shown above into one program. The program assumes that you are +running on Compute Engine or from your own desktop. To run the example on App Engine, simply move +the code from the main method to your application's servlet class and change the print statements to +display on your webpage. Troubleshooting --------------- diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java index 1404b2817802..fbf468d6458d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java @@ -17,35 +17,38 @@ /** * A client to the Google Cloud Datastore. * - *

Here's a simple usage example for using gcloud-java from App/Compute Engine: + *

Here's a simple usage example for using gcloud-java from App/Compute Engine. This example + * shows how to create a Datastore entity. For the complete source code see + * + * CreateEntity.java. *

 {@code
  * Datastore datastore = DatastoreOptions.defaultInstance().service();
- * KeyFactory keyFactory = datastore.newKeyFactory().kind(kind);
- * Key key = keyFactory.newKey(keyName);
+ * KeyFactory keyFactory = datastore.newKeyFactory().kind("keyKind");
+ * Key key = keyFactory.newKey("keyName");
+ * Entity entity = Entity.builder(key)
+ *     .set("name", "John Doe")
+ *     .set("age", 30)
+ *     .set("access_time", DateTime.now())
+ *     .build();
+ * datastore.put(entity);
+ * } 
+ *

+ * This second example shows how to get and update a Datastore entity if it exists. For the complete + * source code see + * + * UpdateEntity.java. + *

 {@code
+ * Datastore datastore = DatastoreOptions.defaultInstance().service();
+ * KeyFactory keyFactory = datastore.newKeyFactory().kind("keyKind");
+ * Key key = keyFactory.newKey("keyName");
  * Entity entity = datastore.get(key);
- * if (entity == null) {
- *   entity = Entity.builder(key)
- *       .set("name", "John Do")
- *       .set("age", LongValue.builder(100).indexed(false).build())
- *       .set("updated", false)
+ * if (entity != null) {
+ *   System.out.println("Updating access_time for " + entity.getString("name"));
+ *   entity = Entity.builder(entity)
+ *       .set("access_time", DateTime.now())
  *       .build();
- *   datastore.put(entity);
- * } else {
- *   boolean updated = entity.getBoolean("updated");
- *   if (!updated) {
- *     String[] name = entity.getString("name").split(" ");
- *     entity = Entity.builder(entity)
- *         .set("name", name[0])
- *         .set("last_name", StringValue.builder(name[1]).indexed(false).build())
- *         .set("updated", true)
- *         .remove("old_property")
- *         .set("new_property", 1.1)
- *         .build();
- *     datastore.update(entity);
- *   }
- * }
- * } 
- * + * datastore.update(entity); + * }} *

When using gcloud-java from outside of App/Compute Engine, you have to specify a * project ID and diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 8030d14d09e7..7d24febeac80 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -6,6 +6,7 @@ Examples for gcloud-java (Java idiomatic client for [Google Cloud Platform][clou [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-examples.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-examples.svg) +[![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [Examples] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/examples/package-summary.html) @@ -53,39 +54,39 @@ To run examples from your command line: ``` Then you are ready to run the following example: ``` - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.BigQueryExample" -Dexec.args="create dataset new_dataset_id" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.BigQueryExample" -Dexec.args="create table new_dataset_id new_table_id field_name:string" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.BigQueryExample" -Dexec.args="list tables new_dataset_id" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.BigQueryExample" -Dexec.args="load new_dataset_id new_table_id CSV gs://my_bucket/my_csv_file" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.BigQueryExample" -Dexec.args="query 'select * from new_dataset_id.new_table_id'" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.bigquery.BigQueryExample" -Dexec.args="create dataset new_dataset_id" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.bigquery.BigQueryExample" -Dexec.args="create table new_dataset_id new_table_id field_name:string" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.bigquery.BigQueryExample" -Dexec.args="list tables new_dataset_id" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.bigquery.BigQueryExample" -Dexec.args="load new_dataset_id new_table_id CSV gs://my_bucket/my_csv_file" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.bigquery.BigQueryExample" -Dexec.args="query 'select * from new_dataset_id.new_table_id'" ``` * Here's an example run of `DatastoreExample`. Be sure to change the placeholder project ID "your-project-id" with your own project ID. Also note that you have to enable the Google Cloud Datastore API on the [Google Developers Console][developers-console] before running the following commands. ``` - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DatastoreExample" -Dexec.args="your-project-id my_name add my\ comment" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DatastoreExample" -Dexec.args="your-project-id my_name display" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DatastoreExample" -Dexec.args="your-project-id my_name delete" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name add my\ comment" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name display" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name delete" ``` * Here's an example run of `ResourceManagerExample`. Be sure to change the placeholder project ID "your-project-id" with your own globally unique project ID. ``` - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.ResourceManagerExample" -Dexec.args="create your-project-id" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.ResourceManagerExample" -Dexec.args="list" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.ResourceManagerExample" -Dexec.args="get your-project-id" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.resourcemanager.ResourceManagerExample" -Dexec.args="create your-project-id" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.resourcemanager.ResourceManagerExample" -Dexec.args="list" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.resourcemanager.ResourceManagerExample" -Dexec.args="get your-project-id" ``` * Here's an example run of `StorageExample`. Before running the example, go to the [Google Developers Console][developers-console] to ensure that Google Cloud Storage API is enabled and that you have a bucket. Also ensure that you have a test file (`test.txt` is chosen here) to upload to Cloud Storage stored locally on your machine. ``` - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.StorageExample" -Dexec.args="upload /path/to/test.txt " - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.StorageExample" -Dexec.args="list " - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.StorageExample" -Dexec.args="download test.txt" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.StorageExample" -Dexec.args="delete test.txt" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.storage.StorageExample" -Dexec.args="upload /path/to/test.txt " + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.storage.StorageExample" -Dexec.args="list " + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.storage.StorageExample" -Dexec.args="download test.txt" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.storage.StorageExample" -Dexec.args="delete test.txt" ``` Troubleshooting diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/BigQueryExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java similarity index 99% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/BigQueryExample.java rename to gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java index 7fb7e056d8cc..c8fbe7289f9c 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/BigQueryExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.examples; +package com.google.gcloud.examples.bigquery; import com.google.common.collect.ImmutableMap; import com.google.gcloud.WriteChannel; @@ -63,7 +63,7 @@ *

  • login using gcloud SDK - {@code gcloud auth login}.
  • *
  • compile using maven - {@code mvn compile}
  • *
  • run using maven - - *
    {@code mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.BigQueryExample"
    + * 
    {@code mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.bigquery.BigQueryExample"
      *  -Dexec.args="[]
      *  list datasets |
      *  list tables  |
    diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/CreateTableAndLoadData.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/CreateTableAndLoadData.java
    new file mode 100644
    index 000000000000..857f6b43d013
    --- /dev/null
    +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/CreateTableAndLoadData.java
    @@ -0,0 +1,64 @@
    +/*
    + * 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 READMEs and javadoc. Any change to this file should be reflected in
    + * the project's READMEs and package-info.java.
    + */
    +
    +package com.google.gcloud.examples.bigquery.snippets;
    +
    +import com.google.gcloud.bigquery.BigQuery;
    +import com.google.gcloud.bigquery.BigQueryOptions;
    +import com.google.gcloud.bigquery.Field;
    +import com.google.gcloud.bigquery.FormatOptions;
    +import com.google.gcloud.bigquery.Job;
    +import com.google.gcloud.bigquery.Schema;
    +import com.google.gcloud.bigquery.StandardTableDefinition;
    +import com.google.gcloud.bigquery.Table;
    +import com.google.gcloud.bigquery.TableId;
    +import com.google.gcloud.bigquery.TableInfo;
    +
    +/**
    + * A snippet for Google Cloud BigQuery showing how to get a BigQuery table or create it if it does
    + * not exist. The snippet also starts a BigQuery job to load data into the table from a Cloud
    + * Storage blob and wait until the job completes.
    + */
    +public class CreateTableAndLoadData {
    +
    +  public static void main(String... args) throws InterruptedException {
    +    BigQuery bigquery = BigQueryOptions.defaultInstance().service();
    +    TableId tableId = TableId.of("dataset", "table");
    +    Table table = bigquery.getTable(tableId);
    +    if (table == null) {
    +      System.out.println("Creating table " + tableId);
    +      Field integerField = Field.of("fieldName", Field.Type.integer());
    +      Schema schema = Schema.of(integerField);
    +      table = bigquery.create(TableInfo.of(tableId, StandardTableDefinition.of(schema)));
    +    }
    +    System.out.println("Loading data into table " + tableId);
    +    Job loadJob = table.load(FormatOptions.csv(), "gs://bucket/path");
    +    while (!loadJob.isDone()) {
    +      Thread.sleep(1000L);
    +    }
    +    if (loadJob.status().error() != null) {
    +      System.out.println("Job completed with errors");
    +    } else {
    +      System.out.println("Job succeeded");
    +    }
    +  }
    +}
    diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/InsertDataAndQueryTable.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/InsertDataAndQueryTable.java
    new file mode 100644
    index 000000000000..f421bc832441
    --- /dev/null
    +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/InsertDataAndQueryTable.java
    @@ -0,0 +1,102 @@
    +/*
    + * 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 READMEs and javadoc. Any change to this file should be reflected in
    + * the project's READMEs and package-info.java.
    + */
    +
    +package com.google.gcloud.examples.bigquery.snippets;
    +
    +import com.google.gcloud.bigquery.BigQuery;
    +import com.google.gcloud.bigquery.BigQueryOptions;
    +import com.google.gcloud.bigquery.DatasetInfo;
    +import com.google.gcloud.bigquery.Field;
    +import com.google.gcloud.bigquery.FieldValue;
    +import com.google.gcloud.bigquery.InsertAllRequest;
    +import com.google.gcloud.bigquery.InsertAllResponse;
    +import com.google.gcloud.bigquery.QueryRequest;
    +import com.google.gcloud.bigquery.QueryResponse;
    +import com.google.gcloud.bigquery.Schema;
    +import com.google.gcloud.bigquery.StandardTableDefinition;
    +import com.google.gcloud.bigquery.TableId;
    +import com.google.gcloud.bigquery.TableInfo;
    +
    +import java.util.HashMap;
    +import java.util.Iterator;
    +import java.util.List;
    +import java.util.Map;
    +
    +/**
    + * A snippet for Google Cloud BigQuery showing how to create a BigQuery dataset and table. Once
    + * created, the snippet streams data into the table and then queries it.
    + */
    +public class InsertDataAndQueryTable {
    +
    +  public static void main(String... args) throws InterruptedException {
    +    // Create a service instance
    +    BigQuery bigquery = BigQueryOptions.defaultInstance().service();
    +
    +    // Create a dataset
    +    String datasetId = "my_dataset_id";
    +    bigquery.create(DatasetInfo.builder(datasetId).build());
    +
    +    TableId tableId = TableId.of(datasetId, "my_table_id");
    +    // Table field definition
    +    Field stringField = Field.of("StringField", Field.Type.string());
    +    // Table schema definition
    +    Schema schema = Schema.of(stringField);
    +    // Create a table
    +    StandardTableDefinition tableDefinition = StandardTableDefinition.of(schema);
    +    bigquery.create(TableInfo.of(tableId, tableDefinition));
    +
    +    // Define rows to insert
    +    Map firstRow = new HashMap<>();
    +    Map secondRow = new HashMap<>();
    +    firstRow.put("StringField", "value1");
    +    secondRow.put("StringField", "value2");
    +    // Create an insert request
    +    InsertAllRequest insertRequest = InsertAllRequest.builder(tableId)
    +        .addRow(firstRow)
    +        .addRow(secondRow)
    +        .build();
    +    // Insert rows
    +    InsertAllResponse insertResponse = bigquery.insertAll(insertRequest);
    +    // Check if errors occurred
    +    if (insertResponse.hasErrors()) {
    +      System.out.println("Errors occurred while inserting rows");
    +    }
    +
    +    // Create a query request
    +    QueryRequest queryRequest = QueryRequest.builder("SELECT * FROM my_dataset_id.my_table_id")
    +        .maxWaitTime(60000L)
    +        .maxResults(1000L)
    +        .build();
    +    // Request query to be executed and wait for results
    +    QueryResponse queryResponse = bigquery.query(queryRequest);
    +    while (!queryResponse.jobCompleted()) {
    +      Thread.sleep(1000L);
    +      queryResponse = bigquery.getQueryResults(queryResponse.jobId());
    +    }
    +    // Read rows
    +    Iterator> rowIterator = queryResponse.result().iterateAll();
    +    System.out.println("Table rows:");
    +    while (rowIterator.hasNext()) {
    +      System.out.println(rowIterator.next());
    +    }
    +  }
    +}
    diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/DatastoreExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java
    similarity index 98%
    rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/DatastoreExample.java
    rename to gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java
    index 1e65a018a1fb..cc4331734200 100644
    --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/DatastoreExample.java
    +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.examples;
    +package com.google.gcloud.examples.datastore;
     
     import com.google.gcloud.datastore.Datastore;
     import com.google.gcloud.datastore.DatastoreOptions;
    @@ -44,7 +44,7 @@
      * 
  • login using gcloud SDK - {@code gcloud auth login}.
  • *
  • compile using maven - {@code mvn compile}
  • *
  • run using maven - {@code mvn exec:java - * -Dexec.mainClass="com.google.gcloud.examples.DatastoreExample" + * -Dexec.mainClass="com.google.gcloud.examples.datastore.DatastoreExample" * -Dexec.args="[projectId] [user] [delete|display|add comment]"}
  • * */ @@ -67,7 +67,7 @@ private static class DeleteAction implements DatastoreAction { public void run(Transaction tx, Key userKey, String... args) { Entity user = tx.get(userKey); if (user == null) { - System.out.println("Nothing to delete, user does not exists."); + System.out.println("Nothing to delete, user does not exist."); return; } Query query = Query.keyQueryBuilder() diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java new file mode 100644 index 000000000000..f1e844c79b24 --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java @@ -0,0 +1,84 @@ +/* + * 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 READMEs and javadoc. Any change to this file should be reflected in + * the project's READMEs and package-info.java. + */ + +package com.google.gcloud.examples.datastore.snippets; + +import com.google.gcloud.datastore.Datastore; +import com.google.gcloud.datastore.DatastoreOptions; +import com.google.gcloud.datastore.Entity; +import com.google.gcloud.datastore.Key; +import com.google.gcloud.datastore.KeyFactory; +import com.google.gcloud.datastore.Query; +import com.google.gcloud.datastore.QueryResults; +import com.google.gcloud.datastore.StructuredQuery.PropertyFilter; + +/** + * A snippet for Google Cloud Datastore showing how to create and get entities. The snippet also + * shows how to run a query against Datastore. + */ +public class AddEntitiesAndRunQuery { + + public static void main(String... args) { + // Create datastore service object. + // By default, credentials are inferred from the runtime environment. + Datastore datastore = DatastoreOptions.defaultInstance().service(); + + // Add an entity to Datastore + KeyFactory keyFactory = datastore.newKeyFactory().kind("Person"); + Key key = keyFactory.newKey("john.doe@gmail.com"); + Entity entity = Entity.builder(key) + .set("name", "John Doe") + .set("age", 51) + .set("favorite_food", "pizza") + .build(); + datastore.put(entity); + + // Get an entity from Datastore + Entity johnEntity = datastore.get(key); + + // Add a couple more entities to make the query results more interesting + Key janeKey = keyFactory.newKey("jane.doe@gmail.com"); + Entity janeEntity = Entity.builder(janeKey) + .set("name", "Jane Doe") + .set("age", 44) + .set("favorite_food", "pizza") + .build(); + Key joeKey = keyFactory.newKey("joe.shmoe@gmail.com"); + Entity joeEntity = Entity.builder(joeKey) + .set("name", "Joe Shmoe") + .set("age", 27) + .set("favorite_food", "sushi") + .build(); + datastore.put(janeEntity, joeEntity); + + // Run a query + Query query = Query.entityQueryBuilder() + .kind("Person") + .filter(PropertyFilter.eq("favorite_food", "pizza")) + .build(); + QueryResults results = datastore.run(query); + while (results.hasNext()) { + Entity currentEntity = results.next(); + System.out.println(currentEntity.getString("name") + ", you're invited to a pizza party!"); + } + } +} diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/CreateEntity.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/CreateEntity.java new file mode 100644 index 000000000000..3981162a2943 --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/CreateEntity.java @@ -0,0 +1,48 @@ +/* + * 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 READMEs and javadoc. Any change to this file should be reflected in + * the project's READMEs and package-info.java. + */ + +package com.google.gcloud.examples.datastore.snippets; + +import com.google.gcloud.datastore.Datastore; +import com.google.gcloud.datastore.DatastoreOptions; +import com.google.gcloud.datastore.DateTime; +import com.google.gcloud.datastore.Entity; +import com.google.gcloud.datastore.Key; +import com.google.gcloud.datastore.KeyFactory; + +/** + * A snippet for Google Cloud Datastore showing how to create an entity. + */ +public class CreateEntity { + + public static void main(String... args) { + Datastore datastore = DatastoreOptions.defaultInstance().service(); + KeyFactory keyFactory = datastore.newKeyFactory().kind("keyKind"); + Key key = keyFactory.newKey("keyName"); + Entity entity = Entity.builder(key) + .set("name", "John Doe") + .set("age", 30) + .set("access_time", DateTime.now()) + .build(); + datastore.put(entity); + } +} diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/UpdateEntity.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/UpdateEntity.java new file mode 100644 index 000000000000..cbc97f0784dd --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/UpdateEntity.java @@ -0,0 +1,50 @@ +/* + * 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 READMEs and javadoc. Any change to this file should be reflected in + * the project's READMEs and package-info.java. + */ + +package com.google.gcloud.examples.datastore.snippets; + +import com.google.gcloud.datastore.Datastore; +import com.google.gcloud.datastore.DatastoreOptions; +import com.google.gcloud.datastore.DateTime; +import com.google.gcloud.datastore.Entity; +import com.google.gcloud.datastore.Key; +import com.google.gcloud.datastore.KeyFactory; + +/** + * A snippet for Google Cloud Datastore showing how to get an entity and update it if it exists. + */ +public class UpdateEntity { + + public static void main(String... args) { + Datastore datastore = DatastoreOptions.defaultInstance().service(); + KeyFactory keyFactory = datastore.newKeyFactory().kind("keyKind"); + Key key = keyFactory.newKey("keyName"); + Entity entity = datastore.get(key); + if (entity != null) { + System.out.println("Updating access_time for " + entity.getString("name")); + entity = Entity.builder(entity) + .set("access_time", DateTime.now()) + .build(); + datastore.update(entity); + } + } +} diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/ResourceManagerExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java similarity index 98% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/ResourceManagerExample.java rename to gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java index 46ff82bfaf12..349c0eebe73d 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/ResourceManagerExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.examples; +package com.google.gcloud.examples.resourcemanager; import com.google.common.base.Joiner; import com.google.gcloud.resourcemanager.Project; @@ -36,7 +36,7 @@ *
  • login using gcloud SDK - {@code gcloud auth login}.
  • *
  • compile using maven - {@code mvn compile}
  • *
  • run using maven - {@code mvn exec:java - * -Dexec.mainClass="com.google.gcloud.examples.ResourceManagerExample" + * -Dexec.mainClass="com.google.gcloud.examples.resourcemanager.ResourceManagerExample" * -Dexec.args="[list | [create | delete | get] projectId]"}
  • * */ diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/GetOrCreateProject.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/GetOrCreateProject.java new file mode 100644 index 000000000000..5a298107cc60 --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/GetOrCreateProject.java @@ -0,0 +1,49 @@ +/* + * 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 READMEs and javadoc. Any change to this file should be reflected in + * the project's READMEs and package-info.java. + */ + +package com.google.gcloud.examples.resourcemanager.snippets; + +import com.google.gcloud.resourcemanager.Project; +import com.google.gcloud.resourcemanager.ProjectInfo; +import com.google.gcloud.resourcemanager.ResourceManager; +import com.google.gcloud.resourcemanager.ResourceManagerOptions; + +/** + * A snippet for Google Cloud Resource Manager showing how to create a project if it does not exist. + */ +public class GetOrCreateProject { + + public static void main(String... args) { + // Create Resource Manager service object. + // By default, credentials are inferred from the runtime environment. + ResourceManager resourceManager = ResourceManagerOptions.defaultInstance().service(); + + String projectId = "my-globally-unique-project-id"; // Change to a unique project ID. + // Get a project from the server. + Project project = resourceManager.get(projectId); + if (project == null) { + // Create a project. + project = resourceManager.create(ProjectInfo.builder(projectId).build()); + } + System.out.println("Got project " + project.projectId() + " from the server."); + } +} diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/UpdateAndListProjects.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/UpdateAndListProjects.java new file mode 100644 index 000000000000..b194de0815d5 --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/UpdateAndListProjects.java @@ -0,0 +1,62 @@ +/* + * 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 READMEs and javadoc. Any change to this file should be reflected in + * the project's READMEs and package-info.java. + */ + +package com.google.gcloud.examples.resourcemanager.snippets; + +import com.google.gcloud.resourcemanager.Project; +import com.google.gcloud.resourcemanager.ResourceManager; +import com.google.gcloud.resourcemanager.ResourceManagerOptions; + +import java.util.Iterator; + +/** + * A snippet for Google Cloud Resource Manager showing how to update a project and list all projects + * the user has permission to view. + */ +public class UpdateAndListProjects { + + public static void main(String... args) { + // Create Resource Manager service object + // By default, credentials are inferred from the runtime environment. + ResourceManager resourceManager = ResourceManagerOptions.defaultInstance().service(); + + // Get a project from the server + Project project = resourceManager.get("some-project-id"); // Use an existing project's ID + + // Update a project + if (project != null) { + Project newProject = project.toBuilder() + .addLabel("launch-status", "in-development") + .build() + .replace(); + System.out.println("Updated the labels of project " + newProject.projectId() + + " to be " + newProject.labels()); + } + + // List all the projects you have permission to view. + Iterator projectIterator = resourceManager.list().iterateAll(); + System.out.println("Projects I can view:"); + while (projectIterator.hasNext()) { + System.out.println(projectIterator.next().projectId()); + } + } +} diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java similarity index 93% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java rename to gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java index e3bee626f49c..e73cfc427129 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.examples; +package com.google.gcloud.examples.storage; import com.google.gcloud.AuthCredentials; import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; @@ -25,7 +25,6 @@ import com.google.gcloud.storage.BlobId; import com.google.gcloud.storage.BlobInfo; import com.google.gcloud.storage.Bucket; -import com.google.gcloud.storage.BucketInfo; import com.google.gcloud.storage.CopyWriter; import com.google.gcloud.storage.Storage; import com.google.gcloud.storage.Storage.ComposeRequest; @@ -66,7 +65,7 @@ *
  • login using gcloud SDK - {@code gcloud auth login}.
  • *
  • compile using maven - {@code mvn compile}
  • *
  • run using maven - - *
    {@code mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.StorageExample"
    + * 
    {@code mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.storage.StorageExample"
      *  -Dexec.args="[]
      *  list [] |
      *  info [ []] |
    @@ -133,27 +132,27 @@ public void run(Storage storage, BlobId... blobIds) {
           if (blobIds.length == 1) {
             if (blobIds[0].name().isEmpty()) {
               // get Bucket
    -          Bucket bucket = Bucket.get(storage, blobIds[0].bucket());
    +          Bucket bucket = storage.get(blobIds[0].bucket());
               if (bucket == null) {
                 System.out.println("No such bucket");
                 return;
               }
    -          System.out.println("Bucket info: " + bucket.info());
    +          System.out.println("Bucket info: " + bucket);
             } else {
               // get Blob
    -          Blob blob = Blob.get(storage, blobIds[0]);
    +          Blob blob = storage.get(blobIds[0]);
               if (blob == null) {
                 System.out.println("No such object");
                 return;
               }
    -          System.out.println("Blob info: " + blob.info());
    +          System.out.println("Blob info: " + blob);
             }
           } else {
             // use batch to get multiple blobs.
    -        List blobs = Blob.get(storage, Arrays.asList(blobIds));
    +        List blobs = storage.get(blobIds);
             for (Blob blob : blobs) {
               if (blob != null) {
    -            System.out.println(blob.info());
    +            System.out.println(blob);
               }
             }
           }
    @@ -184,7 +183,7 @@ private static class DeleteAction extends BlobsAction {
         @Override
         public void run(Storage storage, BlobId... blobIds) {
           // use batch operation
    -      List deleteResults = Blob.delete(storage, blobIds);
    +      List deleteResults = storage.delete(blobIds);
           int index = 0;
           for (Boolean deleted : deleteResults) {
             if (deleted) {
    @@ -218,20 +217,20 @@ String parse(String... args) {
         public void run(Storage storage, String bucketName) {
           if (bucketName == null) {
             // list buckets
    -        Iterator bucketInfoIterator = storage.list().iterateAll();
    -        while (bucketInfoIterator.hasNext()) {
    -          System.out.println(bucketInfoIterator.next());
    +        Iterator bucketIterator = storage.list().iterateAll();
    +        while (bucketIterator.hasNext()) {
    +          System.out.println(bucketIterator.next());
             }
           } else {
             // list a bucket's blobs
    -        Bucket bucket = Bucket.get(storage, bucketName);
    +        Bucket bucket = storage.get(bucketName);
             if (bucket == null) {
               System.out.println("No such bucket");
               return;
             }
             Iterator blobIterator = bucket.list().iterateAll();
             while (blobIterator.hasNext()) {
    -          System.out.println(blobIterator.next().info());
    +          System.out.println(blobIterator.next());
             }
           }
         }
    @@ -257,8 +256,7 @@ private void run(Storage storage, Path uploadFrom, BlobInfo blobInfo) throws IOE
           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.
    -        Blob blob = new Blob(storage, blobInfo);
    -        try (WriteChannel writer = blob.writer()) {
    +        try (WriteChannel writer = storage.writer(blobInfo)) {
               byte[] buffer = new byte[1024];
               try (InputStream input = Files.newInputStream(uploadFrom)) {
                 int limit;
    @@ -311,7 +309,7 @@ public void run(Storage storage, Tuple tuple) throws IOException {
         }
     
         private void run(Storage storage, BlobId blobId, Path downloadTo) throws IOException {
    -      Blob blob = Blob.get(storage, blobId);
    +      Blob blob = storage.get(blobId);
           if (blob == null) {
             System.out.println("No such object");
             return;
    @@ -320,7 +318,7 @@ private void run(Storage storage, BlobId blobId, Path downloadTo) throws IOExcep
           if (downloadTo != null) {
             writeTo = new PrintStream(new FileOutputStream(downloadTo.toFile()));
           }
    -      if (blob.info().size() < 1_000_000) {
    +      if (blob.size() < 1_000_000) {
             // Blob is small read all its content in one request
             byte[] content = blob.content();
             writeTo.write(content);
    @@ -438,13 +436,13 @@ public void run(Storage storage, Tuple> tuple)
         }
     
         private void run(Storage storage, BlobId blobId, Map metadata) {
    -      Blob blob = Blob.get(storage, blobId);
    +      Blob blob = storage.get(blobId);
           if (blob == null) {
             System.out.println("No such object");
             return;
           }
    -      Blob updateBlob = blob.update(blob.info().toBuilder().metadata(metadata).build());
    -      System.out.println("Updated " + updateBlob.info());
    +      Blob updateBlob = blob.toBuilder().metadata(metadata).build().update();
    +      System.out.println("Updated " + updateBlob);
         }
     
         @Override
    @@ -488,9 +486,8 @@ public void run(Storage storage, Tuple
           run(storage, tuple.x(), tuple.y());
         }
     
    -    private void run(Storage storage, ServiceAccountAuthCredentials cred, BlobInfo blobInfo)
    -        throws IOException {
    -      Blob blob = new Blob(storage, blobInfo);
    +    private void run(Storage storage, ServiceAccountAuthCredentials cred, BlobInfo blobInfo) {
    +      Blob blob = storage.get(blobInfo.blobId());
           System.out.println("Signed URL: "
               + blob.signUrl(1, TimeUnit.DAYS, SignUrlOption.serviceAccount(cred)));
         }
    diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateAndListBucketsAndBlobs.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateAndListBucketsAndBlobs.java
    new file mode 100644
    index 000000000000..435cc90b03d8
    --- /dev/null
    +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateAndListBucketsAndBlobs.java
    @@ -0,0 +1,70 @@
    +/*
    + * 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 READMEs and javadoc. Any change to this file should be reflected in
    + * the project's READMEs and package-info.java.
    + */
    +
    +package com.google.gcloud.examples.storage.snippets;
    +
    +import static java.nio.charset.StandardCharsets.UTF_8;
    +
    +import com.google.gcloud.storage.Blob;
    +import com.google.gcloud.storage.Bucket;
    +import com.google.gcloud.storage.BucketInfo;
    +import com.google.gcloud.storage.Storage;
    +import com.google.gcloud.storage.StorageOptions;
    +
    +import java.util.Iterator;
    +
    +/**
    + * A snippet for Google Cloud Storage showing how to create a bucket and a blob in it. The snippet
    + * also shows how to get a blob's content, list buckets and list blobs.
    + */
    +public class CreateAndListBucketsAndBlobs {
    +
    +  public static void main(String... args) {
    +    // Create a service object
    +    // Credentials are inferred from the environment.
    +    Storage storage = StorageOptions.defaultInstance().service();
    +
    +    // Create a bucket
    +    String bucketName = "my_unique_bucket"; // Change this to something unique
    +    Bucket bucket = storage.create(BucketInfo.of(bucketName));
    +
    +    // Upload a blob to the newly created bucket
    +    Blob blob = bucket.create("my_blob_name", "a simple blob".getBytes(UTF_8), "text/plain");
    +
    +    // Read the blob content from the server
    +    String blobContent = new String(blob.content(), UTF_8);
    +
    +    // List all your buckets
    +    Iterator bucketIterator = storage.list().iterateAll();
    +    System.out.println("My buckets:");
    +    while (bucketIterator.hasNext()) {
    +      System.out.println(bucketIterator.next());
    +    }
    +
    +    // List the blobs in a particular bucket
    +    Iterator blobIterator = bucket.list().iterateAll();
    +    System.out.println("My blobs:");
    +    while (blobIterator.hasNext()) {
    +      System.out.println(blobIterator.next());
    +    }
    +  }
    +}
    diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateBlob.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateBlob.java
    new file mode 100644
    index 000000000000..2c1304a478ab
    --- /dev/null
    +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateBlob.java
    @@ -0,0 +1,44 @@
    +/*
    + * 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 READMEs and javadoc. Any change to this file should be reflected in
    + * the project's READMEs and package-info.java.
    + */
    +
    +package com.google.gcloud.examples.storage.snippets;
    +
    +import static java.nio.charset.StandardCharsets.UTF_8;
    +
    +import com.google.gcloud.storage.Blob;
    +import com.google.gcloud.storage.BlobId;
    +import com.google.gcloud.storage.BlobInfo;
    +import com.google.gcloud.storage.Storage;
    +import com.google.gcloud.storage.StorageOptions;
    +
    +/**
    + * A snippet for Google Cloud Storage showing how to create a blob.
    + */
    +public class CreateBlob {
    +
    +  public static void main(String... args) {
    +    Storage storage = StorageOptions.defaultInstance().service();
    +    BlobId blobId = BlobId.of("bucket", "blob_name");
    +    BlobInfo blobInfo = BlobInfo.builder(blobId).contentType("text/plain").build();
    +    Blob blob = storage.create(blobInfo, "Hello, Cloud Storage!".getBytes(UTF_8));
    +  }
    +}
    diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/UpdateBlob.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/UpdateBlob.java
    new file mode 100644
    index 000000000000..13290b201787
    --- /dev/null
    +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/UpdateBlob.java
    @@ -0,0 +1,53 @@
    +/*
    + * 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 READMEs and javadoc. Any change to this file should be reflected in
    + * the project's READMEs and package-info.java.
    + */
    +
    +package com.google.gcloud.examples.storage.snippets;
    +
    +import static java.nio.charset.StandardCharsets.UTF_8;
    +
    +import com.google.gcloud.storage.Blob;
    +import com.google.gcloud.storage.BlobId;
    +import com.google.gcloud.storage.Storage;
    +import com.google.gcloud.storage.StorageOptions;
    +
    +import java.io.IOException;
    +import java.nio.ByteBuffer;
    +import java.nio.channels.WritableByteChannel;
    +
    +/**
    + * A snippet for Google Cloud Storage showing how to update the blob's content if the blob exists.
    + */
    +public class UpdateBlob {
    +
    +  public static void main(String... args) throws IOException {
    +    Storage storage = StorageOptions.defaultInstance().service();
    +    BlobId blobId = BlobId.of("bucket", "blob_name");
    +    Blob blob = storage.get(blobId);
    +    if (blob != null) {
    +      byte[] prevContent = blob.content();
    +      System.out.println(new String(prevContent, UTF_8));
    +      WritableByteChannel channel = blob.writer();
    +      channel.write(ByteBuffer.wrap("Updated content".getBytes(UTF_8)));
    +      channel.close();
    +    }
    +  }
    +}
    diff --git a/gcloud-java-resourcemanager/README.md b/gcloud-java-resourcemanager/README.md
    index d9a99e12b7a5..6f7d52386fc0 100644
    --- a/gcloud-java-resourcemanager/README.md
    +++ b/gcloud-java-resourcemanager/README.md
    @@ -6,6 +6,7 @@ Java idiomatic client for [Google Cloud Resource Manager] (https://cloud.google.
     [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java)
     [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master)
     [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-resourcemanager.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-resourcemanager.svg)
    +[![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java)
     
     -  [Homepage] (https://googlecloudplatform.github.io/gcloud-java/)
     -  [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/resourcemanager/package-summary.html)
    @@ -34,7 +35,7 @@ libraryDependencies += "com.google.gcloud" % "gcloud-java-resourcemanager" % "0.
     
     Example Application
     --------------------
    -[`ResourceManagerExample`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-examples/src/main/java/com/google/gcloud/examples/ResourceManagerExample.java) is a simple command line interface for the Cloud Resource Manager.  Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/ResourceManagerExample.html).
    +[`ResourceManagerExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java) is a simple command line interface for the Cloud Resource Manager.  Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/ResourceManagerExample.html).
     
     Authentication
     --------------
    @@ -70,7 +71,12 @@ You will need to set up the local development environment by [installing the Goo
     You'll need to obtain the `gcloud-java-resourcemanager` library.  See the [Quickstart](#quickstart) section to add `gcloud-java-resourcemanager` as a dependency in your code.
     
     #### Creating an authorized service object
    -To make authenticated requests to Google Cloud Resource Manager, you must create a service object with Google Cloud SDK credentials. You can then make API calls by calling methods on the Resource Manager service object. The simplest way to authenticate is to use [Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials). These credentials are automatically inferred from your environment, so you only need the following code to create your service object:
    +To make authenticated requests to Google Cloud Resource Manager, you must create a service object
    +with Google Cloud SDK credentials. You can then make API calls by calling methods on the Resource
    +Manager service object. The simplest way to authenticate is to use
    +[Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials).
    +These credentials are automatically inferred from your environment, so you only need the following
    +code to create your service object:
     
     ```java
     import com.google.gcloud.resourcemanager.ResourceManager;
    @@ -79,46 +85,68 @@ import com.google.gcloud.resourcemanager.ResourceManagerOptions;
     ResourceManager resourceManager = ResourceManagerOptions.defaultInstance().service();
     ```
     
    -#### Creating a project
    -All you need to create a project is a globally unique project ID.  You can also optionally attach a non-unique name and labels to your project. Read more about naming guidelines for project IDs, names, and labels [here](https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects). To create a project, add the following import at the top of your file:
    +#### Getting a specific project
    +You can load a project if you know it's project ID and have read permissions to the project.
    +To get a project, add the following import at the top of your file:
     
     ```java
     import com.google.gcloud.resourcemanager.Project;
    -import com.google.gcloud.resourcemanager.ProjectInfo;
     ```
     
    -Then add the following code to create a project (be sure to change `myProjectId` to your own unique project ID).
    +Then use the following code to get the project:
     
     ```java
    -String myProjectId = "my-globally-unique-project-id"; // Change to a unique project ID.
    -Project myProject = resourceManager.create(ProjectInfo.builder(myProjectId).build());
    +String projectId = "my-globally-unique-project-id"; // Change to a unique project ID
    +Project project = resourceManager.get(projectId);
     ```
     
    -Note that the return value from `create` is a `Project` that includes additional read-only information, like creation time, project number, and lifecycle state. Read more about these fields on the [Projects page](https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects). `Project`, a subclass of `ProjectInfo`, adds a layer of service-related functionality over `ProjectInfo`.
    +#### Creating a project
    +All you need to create a project is a globally unique project ID. You can also optionally attach a
    +non-unique name and labels to your project. Read more about naming guidelines for project IDs,
    +names, and labels [here](https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects).
    +To create a project, add the following imports at the top of your file:
     
    -#### Getting a specific project
    -You can load a project if you know it's project ID and have read permissions to the project. For example, to get the project we just created we can do the following:
    +```java
    +import com.google.gcloud.resourcemanager.Project;
    +import com.google.gcloud.resourcemanager.ProjectInfo;
    +```
    +
    +Then add the following code to create a project (be sure to change `projectId` to your own unique
    +project ID).
     
     ```java
    -Project projectFromServer = resourceManager.get(myProjectId);
    +String projectId = "my-globally-unique-project-id"; // Change to a unique project ID
    +Project project = resourceManager.create(ProjectInfo.builder(projectId).build());
     ```
     
    +Note that the return value from `create` is a `Project` that includes additional read-only
    +information, like creation time, project number, and lifecycle state. Read more about these fields
    +on the [Projects page](https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects).
    +`Project`, a subclass of `ProjectInfo`, adds a layer of service-related functionality over
    +`ProjectInfo`.
    +
     #### Editing a project
     To edit a project, create a new `ProjectInfo` object and pass it in to the `Project.replace` method.
    -
    -For example, to add a label for the newly created project to denote that it's launch status is "in development", add the following code:
    +For example, to add a label to a project to denote that it's launch status is "in development", add
    +the following code:
     
     ```java
    -Project newProject = myProject.toBuilder()
    +Project newProject = project.toBuilder()
         .addLabel("launch-status", "in-development")
         .build()
         .replace();
     ```
     
    -Note that the values of the project you pass in to `replace` overwrite the server's values for non-read-only fields, namely `projectName` and `labels`. For example, if you create a project with `projectName` "some-project-name" and subsequently call replace using a `ProjectInfo` object that didn't set the `projectName`, then the server will unset the project's name. The server ignores any attempted changes to the read-only fields `projectNumber`, `lifecycleState`, and `createTime`. The `projectId` cannot change.
    +Note that the values of the project you pass in to `replace` overwrite the server's values for
    +non-read-only fields, namely `projectName` and `labels`. For example, if you create a project with
    +`projectName` "some-project-name" and subsequently call replace using a `ProjectInfo` object that
    +didn't set the `projectName`, then the server will unset the project's name. The server ignores any
    +attempted changes to the read-only fields `projectNumber`, `lifecycleState`, and `createTime`.
    +The `projectId` cannot change.
     
     #### Listing all projects
    -Suppose that we want a list of all projects for which we have read permissions. Add the following import:
    +Suppose that we want a list of all projects for which we have read permissions. Add the following
    +import:
     
     ```java
     import java.util.Iterator;
    @@ -136,48 +164,15 @@ while (projectIterator.hasNext()) {
     
     #### Complete source code
     
    -Here we put together all the code shown above into one program.  This program assumes that you are running from your own desktop and used the Google Cloud SDK to authenticate yourself.
    -
    -```java
    -import com.google.gcloud.resourcemanager.Project;
    -import com.google.gcloud.resourcemanager.ProjectInfo;
    -import com.google.gcloud.resourcemanager.ResourceManager;
    -import com.google.gcloud.resourcemanager.ResourceManagerOptions;
    +We put together all the code shown above into two programs. Both programs assume that you are
    +running from your own desktop and used the Google Cloud SDK to authenticate yourself.
     
    -import java.util.Iterator;
    +The first program creates a project if it does not exist. Complete source code can be found at
    +[GetOrCreateProject.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/GetOrCreateProject.java).
     
    -public class GcloudJavaResourceManagerExample {
    -
    -  public static void main(String[] args) {
    -    // Create Resource Manager service object.
    -    // By default, credentials are inferred from the runtime environment.
    -    ResourceManager resourceManager = ResourceManagerOptions.defaultInstance().service();
    -
    -    // Create a project.
    -    String myProjectId = "my-globally-unique-project-id"; // Change to a unique project ID.
    -    Project myProject = resourceManager.create(ProjectInfo.builder(myProjectId).build());
    -
    -    // Get a project from the server.
    -    Project projectFromServer = resourceManager.get(myProjectId);
    -    System.out.println("Got project " + projectFromServer.projectId() + " from the server.");
    -
    -    // Update a project
    -    Project newProject = myProject.toBuilder()
    -        .addLabel("launch-status", "in-development")
    -        .build()
    -        .replace();
    -    System.out.println("Updated the labels of project " + newProject.projectId()
    -        + " to be " + newProject.labels());
    -
    -    // List all the projects you have permission to view.
    -    Iterator projectIterator = resourceManager.list().iterateAll();
    -    System.out.println("Projects I can view:");
    -    while (projectIterator.hasNext()) {
    -      System.out.println(projectIterator.next().projectId());
    -    }
    -  }
    -}
    -```
    +The second program updates a project if it exists and lists all projects the user has permission to
    +view. Complete source code can be found at
    +[UpdateAndListProjects.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/UpdateAndListProjects.java).
     
     Java Versions
     -------------
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java
    index f12a7ea50676..4d12a31274c0 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java
    @@ -38,14 +38,12 @@ public class Project extends ProjectInfo {
       private final ResourceManagerOptions options;
       private transient ResourceManager resourceManager;
     
    +  /**
    +   * Builder for {@code Project}.
    +   */
       public static class Builder extends ProjectInfo.Builder {
         private final ResourceManager resourceManager;
    -    private ProjectInfo.BuilderImpl infoBuilder;
    -
    -    Builder(ResourceManager resourceManager) {
    -      this.resourceManager = resourceManager;
    -      this.infoBuilder = new ProjectInfo.BuilderImpl();
    -    }
    +    private final ProjectInfo.BuilderImpl infoBuilder;
     
         Builder(Project project) {
           this.resourceManager = project.resourceManager;
    @@ -124,16 +122,6 @@ public Project build() {
         this.options = resourceManager.options();
       }
     
    -  /**
    -   * Constructs a Project object that contains project information got from the server.
    -   *
    -   * @return Project object containing the project's metadata or {@code null} if not found
    -   * @throws ResourceManagerException upon failure
    -   */
    -  public static Project get(ResourceManager resourceManager, String projectId) {
    -    return resourceManager.get(projectId);
    -  }
    -
       /**
        * Returns the {@link ResourceManager} service object associated with this Project.
        */
    @@ -142,14 +130,14 @@ public ResourceManager resourceManager() {
       }
     
       /**
    -   * Fetches the current project's latest information. Returns {@code null} if the job does not
    +   * Fetches the project's latest information. Returns {@code null} if the project does not
        * exist.
        *
        * @return Project containing the project's updated metadata or {@code null} if not found
        * @throws ResourceManagerException upon failure
        */
       public Project reload() {
    -    return Project.get(resourceManager, projectId());
    +    return resourceManager.get(projectId());
       }
     
       /**
    @@ -210,10 +198,6 @@ public Project replace() {
         return resourceManager.replace(this);
       }
     
    -  static Builder builder(ResourceManager resourceManager, String projectId) {
    -    return new Builder(resourceManager).projectId(projectId);
    -  }
    -
       @Override
       public Builder toBuilder() {
         return new Builder(this);
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ProjectInfo.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ProjectInfo.java
    index 7553a207cd29..260e8a8e2f26 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ProjectInfo.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ProjectInfo.java
    @@ -115,7 +115,10 @@ static ResourceId fromPb(
         }
       }
     
    -  public static abstract class Builder {
    +  /**
    +   * Builder for {@code ProjectInfo}.
    +   */
    +  public abstract static class Builder {
     
         /**
          * Set the user-assigned name of the project.
    @@ -184,7 +187,9 @@ static class BuilderImpl extends Builder {
         private Long createTimeMillis;
         private ResourceId parent;
     
    -    BuilderImpl() {}
    +    BuilderImpl(String projectId) {
    +      this.projectId = projectId;
    +    }
     
         BuilderImpl(ProjectInfo info) {
           this.name = info.name;
    @@ -331,7 +336,7 @@ public Long createTimeMillis() {
     
       @Override
       public boolean equals(Object obj) {
    -    return obj.getClass().equals(ProjectInfo.class)
    +    return obj != null && obj.getClass().equals(ProjectInfo.class)
             && Objects.equals(toPb(), ((ProjectInfo) obj).toPb());
       }
     
    @@ -341,7 +346,7 @@ public int hashCode() {
       }
     
       public static Builder builder(String id) {
    -    return new BuilderImpl().projectId(id);
    +    return new BuilderImpl(id);
       }
     
       public Builder toBuilder() {
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/package-info.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/package-info.java
    index 22a81499eb7a..d1794447e9fb 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/package-info.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/package-info.java
    @@ -17,21 +17,40 @@
     /**
      * A client to Google Cloud Resource Manager.
      *
    - * 

    Here's a simple usage example for using gcloud-java-resourcemanager: + *

    Here's a simple usage example for using gcloud-java from App/Compute Engine. This example + * creates a project if it does not exist. For the complete source code see + * + * GetOrCreateProject.java. *

     {@code
      * ResourceManager resourceManager = ResourceManagerOptions.defaultInstance().service();
    - * String myProjectId = "my-globally-unique-project-id"; // Change to a unique project ID.
    - * Project myProject = resourceManager.create(ProjectInfo.builder(myProjectId).build());
    - * Project newProject = myProject.toBuilder()
    - *     .addLabel("launch-status", "in-development")
    - *     .build()
    - *     .replace();
    + * String projectId = "my-globally-unique-project-id"; // Change to a unique project ID.
    + * Project project = resourceManager.get(projectId);
    + * if (project == null) {
    + *   project = resourceManager.create(ProjectInfo.builder(projectId).build());
    + * }
    + * System.out.println("Got project " + project.projectId() + " from the server.");
    + * }
    + *

    + * This second example shows how to update a project if it exists and list all projects the user has + * permission to view. For the complete source code see + * + * UpdateAndListProjects.java. + *

     {@code
    + * ResourceManager resourceManager = ResourceManagerOptions.defaultInstance().service();
    + * Project project = resourceManager.get("some-project-id"); // Use an existing project's ID
    + * if (project != null) {
    + *   Project newProject = project.toBuilder()
    + *       .addLabel("launch-status", "in-development")
    + *       .build()
    + *       .replace();
    + *   System.out.println("Updated the labels of project " + newProject.projectId()
    + *       + " to be " + newProject.labels());
    + * }
      * Iterator projectIterator = resourceManager.list().iterateAll();
      * System.out.println("Projects I can view:");
      * while (projectIterator.hasNext()) {
      *   System.out.println(projectIterator.next().projectId());
      * }}
    - * *

    Remember that you must authenticate using the Google Cloud SDK. See more about * providing * credentials here. diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java index a741963913c6..4e239acc45ef 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java @@ -24,11 +24,11 @@ import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; import com.google.common.collect.ImmutableMap; import org.junit.After; +import org.junit.Before; import org.junit.Test; import java.util.Map; @@ -54,6 +54,11 @@ public class ProjectTest { private Project expectedProject; private Project project; + @Before + public void setUp() { + resourceManager = createStrictMock(ResourceManager.class); + } + @After public void tearDown() throws Exception { verify(resourceManager); @@ -62,7 +67,6 @@ public void tearDown() throws Exception { private void initializeExpectedProject(int optionsCalls) { expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); replay(serviceMockReturnsOptions); - resourceManager = createStrictMock(ResourceManager.class); expectedProject = new Project(serviceMockReturnsOptions, new ProjectInfo.BuilderImpl(PROJECT_INFO)); } @@ -71,31 +75,33 @@ private void initializeProject() { project = new Project(resourceManager, new ProjectInfo.BuilderImpl(PROJECT_INFO)); } + @Test + public void testToBuilder() { + initializeExpectedProject(4); + replay(resourceManager); + compareProjects(expectedProject, expectedProject.toBuilder().build()); + } + @Test public void testBuilder() { - initializeExpectedProject(2); + initializeExpectedProject(4); + expect(resourceManager.options()).andReturn(mockOptions).times(4); replay(resourceManager); - Project builtProject = Project.builder(serviceMockReturnsOptions, PROJECT_ID) - .name(NAME) + Project.Builder builder = + new Project.Builder(new Project(resourceManager, new ProjectInfo.BuilderImpl(PROJECT_ID))); + Project project = builder.name(NAME) .labels(LABELS) .projectNumber(PROJECT_NUMBER) .createTimeMillis(CREATE_TIME_MILLIS) .state(STATE) .build(); - assertEquals(PROJECT_ID, builtProject.projectId()); - assertEquals(NAME, builtProject.name()); - assertEquals(LABELS, builtProject.labels()); - assertEquals(PROJECT_NUMBER, builtProject.projectNumber()); - assertEquals(CREATE_TIME_MILLIS, builtProject.createTimeMillis()); - assertEquals(STATE, builtProject.state()); - assertSame(serviceMockReturnsOptions, builtProject.resourceManager()); - } - - @Test - public void testToBuilder() { - initializeExpectedProject(4); - replay(resourceManager); - compareProjects(expectedProject, expectedProject.toBuilder().build()); + assertEquals(PROJECT_ID, project.projectId()); + assertEquals(NAME, project.name()); + assertEquals(LABELS, project.labels()); + assertEquals(PROJECT_NUMBER, project.projectNumber()); + assertEquals(CREATE_TIME_MILLIS, project.createTimeMillis()); + assertEquals(STATE, project.state()); + assertEquals(resourceManager.options(), project.resourceManager().options()); } @Test @@ -103,7 +109,7 @@ public void testGet() { initializeExpectedProject(1); expect(resourceManager.get(PROJECT_INFO.projectId())).andReturn(expectedProject); replay(resourceManager); - Project loadedProject = Project.get(resourceManager, PROJECT_INFO.projectId()); + Project loadedProject = resourceManager.get(PROJECT_INFO.projectId()); assertEquals(expectedProject, loadedProject); } @@ -126,7 +132,7 @@ public void testLoadNull() { initializeExpectedProject(1); expect(resourceManager.get(PROJECT_INFO.projectId())).andReturn(null); replay(resourceManager); - assertNull(Project.get(resourceManager, PROJECT_INFO.projectId())); + assertNull(resourceManager.get(PROJECT_INFO.projectId())); } @Test diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md index 7260ab5fe5c5..554f22b38e7f 100644 --- a/gcloud-java-storage/README.md +++ b/gcloud-java-storage/README.md @@ -6,6 +6,7 @@ Java idiomatic client for [Google Cloud Storage] (https://cloud.google.com/stora [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-storage.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-storage.svg) +[![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/storage/package-summary.html) @@ -35,7 +36,7 @@ libraryDependencies += "com.google.gcloud" % "gcloud-java-storage" % "0.1.3" Example Application ------------------- -[`StorageExample`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java) is a simple command line interface that provides some of Cloud Storage's functionality. Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/StorageExample.html). +[`StorageExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java) is a simple command line interface that provides some of Cloud Storage's functionality. Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/StorageExample.html). Authentication -------------- @@ -77,15 +78,15 @@ Storage storage = StorageOptions.defaultInstance().service(); For other authentication options, see the [Authentication](https://github.com/GoogleCloudPlatform/gcloud-java#authentication) page. #### Storing data -Stored objects are called "blobs" in `gcloud-java` and are organized into containers called "buckets". In this code snippet, we will create a new bucket and upload a blob to that bucket. +Stored objects are called "blobs" in `gcloud-java` and are organized into containers called "buckets". `Blob`, a subclass of `BlobInfo`, adds a layer of service-related functionality over `BlobInfo`. Similarly, `Bucket` adds a layer of service-related functionality over `BucketInfo`. In this code snippet, we will create a new bucket and upload a blob to that bucket. Add the following imports at the top of your file: ```java import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.gcloud.storage.BlobId; -import com.google.gcloud.storage.BlobInfo; +import com.google.gcloud.storage.Blob; +import com.google.gcloud.storage.Bucket; import com.google.gcloud.storage.BucketInfo; ``` @@ -96,13 +97,12 @@ Then add the following code to create a bucket and upload a simple blob. ```java // Create a bucket String bucketName = "my_unique_bucket"; // Change this to something unique -BucketInfo bucketInfo = storage.create(BucketInfo.of(bucketName)); +Bucket bucket = storage.create(BucketInfo.of(bucketName)); // Upload a blob to the newly created bucket BlobId blobId = BlobId.of(bucketName, "my_blob_name"); -BlobInfo blobInfo = storage.create( - BlobInfo.builder(blobId).contentType("text/plain").build(), - "a simple blob".getBytes(UTF_8)); +Blob blob = storage.create( + "my_blob_name", "a simple blob".getBytes(UTF_8), "text/plain"); ``` At this point, you will be able to see your newly created bucket and blob on the Google Developers Console. @@ -111,7 +111,7 @@ At this point, you will be able to see your newly created bucket and blob on the Now that we have content uploaded to the server, we can see how to read data from the server. Add the following line to your program to get back the blob we uploaded. ```java -String blobContent = new String(storage.readAllBytes(blobId), UTF_8); +String blobContent = new String(blob.content(), UTF_8); ``` #### Listing buckets and contents of buckets @@ -125,14 +125,14 @@ Then add the following code to list all your buckets and all the blobs inside yo ```java // List all your buckets -Iterator bucketInfoIterator = storage.list().iterateAll(); +Iterator bucketIterator = storage.list().iterateAll(); System.out.println("My buckets:"); -while (bucketInfoIterator.hasNext()) { - System.out.println(bucketInfoIterator.next()); +while (bucketIterator.hasNext()) { + System.out.println(bucketIterator.next()); } // List the blobs in a particular bucket -Iterator blobIterator = storage.list(bucketName).iterateAll(); +Iterator blobIterator = bucket.list().iterateAll(); System.out.println("My blobs:"); while (blobIterator.hasNext()) { System.out.println(blobIterator.next()); @@ -141,55 +141,12 @@ while (blobIterator.hasNext()) { #### Complete source code -Here we put together all the code shown above into one program. This program assumes that you are running on Compute Engine or from your own desktop. To run this example on App Engine, simply move the code from the main method to your application's servlet class and change the print statements to display on your webpage. - -```java -import static java.nio.charset.StandardCharsets.UTF_8; - -import com.google.gcloud.storage.BlobId; -import com.google.gcloud.storage.BlobInfo; -import com.google.gcloud.storage.BucketInfo; -import com.google.gcloud.storage.Storage; -import com.google.gcloud.storage.StorageOptions; - -import java.util.Iterator; - -public class GcloudStorageExample { - - public static void main(String[] args) { - // Create a service object - // Credentials are inferred from the environment. - Storage storage = StorageOptions.defaultInstance().service(); - - // Create a bucket - String bucketName = "my_unique_bucket"; // Change this to something unique - BucketInfo bucketInfo = storage.create(BucketInfo.of(bucketName)); - - // Upload a blob to the newly created bucket - BlobId blobId = BlobId.of(bucketName, "my_blob_name"); - BlobInfo blobInfo = storage.create( - BlobInfo.builder(blobId).contentType("text/plain").build(), - "a simple blob".getBytes(UTF_8)); - - // Retrieve a blob from the server - String blobContent = new String(storage.readAllBytes(blobId), UTF_8); - - // List all your buckets - Iterator bucketInfoIterator = storage.list().iterateAll(); - System.out.println("My buckets:"); - while (bucketInfoIterator.hasNext()) { - System.out.println(bucketInfoIterator.next()); - } - - // List the blobs in a particular bucket - Iterator blobIterator = storage.list(bucketName).iterateAll(); - System.out.println("My blobs:"); - while (blobIterator.hasNext()) { - System.out.println(blobIterator.next()); - } - } -} -``` +In +[CreateAndListBucketsAndBlobs.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateAndListBucketsAndBlobs.java) +we put together all the code shown above into one program. The program assumes that you are +running on Compute Engine or from your own desktop. To run the example on App Engine, simply move +the code from the main method to your application's servlet class and change the print statements to +display on your webpage. Troubleshooting --------------- diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BatchResponse.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BatchResponse.java index 98e7ce09cef0..fe5f6f5743c8 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BatchResponse.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BatchResponse.java @@ -31,8 +31,8 @@ public final class BatchResponse implements Serializable { private static final long serialVersionUID = 1057416839397037706L; private final List> deleteResult; - private final List> updateResult; - private final List> getResult; + private final List> updateResult; + private final List> getResult; public static class Result implements Serializable { @@ -113,8 +113,8 @@ static Result empty() { } } - BatchResponse(List> deleteResult, List> updateResult, - List> getResult) { + BatchResponse(List> deleteResult, List> updateResult, + List> getResult) { this.deleteResult = ImmutableList.copyOf(deleteResult); this.updateResult = ImmutableList.copyOf(updateResult); this.getResult = ImmutableList.copyOf(getResult); @@ -146,14 +146,14 @@ public List> deletes() { /** * Returns the results for the update operations using the request order. */ - public List> updates() { + public List> updates() { return updateResult; } /** * Returns the results for the get operations using the request order. */ - public List> gets() { + public List> gets() { return getResult; } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java index fe65f6ee010b..ec8ab361328e 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java @@ -16,26 +16,27 @@ package com.google.gcloud.storage; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.gcloud.storage.Blob.BlobSourceOption.toGetOptions; import static com.google.gcloud.storage.Blob.BlobSourceOption.toSourceOptions; +import com.google.api.services.storage.model.StorageObject; import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; import com.google.gcloud.ReadChannel; import com.google.gcloud.WriteChannel; import com.google.gcloud.spi.StorageRpc; +import com.google.gcloud.spi.StorageRpc.Tuple; import com.google.gcloud.storage.Storage.BlobTargetOption; import com.google.gcloud.storage.Storage.BlobWriteOption; import com.google.gcloud.storage.Storage.CopyRequest; import com.google.gcloud.storage.Storage.SignUrlOption; +import java.io.IOException; +import java.io.ObjectInputStream; import java.net.URL; import java.util.Arrays; -import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.concurrent.TimeUnit; @@ -44,13 +45,24 @@ * *

    Objects of this class are immutable. Operations that modify the blob like {@link #update} and * {@link #copyTo} return a new object. To get a {@code Blob} object with the most recent - * information use {@link #reload}. + * information use {@link #reload}. {@code Blob} adds a layer of service-related functionality over + * {@link BlobInfo}. *

    */ -public final class Blob { +public final class Blob extends BlobInfo { - private final Storage storage; - private final BlobInfo info; + private static final long serialVersionUID = -6806832496717441434L; + + private final StorageOptions options; + private transient Storage storage; + + static final Function, Blob> BLOB_FROM_PB_FUNCTION = + new Function, Blob>() { + @Override + public Blob apply(Tuple pb) { + return Blob.fromPb(pb.x(), pb.y()); + } + }; /** * Class for specifying blob source options when {@code Blob} methods are used. @@ -146,60 +158,148 @@ static Storage.BlobGetOption[] toGetOptions(BlobInfo blobInfo, BlobSourceOption. } /** - * Constructs a {@code Blob} object for the provided {@code BlobInfo}. The storage service is used - * to issue requests. - * - * @param storage the storage service used for issuing requests - * @param info blob's info + * Builder for {@code Blob}. */ - public Blob(Storage storage, BlobInfo info) { - this.storage = checkNotNull(storage); - this.info = checkNotNull(info); - } + public static class Builder extends BlobInfo.Builder { - /** - * Creates a {@code Blob} object for the provided bucket and blob names. Performs an RPC call to - * get the latest blob information. Returns {@code null} if the blob does not exist. - * - * @param storage the storage service used for issuing requests - * @param bucket bucket's name - * @param options blob get options - * @param blob blob's name - * @return the {@code Blob} object or {@code null} if not found - * @throws StorageException upon failure - */ - public static Blob get(Storage storage, String bucket, String blob, - Storage.BlobGetOption... options) { - return get(storage, BlobId.of(bucket, blob), options); - } + private final Storage storage; + private final BlobInfo.BuilderImpl infoBuilder; - /** - * Creates a {@code Blob} object for the provided {@code blobId}. Performs an RPC call to get the - * latest blob information. Returns {@code null} if the blob does not exist. - * - * @param storage the storage service used for issuing requests - * @param blobId blob's identifier - * @param options blob get options - * @return the {@code Blob} object or {@code null} if not found - * @throws StorageException upon failure - */ - public static Blob get(Storage storage, BlobId blobId, Storage.BlobGetOption... options) { - BlobInfo info = storage.get(blobId, options); - return info != null ? new Blob(storage, info) : null; - } + Builder(Blob blob) { + this.storage = blob.storage(); + this.infoBuilder = new BlobInfo.BuilderImpl(blob); + } - /** - * Returns the blob's information. - */ - public BlobInfo info() { - return info; + @Override + public Builder blobId(BlobId blobId) { + infoBuilder.blobId(blobId); + return this; + } + + @Override + Builder id(String id) { + infoBuilder.id(id); + return this; + } + + @Override + public Builder contentType(String contentType) { + infoBuilder.contentType(contentType); + return this; + } + + @Override + public Builder contentDisposition(String contentDisposition) { + infoBuilder.contentDisposition(contentDisposition); + return this; + } + + @Override + public Builder contentLanguage(String contentLanguage) { + infoBuilder.contentLanguage(contentLanguage); + return this; + } + + @Override + public Builder contentEncoding(String contentEncoding) { + infoBuilder.contentEncoding(contentEncoding); + return this; + } + + @Override + Builder componentCount(Integer componentCount) { + infoBuilder.componentCount(componentCount); + return this; + } + + @Override + public Builder cacheControl(String cacheControl) { + infoBuilder.cacheControl(cacheControl); + return this; + } + + @Override + public Builder acl(List acl) { + infoBuilder.acl(acl); + return this; + } + + @Override + Builder owner(Acl.Entity owner) { + infoBuilder.owner(owner); + return this; + } + + @Override + Builder size(Long size) { + infoBuilder.size(size); + return this; + } + + @Override + Builder etag(String etag) { + infoBuilder.etag(etag); + return this; + } + + @Override + Builder selfLink(String selfLink) { + infoBuilder.selfLink(selfLink); + return this; + } + + @Override + public Builder md5(String md5) { + infoBuilder.md5(md5); + return this; + } + + @Override + public Builder crc32c(String crc32c) { + infoBuilder.crc32c(crc32c); + return this; + } + + @Override + Builder mediaLink(String mediaLink) { + infoBuilder.mediaLink(mediaLink); + return this; + } + + @Override + public Builder metadata(Map metadata) { + infoBuilder.metadata(metadata); + return this; + } + + @Override + Builder metageneration(Long metageneration) { + infoBuilder.metageneration(metageneration); + return this; + } + + @Override + Builder deleteTime(Long deleteTime) { + infoBuilder.deleteTime(deleteTime); + return this; + } + + @Override + Builder updateTime(Long updateTime) { + infoBuilder.updateTime(updateTime); + return this; + } + + @Override + public Blob build() { + return new Blob(storage, infoBuilder); + } } - /** - * Returns the blob's id. - */ - public BlobId id() { - return info.blobId(); + Blob(Storage storage, BlobInfo.BuilderImpl infoBuilder) { + super(infoBuilder); + this.storage = checkNotNull(storage); + this.options = storage.options(); } /** @@ -211,9 +311,9 @@ public BlobId id() { */ public boolean exists(BlobSourceOption... options) { int length = options.length; - Storage.BlobGetOption[] getOptions = Arrays.copyOf(toGetOptions(info, options), length + 1); + Storage.BlobGetOption[] getOptions = Arrays.copyOf(toGetOptions(this, options), length + 1); getOptions[length] = Storage.BlobGetOption.fields(); - return storage.get(info.blobId(), getOptions) != null; + return storage.get(blobId(), getOptions) != null; } /** @@ -223,7 +323,7 @@ public boolean exists(BlobSourceOption... options) { * @throws StorageException upon failure */ public byte[] content(Storage.BlobSourceOption... options) { - return storage.readAllBytes(info.blobId(), options); + return storage.readAllBytes(blobId(), options); } /** @@ -234,7 +334,7 @@ public byte[] content(Storage.BlobSourceOption... options) { * @throws StorageException upon failure */ public Blob reload(BlobSourceOption... options) { - return Blob.get(storage, info.blobId(), toGetOptions(info, options)); + return storage.get(blobId(), toGetOptions(this, options)); } /** @@ -243,27 +343,24 @@ public Blob reload(BlobSourceOption... options) { * {@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())}. + * option: {@code newBlob.update(BlobTargetOption.metagenerationMatch())}. * - *

    Original metadata are merged with metadata in the provided {@code blobInfo}. To replace - * metadata instead you first have to unset them. Unsetting metadata can be done by setting the - * provided {@code blobInfo}'s metadata to {@code null}. + *

    Original metadata are merged with metadata in the provided in this {@code blob}. To replace + * metadata instead you first have to unset them. Unsetting metadata can be done by setting this + * {@code blob}'s metadata to {@code null}. *

    * *

    Example usage of replacing blob's metadata: - *

        {@code blob.update(blob.info().toBuilder().metadata(null).build());}
    -   *    {@code blob.update(blob.info().toBuilder().metadata(newMetadata).build());}
    +   * 
        {@code blob.toBuilder().metadata(null).build().update();}
    +   *    {@code blob.toBuilder().metadata(newMetadata).build().update();}
        * 
    * - * @param blobInfo new blob's information. Bucket and blob names must match the current ones * @param options update options * @return a {@code Blob} object with updated information * @throws StorageException upon failure */ - public Blob update(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.update(blobInfo, options)); + public Blob update(BlobTargetOption... options) { + return storage.update(this, options); } /** @@ -274,7 +371,7 @@ public Blob update(BlobInfo blobInfo, BlobTargetOption... options) { * @throws StorageException upon failure */ public boolean delete(BlobSourceOption... options) { - return storage.delete(info.blobId(), toSourceOptions(info, options)); + return storage.delete(blobId(), toSourceOptions(this, options)); } /** @@ -288,8 +385,11 @@ public boolean delete(BlobSourceOption... options) { * @throws StorageException upon failure */ public CopyWriter copyTo(BlobId targetBlob, BlobSourceOption... options) { - CopyRequest copyRequest = CopyRequest.builder().source(info.bucket(), info.name()) - .sourceOptions(toSourceOptions(info, options)).target(targetBlob).build(); + CopyRequest copyRequest = CopyRequest.builder() + .source(bucket(), name()) + .sourceOptions(toSourceOptions(this, options)) + .target(targetBlob) + .build(); return storage.copy(copyRequest); } @@ -304,7 +404,7 @@ public CopyWriter copyTo(BlobId targetBlob, BlobSourceOption... options) { * @throws StorageException upon failure */ public CopyWriter copyTo(String targetBucket, BlobSourceOption... options) { - return copyTo(targetBucket, info.name(), options); + return copyTo(targetBucket, name(), options); } /** @@ -329,7 +429,7 @@ public CopyWriter copyTo(String targetBucket, String targetBlob, BlobSourceOptio * @throws StorageException upon failure */ public ReadChannel reader(BlobSourceOption... options) { - return storage.reader(info.blobId(), toSourceOptions(info, options)); + return storage.reader(blobId(), toSourceOptions(this, options)); } /** @@ -341,7 +441,7 @@ public ReadChannel reader(BlobSourceOption... options) { * @throws StorageException upon failure */ public WriteChannel writer(BlobWriteOption... options) { - return storage.writer(info, options); + return storage.writer(this, options); } /** @@ -358,7 +458,7 @@ public WriteChannel writer(BlobWriteOption... options) { * @see Signed-URLs */ public URL signUrl(long duration, TimeUnit unit, SignUrlOption... options) { - return storage.signUrl(info, duration, unit, options); + return storage.signUrl(this, duration, unit, options); } /** @@ -368,97 +468,29 @@ public Storage storage() { return storage; } - /** - * Gets the requested blobs. A batch request is used to fetch blobs. - * - * @param storage the storage service used to issue the request - * @param first the first blob to get - * @param second the second blob to get - * @param other other 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 get(Storage storage, BlobId first, BlobId second, BlobId... other) { - checkNotNull(storage); - checkNotNull(first); - checkNotNull(second); - checkNotNull(other); - ImmutableList blobs = ImmutableList.builder() - .add(first) - .add(second) - .addAll(Arrays.asList(other)) - .build(); - return get(storage, blobs); + @Override + public Builder toBuilder() { + return new Builder(this); } - /** - * Gets the requested blobs. A batch request is used to fetch blobs. - * - * @param storage the storage service used to issue the request - * @param blobs list of 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 get(final Storage storage, List blobs) { - checkNotNull(storage); - checkNotNull(blobs); - BlobId[] blobArray = blobs.toArray(new BlobId[blobs.size()]); - return Collections.unmodifiableList(Lists.transform(storage.get(blobArray), - new Function() { - @Override - public Blob apply(BlobInfo blobInfo) { - return blobInfo != null ? new Blob(storage, blobInfo) : null; - } - })); + @Override + public boolean equals(Object obj) { + return obj instanceof Blob && Objects.equals(toPb(), ((Blob) obj).toPb()) + && Objects.equals(options, ((Blob) obj).options); } - /** - * Updates the requested blobs. A batch request is used to update blobs. Original metadata are - * merged with metadata in the provided {@code BlobInfo} objects. To replace metadata instead - * you first have to unset them. Unsetting metadata can be done by setting the provided - * {@code BlobInfo} objects metadata to {@code null}. See - * {@link #update(com.google.gcloud.storage.BlobInfo, - * com.google.gcloud.storage.Storage.BlobTargetOption...) } for a code example. - * - * @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 - */ - public static List update(final Storage storage, BlobInfo... infos) { - checkNotNull(storage); - checkNotNull(infos); - if (infos.length == 0) { - return Collections.emptyList(); - } - return Collections.unmodifiableList(Lists.transform(storage.update(infos), - new Function() { - @Override - public Blob apply(BlobInfo blobInfo) { - return blobInfo != null ? new Blob(storage, blobInfo) : null; - } - })); + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), options); } - /** - * Deletes the requested blobs. A batch request is used to delete blobs. - * - * @param storage the storage service used to issue the request - * @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 a blob was not found, deletion failed or access to the resource - * was denied the corresponding item is {@code false} - * @throws StorageException upon failure - */ - public static List delete(Storage storage, BlobId... blobs) { - checkNotNull(storage); - checkNotNull(blobs); - if (blobs.length == 0) { - return Collections.emptyList(); - } - return storage.delete(blobs); + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + this.storage = options.service(); + } + + static Blob fromPb(Storage storage, StorageObject storageObject) { + BlobInfo info = BlobInfo.fromPb(storageObject); + return new Blob(storage, new BlobInfo.BuilderImpl(info)); } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java index b27d00d68a16..54fabe87d766 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java @@ -47,22 +47,16 @@ * @see Concepts and * Terminology */ -public final class BlobInfo implements Serializable { +public class BlobInfo implements Serializable { - static final Function FROM_PB_FUNCTION = - new Function() { - @Override - public BlobInfo apply(StorageObject pb) { - return BlobInfo.fromPb(pb); - } - }; - static final Function TO_PB_FUNCTION = + static final Function INFO_TO_PB_FUNCTION = new Function() { @Override public StorageObject apply(BlobInfo blobInfo) { return blobInfo.toPb(); } }; + private static final long serialVersionUID = 2228487739943277159L; private final BlobId blobId; private final String id; @@ -96,7 +90,110 @@ public Set> entrySet() { } } - public static final class Builder { + /** + * Builder for {@code BlobInfo}. + */ + public abstract static class Builder { + + /** + * Sets the blob identity. + */ + public abstract Builder blobId(BlobId blobId); + + abstract Builder id(String id); + + /** + * Sets the blob's data content type. + * + * @see Content-Type + */ + public abstract Builder contentType(String contentType); + + /** + * Sets the blob's data content disposition. + * + * @see Content-Disposition + */ + public abstract Builder contentDisposition(String contentDisposition); + + /** + * Sets the blob's data content language. + * + * @see Content-Language + */ + public abstract Builder contentLanguage(String contentLanguage); + + /** + * Sets the blob's data content encoding. + * + * @see Content-Encoding + */ + public abstract Builder contentEncoding(String contentEncoding); + + abstract Builder componentCount(Integer componentCount); + + /** + * Sets the blob's data cache control. + * + * @see Cache-Control + */ + public abstract Builder cacheControl(String cacheControl); + + /** + * Sets the blob's access control configuration. + * + * @see + * About Access Control Lists + */ + public abstract Builder acl(List acl); + + abstract Builder owner(Acl.Entity owner); + + abstract Builder size(Long size); + + abstract Builder etag(String etag); + + abstract Builder selfLink(String selfLink); + + /** + * Sets the MD5 hash of blob's data. MD5 value must be encoded in base64. + * + * @see + * Hashes and ETags: Best Practices + */ + public abstract Builder md5(String md5); + + /** + * Sets the CRC32C checksum of blob's data as described in + * RFC 4960, Appendix B; encoded in + * base64 in big-endian order. + * + * @see + * Hashes and ETags: Best Practices + */ + public abstract Builder crc32c(String crc32c); + + abstract Builder mediaLink(String mediaLink); + + /** + * Sets the blob's user provided metadata. + */ + public abstract Builder metadata(Map metadata); + + abstract Builder metageneration(Long metageneration); + + abstract Builder deleteTime(Long deleteTime); + + abstract Builder updateTime(Long updateTime); + + /** + * Creates a {@code BlobInfo} object. + */ + public abstract BlobInfo build(); + } + + static final class BuilderImpl extends Builder { private BlobId blobId; private String id; @@ -119,9 +216,11 @@ public static final class Builder { private Long deleteTime; private Long updateTime; - private Builder() {} + BuilderImpl(BlobId blobId) { + this.blobId = blobId; + } - private Builder(BlobInfo blobInfo) { + BuilderImpl(BlobInfo blobInfo) { blobId = blobInfo.blobId; id = blobInfo.id; cacheControl = blobInfo.cacheControl; @@ -144,168 +243,135 @@ private Builder(BlobInfo blobInfo) { updateTime = blobInfo.updateTime; } - /** - * Sets the blob identity. - */ + @Override public Builder blobId(BlobId blobId) { this.blobId = checkNotNull(blobId); return this; } + @Override Builder id(String id) { this.id = id; return this; } - /** - * Sets the blob's data content type. - * - * @see Content-Type - */ + @Override public Builder contentType(String contentType) { this.contentType = firstNonNull(contentType, Data.nullOf(String.class)); return this; } - /** - * Sets the blob's data content disposition. - * - * @see Content-Disposition - */ + @Override public Builder contentDisposition(String contentDisposition) { this.contentDisposition = firstNonNull(contentDisposition, Data.nullOf(String.class)); return this; } - /** - * Sets the blob's data content language. - * - * @see Content-Language - */ + @Override public Builder contentLanguage(String contentLanguage) { this.contentLanguage = firstNonNull(contentLanguage, Data.nullOf(String.class)); return this; } - /** - * Sets the blob's data content encoding. - * - * @see Content-Encoding - */ + @Override public Builder contentEncoding(String contentEncoding) { this.contentEncoding = firstNonNull(contentEncoding, Data.nullOf(String.class)); return this; } + @Override Builder componentCount(Integer componentCount) { this.componentCount = componentCount; return this; } - /** - * Sets the blob's data cache control. - * - * @see Cache-Control - */ + @Override public Builder cacheControl(String cacheControl) { this.cacheControl = firstNonNull(cacheControl, Data.nullOf(String.class)); return this; } - /** - * Sets the blob's access control configuration. - * - * @see - * About Access Control Lists - */ + @Override public Builder acl(List acl) { this.acl = acl != null ? ImmutableList.copyOf(acl) : null; return this; } + @Override Builder owner(Acl.Entity owner) { this.owner = owner; return this; } + @Override Builder size(Long size) { this.size = size; return this; } + @Override Builder etag(String etag) { this.etag = etag; return this; } + @Override Builder selfLink(String selfLink) { this.selfLink = selfLink; return this; } - /** - * Sets the MD5 hash of blob's data. MD5 value must be encoded in base64. - * - * @see - * Hashes and ETags: Best Practices - */ + @Override public Builder md5(String md5) { this.md5 = firstNonNull(md5, Data.nullOf(String.class)); return this; } - /** - * Sets the CRC32C checksum of blob's data as described in - * RFC 4960, Appendix B; encoded in - * base64 in big-endian order. - * - * @see - * Hashes and ETags: Best Practices - */ + @Override public Builder crc32c(String crc32c) { this.crc32c = firstNonNull(crc32c, Data.nullOf(String.class)); return this; } + @Override Builder mediaLink(String mediaLink) { this.mediaLink = mediaLink; return this; } - /** - * Sets the blob's user provided metadata. - */ + @Override public Builder metadata(Map metadata) { this.metadata = metadata != null ? new HashMap<>(metadata) : Data.>nullOf(ImmutableEmptyMap.class); return this; } + @Override Builder metageneration(Long metageneration) { this.metageneration = metageneration; return this; } + @Override Builder deleteTime(Long deleteTime) { this.deleteTime = deleteTime; return this; } + @Override Builder updateTime(Long updateTime) { this.updateTime = updateTime; return this; } - /** - * Creates a {@code BlobInfo} object. - */ + @Override public BlobInfo build() { checkNotNull(blobId); return new BlobInfo(this); } } - private BlobInfo(Builder builder) { + BlobInfo(BuilderImpl builder) { blobId = builder.blobId; id = builder.id; cacheControl = builder.cacheControl; @@ -526,7 +592,7 @@ public Long updateTime() { * Returns a builder for the current blob. */ public Builder toBuilder() { - return new Builder(this); + return new BuilderImpl(this); } @Override @@ -548,7 +614,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof BlobInfo && Objects.equals(toPb(), ((BlobInfo) obj).toPb()); + return obj != null && obj.getClass().equals(BlobInfo.class) + && Objects.equals(toPb(), ((BlobInfo) obj).toPb()); } StorageObject toPb() { @@ -609,7 +676,7 @@ public static Builder builder(BucketInfo bucketInfo, String name) { * Returns a {@code BlobInfo} builder where blob identity is set using the provided values. */ public static Builder builder(String bucket, String name) { - return new Builder().blobId(BlobId.of(bucket, name)); + return builder(BlobId.of(bucket, name)); } /** @@ -623,11 +690,11 @@ public static Builder builder(BucketInfo bucketInfo, String name, Long generatio * 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)); + return builder(BlobId.of(bucket, name, generation)); } public static Builder builder(BlobId blobId) { - return new Builder().blobId(blobId); + return new BuilderImpl(blobId); } static BlobInfo fromPb(StorageObject storageObject) { diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java index 3acd3f5d79b9..c438f497730e 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java @@ -16,16 +16,12 @@ package com.google.gcloud.storage; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.gcloud.storage.Bucket.BucketSourceOption.toGetOptions; import static com.google.gcloud.storage.Bucket.BucketSourceOption.toSourceOptions; -import com.google.common.base.Function; import com.google.common.base.MoreObjects; -import com.google.common.collect.Iterators; import com.google.gcloud.Page; -import com.google.gcloud.PageImpl; import com.google.gcloud.spi.StorageRpc; import com.google.gcloud.storage.Storage.BlobGetOption; import com.google.gcloud.storage.Storage.BlobTargetOption; @@ -35,11 +31,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; -import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Iterator; import java.util.List; import java.util.Objects; @@ -48,78 +42,16 @@ * *

    Objects of this class are immutable. Operations that modify the bucket like {@link #update} * return a new object. To get a {@code Bucket} object with the most recent information use - * {@link #reload}. + * {@link #reload}. {@code Bucket} adds a layer of service-related functionality over + * {@link BucketInfo}. *

    */ -public final class Bucket { +public final class Bucket extends BucketInfo { - private final Storage storage; - private final BucketInfo info; + private static final long serialVersionUID = 8574601739542252586L; - private static class BlobPageFetcher implements PageImpl.NextPageFetcher { - - private static final long serialVersionUID = 3221100177471323801L; - - private final StorageOptions options; - private final Page infoPage; - - BlobPageFetcher(StorageOptions options, Page infoPage) { - this.options = options; - this.infoPage = infoPage; - } - - @Override - public Page nextPage() { - Page nextInfoPage = infoPage.nextPage(); - return new PageImpl<>(new BlobPageFetcher(options, nextInfoPage), - nextInfoPage.nextPageCursor(), new LazyBlobIterable(options, nextInfoPage.values())); - } - } - - private static class LazyBlobIterable implements Iterable, Serializable { - - private static final long serialVersionUID = -3092290247725378832L; - - private final StorageOptions options; - private final Iterable infoIterable; - private transient Storage storage; - - public LazyBlobIterable(StorageOptions options, Iterable infoIterable) { - this.options = options; - this.infoIterable = infoIterable; - this.storage = options.service(); - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - this.storage = options.service(); - } - - @Override - public Iterator iterator() { - return Iterators.transform(infoIterable.iterator(), new Function() { - @Override - public Blob apply(BlobInfo blobInfo) { - return new Blob(storage, blobInfo); - } - }); - } - - @Override - public int hashCode() { - return Objects.hash(options, infoIterable); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof LazyBlobIterable)) { - return false; - } - LazyBlobIterable other = (LazyBlobIterable) obj; - return Objects.equals(options, other.options) - && Objects.equals(infoIterable, other.infoIterable); - } - } + private final StorageOptions options; + private transient Storage storage; /** * Class for specifying bucket source options when {@code Bucket} methods are used. @@ -193,37 +125,123 @@ static Storage.BucketGetOption[] toGetOptions(BucketInfo bucketInfo, } /** - * Constructs a {@code Bucket} object for the provided {@code BucketInfo}. The storage service is - * used to issue requests. - * - * @param storage the storage service used for issuing requests - * @param info bucket's info + * Builder for {@code Bucket}. */ - public Bucket(Storage storage, BucketInfo info) { - this.storage = checkNotNull(storage); - this.info = checkNotNull(info); - } + public static class Builder extends BucketInfo.Builder { + private final Storage storage; + private final BucketInfo.BuilderImpl infoBuilder; - /** - * Creates a {@code Bucket} object for the provided bucket name. Performs an RPC call to get the - * latest bucket information. - * - * @param storage the storage service used for issuing requests - * @param bucket bucket's name - * @param options blob get options - * @return the {@code Bucket} object or {@code null} if not found - * @throws StorageException upon failure - */ - public static Bucket get(Storage storage, String bucket, Storage.BucketGetOption... options) { - BucketInfo info = storage.get(bucket, options); - return info != null ? new Bucket(storage, info) : null; + Builder(Bucket bucket) { + this.storage = bucket.storage; + this.infoBuilder = new BucketInfo.BuilderImpl(bucket); + } + + @Override + public Builder name(String name) { + infoBuilder.name(name); + return this; + } + + @Override + Builder id(String id) { + infoBuilder.id(id); + return this; + } + + @Override + Builder owner(Acl.Entity owner) { + infoBuilder.owner(owner); + return this; + } + + @Override + Builder selfLink(String selfLink) { + infoBuilder.selfLink(selfLink); + return this; + } + + @Override + public Builder versioningEnabled(Boolean enable) { + infoBuilder.versioningEnabled(enable); + return this; + } + + @Override + public Builder indexPage(String indexPage) { + infoBuilder.indexPage(indexPage); + return this; + } + + @Override + public Builder notFoundPage(String notFoundPage) { + infoBuilder.notFoundPage(notFoundPage); + return this; + } + + @Override + public Builder deleteRules(Iterable rules) { + infoBuilder.deleteRules(rules); + return this; + } + + @Override + public Builder storageClass(String storageClass) { + infoBuilder.storageClass(storageClass); + return this; + } + + @Override + public Builder location(String location) { + infoBuilder.location(location); + return this; + } + + @Override + Builder etag(String etag) { + infoBuilder.etag(etag); + return this; + } + + @Override + Builder createTime(Long createTime) { + infoBuilder.createTime(createTime); + return this; + } + + @Override + Builder metageneration(Long metageneration) { + infoBuilder.metageneration(metageneration); + return this; + } + + @Override + public Builder cors(Iterable cors) { + infoBuilder.cors(cors); + return this; + } + + @Override + public Builder acl(Iterable acl) { + infoBuilder.acl(acl); + return this; + } + + @Override + public Builder defaultAcl(Iterable acl) { + infoBuilder.defaultAcl(acl); + return this; + } + + @Override + public Bucket build() { + return new Bucket(storage, infoBuilder); + } } - /** - * Returns the bucket's information. - */ - public BucketInfo info() { - return info; + Bucket(Storage storage, BucketInfo.BuilderImpl infoBuilder) { + super(infoBuilder); + this.storage = checkNotNull(storage); + this.options = storage.options(); } /** @@ -234,9 +252,9 @@ public BucketInfo info() { */ public boolean exists(BucketSourceOption... options) { int length = options.length; - Storage.BucketGetOption[] getOptions = Arrays.copyOf(toGetOptions(info, options), length + 1); + Storage.BucketGetOption[] getOptions = Arrays.copyOf(toGetOptions(this, options), length + 1); getOptions[length] = Storage.BucketGetOption.fields(); - return storage.get(info.name(), getOptions) != null; + return storage.get(name(), getOptions) != null; } /** @@ -247,7 +265,7 @@ public boolean exists(BucketSourceOption... options) { * @throws StorageException upon failure */ public Bucket reload(BucketSourceOption... options) { - return Bucket.get(storage, info.name(), toGetOptions(info, options)); + return storage.get(name(), toGetOptions(this, options)); } /** @@ -255,16 +273,14 @@ public Bucket reload(BucketSourceOption... options) { * is returned. By default no checks are made on the metadata generation of the current bucket. * If you want to update the information only if the current bucket metadata are at their latest * version use the {@code metagenerationMatch} option: - * {@code bucket.update(newInfo, BucketTargetOption.metagenerationMatch())} + * {@code bucket.update(BucketTargetOption.metagenerationMatch())} * - * @param bucketInfo new bucket's information. Name must match the one of the current bucket * @param options update options * @return a {@code Bucket} object with updated information * @throws StorageException upon failure */ - public Bucket update(BucketInfo bucketInfo, BucketTargetOption... options) { - checkArgument(Objects.equals(bucketInfo.name(), info.name()), "Bucket name must match"); - return new Bucket(storage, storage.update(bucketInfo, options)); + public Bucket update(BucketTargetOption... options) { + return storage.update(this, options); } /** @@ -275,36 +291,33 @@ public Bucket update(BucketInfo bucketInfo, BucketTargetOption... options) { * @throws StorageException upon failure */ public boolean delete(BucketSourceOption... options) { - return storage.delete(info.name(), toSourceOptions(info, options)); + return storage.delete(name(), toSourceOptions(this, options)); } /** * Returns the paginated list of {@code Blob} in this bucket. - * + * * @param options options for listing blobs * @throws StorageException upon failure */ public Page list(Storage.BlobListOption... options) { - Page infoPage = storage.list(info.name(), options); - StorageOptions storageOptions = storage.options(); - return new PageImpl<>(new BlobPageFetcher(storageOptions, infoPage), infoPage.nextPageCursor(), - new LazyBlobIterable(storageOptions, infoPage.values())); + return storage.list(name(), options); } /** * Returns the requested blob in this bucket or {@code null} if not found. - * + * * @param blob name of the requested blob * @param options blob search options * @throws StorageException upon failure */ public Blob get(String blob, BlobGetOption... options) { - return new Blob(storage, storage.get(BlobId.of(info.name(), blob), options)); + return storage.get(BlobId.of(name(), blob), options); } /** * Returns a list of requested blobs in this bucket. Blobs that do not exist are null. - * + * * @param blobName1 first blob to get * @param blobName2 second blob to get * @param blobNames other blobs to get @@ -313,16 +326,16 @@ public Blob get(String blob, BlobGetOption... options) { */ public List get(String blobName1, String blobName2, String... blobNames) { BatchRequest.Builder batch = BatchRequest.builder(); - batch.get(info.name(), blobName1); - batch.get(info.name(), blobName2); + batch.get(name(), blobName1); + batch.get(name(), blobName2); for (String name : blobNames) { - batch.get(info.name(), name); + batch.get(name(), name); } List blobs = new ArrayList<>(blobNames.length); BatchResponse response = storage.submit(batch.build()); - for (BatchResponse.Result result : response.gets()) { + for (BatchResponse.Result result : response.gets()) { BlobInfo blobInfo = result.get(); - blobs.add(blobInfo != null ? new Blob(storage, blobInfo) : null); + blobs.add(blobInfo != null ? new Blob(storage, new BlobInfo.BuilderImpl(blobInfo)) : null); } return Collections.unmodifiableList(blobs); } @@ -332,7 +345,7 @@ public List get(String blobName1, String blobName2, String... blobNames) { * For large content, {@link Blob#writer(com.google.gcloud.storage.Storage.BlobWriteOption...)} * is recommended as it uses resumable upload. MD5 and CRC32C hashes of {@code content} are * computed and used for validating transferred data. - * + * * @param blob a blob name * @param content the blob content * @param contentType the blob content type. If {@code null} then @@ -342,16 +355,16 @@ public List get(String blobName1, String blobName2, String... blobNames) { * @throws StorageException upon failure */ public Blob create(String blob, byte[] content, String contentType, BlobTargetOption... options) { - BlobInfo blobInfo = BlobInfo.builder(BlobId.of(info.name(), blob)) + BlobInfo blobInfo = BlobInfo.builder(BlobId.of(name(), blob)) .contentType(MoreObjects.firstNonNull(contentType, Storage.DEFAULT_CONTENT_TYPE)).build(); - return new Blob(storage, storage.create(blobInfo, content, options)); + return storage.create(blobInfo, content, options); } /** * Creates a new blob in this bucket. Direct upload is used to upload {@code content}. * For large content, {@link Blob#writer(com.google.gcloud.storage.Storage.BlobWriteOption...)} * is recommended as it uses resumable upload. - * + * * @param blob a blob name * @param content the blob content as a stream * @param contentType the blob content type. If {@code null} then @@ -362,9 +375,9 @@ public Blob create(String blob, byte[] content, String contentType, BlobTargetOp */ public Blob create(String blob, InputStream content, String contentType, BlobWriteOption... options) { - BlobInfo blobInfo = BlobInfo.builder(BlobId.of(info.name(), blob)) + BlobInfo blobInfo = BlobInfo.builder(BlobId.of(name(), blob)) .contentType(MoreObjects.firstNonNull(contentType, Storage.DEFAULT_CONTENT_TYPE)).build(); - return new Blob(storage, storage.create(blobInfo, content, options)); + return storage.create(blobInfo, content, options); } /** @@ -373,4 +386,29 @@ public Blob create(String blob, InputStream content, String contentType, public Storage storage() { return storage; } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof Bucket && Objects.equals(toPb(), ((Bucket) obj).toPb()) + && Objects.equals(options, ((Bucket) obj).options); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), options); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + this.storage = options.service(); + } + + static Bucket fromPb(Storage storage, com.google.api.services.storage.model.Bucket bucketPb) { + return new Bucket(storage, new BucketInfo.BuilderImpl(BucketInfo.fromPb(bucketPb))); + } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java index 62fbf9c6521f..bf34413f417f 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java @@ -48,7 +48,7 @@ * @see Concepts and * Terminology */ -public final class BucketInfo implements Serializable { +public class BucketInfo implements Serializable { static final Function FROM_PB_FUNCTION = new Function() { @@ -317,7 +317,99 @@ void populateCondition(Rule.Condition condition) { } } - public static final class Builder { + /** + * Builder for {@code BucketInfo}. + */ + public abstract static class Builder { + /** + * Sets the bucket's name. + */ + public abstract Builder name(String name); + + abstract Builder id(String id); + + abstract Builder owner(Acl.Entity owner); + + abstract Builder selfLink(String selfLink); + + /** + * Sets whether versioning should be enabled for this bucket. When set to true, versioning is + * fully enabled. + */ + public abstract Builder versioningEnabled(Boolean enable); + + /** + * Sets the bucket's website index page. Behaves as the bucket's directory index where missing + * blobs are treated as potential directories. + */ + public abstract Builder indexPage(String indexPage); + + /** + * Sets the custom object to return when a requested resource is not found. + */ + public abstract Builder notFoundPage(String notFoundPage); + + /** + * Sets the bucket's lifecycle configuration as a number of delete rules. + * + * @see Lifecycle Management + */ + public abstract Builder deleteRules(Iterable rules); + + /** + * Sets the bucket's storage class. This defines how blobs in the bucket are stored and + * determines the SLA and the cost of storage. A list of supported values is available + * here. + */ + public abstract Builder storageClass(String storageClass); + + /** + * Sets the bucket's location. Data for blobs in the bucket resides in physical storage within + * this region. A list of supported values is available + * here. + */ + public abstract Builder location(String location); + + abstract Builder etag(String etag); + + abstract Builder createTime(Long createTime); + + abstract Builder metageneration(Long metageneration); + + /** + * Sets the bucket's Cross-Origin Resource Sharing (CORS) configuration. + * + * @see + * Cross-Origin Resource Sharing (CORS) + */ + public abstract Builder cors(Iterable cors); + + /** + * Sets the bucket's access control configuration. + * + * @see + * About Access Control Lists + */ + public abstract Builder acl(Iterable acl); + + /** + * Sets the default access control configuration to apply to bucket's blobs when no other + * configuration is specified. + * + * @see + * About Access Control Lists + */ + public abstract Builder defaultAcl(Iterable acl); + + /** + * Creates a {@code BucketInfo} object. + */ + public abstract BucketInfo build(); + } + + static final class BuilderImpl extends Builder { private String id; private String name; @@ -336,9 +428,11 @@ public static final class Builder { private List acl; private List defaultAcl; - private Builder() {} + BuilderImpl(String name) { + this.name = name; + } - private Builder(BucketInfo bucketInfo) { + BuilderImpl(BucketInfo bucketInfo) { id = bucketInfo.id; name = bucketInfo.name; etag = bucketInfo.etag; @@ -357,144 +451,110 @@ private Builder(BucketInfo bucketInfo) { deleteRules = bucketInfo.deleteRules; } - /** - * Sets the bucket's name. - */ + @Override public Builder name(String name) { this.name = checkNotNull(name); return this; } + @Override Builder id(String id) { this.id = id; return this; } + @Override Builder owner(Acl.Entity owner) { this.owner = owner; return this; } + @Override Builder selfLink(String selfLink) { this.selfLink = selfLink; return this; } - /** - * Sets whether versioning should be enabled for this bucket. When set to true, versioning is - * fully enabled. - */ + @Override public Builder versioningEnabled(Boolean enable) { this.versioningEnabled = firstNonNull(enable, Data.nullOf(Boolean.class)); return this; } - /** - * Sets the bucket's website index page. Behaves as the bucket's directory index where missing - * blobs are treated as potential directories. - */ + @Override public Builder indexPage(String indexPage) { this.indexPage = indexPage; return this; } - /** - * Sets the custom object to return when a requested resource is not found. - */ + @Override public Builder notFoundPage(String notFoundPage) { this.notFoundPage = notFoundPage; return this; } - /** - * Sets the bucket's lifecycle configuration as a number of delete rules. - * - * @see Lifecycle Management - */ + @Override public Builder deleteRules(Iterable rules) { this.deleteRules = rules != null ? ImmutableList.copyOf(rules) : null; return this; } - /** - * Sets the bucket's storage class. This defines how blobs in the bucket are stored and - * determines the SLA and the cost of storage. A list of supported values is available - * here. - */ + @Override public Builder storageClass(String storageClass) { this.storageClass = storageClass; return this; } - /** - * Sets the bucket's location. Data for blobs in the bucket resides in physical storage within - * this region. A list of supported values is available - * here. - */ + @Override public Builder location(String location) { this.location = location; return this; } + @Override Builder etag(String etag) { this.etag = etag; return this; } + @Override Builder createTime(Long createTime) { this.createTime = createTime; return this; } + @Override Builder metageneration(Long metageneration) { this.metageneration = metageneration; return this; } - /** - * Sets the bucket's Cross-Origin Resource Sharing (CORS) configuration. - * - * @see - * Cross-Origin Resource Sharing (CORS) - */ + @Override public Builder cors(Iterable cors) { this.cors = cors != null ? ImmutableList.copyOf(cors) : null; return this; } - /** - * Sets the bucket's access control configuration. - * - * @see - * About Access Control Lists - */ + @Override public Builder acl(Iterable acl) { this.acl = acl != null ? ImmutableList.copyOf(acl) : null; return this; } - /** - * Sets the default access control configuration to apply to bucket's blobs when no other - * configuration is specified. - * - * @see - * About Access Control Lists - */ + @Override public Builder defaultAcl(Iterable acl) { this.defaultAcl = acl != null ? ImmutableList.copyOf(acl) : null; return this; } - /** - * Creates a {@code BucketInfo} object. - */ + @Override public BucketInfo build() { checkNotNull(name); return new BucketInfo(this); } } - private BucketInfo(Builder builder) { + BucketInfo(BuilderImpl builder) { id = builder.id; name = builder.name; etag = builder.etag; @@ -649,7 +709,7 @@ public List defaultAcl() { * Returns a builder for the current bucket. */ public Builder toBuilder() { - return new Builder(this); + return new BuilderImpl(this); } @Override @@ -659,7 +719,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof BucketInfo && Objects.equals(toPb(), ((BucketInfo) obj).toPb()); + return obj != null && obj.getClass().equals(BucketInfo.class) + && Objects.equals(toPb(), ((BucketInfo) obj).toPb()); } @Override @@ -743,11 +804,11 @@ public static BucketInfo of(String name) { * Returns a {@code BucketInfo} builder where the bucket's name is set to the provided name. */ public static Builder builder(String name) { - return new Builder().name(name); + return new BuilderImpl(name); } static BucketInfo fromPb(com.google.api.services.storage.model.Bucket bucketPb) { - Builder builder = new Builder().name(bucketPb.getName()); + Builder builder = new BuilderImpl(bucketPb.getName()); if (bucketPb.getId() != null) { builder.id(bucketPb.getId()); } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index b550015d0516..d1799daede3e 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -1208,29 +1208,29 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx /** * Create a new bucket. * - * @return a complete bucket information + * @return a complete bucket * @throws StorageException upon failure */ - BucketInfo create(BucketInfo bucketInfo, BucketTargetOption... options); + Bucket create(BucketInfo bucketInfo, BucketTargetOption... options); /** * Create a new blob with no content. * - * @return a complete blob information + * @return a [@code Blob} with complete information * @throws StorageException upon failure */ - BlobInfo create(BlobInfo blobInfo, BlobTargetOption... options); + Blob create(BlobInfo blobInfo, BlobTargetOption... options); /** * Create a new blob. Direct upload is used to upload {@code content}. For large content, * {@link #writer} is recommended as it uses resumable upload. MD5 and CRC32C hashes of * {@code content} are computed and used for validating transferred data. * - * @return a complete blob information + * @return a [@code Blob} with complete information * @throws StorageException upon failure * @see Hashes and ETags */ - BlobInfo create(BlobInfo blobInfo, byte[] content, BlobTargetOption... options); + Blob create(BlobInfo blobInfo, byte[] content, BlobTargetOption... options); /** * Create a new blob. Direct upload is used to upload {@code content}. For large content, @@ -1239,52 +1239,52 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * {@code BlobWriteOption.md5Match} and {@code BlobWriteOption.crc32cMatch} options. The given * input stream is closed upon success. * - * @return a complete blob information + * @return a [@code Blob} with complete information * @throws StorageException upon failure */ - BlobInfo create(BlobInfo blobInfo, InputStream content, BlobWriteOption... options); + Blob create(BlobInfo blobInfo, InputStream content, BlobWriteOption... options); /** * Return the requested bucket or {@code null} if not found. * * @throws StorageException upon failure */ - BucketInfo get(String bucket, BucketGetOption... options); + Bucket get(String bucket, BucketGetOption... options); /** * Return the requested blob or {@code null} if not found. * * @throws StorageException upon failure */ - BlobInfo get(String bucket, String blob, BlobGetOption... options); + Blob get(String bucket, String blob, BlobGetOption... options); /** * Return the requested blob or {@code null} if not found. * * @throws StorageException upon failure */ - BlobInfo get(BlobId blob, BlobGetOption... options); + Blob get(BlobId blob, BlobGetOption... options); /** * Return the requested blob or {@code null} if not found. * * @throws StorageException upon failure */ - BlobInfo get(BlobId blob); + Blob get(BlobId blob); /** * List the project's buckets. * * @throws StorageException upon failure */ - Page list(BucketListOption... options); + Page list(BucketListOption... options); /** * List the bucket's blobs. * * @throws StorageException upon failure */ - Page list(String bucket, BlobListOption... options); + Page list(String bucket, BlobListOption... options); /** * Update bucket information. @@ -1292,7 +1292,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * @return the updated bucket * @throws StorageException upon failure */ - BucketInfo update(BucketInfo bucketInfo, BucketTargetOption... options); + Bucket update(BucketInfo bucketInfo, BucketTargetOption... options); /** * Update blob information. Original metadata are merged with metadata in the provided @@ -1307,7 +1307,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * @return the updated blob * @throws StorageException upon failure */ - BlobInfo update(BlobInfo blobInfo, BlobTargetOption... options); + Blob update(BlobInfo blobInfo, BlobTargetOption... options); /** * Update blob information. Original metadata are merged with metadata in the provided @@ -1322,7 +1322,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * @return the updated blob * @throws StorageException upon failure */ - BlobInfo update(BlobInfo blobInfo); + Blob update(BlobInfo blobInfo); /** * Delete the requested bucket. @@ -1362,7 +1362,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * @return the composed blob * @throws StorageException upon failure */ - BlobInfo compose(ComposeRequest composeRequest); + Blob compose(ComposeRequest composeRequest); /** * Sends a copy request. Returns a {@link CopyWriter} object for the provided @@ -1467,7 +1467,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * }
    * * @param blobInfo the blob associated with the signed URL - * @param duration time until the signed URL expires, expressed in {@code unit}. The finer + * @param duration time until the signed URL expires, expressed in {@code unit}. The finest * granularity supported is 1 second, finer granularities will be truncated * @param unit time unit of the {@code duration} parameter * @param options optional URL signing options @@ -1479,11 +1479,11 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * Gets the requested blobs. A batch request is used to perform this call. * * @param blobIds blobs to get - * @return an immutable list of {@code BlobInfo} objects. If a blob does not exist or access to it + * @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 */ - List get(BlobId... blobIds); + List get(BlobId... blobIds); /** * Updates the requested blobs. A batch request is used to perform this call. Original metadata @@ -1493,11 +1493,11 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * {@link #update(com.google.gcloud.storage.BlobInfo)} for a code example. * * @param blobInfos blobs to update - * @return an immutable list of {@code BlobInfo} objects. If a blob does not exist or access to it + * @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 */ - List update(BlobInfo... blobInfos); + List update(BlobInfo... blobInfos); /** * Deletes the requested blobs. A batch request is used to perform this call. diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java index b6a833f26ab4..de77cba021a1 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java @@ -33,7 +33,6 @@ import com.google.api.services.storage.model.StorageObject; import com.google.auth.oauth2.ServiceAccountCredentials; import com.google.common.base.Function; -import com.google.common.base.Functions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; @@ -78,6 +77,14 @@ final class StorageImpl extends BaseService implements Storage { private static final String EMPTY_BYTE_ARRAY_MD5 = "1B2M2Y8AsgTpgAmY7PhCfg=="; private static final String EMPTY_BYTE_ARRAY_CRC32C = "AAAAAA=="; + private static final Function, Boolean> DELETE_FUNCTION = + new Function, Boolean>() { + @Override + public Boolean apply(Tuple tuple) { + return tuple.y(); + } + }; + private final StorageRpc storageRpc; StorageImpl(StorageOptions options) { @@ -86,11 +93,11 @@ final class StorageImpl extends BaseService implements Storage { } @Override - public BucketInfo create(BucketInfo bucketInfo, BucketTargetOption... options) { + public Bucket create(BucketInfo bucketInfo, BucketTargetOption... options) { final com.google.api.services.storage.model.Bucket bucketPb = bucketInfo.toPb(); final Map optionsMap = optionMap(bucketInfo, options); try { - return BucketInfo.fromPb(runWithRetries( + return Bucket.fromPb(this, runWithRetries( new Callable() { @Override public com.google.api.services.storage.model.Bucket call() { @@ -103,7 +110,7 @@ public com.google.api.services.storage.model.Bucket call() { } @Override - public BlobInfo create(BlobInfo blobInfo, BlobTargetOption... options) { + public Blob create(BlobInfo blobInfo, BlobTargetOption... options) { BlobInfo updatedInfo = blobInfo.toBuilder() .md5(EMPTY_BYTE_ARRAY_MD5) .crc32c(EMPTY_BYTE_ARRAY_CRC32C) @@ -112,7 +119,7 @@ public BlobInfo create(BlobInfo blobInfo, BlobTargetOption... options) { } @Override - public BlobInfo create(BlobInfo blobInfo, byte[] content, BlobTargetOption... options) { + public Blob create(BlobInfo blobInfo, byte[] content, BlobTargetOption... options) { content = firstNonNull(content, EMPTY_BYTE_ARRAY); BlobInfo updatedInfo = blobInfo.toBuilder() .md5(BaseEncoding.base64().encode(Hashing.md5().hashBytes(content).asBytes())) @@ -123,16 +130,16 @@ public BlobInfo create(BlobInfo blobInfo, byte[] content, BlobTargetOption... op } @Override - public BlobInfo create(BlobInfo blobInfo, InputStream content, BlobWriteOption... options) { + public Blob create(BlobInfo blobInfo, InputStream content, BlobWriteOption... options) { Tuple targetOptions = BlobTargetOption.convert(blobInfo, options); return create(targetOptions.x(), content, targetOptions.y()); } - private BlobInfo create(BlobInfo info, final InputStream content, BlobTargetOption... options) { + private Blob create(BlobInfo info, final InputStream content, BlobTargetOption... options) { final StorageObject blobPb = info.toPb(); final Map optionsMap = optionMap(info, options); try { - return BlobInfo.fromPb(runWithRetries(new Callable() { + return Blob.fromPb(this, runWithRetries(new Callable() { @Override public StorageObject call() { return storageRpc.create(blobPb, @@ -145,7 +152,7 @@ public StorageObject call() { } @Override - public BucketInfo get(String bucket, BucketGetOption... options) { + public Bucket get(String bucket, BucketGetOption... options) { final com.google.api.services.storage.model.Bucket bucketPb = BucketInfo.of(bucket).toPb(); final Map optionsMap = optionMap(options); try { @@ -156,19 +163,19 @@ public com.google.api.services.storage.model.Bucket call() { return storageRpc.get(bucketPb, optionsMap); } }, options().retryParams(), EXCEPTION_HANDLER); - return answer == null ? null : BucketInfo.fromPb(answer); + return answer == null ? null : Bucket.fromPb(this, answer); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); } } @Override - public BlobInfo get(String bucket, String blob, BlobGetOption... options) { + public Blob get(String bucket, String blob, BlobGetOption... options) { return get(BlobId.of(bucket, blob), options); } @Override - public BlobInfo get(BlobId blob, BlobGetOption... options) { + public Blob get(BlobId blob, BlobGetOption... options) { final StorageObject storedObject = blob.toPb(); final Map optionsMap = optionMap(blob, options); try { @@ -178,18 +185,18 @@ public StorageObject call() { return storageRpc.get(storedObject, optionsMap); } }, options().retryParams(), EXCEPTION_HANDLER); - return storageObject == null ? null : BlobInfo.fromPb(storageObject); + return storageObject == null ? null : Blob.fromPb(this, storageObject); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); } } @Override - public BlobInfo get(BlobId blob) { + public Blob get(BlobId blob) { return get(blob, new BlobGetOption[0]); } - private static class BucketPageFetcher implements NextPageFetcher { + private static class BucketPageFetcher implements NextPageFetcher { private static final long serialVersionUID = 5850406828803613729L; private final Map requestOptions; @@ -204,12 +211,12 @@ private static class BucketPageFetcher implements NextPageFetcher { } @Override - public Page nextPage() { + public Page nextPage() { return listBuckets(serviceOptions, requestOptions); } } - private static class BlobPageFetcher implements NextPageFetcher { + private static class BlobPageFetcher implements NextPageFetcher { private static final long serialVersionUID = 81807334445874098L; private final Map requestOptions; @@ -225,22 +232,22 @@ private static class BlobPageFetcher implements NextPageFetcher { } @Override - public Page nextPage() { + public Page nextPage() { return listBlobs(bucket, serviceOptions, requestOptions); } } @Override - public Page list(BucketListOption... options) { + public Page list(BucketListOption... options) { return listBuckets(options(), optionMap(options)); } @Override - public Page list(final String bucket, BlobListOption... options) { + public Page list(final String bucket, BlobListOption... options) { return listBlobs(bucket, options(), optionMap(options)); } - private static Page listBuckets(final StorageOptions serviceOptions, + private static Page listBuckets(final StorageOptions serviceOptions, final Map optionsMap) { try { Tuple> result = runWithRetries( @@ -251,22 +258,23 @@ public Tuple> cal } }, serviceOptions.retryParams(), EXCEPTION_HANDLER); String cursor = result.x(); - Iterable buckets = - result.y() == null ? ImmutableList.of() : Iterables.transform(result.y(), - new Function() { + Iterable buckets = + result.y() == null ? ImmutableList.of() : Iterables.transform(result.y(), + new Function() { @Override - public BucketInfo apply(com.google.api.services.storage.model.Bucket bucketPb) { - return BucketInfo.fromPb(bucketPb); + public Bucket apply(com.google.api.services.storage.model.Bucket bucketPb) { + return Bucket.fromPb(serviceOptions.service(), bucketPb); } }); - return new PageImpl<>(new BucketPageFetcher(serviceOptions, cursor, optionsMap), cursor, + return new PageImpl<>( + new BucketPageFetcher(serviceOptions, cursor, optionsMap), cursor, buckets); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); } } - private static Page listBlobs(final String bucket, + private static Page listBlobs(final String bucket, final StorageOptions serviceOptions, final Map optionsMap) { try { Tuple> result = runWithRetries( @@ -277,15 +285,17 @@ public Tuple> call() { } }, serviceOptions.retryParams(), EXCEPTION_HANDLER); String cursor = result.x(); - Iterable blobs = - result.y() == null ? ImmutableList.of() : Iterables.transform(result.y(), - new Function() { + Iterable blobs = + result.y() == null + ? ImmutableList.of() + : Iterables.transform(result.y(), new Function() { @Override - public BlobInfo apply(StorageObject storageObject) { - return BlobInfo.fromPb(storageObject); + public Blob apply(StorageObject storageObject) { + return Blob.fromPb(serviceOptions.service(), storageObject); } }); - return new PageImpl<>(new BlobPageFetcher(bucket, serviceOptions, cursor, optionsMap), + return new PageImpl<>( + new BlobPageFetcher(bucket, serviceOptions, cursor, optionsMap), cursor, blobs); } catch (RetryHelperException e) { @@ -294,11 +304,11 @@ public BlobInfo apply(StorageObject storageObject) { } @Override - public BucketInfo update(BucketInfo bucketInfo, BucketTargetOption... options) { + public Bucket update(BucketInfo bucketInfo, BucketTargetOption... options) { final com.google.api.services.storage.model.Bucket bucketPb = bucketInfo.toPb(); final Map optionsMap = optionMap(bucketInfo, options); try { - return BucketInfo.fromPb(runWithRetries( + return Bucket.fromPb(this, runWithRetries( new Callable() { @Override public com.google.api.services.storage.model.Bucket call() { @@ -311,11 +321,11 @@ public com.google.api.services.storage.model.Bucket call() { } @Override - public BlobInfo update(BlobInfo blobInfo, BlobTargetOption... options) { + public Blob update(BlobInfo blobInfo, BlobTargetOption... options) { final StorageObject storageObject = blobInfo.toPb(); final Map optionsMap = optionMap(blobInfo, options); try { - return BlobInfo.fromPb(runWithRetries(new Callable() { + return Blob.fromPb(this, runWithRetries(new Callable() { @Override public StorageObject call() { return storageRpc.patch(storageObject, optionsMap); @@ -327,7 +337,7 @@ public StorageObject call() { } @Override - public BlobInfo update(BlobInfo blobInfo) { + public Blob update(BlobInfo blobInfo) { return update(blobInfo, new BlobTargetOption[0]); } @@ -374,7 +384,7 @@ public boolean delete(BlobId blob) { } @Override - public BlobInfo compose(final ComposeRequest composeRequest) { + public Blob compose(final ComposeRequest composeRequest) { final List sources = Lists.newArrayListWithCapacity(composeRequest.sourceBlobs().size()); for (ComposeRequest.SourceBlob sourceBlob : composeRequest.sourceBlobs()) { @@ -386,7 +396,7 @@ public BlobInfo compose(final ComposeRequest composeRequest) { final Map targetOptions = optionMap(composeRequest.target().generation(), composeRequest.target().metageneration(), composeRequest.targetOptions()); try { - return BlobInfo.fromPb(runWithRetries(new Callable() { + return Blob.fromPb(this, runWithRetries(new Callable() { @Override public StorageObject call() { return storageRpc.compose(sources, target, targetOptions); @@ -468,18 +478,19 @@ public BatchResponse submit(BatchRequest batchRequest) { } StorageRpc.BatchResponse response = storageRpc.batch(new StorageRpc.BatchRequest(toDelete, toUpdate, toGet)); - List> deletes = transformBatchResult( - toDelete, response.deletes, Functions.identity()); - List> updates = transformBatchResult( - toUpdate, response.updates, BlobInfo.FROM_PB_FUNCTION); - List> gets = transformBatchResult( - toGet, response.gets, BlobInfo.FROM_PB_FUNCTION); + List> deletes = + transformBatchResult(toDelete, response.deletes, DELETE_FUNCTION); + List> updates = + transformBatchResult(toUpdate, response.updates, Blob.BLOB_FROM_PB_FUNCTION); + List> gets = + transformBatchResult(toGet, response.gets, Blob.BLOB_FROM_PB_FUNCTION); return new BatchResponse(deletes, updates, gets); } private List> transformBatchResult( Iterable>> request, - Map> results, Function transform) { + Map> results, + Function, O> transform) { List> response = Lists.newArrayListWithCapacity(results.size()); for (Tuple tuple : request) { Tuple result = results.get(tuple.x()); @@ -489,7 +500,8 @@ private List> transformBatch response.add(new BatchResponse.Result(exception)); } else { response.add(object != null - ? BatchResponse.Result.of(transform.apply(object)) : BatchResponse.Result.empty()); + ? BatchResponse.Result.of(transform.apply(Tuple.of((Storage) this, object))) + : BatchResponse.Result.empty()); } } return response; @@ -587,7 +599,7 @@ public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOptio } @Override - public List get(BlobId... blobIds) { + public List get(BlobId... blobIds) { BatchRequest.Builder requestBuilder = BatchRequest.builder(); for (BlobId blob : blobIds) { requestBuilder.get(blob); @@ -597,7 +609,7 @@ public List get(BlobId... blobIds) { } @Override - public List update(BlobInfo... blobInfos) { + public List update(BlobInfo... blobInfos) { BatchRequest.Builder requestBuilder = BatchRequest.builder(); for (BlobInfo blobInfo : blobInfos) { requestBuilder.update(blobInfo); diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/package-info.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/package-info.java index fda14ea2e808..181e63b08d0b 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/package-info.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/package-info.java @@ -17,23 +17,32 @@ /** * A client to Google Cloud Storage. * - *

    Here's a simple usage example for using gcloud-java from App/Compute Engine: + *

    Here's a simple usage example for using gcloud-java from App/Compute Engine. This example + * shows how to create a Storage blob. For the complete source code see + * + * CreateBlob.java. *

     {@code
      * Storage storage = StorageOptions.defaultInstance().service();
      * BlobId blobId = BlobId.of("bucket", "blob_name");
    - * Blob blob = Blob.get(storage, blobId);
    - * if (blob == null) {
    - *   BlobInfo blobInfo = BlobInfo.builder(blobId).contentType("text/plain").build();
    - *   storage.create(blobInfo, "Hello, Cloud Storage!".getBytes(UTF_8));
    - * } else {
    - *   System.out.println("Updating content for " + blobId.name());
    + * BlobInfo blobInfo = BlobInfo.builder(blobId).contentType("text/plain").build();
    + * Blob blob = storage.create(blobInfo, "Hello, Cloud Storage!".getBytes(UTF_8));
    + * }
    + *

    + * This second example shows how to update the blob's content if the blob exists. For the complete + * source code see + * + * UpdateBlob.java. + *

     {@code
    + * Storage storage = StorageOptions.defaultInstance().service();
    + * BlobId blobId = BlobId.of("bucket", "blob_name");
    + * Blob blob = storage.get(blobId);
    + * if (blob != null) {
      *   byte[] prevContent = blob.content();
      *   System.out.println(new String(prevContent, UTF_8));
      *   WritableByteChannel channel = blob.writer();
      *   channel.write(ByteBuffer.wrap("Updated content".getBytes(UTF_8)));
      *   channel.close();
      * }}
    - * *

    When using gcloud-java from outside of App/Compute Engine, you have to specify a * project ID and diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BatchResponseTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BatchResponseTest.java index 5985329e0183..eb45b8b51271 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BatchResponseTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BatchResponseTest.java @@ -22,22 +22,35 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.storage.BatchResponse.Result; +import org.easymock.EasyMock; +import org.junit.Before; import org.junit.Test; import java.util.List; public class BatchResponseTest { - private static final BlobInfo BLOB_INFO_1 = BlobInfo.builder("b", "o1").build(); - private static final BlobInfo BLOB_INFO_2 = BlobInfo.builder("b", "o2").build(); - private static final BlobInfo BLOB_INFO_3 = BlobInfo.builder("b", "o3").build(); + private Storage mockStorage; + private Blob blob1; + private Blob blob2; + private Blob blob3; + + @Before + public void setUp() { + mockStorage = EasyMock.createMock(Storage.class); + EasyMock.expect(mockStorage.options()).andReturn(null).times(3); + EasyMock.replay(mockStorage); + blob1 = new Blob(mockStorage, new BlobInfo.BuilderImpl(BlobInfo.builder("b", "o1").build())); + blob2 = new Blob(mockStorage, new BlobInfo.BuilderImpl(BlobInfo.builder("b", "o2").build())); + blob3 = new Blob(mockStorage, new BlobInfo.BuilderImpl(BlobInfo.builder("b", "o3").build())); + } @Test public void testBatchResponse() { List> deletes = ImmutableList.of(Result.of(true), Result.of(false)); - List> updates = - ImmutableList.of(Result.of(BLOB_INFO_1), Result.of(BLOB_INFO_2)); - List> gets = ImmutableList.of(Result.of(BLOB_INFO_2), Result.of(BLOB_INFO_3)); + List> updates = + ImmutableList.of(Result.of(blob1), Result.of(blob2)); + List> gets = ImmutableList.of(Result.of(blob2), Result.of(blob3)); BatchResponse response = new BatchResponse(deletes, updates, gets); assertEquals(deletes, response.deletes()); assertEquals(updates, response.updates()); @@ -47,14 +60,13 @@ public void testBatchResponse() { @Test public void testEquals() { List> deletes = ImmutableList.of(Result.of(true), Result.of(false)); - List> updates = - ImmutableList.of(Result.of(BLOB_INFO_1), Result.of(BLOB_INFO_2)); - List> gets = ImmutableList.of(Result.of(BLOB_INFO_2), Result.of(BLOB_INFO_3)); + List> updates = + ImmutableList.of(Result.of(blob1), Result.of(blob2)); + List> gets = ImmutableList.of(Result.of(blob2), Result.of(blob3)); List> otherDeletes = ImmutableList.of(Result.of(false), Result.of(true)); - List> otherUpdates = - ImmutableList.of(Result.of(BLOB_INFO_2), Result.of(BLOB_INFO_3)); - List> otherGets = - ImmutableList.of(Result.of(BLOB_INFO_1), Result.of(BLOB_INFO_2)); + List> otherUpdates = ImmutableList.of(Result.of(blob2), Result.of(blob3)); + List> otherGets = + ImmutableList.of(Result.of(blob1), Result.of(blob2)); BatchResponse response = new BatchResponse(deletes, updates, gets); BatchResponse responseEquals = new BatchResponse(deletes, updates, gets); BatchResponse responseNotEquals1 = new BatchResponse(otherDeletes, updates, gets); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java index 586e7fd0fd39..c7508593f8c9 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java @@ -16,22 +16,28 @@ package com.google.gcloud.storage; +import static com.google.gcloud.storage.Acl.Project.ProjectRole.VIEWERS; +import static com.google.gcloud.storage.Acl.Role.READER; +import static com.google.gcloud.storage.Acl.Role.WRITER; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import com.google.api.client.util.Lists; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.gcloud.ReadChannel; +import com.google.gcloud.storage.Acl.Project; +import com.google.gcloud.storage.Acl.User; import com.google.gcloud.storage.Storage.CopyRequest; import org.easymock.Capture; @@ -40,25 +46,65 @@ import org.junit.Test; import java.net.URL; -import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; public class BlobTest { + private static final List ACL = ImmutableList.of( + Acl.of(User.ofAllAuthenticatedUsers(), READER), Acl.of(new Project(VIEWERS, "p1"), WRITER)); + private static final Integer COMPONENT_COUNT = 2; + private static final String CONTENT_TYPE = "text/html"; + private static final String CACHE_CONTROL = "cache"; + private static final String CONTENT_DISPOSITION = "content-disposition"; + private static final String CONTENT_ENCODING = "UTF-8"; + private static final String CONTENT_LANGUAGE = "En"; + private static final String CRC32 = "0xFF00"; + private static final Long DELETE_TIME = System.currentTimeMillis(); + private static final String ETAG = "0xFF00"; + private static final Long GENERATION = 1L; + private static final String ID = "B/N:1"; + private static final String MD5 = "0xFF00"; + private static final String MEDIA_LINK = "http://media/b/n"; + private static final Map METADATA = ImmutableMap.of("n1", "v1", "n2", "v2"); + private static final Long META_GENERATION = 10L; + private static final User OWNER = new User("user@gmail.com"); + private static final String SELF_LINK = "http://storage/b/n"; + private static final Long SIZE = 1024L; + private static final Long UPDATE_TIME = DELETE_TIME - 1L; + private static final BlobInfo FULL_BLOB_INFO = BlobInfo.builder("b", "n", GENERATION) + .acl(ACL) + .componentCount(COMPONENT_COUNT) + .contentType(CONTENT_TYPE) + .cacheControl(CACHE_CONTROL) + .contentDisposition(CONTENT_DISPOSITION) + .contentEncoding(CONTENT_ENCODING) + .contentLanguage(CONTENT_LANGUAGE) + .crc32c(CRC32) + .deleteTime(DELETE_TIME) + .etag(ETAG) + .id(ID) + .md5(MD5) + .mediaLink(MEDIA_LINK) + .metadata(METADATA) + .metageneration(META_GENERATION) + .owner(OWNER) + .selfLink(SELF_LINK) + .size(SIZE) + .updateTime(UPDATE_TIME) + .build(); private static final BlobInfo BLOB_INFO = BlobInfo.builder("b", "n").metageneration(42L).build(); - private static final BlobId[] BLOB_ID_ARRAY = {BlobId.of("b1", "n1"), - BlobId.of("b2", "n2"), BlobId.of("b3", "n3")}; - private static final BlobInfo[] BLOB_INFO_ARRAY = {BlobInfo.builder("b1", "n1").build(), - BlobInfo.builder("b2", "n2").build(), BlobInfo.builder("b3", "n3").build()}; private Storage storage; private Blob blob; + private Blob expectedBlob; + private Storage serviceMockReturnsOptions = createMock(Storage.class); + private StorageOptions mockOptions = createMock(StorageOptions.class); @Before - public void setUp() throws Exception { + public void setUp() { storage = createStrictMock(Storage.class); - blob = new Blob(storage, BLOB_INFO); } @After @@ -66,91 +112,122 @@ public void tearDown() throws Exception { verify(storage); } - @Test - public void testInfo() throws Exception { - assertEquals(BLOB_INFO, blob.info()); - replay(storage); + private void initializeExpectedBlob(int optionsCalls) { + expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); + replay(serviceMockReturnsOptions); + expectedBlob = new Blob(serviceMockReturnsOptions, new BlobInfo.BuilderImpl(BLOB_INFO)); + } + + private void initializeBlob() { + blob = new Blob(storage, new BlobInfo.BuilderImpl(BLOB_INFO)); } @Test public void testExists_True() throws Exception { + initializeExpectedBlob(1); Storage.BlobGetOption[] expectedOptions = {Storage.BlobGetOption.fields()}; - expect(storage.get(BLOB_INFO.blobId(), expectedOptions)).andReturn(BLOB_INFO); + expect(storage.options()).andReturn(mockOptions); + expect(storage.get(expectedBlob.blobId(), expectedOptions)).andReturn(expectedBlob); replay(storage); + initializeBlob(); assertTrue(blob.exists()); } @Test public void testExists_False() throws Exception { Storage.BlobGetOption[] expectedOptions = {Storage.BlobGetOption.fields()}; + expect(storage.options()).andReturn(null); expect(storage.get(BLOB_INFO.blobId(), expectedOptions)).andReturn(null); replay(storage); + initializeBlob(); assertFalse(blob.exists()); } @Test public void testContent() throws Exception { + initializeExpectedBlob(2); byte[] content = {1, 2}; + expect(storage.options()).andReturn(mockOptions); expect(storage.readAllBytes(BLOB_INFO.blobId())).andReturn(content); replay(storage); + initializeBlob(); assertArrayEquals(content, blob.content()); } @Test public void testReload() throws Exception { - BlobInfo updatedInfo = BLOB_INFO.toBuilder().cacheControl("c").build(); - expect(storage.get(BLOB_INFO.blobId(), new Storage.BlobGetOption[0])).andReturn(updatedInfo); + initializeExpectedBlob(2); + Blob expectedReloadedBlob = expectedBlob.toBuilder().cacheControl("c").build(); + expect(storage.options()).andReturn(mockOptions); + expect(storage.get(BLOB_INFO.blobId(), new Storage.BlobGetOption[0])) + .andReturn(expectedReloadedBlob); replay(storage); + initializeBlob(); Blob updatedBlob = blob.reload(); - assertSame(storage, updatedBlob.storage()); - assertEquals(updatedInfo, updatedBlob.info()); + assertEquals(expectedReloadedBlob, updatedBlob); } @Test public void testReloadNull() throws Exception { + initializeExpectedBlob(1); + expect(storage.options()).andReturn(mockOptions); expect(storage.get(BLOB_INFO.blobId(), new Storage.BlobGetOption[0])).andReturn(null); replay(storage); - assertNull(blob.reload()); + initializeBlob(); + Blob reloadedBlob = blob.reload(); + assertNull(reloadedBlob); } @Test public void testReloadWithOptions() throws Exception { - BlobInfo updatedInfo = BLOB_INFO.toBuilder().cacheControl("c").build(); + initializeExpectedBlob(2); + Blob expectedReloadedBlob = expectedBlob.toBuilder().cacheControl("c").build(); Storage.BlobGetOption[] options = {Storage.BlobGetOption.metagenerationMatch(42L)}; - expect(storage.get(BLOB_INFO.blobId(), options)).andReturn(updatedInfo); + expect(storage.options()).andReturn(mockOptions); + expect(storage.get(BLOB_INFO.blobId(), options)).andReturn(expectedReloadedBlob); replay(storage); + initializeBlob(); Blob updatedBlob = blob.reload(Blob.BlobSourceOption.metagenerationMatch()); - assertSame(storage, updatedBlob.storage()); - assertEquals(updatedInfo, updatedBlob.info()); + assertEquals(expectedReloadedBlob, updatedBlob); } @Test public void testUpdate() throws Exception { - BlobInfo updatedInfo = BLOB_INFO.toBuilder().cacheControl("c").build(); - expect(storage.update(updatedInfo, new Storage.BlobTargetOption[0])).andReturn(updatedInfo); + initializeExpectedBlob(2); + Blob expectedUpdatedBlob = expectedBlob.toBuilder().cacheControl("c").build(); + expect(storage.options()).andReturn(mockOptions).times(2); + expect(storage.update(eq(expectedUpdatedBlob), new Storage.BlobTargetOption[0])) + .andReturn(expectedUpdatedBlob); replay(storage); - Blob updatedBlob = blob.update(updatedInfo); - assertSame(storage, blob.storage()); - assertEquals(updatedInfo, updatedBlob.info()); + initializeBlob(); + Blob updatedBlob = new Blob(storage, new BlobInfo.BuilderImpl(expectedUpdatedBlob)); + Blob actualUpdatedBlob = updatedBlob.update(); + assertEquals(expectedUpdatedBlob, actualUpdatedBlob); } @Test public void testDelete() throws Exception { + initializeExpectedBlob(2); + expect(storage.options()).andReturn(mockOptions); expect(storage.delete(BLOB_INFO.blobId(), new Storage.BlobSourceOption[0])).andReturn(true); replay(storage); + initializeBlob(); assertTrue(blob.delete()); } @Test public void testCopyToBucket() throws Exception { + initializeExpectedBlob(2); BlobInfo target = BlobInfo.builder(BlobId.of("bt", "n")).build(); CopyWriter copyWriter = createMock(CopyWriter.class); Capture capturedCopyRequest = Capture.newInstance(); + expect(storage.options()).andReturn(mockOptions); expect(storage.copy(capture(capturedCopyRequest))).andReturn(copyWriter); replay(storage); + initializeBlob(); CopyWriter returnedCopyWriter = blob.copyTo("bt"); assertEquals(copyWriter, returnedCopyWriter); - assertEquals(capturedCopyRequest.getValue().source(), blob.id()); + assertEquals(capturedCopyRequest.getValue().source(), blob.blobId()); assertEquals(capturedCopyRequest.getValue().target(), target); assertTrue(capturedCopyRequest.getValue().sourceOptions().isEmpty()); assertTrue(capturedCopyRequest.getValue().targetOptions().isEmpty()); @@ -158,14 +235,17 @@ public void testCopyToBucket() throws Exception { @Test public void testCopyTo() throws Exception { + initializeExpectedBlob(2); BlobInfo target = BlobInfo.builder(BlobId.of("bt", "nt")).build(); CopyWriter copyWriter = createMock(CopyWriter.class); Capture capturedCopyRequest = Capture.newInstance(); + expect(storage.options()).andReturn(mockOptions); expect(storage.copy(capture(capturedCopyRequest))).andReturn(copyWriter); replay(storage); + initializeBlob(); CopyWriter returnedCopyWriter = blob.copyTo("bt", "nt"); assertEquals(copyWriter, returnedCopyWriter); - assertEquals(capturedCopyRequest.getValue().source(), blob.id()); + assertEquals(capturedCopyRequest.getValue().source(), blob.blobId()); assertEquals(capturedCopyRequest.getValue().target(), target); assertTrue(capturedCopyRequest.getValue().sourceOptions().isEmpty()); assertTrue(capturedCopyRequest.getValue().targetOptions().isEmpty()); @@ -173,15 +253,18 @@ public void testCopyTo() throws Exception { @Test public void testCopyToBlobId() throws Exception { + initializeExpectedBlob(2); BlobId targetId = BlobId.of("bt", "nt"); CopyWriter copyWriter = createMock(CopyWriter.class); BlobInfo target = BlobInfo.builder(targetId).build(); Capture capturedCopyRequest = Capture.newInstance(); + expect(storage.options()).andReturn(mockOptions); expect(storage.copy(capture(capturedCopyRequest))).andReturn(copyWriter); replay(storage); + initializeBlob(); CopyWriter returnedCopyWriter = blob.copyTo(targetId); assertEquals(copyWriter, returnedCopyWriter); - assertEquals(capturedCopyRequest.getValue().source(), blob.id()); + assertEquals(capturedCopyRequest.getValue().source(), blob.blobId()); assertEquals(capturedCopyRequest.getValue().target(), target); assertTrue(capturedCopyRequest.getValue().sourceOptions().isEmpty()); assertTrue(capturedCopyRequest.getValue().targetOptions().isEmpty()); @@ -189,174 +272,93 @@ public void testCopyToBlobId() throws Exception { @Test public void testReader() throws Exception { + initializeExpectedBlob(2); ReadChannel channel = createMock(ReadChannel.class); + expect(storage.options()).andReturn(mockOptions); expect(storage.reader(BLOB_INFO.blobId())).andReturn(channel); replay(storage); + initializeBlob(); assertSame(channel, blob.reader()); } @Test public void testWriter() throws Exception { + initializeExpectedBlob(2); BlobWriteChannel channel = createMock(BlobWriteChannel.class); - expect(storage.writer(BLOB_INFO)).andReturn(channel); + expect(storage.options()).andReturn(mockOptions); + expect(storage.writer(eq(expectedBlob))).andReturn(channel); replay(storage); + initializeBlob(); assertSame(channel, blob.writer()); } @Test public void testSignUrl() throws Exception { + initializeExpectedBlob(2); URL url = new URL("http://localhost:123/bla"); - expect(storage.signUrl(BLOB_INFO, 100, TimeUnit.SECONDS)).andReturn(url); + expect(storage.options()).andReturn(mockOptions); + expect(storage.signUrl(expectedBlob, 100, TimeUnit.SECONDS)).andReturn(url); replay(storage); + initializeBlob(); assertEquals(url, blob.signUrl(100, TimeUnit.SECONDS)); } @Test - public void testGetSome() throws Exception { - List blobInfoList = Arrays.asList(BLOB_INFO_ARRAY); - expect(storage.get(BLOB_ID_ARRAY)).andReturn(blobInfoList); - replay(storage); - List result = Blob.get(storage, BLOB_ID_ARRAY[0], BLOB_ID_ARRAY[1], BLOB_ID_ARRAY[2]); - assertEquals(blobInfoList.size(), result.size()); - for (int i = 0; i < blobInfoList.size(); i++) { - assertEquals(blobInfoList.get(i), result.get(i).info()); - } - } - - @Test - public void testGetSomeList() throws Exception { - List blobInfoList = Arrays.asList(BLOB_INFO_ARRAY); - expect(storage.get(BLOB_ID_ARRAY)).andReturn(blobInfoList); - replay(storage); - List result = Blob.get(storage, Arrays.asList(BLOB_ID_ARRAY)); - assertEquals(blobInfoList.size(), result.size()); - for (int i = 0; i < blobInfoList.size(); i++) { - assertEquals(blobInfoList.get(i), result.get(i).info()); - } - } - - @Test - public void testGetSomeNull() throws Exception { - List blobInfoList = Arrays.asList(BLOB_INFO_ARRAY[0], null, BLOB_INFO_ARRAY[2]); - expect(storage.get(BLOB_ID_ARRAY)).andReturn(blobInfoList); - replay(storage); - List result = Blob.get(storage, BLOB_ID_ARRAY[0], BLOB_ID_ARRAY[1], BLOB_ID_ARRAY[2]); - assertEquals(blobInfoList.size(), result.size()); - for (int i = 0; i < blobInfoList.size(); i++) { - if (blobInfoList.get(i) != null) { - assertEquals(blobInfoList.get(i), result.get(i).info()); - } else { - assertNull(result.get(i)); - } - } - } - - @Test - public void testUpdateNone() throws Exception { - replay(storage); - assertTrue(Blob.update(storage).isEmpty()); - } - - @Test - public void testUpdateSome() throws Exception { - List blobInfoList = Lists.newArrayListWithCapacity(BLOB_ID_ARRAY.length); - for (BlobInfo info : BLOB_INFO_ARRAY) { - blobInfoList.add(info.toBuilder().contentType("content").build()); - } - expect(storage.update(BLOB_INFO_ARRAY)).andReturn(blobInfoList); - replay(storage); - List result = Blob.update(storage, BLOB_INFO_ARRAY); - assertEquals(blobInfoList.size(), result.size()); - for (int i = 0; i < blobInfoList.size(); i++) { - assertEquals(blobInfoList.get(i), result.get(i).info()); - } - } - - @Test - public void testUpdateSomeNull() throws Exception { - List blobInfoList = Arrays.asList( - BLOB_INFO_ARRAY[0].toBuilder().contentType("content").build(), null, - BLOB_INFO_ARRAY[2].toBuilder().contentType("content").build()); - expect(storage.update(BLOB_INFO_ARRAY)).andReturn(blobInfoList); - replay(storage); - List result = Blob.update(storage, BLOB_INFO_ARRAY); - assertEquals(blobInfoList.size(), result.size()); - for (int i = 0; i < blobInfoList.size(); i++) { - if (blobInfoList.get(i) != null) { - assertEquals(blobInfoList.get(i), result.get(i).info()); - } else { - assertNull(result.get(i)); - } - } - } - - @Test - public void testDeleteNone() throws Exception { - replay(storage); - assertTrue(Blob.delete(storage).isEmpty()); - } - - @Test - public void testDeleteSome() throws Exception { - List deleteResult = Arrays.asList(true, true, true); - expect(storage.delete(BLOB_ID_ARRAY)).andReturn(deleteResult); - replay(storage); - List result = Blob.delete(storage, BLOB_ID_ARRAY); - assertEquals(deleteResult.size(), result.size()); - for (int i = 0; i < deleteResult.size(); i++) { - assertEquals(deleteResult.get(i), result.get(i)); - } - } - - @Test - public void testGetFromString() throws Exception { - expect(storage.get(BLOB_INFO.blobId(), new Storage.BlobGetOption[0])).andReturn(BLOB_INFO); - replay(storage); - Blob loadedBlob = Blob.get(storage, BLOB_INFO.bucket(), BLOB_INFO.name()); - assertEquals(BLOB_INFO, loadedBlob.info()); - } - - @Test - public void testGetFromId() throws Exception { - expect(storage.get(BLOB_INFO.blobId(), new Storage.BlobGetOption[0])).andReturn(BLOB_INFO); - replay(storage); - Blob loadedBlob = Blob.get(storage, BLOB_INFO.blobId()); - assertNotNull(loadedBlob); - assertEquals(BLOB_INFO, loadedBlob.info()); - } - - @Test - public void testGetFromStringNull() throws Exception { - expect(storage.get(BLOB_INFO.blobId(), new Storage.BlobGetOption[0])).andReturn(null); - replay(storage); - assertNull(Blob.get(storage, BLOB_INFO.bucket(), BLOB_INFO.name())); - } - - @Test - public void testGetFromIdNull() throws Exception { - expect(storage.get(BLOB_INFO.blobId(), new Storage.BlobGetOption[0])).andReturn(null); - replay(storage); - assertNull(Blob.get(storage, BLOB_INFO.blobId())); - } - - @Test - public void testGetFromStringWithOptions() throws Exception { - expect(storage.get(BLOB_INFO.blobId(), Storage.BlobGetOption.generationMatch(42L))) - .andReturn(BLOB_INFO); + public void testToBuilder() { + expect(storage.options()).andReturn(mockOptions).times(4); replay(storage); - Blob loadedBlob = Blob.get(storage, BLOB_INFO.bucket(), BLOB_INFO.name(), - Storage.BlobGetOption.generationMatch(42L)); - assertEquals(BLOB_INFO, loadedBlob.info()); + Blob fullBlob = new Blob(storage, new BlobInfo.BuilderImpl(FULL_BLOB_INFO)); + assertEquals(fullBlob, fullBlob.toBuilder().build()); + Blob simpleBlob = new Blob(storage, new BlobInfo.BuilderImpl(BLOB_INFO)); + assertEquals(simpleBlob, simpleBlob.toBuilder().build()); } @Test - public void testGetFromIdWithOptions() throws Exception { - expect(storage.get(BLOB_INFO.blobId(), Storage.BlobGetOption.generationMatch(42L))) - .andReturn(BLOB_INFO); + public void testBuilder() { + initializeExpectedBlob(4); + expect(storage.options()).andReturn(mockOptions).times(2); replay(storage); - Blob loadedBlob = - Blob.get(storage, BLOB_INFO.blobId(), Storage.BlobGetOption.generationMatch(42L)); - assertNotNull(loadedBlob); - assertEquals(BLOB_INFO, loadedBlob.info()); + Blob.Builder builder = new Blob.Builder(new Blob(storage, new BlobInfo.BuilderImpl(BLOB_INFO))); + Blob blob = builder.acl(ACL) + .componentCount(COMPONENT_COUNT) + .contentType(CONTENT_TYPE) + .cacheControl(CACHE_CONTROL) + .contentDisposition(CONTENT_DISPOSITION) + .contentEncoding(CONTENT_ENCODING) + .contentLanguage(CONTENT_LANGUAGE) + .crc32c(CRC32) + .deleteTime(DELETE_TIME) + .etag(ETAG) + .id(ID) + .md5(MD5) + .mediaLink(MEDIA_LINK) + .metadata(METADATA) + .metageneration(META_GENERATION) + .owner(OWNER) + .selfLink(SELF_LINK) + .size(SIZE) + .updateTime(UPDATE_TIME) + .build(); + assertEquals("b", blob.bucket()); + assertEquals("n", blob.name()); + assertEquals(ACL, blob.acl()); + assertEquals(COMPONENT_COUNT, blob.componentCount()); + assertEquals(CONTENT_TYPE, blob.contentType()); + assertEquals(CACHE_CONTROL, blob.cacheControl()); + assertEquals(CONTENT_DISPOSITION, blob.contentDisposition()); + assertEquals(CONTENT_ENCODING, blob.contentEncoding()); + assertEquals(CONTENT_LANGUAGE, blob.contentLanguage()); + assertEquals(CRC32, blob.crc32c()); + assertEquals(DELETE_TIME, blob.deleteTime()); + assertEquals(ETAG, blob.etag()); + assertEquals(ID, blob.id()); + assertEquals(MD5, blob.md5()); + assertEquals(MEDIA_LINK, blob.mediaLink()); + assertEquals(METADATA, blob.metadata()); + assertEquals(META_GENERATION, blob.metageneration()); + assertEquals(OWNER, blob.owner()); + assertEquals(SELF_LINK, blob.selfLink()); + assertEquals(SIZE, blob.size()); + assertEquals(UPDATE_TIME, blob.updateTime()); } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java index 4e253033c6f2..aac8a79d3a47 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java @@ -16,22 +16,28 @@ package com.google.gcloud.storage; +import static com.google.gcloud.storage.Acl.Project.ProjectRole.VIEWERS; +import static com.google.gcloud.storage.Acl.Role.READER; +import static com.google.gcloud.storage.Acl.Role.WRITER; import static org.easymock.EasyMock.capture; +import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createStrictMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableList; import com.google.gcloud.Page; import com.google.gcloud.PageImpl; +import com.google.gcloud.storage.Acl.Project; +import com.google.gcloud.storage.Acl.User; import com.google.gcloud.storage.BatchResponse.Result; +import com.google.gcloud.storage.BucketInfo.AgeDeleteRule; +import com.google.gcloud.storage.BucketInfo.DeleteRule; import org.easymock.Capture; import org.junit.After; @@ -48,20 +54,54 @@ public class BucketTest { + private static final List ACL = ImmutableList.of( + Acl.of(User.ofAllAuthenticatedUsers(), READER), Acl.of(new Project(VIEWERS, "p1"), WRITER)); + private static final String ETAG = "0xFF00"; + private static final String ID = "B/N:1"; + private static final Long META_GENERATION = 10L; + private static final User OWNER = new User("user@gmail.com"); + private static final String SELF_LINK = "http://storage/b/n"; + private static final Long CREATE_TIME = System.currentTimeMillis(); + private static final List CORS = Collections.singletonList(Cors.builder().build()); + private static final List DEFAULT_ACL = + Collections.singletonList(Acl.of(User.ofAllAuthenticatedUsers(), WRITER)); + private static final List DELETE_RULES = + Collections.singletonList(new AgeDeleteRule(5)); + private static final String INDEX_PAGE = "index.html"; + private static final String NOT_FOUND_PAGE = "error.html"; + private static final String LOCATION = "ASIA"; + private static final String STORAGE_CLASS = "STANDARD"; + private static final Boolean VERSIONING_ENABLED = true; + private static final BucketInfo FULL_BUCKET_INFO = BucketInfo.builder("b") + .acl(ACL) + .etag(ETAG) + .id(ID) + .metageneration(META_GENERATION) + .owner(OWNER) + .selfLink(SELF_LINK) + .cors(CORS) + .createTime(CREATE_TIME) + .defaultAcl(DEFAULT_ACL) + .deleteRules(DELETE_RULES) + .indexPage(INDEX_PAGE) + .notFoundPage(NOT_FOUND_PAGE) + .location(LOCATION) + .storageClass(STORAGE_CLASS) + .versioningEnabled(VERSIONING_ENABLED) + .build(); private static final BucketInfo BUCKET_INFO = BucketInfo.builder("b").metageneration(42L).build(); - private static final Iterable BLOB_INFO_RESULTS = ImmutableList.of( - BlobInfo.builder("b", "n1").build(), - BlobInfo.builder("b", "n2").build(), - BlobInfo.builder("b", "n3").build()); private static final String CONTENT_TYPE = "text/plain"; private Storage storage; + private Storage serviceMockReturnsOptions = createMock(Storage.class); + private StorageOptions mockOptions = createMock(StorageOptions.class); private Bucket bucket; + private Bucket expectedBucket; + private Iterable blobResults; @Before - public void setUp() throws Exception { + public void setUp() { storage = createStrictMock(Storage.class); - bucket = new Bucket(storage, BUCKET_INFO); } @After @@ -69,124 +109,165 @@ public void tearDown() throws Exception { verify(storage); } - @Test - public void testInfo() throws Exception { - assertEquals(BUCKET_INFO, bucket.info()); - replay(storage); + private void initializeExpectedBucket(int optionsCalls) { + expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); + replay(serviceMockReturnsOptions); + expectedBucket = new Bucket(serviceMockReturnsOptions, new BucketInfo.BuilderImpl(BUCKET_INFO)); + blobResults = ImmutableList.of( + new Blob(serviceMockReturnsOptions, + new BlobInfo.BuilderImpl(BlobInfo.builder("b", "n1").build())), + new Blob(serviceMockReturnsOptions, + new BlobInfo.BuilderImpl(BlobInfo.builder("b", "n2").build())), + new Blob(serviceMockReturnsOptions, + new BlobInfo.BuilderImpl(BlobInfo.builder("b", "n3").build()))); + } + + private void initializeBucket() { + bucket = new Bucket(storage, new BucketInfo.BuilderImpl(BUCKET_INFO)); } @Test public void testExists_True() throws Exception { + initializeExpectedBucket(4); Storage.BucketGetOption[] expectedOptions = {Storage.BucketGetOption.fields()}; - expect(storage.get(BUCKET_INFO.name(), expectedOptions)).andReturn(BUCKET_INFO); + expect(storage.options()).andReturn(mockOptions); + expect(storage.get(BUCKET_INFO.name(), expectedOptions)).andReturn(expectedBucket); replay(storage); + initializeBucket(); assertTrue(bucket.exists()); } @Test public void testExists_False() throws Exception { + initializeExpectedBucket(4); Storage.BucketGetOption[] expectedOptions = {Storage.BucketGetOption.fields()}; + expect(storage.options()).andReturn(mockOptions); expect(storage.get(BUCKET_INFO.name(), expectedOptions)).andReturn(null); replay(storage); + initializeBucket(); assertFalse(bucket.exists()); } @Test public void testReload() throws Exception { + initializeExpectedBucket(5); BucketInfo updatedInfo = BUCKET_INFO.toBuilder().notFoundPage("p").build(); - expect(storage.get(updatedInfo.name())).andReturn(updatedInfo); + Bucket expectedUpdatedBucket = + new Bucket(serviceMockReturnsOptions, new BucketInfo.BuilderImpl(updatedInfo)); + expect(storage.options()).andReturn(mockOptions); + expect(storage.get(updatedInfo.name())).andReturn(expectedUpdatedBucket); replay(storage); + initializeBucket(); Bucket updatedBucket = bucket.reload(); - assertSame(storage, updatedBucket.storage()); - assertEquals(updatedInfo, updatedBucket.info()); + assertEquals(expectedUpdatedBucket, updatedBucket); } @Test public void testReloadNull() throws Exception { + initializeExpectedBucket(4); + expect(storage.options()).andReturn(mockOptions); expect(storage.get(BUCKET_INFO.name())).andReturn(null); replay(storage); + initializeBucket(); assertNull(bucket.reload()); } @Test public void testReloadWithOptions() throws Exception { + initializeExpectedBucket(5); BucketInfo updatedInfo = BUCKET_INFO.toBuilder().notFoundPage("p").build(); + Bucket expectedUpdatedBucket = + new Bucket(serviceMockReturnsOptions, new BucketInfo.BuilderImpl(updatedInfo)); + expect(storage.options()).andReturn(mockOptions); expect(storage.get(updatedInfo.name(), Storage.BucketGetOption.metagenerationMatch(42L))) - .andReturn(updatedInfo); + .andReturn(expectedUpdatedBucket); replay(storage); + initializeBucket(); Bucket updatedBucket = bucket.reload(Bucket.BucketSourceOption.metagenerationMatch()); - assertSame(storage, updatedBucket.storage()); - assertEquals(updatedInfo, updatedBucket.info()); + assertEquals(expectedUpdatedBucket, updatedBucket); } @Test public void testUpdate() throws Exception { - BucketInfo updatedInfo = BUCKET_INFO.toBuilder().notFoundPage("p").build(); - expect(storage.update(updatedInfo)).andReturn(updatedInfo); + initializeExpectedBucket(5); + Bucket expectedUpdatedBucket = expectedBucket.toBuilder().notFoundPage("p").build(); + expect(storage.options()).andReturn(mockOptions).times(2); + expect(storage.update(expectedUpdatedBucket)).andReturn(expectedUpdatedBucket); replay(storage); - Bucket updatedBucket = bucket.update(updatedInfo); - assertSame(storage, bucket.storage()); - assertEquals(updatedInfo, updatedBucket.info()); + initializeBucket(); + Bucket updatedBucket = new Bucket(storage, new BucketInfo.BuilderImpl(expectedUpdatedBucket)); + Bucket actualUpdatedBucket = updatedBucket.update(); + assertEquals(expectedUpdatedBucket, actualUpdatedBucket); } @Test public void testDelete() throws Exception { + initializeExpectedBucket(4); + expect(storage.options()).andReturn(mockOptions); expect(storage.delete(BUCKET_INFO.name())).andReturn(true); replay(storage); + initializeBucket(); assertTrue(bucket.delete()); } @Test public void testList() throws Exception { - StorageOptions storageOptions = createStrictMock(StorageOptions.class); - PageImpl blobInfoPage = new PageImpl<>(null, "c", BLOB_INFO_RESULTS); - expect(storage.list(BUCKET_INFO.name())).andReturn(blobInfoPage); - expect(storage.options()).andReturn(storageOptions); - expect(storageOptions.service()).andReturn(storage); - replay(storage, storageOptions); + initializeExpectedBucket(4); + PageImpl expectedBlobPage = new PageImpl<>(null, "c", blobResults); + expect(storage.options()).andReturn(mockOptions); + expect(storage.list(BUCKET_INFO.name())).andReturn(expectedBlobPage); + replay(storage); + initializeBucket(); Page blobPage = bucket.list(); - Iterator blobInfoIterator = blobInfoPage.values().iterator(); + Iterator blobInfoIterator = blobPage.values().iterator(); Iterator blobIterator = blobPage.values().iterator(); while (blobInfoIterator.hasNext() && blobIterator.hasNext()) { - assertEquals(blobInfoIterator.next(), blobIterator.next().info()); + assertEquals(blobInfoIterator.next(), blobIterator.next()); } assertFalse(blobInfoIterator.hasNext()); assertFalse(blobIterator.hasNext()); - assertEquals(blobInfoPage.nextPageCursor(), blobPage.nextPageCursor()); - verify(storageOptions); + assertEquals(expectedBlobPage.nextPageCursor(), blobPage.nextPageCursor()); } @Test public void testGet() throws Exception { - BlobInfo info = BlobInfo.builder("b", "n").build(); - expect(storage.get(BlobId.of(bucket.info().name(), "n"), new Storage.BlobGetOption[0])) - .andReturn(info); + initializeExpectedBucket(5); + Blob expectedBlob = new Blob( + serviceMockReturnsOptions, new BlobInfo.BuilderImpl(BlobInfo.builder("b", "n").build())); + expect(storage.options()).andReturn(mockOptions); + expect(storage.get(BlobId.of(expectedBucket.name(), "n"), new Storage.BlobGetOption[0])) + .andReturn(expectedBlob); replay(storage); + initializeBucket(); Blob blob = bucket.get("n"); - assertEquals(info, blob.info()); + assertEquals(expectedBlob, blob); } @Test public void testGetAll() throws Exception { + initializeExpectedBucket(4); Capture capturedBatchRequest = Capture.newInstance(); - List> batchResultList = new LinkedList<>(); - for (BlobInfo info : BLOB_INFO_RESULTS) { + List> batchResultList = new LinkedList<>(); + for (Blob info : blobResults) { batchResultList.add(new Result<>(info)); } BatchResponse response = new BatchResponse(Collections.>emptyList(), - Collections.>emptyList(), batchResultList); + Collections.>emptyList(), batchResultList); + expect(storage.options()).andReturn(mockOptions); expect(storage.submit(capture(capturedBatchRequest))).andReturn(response); + expect(storage.options()).andReturn(mockOptions).times(3); replay(storage); + initializeBucket(); List blobs = bucket.get("n1", "n2", "n3"); Set blobInfoSet = capturedBatchRequest.getValue().toGet().keySet(); assertEquals(batchResultList.size(), blobInfoSet.size()); - for (BlobInfo info : BLOB_INFO_RESULTS) { + for (BlobInfo info : blobResults) { assertTrue(blobInfoSet.contains(info.blobId())); } Iterator blobIterator = blobs.iterator(); - Iterator> batchResultIterator = response.gets().iterator(); + Iterator> batchResultIterator = response.gets().iterator(); while (batchResultIterator.hasNext() && blobIterator.hasNext()) { - assertEquals(batchResultIterator.next().get(), blobIterator.next().info()); + assertEquals(batchResultIterator.next().get(), blobIterator.next()); } assertFalse(batchResultIterator.hasNext()); assertFalse(blobIterator.hasNext()); @@ -194,70 +275,111 @@ public void testGetAll() throws Exception { @Test public void testCreate() throws Exception { + initializeExpectedBucket(5); BlobInfo info = BlobInfo.builder("b", "n").contentType(CONTENT_TYPE).build(); + Blob expectedBlob = new Blob(serviceMockReturnsOptions, new BlobInfo.BuilderImpl(info)); byte[] content = {0xD, 0xE, 0xA, 0xD}; - expect(storage.create(info, content)).andReturn(info); + expect(storage.options()).andReturn(mockOptions); + expect(storage.create(info, content)).andReturn(expectedBlob); replay(storage); + initializeBucket(); Blob blob = bucket.create("n", content, CONTENT_TYPE); - assertEquals(info, blob.info()); + assertEquals(expectedBlob, blob); } @Test public void testCreateNullContentType() throws Exception { + initializeExpectedBucket(5); BlobInfo info = BlobInfo.builder("b", "n").contentType(Storage.DEFAULT_CONTENT_TYPE).build(); + Blob expectedBlob = new Blob(serviceMockReturnsOptions, new BlobInfo.BuilderImpl(info)); byte[] content = {0xD, 0xE, 0xA, 0xD}; - expect(storage.create(info, content)).andReturn(info); + expect(storage.options()).andReturn(mockOptions); + expect(storage.create(info, content)).andReturn(expectedBlob); replay(storage); + initializeBucket(); Blob blob = bucket.create("n", content, null); - assertEquals(info, blob.info()); + assertEquals(expectedBlob, blob); } @Test public void testCreateFromStream() throws Exception { + initializeExpectedBucket(5); BlobInfo info = BlobInfo.builder("b", "n").contentType(CONTENT_TYPE).build(); + Blob expectedBlob = new Blob(serviceMockReturnsOptions, new BlobInfo.BuilderImpl(info)); byte[] content = {0xD, 0xE, 0xA, 0xD}; InputStream streamContent = new ByteArrayInputStream(content); - expect(storage.create(info, streamContent)).andReturn(info); + expect(storage.options()).andReturn(mockOptions); + expect(storage.create(info, streamContent)).andReturn(expectedBlob); replay(storage); + initializeBucket(); Blob blob = bucket.create("n", streamContent, CONTENT_TYPE); - assertEquals(info, blob.info()); + assertEquals(expectedBlob, blob); } @Test public void testCreateFromStreamNullContentType() throws Exception { + initializeExpectedBucket(5); BlobInfo info = BlobInfo.builder("b", "n").contentType(Storage.DEFAULT_CONTENT_TYPE).build(); + Blob expectedBlob = new Blob(serviceMockReturnsOptions, new BlobInfo.BuilderImpl(info)); byte[] content = {0xD, 0xE, 0xA, 0xD}; InputStream streamContent = new ByteArrayInputStream(content); - expect(storage.create(info, streamContent)).andReturn(info); + expect(storage.options()).andReturn(mockOptions); + expect(storage.create(info, streamContent)).andReturn(expectedBlob); replay(storage); + initializeBucket(); Blob blob = bucket.create("n", streamContent, null); - assertEquals(info, blob.info()); + assertEquals(expectedBlob, blob); } @Test - public void testStaticGet() throws Exception { - expect(storage.get(BUCKET_INFO.name())).andReturn(BUCKET_INFO); - replay(storage); - Bucket loadedBucket = Bucket.get(storage, BUCKET_INFO.name()); - assertNotNull(loadedBucket); - assertEquals(BUCKET_INFO, loadedBucket.info()); - } - - @Test - public void testStaticGetNull() throws Exception { - expect(storage.get(BUCKET_INFO.name())).andReturn(null); + public void testToBuilder() { + expect(storage.options()).andReturn(mockOptions).times(4); replay(storage); - assertNull(Bucket.get(storage, BUCKET_INFO.name())); + Bucket fullBucket = new Bucket(storage, new BucketInfo.BuilderImpl(FULL_BUCKET_INFO)); + assertEquals(fullBucket, fullBucket.toBuilder().build()); + Bucket simpleBlob = new Bucket(storage, new BucketInfo.BuilderImpl(BUCKET_INFO)); + assertEquals(simpleBlob, simpleBlob.toBuilder().build()); } @Test - public void testStaticGetWithOptions() throws Exception { - expect(storage.get(BUCKET_INFO.name(), Storage.BucketGetOption.fields())) - .andReturn(BUCKET_INFO); + public void testBuilder() { + initializeExpectedBucket(4); + expect(storage.options()).andReturn(mockOptions).times(4); replay(storage); - Bucket loadedBucket = - Bucket.get(storage, BUCKET_INFO.name(), Storage.BucketGetOption.fields()); - assertNotNull(loadedBucket); - assertEquals(BUCKET_INFO, loadedBucket.info()); + Bucket.Builder builder = + new Bucket.Builder(new Bucket(storage, new BucketInfo.BuilderImpl(BUCKET_INFO))); + Bucket bucket = builder.acl(ACL) + .etag(ETAG) + .id(ID) + .metageneration(META_GENERATION) + .owner(OWNER) + .selfLink(SELF_LINK) + .cors(CORS) + .createTime(CREATE_TIME) + .defaultAcl(DEFAULT_ACL) + .deleteRules(DELETE_RULES) + .indexPage(INDEX_PAGE) + .notFoundPage(NOT_FOUND_PAGE) + .location(LOCATION) + .storageClass(STORAGE_CLASS) + .versioningEnabled(VERSIONING_ENABLED) + .build(); + assertEquals("b", bucket.name()); + assertEquals(ACL, bucket.acl()); + assertEquals(ETAG, bucket.etag()); + assertEquals(ID, bucket.id()); + assertEquals(META_GENERATION, bucket.metageneration()); + assertEquals(OWNER, bucket.owner()); + assertEquals(SELF_LINK, bucket.selfLink()); + assertEquals(CREATE_TIME, bucket.createTime()); + assertEquals(CORS, bucket.cors()); + assertEquals(DEFAULT_ACL, bucket.defaultAcl()); + assertEquals(DELETE_RULES, bucket.deleteRules()); + assertEquals(INDEX_PAGE, bucket.indexPage()); + assertEquals(NOT_FOUND_PAGE, bucket.notFoundPage()); + assertEquals(LOCATION, bucket.location()); + assertEquals(STORAGE_CLASS, bucket.storageClass()); + assertEquals(VERSIONING_ENABLED, bucket.versioningEnabled()); + assertEquals(storage.options(), bucket.storage().options()); } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/ITStorageTest.java index 63b9d739b686..dffcc366036a 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/ITStorageTest.java @@ -86,7 +86,8 @@ public static void afterClass() throws ExecutionException, InterruptedException @Test(timeout = 5000) public void testListBuckets() throws InterruptedException { - Iterator bucketIterator = storage.list(Storage.BucketListOption.prefix(BUCKET), + Iterator bucketIterator = + storage.list(Storage.BucketListOption.prefix(BUCKET), Storage.BucketListOption.fields()).values().iterator(); while (!bucketIterator.hasNext()) { Thread.sleep(500); @@ -94,7 +95,7 @@ public void testListBuckets() throws InterruptedException { Storage.BucketListOption.fields()).values().iterator(); } while (bucketIterator.hasNext()) { - BucketInfo remoteBucket = bucketIterator.next(); + Bucket remoteBucket = bucketIterator.next(); assertTrue(remoteBucket.name().startsWith(BUCKET)); assertNull(remoteBucket.createTime()); assertNull(remoteBucket.selfLink()); @@ -103,7 +104,7 @@ public void testListBuckets() throws InterruptedException { @Test public void testGetBucketSelectedFields() { - BucketInfo remoteBucket = storage.get(BUCKET, Storage.BucketGetOption.fields(BucketField.ID)); + Bucket remoteBucket = storage.get(BUCKET, Storage.BucketGetOption.fields(BucketField.ID)); assertEquals(BUCKET, remoteBucket.name()); assertNull(remoteBucket.createTime()); assertNotNull(remoteBucket.id()); @@ -111,7 +112,7 @@ public void testGetBucketSelectedFields() { @Test public void testGetBucketAllSelectedFields() { - BucketInfo remoteBucket = storage.get(BUCKET, + Bucket remoteBucket = storage.get(BUCKET, Storage.BucketGetOption.fields(BucketField.values())); assertEquals(BUCKET, remoteBucket.name()); assertNotNull(remoteBucket.createTime()); @@ -120,7 +121,7 @@ public void testGetBucketAllSelectedFields() { @Test public void testGetBucketEmptyFields() { - BucketInfo remoteBucket = storage.get(BUCKET, Storage.BucketGetOption.fields()); + Bucket remoteBucket = storage.get(BUCKET, Storage.BucketGetOption.fields()); assertEquals(BUCKET, remoteBucket.name()); assertNull(remoteBucket.createTime()); assertNull(remoteBucket.selfLink()); @@ -130,26 +131,26 @@ public void testGetBucketEmptyFields() { public void testCreateBlob() { String blobName = "test-create-blob"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build(); - BlobInfo remoteBlob = storage.create(blob, BLOB_BYTE_CONTENT); + Blob remoteBlob = storage.create(blob, BLOB_BYTE_CONTENT); assertNotNull(remoteBlob); assertEquals(blob.bucket(), remoteBlob.bucket()); assertEquals(blob.name(), remoteBlob.name()); byte[] readBytes = storage.readAllBytes(BUCKET, blobName); assertArrayEquals(BLOB_BYTE_CONTENT, readBytes); - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(remoteBlob.delete()); } @Test public void testCreateEmptyBlob() { String blobName = "test-create-empty-blob"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build(); - BlobInfo remoteBlob = storage.create(blob); + Blob remoteBlob = storage.create(blob); assertNotNull(remoteBlob); assertEquals(blob.bucket(), remoteBlob.bucket()); assertEquals(blob.name(), remoteBlob.name()); byte[] readBytes = storage.readAllBytes(BUCKET, blobName); assertArrayEquals(new byte[0], readBytes); - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(remoteBlob.delete()); } @Test @@ -157,21 +158,22 @@ public void testCreateBlobStream() { String blobName = "test-create-blob-stream"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).contentType(CONTENT_TYPE).build(); ByteArrayInputStream stream = new ByteArrayInputStream(BLOB_STRING_CONTENT.getBytes(UTF_8)); - BlobInfo remoteBlob = storage.create(blob, stream); + Blob remoteBlob = storage.create(blob, stream); assertNotNull(remoteBlob); assertEquals(blob.bucket(), remoteBlob.bucket()); assertEquals(blob.name(), remoteBlob.name()); assertEquals(blob.contentType(), remoteBlob.contentType()); byte[] readBytes = storage.readAllBytes(BUCKET, blobName); assertEquals(BLOB_STRING_CONTENT, new String(readBytes, UTF_8)); - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(remoteBlob.delete()); } @Test public void testCreateBlobFail() { String blobName = "test-create-blob-fail"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build(); - assertNotNull(storage.create(blob)); + Blob remoteBlob = storage.create(blob); + assertNotNull(remoteBlob); BlobInfo wrongGenerationBlob = BlobInfo.builder(BUCKET, blobName, -1L).build(); try { storage.create(wrongGenerationBlob, BLOB_BYTE_CONTENT, @@ -180,7 +182,7 @@ public void testCreateBlobFail() { } catch (StorageException ex) { // expected } - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(remoteBlob.delete()); } @Test @@ -204,10 +206,10 @@ public void testGetBlobEmptySelectedFields() { String blobName = "test-get-empty-selected-fields-blob"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).contentType(CONTENT_TYPE).build(); assertNotNull(storage.create(blob)); - BlobInfo remoteBlob = storage.get(blob.blobId(), Storage.BlobGetOption.fields()); + Blob remoteBlob = storage.get(blob.blobId(), Storage.BlobGetOption.fields()); assertEquals(blob.blobId(), remoteBlob.blobId()); assertNull(remoteBlob.contentType()); - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(remoteBlob.delete()); } @Test @@ -218,12 +220,12 @@ public void testGetBlobSelectedFields() { .metadata(ImmutableMap.of("k", "v")) .build(); assertNotNull(storage.create(blob)); - BlobInfo remoteBlob = storage.get(blob.blobId(), Storage.BlobGetOption.fields( + Blob remoteBlob = storage.get(blob.blobId(), Storage.BlobGetOption.fields( BlobField.METADATA)); assertEquals(blob.blobId(), remoteBlob.blobId()); assertEquals(ImmutableMap.of("k", "v"), remoteBlob.metadata()); assertNull(remoteBlob.contentType()); - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(remoteBlob.delete()); } @Test @@ -234,21 +236,22 @@ public void testGetBlobAllSelectedFields() { .metadata(ImmutableMap.of("k", "v")) .build(); assertNotNull(storage.create(blob)); - BlobInfo remoteBlob = storage.get(blob.blobId(), + Blob remoteBlob = storage.get(blob.blobId(), Storage.BlobGetOption.fields(BlobField.values())); assertEquals(blob.bucket(), remoteBlob.bucket()); assertEquals(blob.name(), remoteBlob.name()); assertEquals(ImmutableMap.of("k", "v"), remoteBlob.metadata()); assertNotNull(remoteBlob.id()); assertNotNull(remoteBlob.selfLink()); - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(remoteBlob.delete()); } @Test public void testGetBlobFail() { String blobName = "test-get-blob-fail"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build(); - assertNotNull(storage.create(blob)); + Blob remoteBlob = storage.create(blob); + assertNotNull(remoteBlob); BlobId wrongGenerationBlob = BlobId.of(BUCKET, blobName); try { storage.get(wrongGenerationBlob, Storage.BlobGetOption.generationMatch(-1)); @@ -256,17 +259,18 @@ public void testGetBlobFail() { } catch (StorageException ex) { // expected } - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(remoteBlob.delete()); } @Test public void testGetBlobFailNonExistingGeneration() { String blobName = "test-get-blob-fail-non-existing-generation"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build(); - assertNotNull(storage.create(blob)); + Blob remoteBlob = storage.create(blob); + assertNotNull(remoteBlob); BlobId wrongGenerationBlob = BlobId.of(BUCKET, blobName, -1L); assertNull(storage.get(wrongGenerationBlob)); - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(remoteBlob.delete()); } @Test @@ -282,20 +286,23 @@ public void testListBlobsSelectedFields() { .contentType(CONTENT_TYPE) .metadata(metadata) .build(); - assertNotNull(storage.create(blob1)); - assertNotNull(storage.create(blob2)); - Page page = storage.list(BUCKET, + Blob remoteBlob1 = storage.create(blob1); + Blob remoteBlob2 = storage.create(blob2); + assertNotNull(remoteBlob1); + assertNotNull(remoteBlob2); + Page page = + storage.list(BUCKET, Storage.BlobListOption.prefix("test-list-blobs-selected-fields-blob"), Storage.BlobListOption.fields(BlobField.METADATA)); int index = 0; - for (BlobInfo remoteBlob : page.values()) { + for (Blob remoteBlob : page.values()) { assertEquals(BUCKET, remoteBlob.bucket()); assertEquals(blobNames[index++], remoteBlob.name()); assertEquals(metadata, remoteBlob.metadata()); assertNull(remoteBlob.contentType()); } - assertTrue(storage.delete(BUCKET, blobNames[0])); - assertTrue(storage.delete(BUCKET, blobNames[1])); + assertTrue(remoteBlob1.delete()); + assertTrue(remoteBlob2.delete()); } @Test @@ -308,32 +315,36 @@ public void testListBlobsEmptySelectedFields() { BlobInfo blob2 = BlobInfo.builder(BUCKET, blobNames[1]) .contentType(CONTENT_TYPE) .build(); - assertNotNull(storage.create(blob1)); - assertNotNull(storage.create(blob2)); - Page page = storage.list(BUCKET, + Blob remoteBlob1 = storage.create(blob1); + Blob remoteBlob2 = storage.create(blob2); + assertNotNull(remoteBlob1); + assertNotNull(remoteBlob2); + Page page = storage.list( + BUCKET, Storage.BlobListOption.prefix("test-list-blobs-empty-selected-fields-blob"), Storage.BlobListOption.fields()); int index = 0; - for (BlobInfo remoteBlob : page.values()) { + for (Blob remoteBlob : page.values()) { assertEquals(BUCKET, remoteBlob.bucket()); assertEquals(blobNames[index++], remoteBlob.name()); assertNull(remoteBlob.contentType()); } - assertTrue(storage.delete(BUCKET, blobNames[0])); - assertTrue(storage.delete(BUCKET, blobNames[1])); + assertTrue(remoteBlob1.delete()); + assertTrue(remoteBlob2.delete()); } @Test public void testUpdateBlob() { String blobName = "test-update-blob"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build(); - assertNotNull(storage.create(blob)); - BlobInfo updatedBlob = storage.update(blob.toBuilder().contentType(CONTENT_TYPE).build()); + Blob remoteBlob = storage.create(blob); + assertNotNull(remoteBlob); + Blob updatedBlob = remoteBlob.toBuilder().contentType(CONTENT_TYPE).build().update(); assertNotNull(updatedBlob); assertEquals(blob.name(), updatedBlob.name()); assertEquals(blob.bucket(), updatedBlob.bucket()); assertEquals(CONTENT_TYPE, updatedBlob.contentType()); - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(updatedBlob.delete()); } @Test @@ -345,15 +356,16 @@ public void testUpdateBlobReplaceMetadata() { .contentType(CONTENT_TYPE) .metadata(metadata) .build(); - assertNotNull(storage.create(blob)); - BlobInfo updatedBlob = storage.update(blob.toBuilder().metadata(null).build()); + Blob remoteBlob = storage.create(blob); + assertNotNull(remoteBlob); + Blob updatedBlob = remoteBlob.toBuilder().metadata(null).build().update(); assertNotNull(updatedBlob); assertNull(updatedBlob.metadata()); - updatedBlob = storage.update(blob.toBuilder().metadata(newMetadata).build()); + updatedBlob = remoteBlob.toBuilder().metadata(newMetadata).build().update(); assertEquals(blob.name(), updatedBlob.name()); assertEquals(blob.bucket(), updatedBlob.bucket()); assertEquals(newMetadata, updatedBlob.metadata()); - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(updatedBlob.delete()); } @Test @@ -366,13 +378,14 @@ public void testUpdateBlobMergeMetadata() { .contentType(CONTENT_TYPE) .metadata(metadata) .build(); - assertNotNull(storage.create(blob)); - BlobInfo updatedBlob = storage.update(blob.toBuilder().metadata(newMetadata).build()); + Blob remoteBlob = storage.create(blob); + assertNotNull(remoteBlob); + Blob updatedBlob = remoteBlob.toBuilder().metadata(newMetadata).build().update(); assertNotNull(updatedBlob); assertEquals(blob.name(), updatedBlob.name()); assertEquals(blob.bucket(), updatedBlob.bucket()); assertEquals(expectedMetadata, updatedBlob.metadata()); - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(updatedBlob.delete()); } @Test @@ -387,20 +400,22 @@ public void testUpdateBlobUnsetMetadata() { .contentType(CONTENT_TYPE) .metadata(metadata) .build(); - assertNotNull(storage.create(blob)); - BlobInfo updatedBlob = storage.update(blob.toBuilder().metadata(newMetadata).build()); + Blob remoteBlob = storage.create(blob); + assertNotNull(remoteBlob); + Blob updatedBlob = remoteBlob.toBuilder().metadata(newMetadata).build().update(); assertNotNull(updatedBlob); assertEquals(blob.name(), updatedBlob.name()); assertEquals(blob.bucket(), updatedBlob.bucket()); assertEquals(expectedMetadata, updatedBlob.metadata()); - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(updatedBlob.delete()); } @Test public void testUpdateBlobFail() { String blobName = "test-update-blob-fail"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build(); - assertNotNull(storage.create(blob)); + Blob remoteBlob = storage.create(blob); + assertNotNull(remoteBlob); BlobInfo wrongGenerationBlob = BlobInfo.builder(BUCKET, blobName, -1L) .contentType(CONTENT_TYPE) .build(); @@ -410,7 +425,7 @@ public void testUpdateBlobFail() { } catch (StorageException ex) { // expected } - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(remoteBlob.delete()); } @Test @@ -431,14 +446,15 @@ public void testDeleteBlobNonExistingGeneration() { public void testDeleteBlobFail() { String blobName = "test-delete-blob-fail"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build(); - assertNotNull(storage.create(blob)); + Blob remoteBlob = storage.create(blob); + assertNotNull(remoteBlob); try { storage.delete(BUCKET, blob.name(), Storage.BlobSourceOption.generationMatch(-1L)); fail("StorageException was expected"); } catch (StorageException ex) { // expected } - assertTrue(storage.delete(BUCKET, blob.name())); + assertTrue(remoteBlob.delete()); } @Test @@ -447,24 +463,26 @@ public void testComposeBlob() { String sourceBlobName2 = "test-compose-blob-source-2"; BlobInfo sourceBlob1 = BlobInfo.builder(BUCKET, sourceBlobName1).build(); BlobInfo sourceBlob2 = BlobInfo.builder(BUCKET, sourceBlobName2).build(); - assertNotNull(storage.create(sourceBlob1, BLOB_BYTE_CONTENT)); - assertNotNull(storage.create(sourceBlob2, BLOB_BYTE_CONTENT)); + Blob remoteSourceBlob1 = storage.create(sourceBlob1, BLOB_BYTE_CONTENT); + Blob remoteSourceBlob2 = storage.create(sourceBlob2, BLOB_BYTE_CONTENT); + assertNotNull(remoteSourceBlob1); + assertNotNull(remoteSourceBlob2); String targetBlobName = "test-compose-blob-target"; BlobInfo targetBlob = BlobInfo.builder(BUCKET, targetBlobName).build(); Storage.ComposeRequest req = Storage.ComposeRequest.of(ImmutableList.of(sourceBlobName1, sourceBlobName2), targetBlob); - BlobInfo remoteBlob = storage.compose(req); - assertNotNull(remoteBlob); - assertEquals(targetBlob.name(), remoteBlob.name()); - assertEquals(targetBlob.bucket(), remoteBlob.bucket()); + Blob remoteTargetBlob = storage.compose(req); + assertNotNull(remoteTargetBlob); + assertEquals(targetBlob.name(), remoteTargetBlob.name()); + assertEquals(targetBlob.bucket(), remoteTargetBlob.bucket()); byte[] readBytes = storage.readAllBytes(BUCKET, targetBlobName); byte[] composedBytes = Arrays.copyOf(BLOB_BYTE_CONTENT, BLOB_BYTE_CONTENT.length * 2); System.arraycopy(BLOB_BYTE_CONTENT, 0, composedBytes, BLOB_BYTE_CONTENT.length, BLOB_BYTE_CONTENT.length); assertArrayEquals(composedBytes, readBytes); - assertTrue(storage.delete(BUCKET, sourceBlobName1)); - assertTrue(storage.delete(BUCKET, sourceBlobName2)); - assertTrue(storage.delete(BUCKET, targetBlobName)); + assertTrue(remoteSourceBlob1.delete()); + assertTrue(remoteSourceBlob2.delete()); + assertTrue(remoteTargetBlob.delete()); } @Test @@ -473,8 +491,10 @@ public void testComposeBlobFail() { String sourceBlobName2 = "test-compose-blob-fail-source-2"; BlobInfo sourceBlob1 = BlobInfo.builder(BUCKET, sourceBlobName1).build(); BlobInfo sourceBlob2 = BlobInfo.builder(BUCKET, sourceBlobName2).build(); - assertNotNull(storage.create(sourceBlob1)); - assertNotNull(storage.create(sourceBlob2)); + Blob remoteSourceBlob1 = storage.create(sourceBlob1); + Blob remoteSourceBlob2 = storage.create(sourceBlob2); + assertNotNull(remoteSourceBlob1); + assertNotNull(remoteSourceBlob2); String targetBlobName = "test-compose-blob-fail-target"; BlobInfo targetBlob = BlobInfo.builder(BUCKET, targetBlobName).build(); Storage.ComposeRequest req = Storage.ComposeRequest.builder() @@ -488,8 +508,8 @@ public void testComposeBlobFail() { } catch (StorageException ex) { // expected } - assertTrue(storage.delete(BUCKET, sourceBlobName1)); - assertTrue(storage.delete(BUCKET, sourceBlobName2)); + assertTrue(remoteSourceBlob1.delete()); + assertTrue(remoteSourceBlob2.delete()); } @Test @@ -501,7 +521,8 @@ public void testCopyBlob() { .contentType(CONTENT_TYPE) .metadata(metadata) .build(); - assertNotNull(storage.create(blob, BLOB_BYTE_CONTENT)); + Blob remoteBlob = storage.create(blob, BLOB_BYTE_CONTENT); + assertNotNull(remoteBlob); String targetBlobName = "test-copy-blob-target"; Storage.CopyRequest req = Storage.CopyRequest.of(source, BlobId.of(BUCKET, targetBlobName)); CopyWriter copyWriter = storage.copy(req); @@ -510,7 +531,7 @@ public void testCopyBlob() { assertEquals(CONTENT_TYPE, copyWriter.result().contentType()); assertEquals(metadata, copyWriter.result().metadata()); assertTrue(copyWriter.isDone()); - assertTrue(storage.delete(BUCKET, sourceBlobName)); + assertTrue(remoteBlob.delete()); assertTrue(storage.delete(BUCKET, targetBlobName)); } @@ -518,7 +539,8 @@ public void testCopyBlob() { public void testCopyBlobUpdateMetadata() { String sourceBlobName = "test-copy-blob-update-metadata-source"; BlobId source = BlobId.of(BUCKET, sourceBlobName); - assertNotNull(storage.create(BlobInfo.builder(source).build(), BLOB_BYTE_CONTENT)); + Blob remoteSourceBlob = storage.create(BlobInfo.builder(source).build(), BLOB_BYTE_CONTENT); + assertNotNull(remoteSourceBlob); String targetBlobName = "test-copy-blob-update-metadata-target"; ImmutableMap metadata = ImmutableMap.of("k", "v"); BlobInfo target = BlobInfo.builder(BUCKET, targetBlobName) @@ -532,7 +554,7 @@ public void testCopyBlobUpdateMetadata() { assertEquals(CONTENT_TYPE, copyWriter.result().contentType()); assertEquals(metadata, copyWriter.result().metadata()); assertTrue(copyWriter.isDone()); - assertTrue(storage.delete(BUCKET, sourceBlobName)); + assertTrue(remoteSourceBlob.delete()); assertTrue(storage.delete(BUCKET, targetBlobName)); } @@ -540,7 +562,8 @@ public void testCopyBlobUpdateMetadata() { public void testCopyBlobFail() { String sourceBlobName = "test-copy-blob-source-fail"; BlobId source = BlobId.of(BUCKET, sourceBlobName, -1L); - assertNotNull(storage.create(BlobInfo.builder(source).build(), BLOB_BYTE_CONTENT)); + Blob remoteSourceBlob = storage.create(BlobInfo.builder(source).build(), BLOB_BYTE_CONTENT); + assertNotNull(remoteSourceBlob); String targetBlobName = "test-copy-blob-target-fail"; BlobInfo target = BlobInfo.builder(BUCKET, targetBlobName).contentType(CONTENT_TYPE).build(); Storage.CopyRequest req = Storage.CopyRequest.builder() @@ -565,7 +588,7 @@ public void testCopyBlobFail() { } catch (StorageException ex) { // expected } - assertTrue(storage.delete(BUCKET, sourceBlobName)); + assertTrue(remoteSourceBlob.delete()); } @Test @@ -658,25 +681,26 @@ public void testBatchRequestManyDeletes() { } // Check updates - BlobInfo remoteUpdatedBlob2 = response.updates().get(0).get(); + Blob remoteUpdatedBlob2 = response.updates().get(0).get(); assertEquals(sourceBlob2.bucket(), remoteUpdatedBlob2.bucket()); assertEquals(sourceBlob2.name(), remoteUpdatedBlob2.name()); assertEquals(updatedBlob2.contentType(), remoteUpdatedBlob2.contentType()); // Check gets - BlobInfo remoteBlob1 = response.gets().get(0).get(); + Blob remoteBlob1 = response.gets().get(0).get(); assertEquals(sourceBlob1.bucket(), remoteBlob1.bucket()); assertEquals(sourceBlob1.name(), remoteBlob1.name()); - assertTrue(storage.delete(BUCKET, sourceBlobName1)); - assertTrue(storage.delete(BUCKET, sourceBlobName2)); + assertTrue(remoteBlob1.delete()); + assertTrue(remoteUpdatedBlob2.delete()); } @Test public void testBatchRequestFail() { String blobName = "test-batch-request-blob-fail"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build(); - assertNotNull(storage.create(blob)); + Blob remoteBlob = storage.create(blob); + assertNotNull(remoteBlob); BlobInfo updatedBlob = BlobInfo.builder(BUCKET, blobName, -1L).build(); BatchRequest batchRequest = BatchRequest.builder() .update(updatedBlob, Storage.BlobTargetOption.generationMatch()) @@ -696,7 +720,7 @@ public void testBatchRequestFail() { assertTrue(batchResponse.deletes().get(0).failed()); assertFalse(batchResponse.deletes().get(1).failed()); assertFalse(batchResponse.deletes().get(1).get()); - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(remoteBlob.delete()); } @Test @@ -755,7 +779,8 @@ public void testReadAndWriteCaptureChannels() throws IOException { public void testReadChannelFail() throws IOException { String blobName = "test-read-channel-blob-fail"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build(); - assertNotNull(storage.create(blob)); + Blob remoteBlob = storage.create(blob); + assertNotNull(remoteBlob); try (ReadChannel reader = storage.reader(blob.blobId(), Storage.BlobSourceOption.metagenerationMatch(-1L))) { reader.read(ByteBuffer.allocate(42)); @@ -778,7 +803,7 @@ public void testReadChannelFail() throws IOException { } catch (StorageException ex) { // expected } - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(remoteBlob.delete()); } @Test @@ -790,7 +815,7 @@ public void testReadChannelFailUpdatedGeneration() throws IOException { int blobSize = 2 * chunkSize; byte[] content = new byte[blobSize]; random.nextBytes(content); - BlobInfo remoteBlob = storage.create(blob, content); + Blob remoteBlob = storage.create(blob, content); assertNotNull(remoteBlob); assertEquals(blobSize, (long) remoteBlob.size()); try (ReadChannel reader = storage.reader(blob.blobId())) { @@ -834,9 +859,9 @@ public void testWriteChannelFail() throws IOException { public void testWriteChannelExistingBlob() throws IOException { String blobName = "test-write-channel-existing-blob"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build(); - BlobInfo remoteBlob = storage.create(blob); + storage.create(blob); byte[] stringBytes; - try (WriteChannel writer = storage.writer(remoteBlob)) { + try (WriteChannel writer = storage.writer(blob)) { stringBytes = BLOB_STRING_CONTENT.getBytes(UTF_8); writer.write(ByteBuffer.wrap(stringBytes)); } @@ -848,14 +873,15 @@ public void testWriteChannelExistingBlob() throws IOException { public void testGetSignedUrl() throws IOException { String blobName = "test-get-signed-url-blob"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build(); - assertNotNull(storage.create(blob, BLOB_BYTE_CONTENT)); + Blob remoteBlob = storage.create(blob, BLOB_BYTE_CONTENT); + assertNotNull(remoteBlob); URL url = storage.signUrl(blob, 1, TimeUnit.HOURS); URLConnection connection = url.openConnection(); byte[] readBytes = new byte[BLOB_BYTE_CONTENT.length]; try (InputStream responseStream = connection.getInputStream()) { assertEquals(BLOB_BYTE_CONTENT.length, responseStream.read(readBytes)); assertArrayEquals(BLOB_BYTE_CONTENT, readBytes); - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(remoteBlob.delete()); } } @@ -869,11 +895,11 @@ public void testPostSignedUrl() throws IOException { URLConnection connection = url.openConnection(); connection.setDoOutput(true); connection.connect(); - BlobInfo remoteBlob = storage.get(BUCKET, blobName); + Blob remoteBlob = storage.get(BUCKET, blobName); assertNotNull(remoteBlob); assertEquals(blob.bucket(), remoteBlob.bucket()); assertEquals(blob.name(), remoteBlob.name()); - assertTrue(storage.delete(BUCKET, blobName)); + assertTrue(remoteBlob.delete()); } @Test @@ -884,13 +910,13 @@ public void testGetBlobs() { BlobInfo sourceBlob2 = BlobInfo.builder(BUCKET, sourceBlobName2).build(); assertNotNull(storage.create(sourceBlob1)); assertNotNull(storage.create(sourceBlob2)); - List remoteBlobs = storage.get(sourceBlob1.blobId(), sourceBlob2.blobId()); + List remoteBlobs = storage.get(sourceBlob1.blobId(), sourceBlob2.blobId()); assertEquals(sourceBlob1.bucket(), remoteBlobs.get(0).bucket()); assertEquals(sourceBlob1.name(), remoteBlobs.get(0).name()); assertEquals(sourceBlob2.bucket(), remoteBlobs.get(1).bucket()); assertEquals(sourceBlob2.name(), remoteBlobs.get(1).name()); - assertTrue(storage.delete(BUCKET, sourceBlobName1)); - assertTrue(storage.delete(BUCKET, sourceBlobName2)); + assertTrue(remoteBlobs.get(0).delete()); + assertTrue(remoteBlobs.get(1).delete()); } @Test @@ -900,11 +926,11 @@ public void testGetBlobsFail() { BlobInfo sourceBlob1 = BlobInfo.builder(BUCKET, sourceBlobName1).build(); BlobInfo sourceBlob2 = BlobInfo.builder(BUCKET, sourceBlobName2).build(); assertNotNull(storage.create(sourceBlob1)); - List remoteBlobs = storage.get(sourceBlob1.blobId(), sourceBlob2.blobId()); + List remoteBlobs = storage.get(sourceBlob1.blobId(), sourceBlob2.blobId()); assertEquals(sourceBlob1.bucket(), remoteBlobs.get(0).bucket()); assertEquals(sourceBlob1.name(), remoteBlobs.get(0).name()); assertNull(remoteBlobs.get(1)); - assertTrue(storage.delete(BUCKET, sourceBlobName1)); + assertTrue(remoteBlobs.get(0).delete()); } @Test @@ -938,11 +964,11 @@ public void testUpdateBlobs() { String sourceBlobName2 = "test-update-blobs-2"; BlobInfo sourceBlob1 = BlobInfo.builder(BUCKET, sourceBlobName1).build(); BlobInfo sourceBlob2 = BlobInfo.builder(BUCKET, sourceBlobName2).build(); - BlobInfo remoteBlob1 = storage.create(sourceBlob1); - BlobInfo remoteBlob2 = storage.create(sourceBlob2); + Blob remoteBlob1 = storage.create(sourceBlob1); + Blob remoteBlob2 = storage.create(sourceBlob2); assertNotNull(remoteBlob1); assertNotNull(remoteBlob2); - List updatedBlobs = storage.update( + List updatedBlobs = storage.update( remoteBlob1.toBuilder().contentType(CONTENT_TYPE).build(), remoteBlob2.toBuilder().contentType(CONTENT_TYPE).build()); assertEquals(sourceBlob1.bucket(), updatedBlobs.get(0).bucket()); @@ -951,8 +977,8 @@ public void testUpdateBlobs() { assertEquals(sourceBlob2.bucket(), updatedBlobs.get(1).bucket()); assertEquals(sourceBlob2.name(), updatedBlobs.get(1).name()); assertEquals(CONTENT_TYPE, updatedBlobs.get(1).contentType()); - assertTrue(storage.delete(BUCKET, sourceBlobName1)); - assertTrue(storage.delete(BUCKET, sourceBlobName2)); + assertTrue(updatedBlobs.get(0).delete()); + assertTrue(updatedBlobs.get(1).delete()); } @Test @@ -963,13 +989,13 @@ public void testUpdateBlobsFail() { BlobInfo sourceBlob2 = BlobInfo.builder(BUCKET, sourceBlobName2).build(); BlobInfo remoteBlob1 = storage.create(sourceBlob1); assertNotNull(remoteBlob1); - List updatedBlobs = storage.update( + List updatedBlobs = storage.update( remoteBlob1.toBuilder().contentType(CONTENT_TYPE).build(), sourceBlob2.toBuilder().contentType(CONTENT_TYPE).build()); assertEquals(sourceBlob1.bucket(), updatedBlobs.get(0).bucket()); assertEquals(sourceBlob1.name(), updatedBlobs.get(0).name()); assertEquals(CONTENT_TYPE, updatedBlobs.get(0).contentType()); assertNull(updatedBlobs.get(1)); - assertTrue(storage.delete(BUCKET, sourceBlobName1)); + assertTrue(updatedBlobs.get(0).delete()); } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java index d06f004fe84c..2f56bbda7bd9 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java @@ -24,6 +24,7 @@ import com.google.gcloud.storage.testing.RemoteGcsHelper; import org.easymock.EasyMock; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -66,42 +67,58 @@ public class RemoteGcsHelperTest { + " \"type\": \"service_account\"\n" + "}"; private static final InputStream JSON_KEY_STREAM = new ByteArrayInputStream(JSON_KEY.getBytes()); - private static final List BLOB_LIST = ImmutableList.of( - BlobInfo.builder(BUCKET_NAME, "n1").build(), - BlobInfo.builder(BUCKET_NAME, "n2").build()); private static final StorageException RETRYABLE_EXCEPTION = new StorageException(409, ""); private static final StorageException FATAL_EXCEPTION = new StorageException(500, ""); - private static final Page BLOB_PAGE = new Page() { - @Override - public String nextPageCursor() { - return "nextPageCursor"; - } - - @Override - public Page nextPage() { - return null; - } - - @Override - public Iterable values() { - return BLOB_LIST; - } - - @Override - public Iterator iterateAll() { - return BLOB_LIST.iterator(); - } - }; + private static Storage serviceMockReturnsOptions; + private List blobList; + private Page blobPage; @Rule public ExpectedException thrown = ExpectedException.none(); + @Before + public void setUp() { + serviceMockReturnsOptions = EasyMock.createMock(Storage.class); + EasyMock.expect(serviceMockReturnsOptions.options()) + .andReturn(EasyMock.createMock(StorageOptions.class)) + .times(2); + EasyMock.replay(serviceMockReturnsOptions); + blobList = ImmutableList.of( + new Blob( + serviceMockReturnsOptions, + new BlobInfo.BuilderImpl(BlobInfo.builder(BUCKET_NAME, "n1").build())), + new Blob( + serviceMockReturnsOptions, + new BlobInfo.BuilderImpl(BlobInfo.builder(BUCKET_NAME, "n2").build()))); + blobPage = new Page() { + @Override + public String nextPageCursor() { + return "nextPageCursor"; + } + + @Override + public Page nextPage() { + return null; + } + + @Override + public Iterable values() { + return blobList; + } + + @Override + public Iterator iterateAll() { + return blobList.iterator(); + } + }; + } + @Test public void testForceDelete() throws InterruptedException, ExecutionException { Storage storageMock = EasyMock.createMock(Storage.class); - EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(BLOB_PAGE); - for (BlobInfo info : BLOB_LIST) { + EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage); + for (BlobInfo info : blobList) { EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true); } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andReturn(true); @@ -113,8 +130,8 @@ public void testForceDelete() throws InterruptedException, ExecutionException { @Test public void testForceDeleteTimeout() throws InterruptedException, ExecutionException { Storage storageMock = EasyMock.createMock(Storage.class); - EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(BLOB_PAGE).anyTimes(); - for (BlobInfo info : BLOB_LIST) { + EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage).anyTimes(); + for (BlobInfo info : blobList) { EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true).anyTimes(); } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andThrow(RETRYABLE_EXCEPTION).anyTimes(); @@ -126,8 +143,8 @@ public void testForceDeleteTimeout() throws InterruptedException, ExecutionExcep @Test public void testForceDeleteFail() throws InterruptedException, ExecutionException { Storage storageMock = EasyMock.createMock(Storage.class); - EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(BLOB_PAGE); - for (BlobInfo info : BLOB_LIST) { + EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage); + for (BlobInfo info : blobList) { EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true); } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andThrow(FATAL_EXCEPTION); @@ -143,8 +160,8 @@ public void testForceDeleteFail() throws InterruptedException, ExecutionExceptio @Test public void testForceDeleteNoTimeout() { Storage storageMock = EasyMock.createMock(Storage.class); - EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(BLOB_PAGE); - for (BlobInfo info : BLOB_LIST) { + EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage); + for (BlobInfo info : blobList) { EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true); } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andReturn(true); @@ -156,8 +173,8 @@ public void testForceDeleteNoTimeout() { @Test public void testForceDeleteNoTimeoutFail() { Storage storageMock = EasyMock.createMock(Storage.class); - EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(BLOB_PAGE); - for (BlobInfo info : BLOB_LIST) { + EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage); + for (BlobInfo info : blobList) { EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true); } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andThrow(FATAL_EXCEPTION); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index 8bef27cb0cd0..c9b957bb936a 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -42,6 +42,7 @@ public class SerializationTest { + private static final Storage STORAGE = StorageOptions.builder().projectId("p").build().service(); private static final Acl.Domain ACL_DOMAIN = new Acl.Domain("domain"); private static final Acl.Group ACL_GROUP = new Acl.Group("group"); private static final Acl.Project ACL_PROJECT_ = new Acl.Project(ProjectRole.VIEWERS, "pid"); @@ -50,16 +51,18 @@ public class SerializationTest { private static final Acl ACL = Acl.of(ACL_DOMAIN, Acl.Role.OWNER); private static final BlobInfo BLOB_INFO = BlobInfo.builder("b", "n").build(); private static final BucketInfo BUCKET_INFO = BucketInfo.of("b"); + private static final Blob BLOB = new Blob(STORAGE, new BlobInfo.BuilderImpl(BLOB_INFO)); + private static final Bucket BUCKET = new Bucket(STORAGE, new BucketInfo.BuilderImpl(BUCKET_INFO)); private static final Cors.Origin ORIGIN = Cors.Origin.any(); private static final Cors CORS = Cors.builder().maxAgeSeconds(1).origins(Collections.singleton(ORIGIN)).build(); private static final BatchRequest BATCH_REQUEST = BatchRequest.builder().delete("B", "N").build(); private static final BatchResponse BATCH_RESPONSE = new BatchResponse( Collections.singletonList(BatchResponse.Result.of(true)), - Collections.>emptyList(), - Collections.>emptyList()); - private static final PageImpl PAGE_RESULT = new PageImpl<>( - null, "c", Collections.singletonList(BlobInfo.builder("b", "n").build())); + Collections.>emptyList(), + Collections.>emptyList()); + private static final PageImpl PAGE_RESULT = + new PageImpl<>(null, "c", Collections.singletonList(BLOB)); private static final Storage.BlobListOption BLOB_LIST_OPTIONS = Storage.BlobListOption.maxResults(100); private static final Storage.BlobSourceOption BLOB_SOURCE_OPTIONS = @@ -96,9 +99,9 @@ public void testServiceOptions() throws Exception { @Test public void testModelAndRequests() throws Exception { Serializable[] objects = {ACL_DOMAIN, ACL_GROUP, ACL_PROJECT_, ACL_USER, ACL_RAW, ACL, - BLOB_INFO, BUCKET_INFO, ORIGIN, CORS, BATCH_REQUEST, BATCH_RESPONSE, PAGE_RESULT, - BLOB_LIST_OPTIONS, BLOB_SOURCE_OPTIONS, BLOB_TARGET_OPTIONS, BUCKET_LIST_OPTIONS, - BUCKET_SOURCE_OPTIONS, BUCKET_TARGET_OPTIONS}; + BLOB_INFO, BLOB, BUCKET_INFO, BUCKET, ORIGIN, CORS, BATCH_REQUEST, BATCH_RESPONSE, + PAGE_RESULT, BLOB_LIST_OPTIONS, BLOB_SOURCE_OPTIONS, BLOB_TARGET_OPTIONS, + BUCKET_LIST_OPTIONS, BUCKET_SOURCE_OPTIONS, BUCKET_TARGET_OPTIONS}; for (Serializable obj : objects) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java index f32a51507857..f49938c5e9c1 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java @@ -238,6 +238,9 @@ public long millis() { private StorageRpc storageRpcMock; private Storage storage; + private Blob expectedBlob1, expectedBlob2, expectedBlob3; + private Bucket expectedBucket1, expectedBucket2; + @Rule public ExpectedException thrown = ExpectedException.none(); @@ -272,10 +275,23 @@ public void tearDown() throws Exception { EasyMock.verify(rpcFactoryMock, storageRpcMock); } + private void initializeService() { + storage = options.service(); + initializeServiceDependentObjects(); + } + + private void initializeServiceDependentObjects() { + expectedBlob1 = new Blob(storage, new BlobInfo.BuilderImpl(BLOB_INFO1)); + expectedBlob2 = new Blob(storage, new BlobInfo.BuilderImpl(BLOB_INFO2)); + expectedBlob3 = new Blob(storage, new BlobInfo.BuilderImpl(BLOB_INFO3)); + expectedBucket1 = new Bucket(storage, new BucketInfo.BuilderImpl(BUCKET_INFO1)); + expectedBucket2 = new Bucket(storage, new BucketInfo.BuilderImpl(BUCKET_INFO2)); + } + @Test public void testGetOptions() { EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); assertSame(options, storage.options()); } @@ -284,9 +300,9 @@ public void testCreateBucket() { EasyMock.expect(storageRpcMock.create(BUCKET_INFO1.toPb(), EMPTY_RPC_OPTIONS)) .andReturn(BUCKET_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BucketInfo bucket = storage.create(BUCKET_INFO1); - assertEquals(BUCKET_INFO1.toPb(), bucket.toPb()); + initializeService(); + Bucket bucket = storage.create(BUCKET_INFO1); + assertEquals(expectedBucket1, bucket); } @Test @@ -294,10 +310,10 @@ public void testCreateBucketWithOptions() { EasyMock.expect(storageRpcMock.create(BUCKET_INFO1.toPb(), BUCKET_TARGET_OPTIONS)) .andReturn(BUCKET_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BucketInfo bucket = + initializeService(); + Bucket bucket = storage.create(BUCKET_INFO1, BUCKET_TARGET_METAGENERATION, BUCKET_TARGET_PREDEFINED_ACL); - assertEquals(BUCKET_INFO1, bucket); + assertEquals(expectedBucket1, bucket); } @Test @@ -309,9 +325,9 @@ public void testCreateBlob() throws IOException { EasyMock.eq(EMPTY_RPC_OPTIONS))) .andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BlobInfo blob = storage.create(BLOB_INFO1, BLOB_CONTENT); - assertEquals(BLOB_INFO1, blob); + initializeService(); + Blob blob = storage.create(BLOB_INFO1, BLOB_CONTENT); + assertEquals(expectedBlob1, blob); ByteArrayInputStream byteStream = capturedStream.getValue(); byte[] streamBytes = new byte[BLOB_CONTENT.length]; assertEquals(BLOB_CONTENT.length, byteStream.read(streamBytes)); @@ -332,9 +348,9 @@ public void testCreateEmptyBlob() throws IOException { EasyMock.eq(EMPTY_RPC_OPTIONS))) .andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BlobInfo blob = storage.create(BLOB_INFO1); - assertEquals(BLOB_INFO1, blob); + initializeService(); + Blob blob = storage.create(BLOB_INFO1); + assertEquals(expectedBlob1, blob); ByteArrayInputStream byteStream = capturedStream.getValue(); byte[] streamBytes = new byte[BLOB_CONTENT.length]; assertEquals(-1, byteStream.read(streamBytes)); @@ -353,11 +369,11 @@ public void testCreateBlobWithOptions() throws IOException { EasyMock.eq(BLOB_TARGET_OPTIONS_CREATE))) .andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BlobInfo blob = + initializeService(); + Blob blob = storage.create(BLOB_INFO1, BLOB_CONTENT, BLOB_TARGET_METAGENERATION, BLOB_TARGET_NOT_EXIST, BLOB_TARGET_PREDEFINED_ACL); - assertEquals(BLOB_INFO1, blob); + assertEquals(expectedBlob1, blob); ByteArrayInputStream byteStream = capturedStream.getValue(); byte[] streamBytes = new byte[BLOB_CONTENT.length]; assertEquals(BLOB_CONTENT.length, byteStream.read(streamBytes)); @@ -374,9 +390,9 @@ public void testCreateBlobFromStream() { EasyMock.expect(storageRpcMock.create(infoWithoutHashes.toPb(), fileStream, EMPTY_RPC_OPTIONS)) .andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BlobInfo blob = storage.create(infoWithHashes, fileStream); - assertEquals(BLOB_INFO1, blob); + initializeService(); + Blob blob = storage.create(infoWithHashes, fileStream); + assertEquals(expectedBlob1, blob); } @Test @@ -384,9 +400,9 @@ public void testGetBucket() { EasyMock.expect(storageRpcMock.get(BucketInfo.of(BUCKET_NAME1).toPb(), EMPTY_RPC_OPTIONS)) .andReturn(BUCKET_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BucketInfo bucket = storage.get(BUCKET_NAME1); - assertEquals(BUCKET_INFO1, bucket); + initializeService(); + Bucket bucket = storage.get(BUCKET_NAME1); + assertEquals(expectedBucket1, bucket); } @Test @@ -394,9 +410,9 @@ public void testGetBucketWithOptions() { EasyMock.expect(storageRpcMock.get(BucketInfo.of(BUCKET_NAME1).toPb(), BUCKET_GET_OPTIONS)) .andReturn(BUCKET_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BucketInfo bucket = storage.get(BUCKET_NAME1, BUCKET_GET_METAGENERATION); - assertEquals(BUCKET_INFO1, bucket); + initializeService(); + Bucket bucket = storage.get(BUCKET_NAME1, BUCKET_GET_METAGENERATION); + assertEquals(expectedBucket1, bucket); } @Test @@ -405,8 +421,8 @@ public void testGetBucketWithSelectedFields() { EasyMock.expect(storageRpcMock.get(EasyMock.eq(BucketInfo.of(BUCKET_NAME1).toPb()), EasyMock.capture(capturedOptions))).andReturn(BUCKET_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BucketInfo bucket = storage.get(BUCKET_NAME1, BUCKET_GET_METAGENERATION, BUCKET_GET_FIELDS); + initializeService(); + Bucket bucket = storage.get(BUCKET_NAME1, BUCKET_GET_METAGENERATION, BUCKET_GET_FIELDS); assertEquals(BUCKET_GET_METAGENERATION.value(), capturedOptions.getValue().get(BUCKET_GET_METAGENERATION.rpcOption())); String selector = (String) capturedOptions.getValue().get(BLOB_GET_FIELDS.rpcOption()); @@ -423,8 +439,8 @@ public void testGetBucketWithEmptyFields() { EasyMock.expect(storageRpcMock.get(EasyMock.eq(BucketInfo.of(BUCKET_NAME1).toPb()), EasyMock.capture(capturedOptions))).andReturn(BUCKET_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BucketInfo bucket = storage.get(BUCKET_NAME1, BUCKET_GET_METAGENERATION, + initializeService(); + Bucket bucket = storage.get(BUCKET_NAME1, BUCKET_GET_METAGENERATION, BUCKET_GET_EMPTY_FIELDS); assertEquals(BUCKET_GET_METAGENERATION.value(), capturedOptions.getValue().get(BUCKET_GET_METAGENERATION.rpcOption())); @@ -440,9 +456,9 @@ public void testGetBlob() { storageRpcMock.get(BlobId.of(BUCKET_NAME1, BLOB_NAME1).toPb(), EMPTY_RPC_OPTIONS)) .andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BlobInfo blob = storage.get(BUCKET_NAME1, BLOB_NAME1); - assertEquals(BLOB_INFO1, blob); + initializeService(); + Blob blob = storage.get(BUCKET_NAME1, BLOB_NAME1); + assertEquals(expectedBlob1, blob); } @Test @@ -451,10 +467,10 @@ public void testGetBlobWithOptions() { storageRpcMock.get(BlobId.of(BUCKET_NAME1, BLOB_NAME1).toPb(), BLOB_GET_OPTIONS)) .andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BlobInfo blob = + initializeService(); + Blob blob = storage.get(BUCKET_NAME1, BLOB_NAME1, BLOB_GET_METAGENERATION, BLOB_GET_GENERATION); - assertEquals(BLOB_INFO1, blob); + assertEquals(expectedBlob1, blob); } @Test @@ -463,10 +479,10 @@ public void testGetBlobWithOptionsFromBlobId() { storageRpcMock.get(BLOB_INFO1.blobId().toPb(), BLOB_GET_OPTIONS)) .andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BlobInfo blob = + initializeService(); + Blob blob = storage.get(BLOB_INFO1.blobId(), BLOB_GET_METAGENERATION, BLOB_GET_GENERATION_FROM_BLOB_ID); - assertEquals(BLOB_INFO1, blob); + assertEquals(expectedBlob1, blob); } @Test @@ -475,8 +491,9 @@ public void testGetBlobWithSelectedFields() { EasyMock.expect(storageRpcMock.get(EasyMock.eq(BlobId.of(BUCKET_NAME1, BLOB_NAME1).toPb()), EasyMock.capture(capturedOptions))).andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BlobInfo blob = storage.get(BUCKET_NAME1, BLOB_NAME1, BLOB_GET_METAGENERATION, + initializeService(); + Blob blob = storage.get( + BUCKET_NAME1, BLOB_NAME1, BLOB_GET_METAGENERATION, BLOB_GET_GENERATION, BLOB_GET_FIELDS); assertEquals(BLOB_GET_METAGENERATION.value(), capturedOptions.getValue().get(BLOB_GET_METAGENERATION.rpcOption())); @@ -488,7 +505,7 @@ public void testGetBlobWithSelectedFields() { assertTrue(selector.contains("contentType")); assertTrue(selector.contains("crc32c")); assertEquals(30, selector.length()); - assertEquals(BLOB_INFO1, blob); + assertEquals(expectedBlob1, blob); } @Test @@ -497,8 +514,8 @@ public void testGetBlobWithEmptyFields() { EasyMock.expect(storageRpcMock.get(EasyMock.eq(BlobId.of(BUCKET_NAME1, BLOB_NAME1).toPb()), EasyMock.capture(capturedOptions))).andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BlobInfo blob = storage.get(BUCKET_NAME1, BLOB_NAME1, BLOB_GET_METAGENERATION, + initializeService(); + Blob blob = storage.get(BUCKET_NAME1, BLOB_NAME1, BLOB_GET_METAGENERATION, BLOB_GET_GENERATION, BLOB_GET_EMPTY_FIELDS); assertEquals(BLOB_GET_METAGENERATION.value(), capturedOptions.getValue().get(BLOB_GET_METAGENERATION.rpcOption())); @@ -508,21 +525,22 @@ public void testGetBlobWithEmptyFields() { assertTrue(selector.contains("bucket")); assertTrue(selector.contains("name")); assertEquals(11, selector.length()); - assertEquals(BLOB_INFO1, blob); + assertEquals(expectedBlob1, blob); } @Test public void testListBuckets() { String cursor = "cursor"; - ImmutableList bucketList = ImmutableList.of(BUCKET_INFO1, BUCKET_INFO2); + ImmutableList bucketInfoList = ImmutableList.of(BUCKET_INFO1, BUCKET_INFO2); Tuple> result = - Tuple.of(cursor, Iterables.transform(bucketList, BucketInfo.TO_PB_FUNCTION)); + Tuple.of(cursor, Iterables.transform(bucketInfoList, BucketInfo.TO_PB_FUNCTION)); EasyMock.expect(storageRpcMock.list(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(storageRpcMock); - storage = options.service(); - Page page = storage.list(); + initializeService(); + ImmutableList bucketList = ImmutableList.of(expectedBucket1, expectedBucket2); + Page page = storage.list(); assertEquals(cursor, page.nextPageCursor()); - assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), BucketInfo.class)); + assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), Bucket.class)); } @Test @@ -530,38 +548,39 @@ public void testListBucketsEmpty() { EasyMock.expect(storageRpcMock.list(EMPTY_RPC_OPTIONS)).andReturn( Tuple.>of(null, null)); EasyMock.replay(storageRpcMock); - storage = options.service(); - Page page = storage.list(); + initializeService(); + Page page = storage.list(); assertNull(page.nextPageCursor()); - assertArrayEquals(ImmutableList.of().toArray(), - Iterables.toArray(page.values(), BucketInfo.class)); + assertArrayEquals(ImmutableList.of().toArray(), Iterables.toArray(page.values(), Bucket.class)); } @Test public void testListBucketsWithOptions() { String cursor = "cursor"; - ImmutableList bucketList = ImmutableList.of(BUCKET_INFO1, BUCKET_INFO2); + ImmutableList bucketInfoList = ImmutableList.of(BUCKET_INFO1, BUCKET_INFO2); Tuple> result = - Tuple.of(cursor, Iterables.transform(bucketList, BucketInfo.TO_PB_FUNCTION)); + Tuple.of(cursor, Iterables.transform(bucketInfoList, BucketInfo.TO_PB_FUNCTION)); EasyMock.expect(storageRpcMock.list(BUCKET_LIST_OPTIONS)).andReturn(result); EasyMock.replay(storageRpcMock); - storage = options.service(); - Page page = storage.list(BUCKET_LIST_MAX_RESULT, BUCKET_LIST_PREFIX); + initializeService(); + ImmutableList bucketList = ImmutableList.of(expectedBucket1, expectedBucket2); + Page page = storage.list(BUCKET_LIST_MAX_RESULT, BUCKET_LIST_PREFIX); assertEquals(cursor, page.nextPageCursor()); - assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), BucketInfo.class)); + assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), Bucket.class)); } @Test public void testListBucketsWithSelectedFields() { String cursor = "cursor"; Capture> capturedOptions = Capture.newInstance(); - ImmutableList bucketList = ImmutableList.of(BUCKET_INFO1, BUCKET_INFO2); + ImmutableList bucketInfoList = ImmutableList.of(BUCKET_INFO1, BUCKET_INFO2); Tuple> result = - Tuple.of(cursor, Iterables.transform(bucketList, BucketInfo.TO_PB_FUNCTION)); + Tuple.of(cursor, Iterables.transform(bucketInfoList, BucketInfo.TO_PB_FUNCTION)); EasyMock.expect(storageRpcMock.list(EasyMock.capture(capturedOptions))).andReturn(result); EasyMock.replay(storageRpcMock); - storage = options.service(); - Page page = storage.list(BUCKET_LIST_FIELDS); + initializeService(); + ImmutableList bucketList = ImmutableList.of(expectedBucket1, expectedBucket2); + Page page = storage.list(BUCKET_LIST_FIELDS); String selector = (String) capturedOptions.getValue().get(BLOB_LIST_FIELDS.rpcOption()); assertTrue(selector.contains("items")); assertTrue(selector.contains("name")); @@ -569,40 +588,42 @@ public void testListBucketsWithSelectedFields() { assertTrue(selector.contains("location")); assertEquals(24, selector.length()); assertEquals(cursor, page.nextPageCursor()); - assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), BucketInfo.class)); + assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), Bucket.class)); } @Test public void testListBucketsWithEmptyFields() { String cursor = "cursor"; Capture> capturedOptions = Capture.newInstance(); - ImmutableList bucketList = ImmutableList.of(BUCKET_INFO1, BUCKET_INFO2); + ImmutableList bucketInfoList = ImmutableList.of(BUCKET_INFO1, BUCKET_INFO2); Tuple> result = - Tuple.of(cursor, Iterables.transform(bucketList, BucketInfo.TO_PB_FUNCTION)); + Tuple.of(cursor, Iterables.transform(bucketInfoList, BucketInfo.TO_PB_FUNCTION)); EasyMock.expect(storageRpcMock.list(EasyMock.capture(capturedOptions))).andReturn(result); EasyMock.replay(storageRpcMock); - storage = options.service(); - Page page = storage.list(BUCKET_LIST_EMPTY_FIELDS); + initializeService(); + ImmutableList bucketList = ImmutableList.of(expectedBucket1, expectedBucket2); + Page page = storage.list(BUCKET_LIST_EMPTY_FIELDS); String selector = (String) capturedOptions.getValue().get(BLOB_LIST_FIELDS.rpcOption()); assertTrue(selector.contains("items")); assertTrue(selector.contains("name")); assertEquals(11, selector.length()); assertEquals(cursor, page.nextPageCursor()); - assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), BucketInfo.class)); + assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), Bucket.class)); } @Test public void testListBlobs() { String cursor = "cursor"; - ImmutableList blobList = ImmutableList.of(BLOB_INFO1, BLOB_INFO2); + ImmutableList blobInfoList = ImmutableList.of(BLOB_INFO1, BLOB_INFO2); Tuple> result = - Tuple.of(cursor, Iterables.transform(blobList, BlobInfo.TO_PB_FUNCTION)); + Tuple.of(cursor, Iterables.transform(blobInfoList, BlobInfo.INFO_TO_PB_FUNCTION)); EasyMock.expect(storageRpcMock.list(BUCKET_NAME1, EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(storageRpcMock); - storage = options.service(); - Page page = storage.list(BUCKET_NAME1); + initializeService(); + ImmutableList blobList = ImmutableList.of(expectedBlob1, expectedBlob2); + Page page = storage.list(BUCKET_NAME1); assertEquals(cursor, page.nextPageCursor()); - assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), BlobInfo.class)); + assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), Blob.class)); } @Test @@ -611,40 +632,41 @@ public void testListBlobsEmpty() { .andReturn(Tuple.>of( null, null)); EasyMock.replay(storageRpcMock); - storage = options.service(); - Page page = storage.list(BUCKET_NAME1); + initializeService(); + Page page = storage.list(BUCKET_NAME1); assertNull(page.nextPageCursor()); - assertArrayEquals(ImmutableList.of().toArray(), - Iterables.toArray(page.values(), BlobInfo.class)); + assertArrayEquals(ImmutableList.of().toArray(), Iterables.toArray(page.values(), Blob.class)); } @Test public void testListBlobsWithOptions() { String cursor = "cursor"; - ImmutableList blobList = ImmutableList.of(BLOB_INFO1, BLOB_INFO2); + ImmutableList blobInfoList = ImmutableList.of(BLOB_INFO1, BLOB_INFO2); Tuple> result = - Tuple.of(cursor, Iterables.transform(blobList, BlobInfo.TO_PB_FUNCTION)); + Tuple.of(cursor, Iterables.transform(blobInfoList, BlobInfo.INFO_TO_PB_FUNCTION)); EasyMock.expect(storageRpcMock.list(BUCKET_NAME1, BLOB_LIST_OPTIONS)).andReturn(result); EasyMock.replay(storageRpcMock); - storage = options.service(); - Page page = storage.list(BUCKET_NAME1, BLOB_LIST_MAX_RESULT, BLOB_LIST_PREFIX); + initializeService(); + ImmutableList blobList = ImmutableList.of(expectedBlob1, expectedBlob2); + Page page = storage.list(BUCKET_NAME1, BLOB_LIST_MAX_RESULT, BLOB_LIST_PREFIX); assertEquals(cursor, page.nextPageCursor()); - assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), BlobInfo.class)); + assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), Blob.class)); } @Test public void testListBlobsWithSelectedFields() { String cursor = "cursor"; Capture> capturedOptions = Capture.newInstance(); - ImmutableList blobList = ImmutableList.of(BLOB_INFO1, BLOB_INFO2); + ImmutableList blobInfoList = ImmutableList.of(BLOB_INFO1, BLOB_INFO2); Tuple> result = - Tuple.of(cursor, Iterables.transform(blobList, BlobInfo.TO_PB_FUNCTION)); + Tuple.of(cursor, Iterables.transform(blobInfoList, BlobInfo.INFO_TO_PB_FUNCTION)); EasyMock.expect( storageRpcMock.list(EasyMock.eq(BUCKET_NAME1), EasyMock.capture(capturedOptions))) .andReturn(result); EasyMock.replay(storageRpcMock); - storage = options.service(); - Page page = + initializeService(); + ImmutableList blobList = ImmutableList.of(expectedBlob1, expectedBlob2); + Page page = storage.list(BUCKET_NAME1, BLOB_LIST_MAX_RESULT, BLOB_LIST_PREFIX, BLOB_LIST_FIELDS); assertEquals(BLOB_LIST_MAX_RESULT.value(), capturedOptions.getValue().get(BLOB_LIST_MAX_RESULT.rpcOption())); @@ -658,22 +680,23 @@ public void testListBlobsWithSelectedFields() { assertTrue(selector.contains("md5Hash")); assertEquals(38, selector.length()); assertEquals(cursor, page.nextPageCursor()); - assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), BlobInfo.class)); + assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), Blob.class)); } @Test public void testListBlobsWithEmptyFields() { String cursor = "cursor"; Capture> capturedOptions = Capture.newInstance(); - ImmutableList blobList = ImmutableList.of(BLOB_INFO1, BLOB_INFO2); + ImmutableList blobInfoList = ImmutableList.of(BLOB_INFO1, BLOB_INFO2); Tuple> result = - Tuple.of(cursor, Iterables.transform(blobList, BlobInfo.TO_PB_FUNCTION)); + Tuple.of(cursor, Iterables.transform(blobInfoList, BlobInfo.INFO_TO_PB_FUNCTION)); EasyMock.expect( storageRpcMock.list(EasyMock.eq(BUCKET_NAME1), EasyMock.capture(capturedOptions))) .andReturn(result); EasyMock.replay(storageRpcMock); - storage = options.service(); - Page page = + initializeService(); + ImmutableList blobList = ImmutableList.of(expectedBlob1, expectedBlob2); + Page page = storage.list(BUCKET_NAME1, BLOB_LIST_MAX_RESULT, BLOB_LIST_PREFIX, BLOB_LIST_EMPTY_FIELDS); assertEquals(BLOB_LIST_MAX_RESULT.value(), capturedOptions.getValue().get(BLOB_LIST_MAX_RESULT.rpcOption())); @@ -685,7 +708,7 @@ public void testListBlobsWithEmptyFields() { assertTrue(selector.contains("name")); assertEquals(18, selector.length()); assertEquals(cursor, page.nextPageCursor()); - assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), BlobInfo.class)); + assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), Blob.class)); } @Test @@ -694,9 +717,9 @@ public void testUpdateBucket() { EasyMock.expect(storageRpcMock.patch(updatedBucketInfo.toPb(), EMPTY_RPC_OPTIONS)) .andReturn(updatedBucketInfo.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BucketInfo bucket = storage.update(updatedBucketInfo); - assertEquals(updatedBucketInfo, bucket); + initializeService(); + Bucket bucket = storage.update(updatedBucketInfo); + assertEquals(new Bucket(storage, new BucketInfo.BuilderImpl(updatedBucketInfo)), bucket); } @Test @@ -705,11 +728,11 @@ public void testUpdateBucketWithOptions() { EasyMock.expect(storageRpcMock.patch(updatedBucketInfo.toPb(), BUCKET_TARGET_OPTIONS)) .andReturn(updatedBucketInfo.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BucketInfo bucket = + initializeService(); + Bucket bucket = storage.update(updatedBucketInfo, BUCKET_TARGET_METAGENERATION, BUCKET_TARGET_PREDEFINED_ACL); - assertEquals(updatedBucketInfo, bucket); + assertEquals(new Bucket(storage, new BucketInfo.BuilderImpl(updatedBucketInfo)), bucket); } @Test @@ -718,9 +741,9 @@ public void testUpdateBlob() { EasyMock.expect(storageRpcMock.patch(updatedBlobInfo.toPb(), EMPTY_RPC_OPTIONS)) .andReturn(updatedBlobInfo.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BlobInfo blob = storage.update(updatedBlobInfo); - assertEquals(updatedBlobInfo, blob); + initializeService(); + Blob blob = storage.update(updatedBlobInfo); + assertEquals(new Blob(storage, new BlobInfo.BuilderImpl(updatedBlobInfo)), blob); } @Test @@ -729,10 +752,10 @@ public void testUpdateBlobWithOptions() { EasyMock.expect(storageRpcMock.patch(updatedBlobInfo.toPb(), BLOB_TARGET_OPTIONS_UPDATE)) .andReturn(updatedBlobInfo.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BlobInfo blob = + initializeService(); + Blob blob = storage.update(updatedBlobInfo, BLOB_TARGET_METAGENERATION, BLOB_TARGET_PREDEFINED_ACL); - assertEquals(updatedBlobInfo, blob); + assertEquals(new Blob(storage, new BlobInfo.BuilderImpl(updatedBlobInfo)), blob); } @Test @@ -740,7 +763,7 @@ public void testDeleteBucket() { EasyMock.expect(storageRpcMock.delete(BucketInfo.of(BUCKET_NAME1).toPb(), EMPTY_RPC_OPTIONS)) .andReturn(true); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); assertTrue(storage.delete(BUCKET_NAME1)); } @@ -750,7 +773,7 @@ public void testDeleteBucketWithOptions() { .expect(storageRpcMock.delete(BucketInfo.of(BUCKET_NAME1).toPb(), BUCKET_SOURCE_OPTIONS)) .andReturn(true); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); assertTrue(storage.delete(BUCKET_NAME1, BUCKET_SOURCE_METAGENERATION)); } @@ -760,7 +783,7 @@ public void testDeleteBlob() { storageRpcMock.delete(BlobId.of(BUCKET_NAME1, BLOB_NAME1).toPb(), EMPTY_RPC_OPTIONS)) .andReturn(true); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); assertTrue(storage.delete(BUCKET_NAME1, BLOB_NAME1)); } @@ -770,7 +793,7 @@ public void testDeleteBlobWithOptions() { storageRpcMock.delete(BlobId.of(BUCKET_NAME1, BLOB_NAME1).toPb(), BLOB_SOURCE_OPTIONS)) .andReturn(true); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); assertTrue(storage.delete(BUCKET_NAME1, BLOB_NAME1, BLOB_SOURCE_GENERATION, BLOB_SOURCE_METAGENERATION)); } @@ -781,7 +804,7 @@ public void testDeleteBlobWithOptionsFromBlobId() { storageRpcMock.delete(BLOB_INFO1.blobId().toPb(), BLOB_SOURCE_OPTIONS)) .andReturn(true); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); assertTrue(storage.delete(BLOB_INFO1.blobId(), BLOB_SOURCE_GENERATION_FROM_BLOB_ID, BLOB_SOURCE_METAGENERATION)); } @@ -795,9 +818,9 @@ public void testCompose() { EasyMock.expect(storageRpcMock.compose(ImmutableList.of(BLOB_INFO2.toPb(), BLOB_INFO3.toPb()), BLOB_INFO1.toPb(), EMPTY_RPC_OPTIONS)).andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BlobInfo blob = storage.compose(req); - assertEquals(BLOB_INFO1, blob); + initializeService(); + Blob blob = storage.compose(req); + assertEquals(expectedBlob1, blob); } @Test @@ -810,9 +833,9 @@ public void testComposeWithOptions() { EasyMock.expect(storageRpcMock.compose(ImmutableList.of(BLOB_INFO2.toPb(), BLOB_INFO3.toPb()), BLOB_INFO1.toPb(), BLOB_TARGET_OPTIONS_COMPOSE)).andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); - storage = options.service(); - BlobInfo blob = storage.compose(req); - assertEquals(BLOB_INFO1, blob); + initializeService(); + Blob blob = storage.compose(req); + assertEquals(expectedBlob1, blob); } @Test @@ -824,7 +847,7 @@ public void testCopy() { false, "token", 21L); EasyMock.expect(storageRpcMock.openRewrite(rpcRequest)).andReturn(rpcResponse); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); CopyWriter writer = storage.copy(request); assertEquals(42L, writer.blobSize()); assertEquals(21L, writer.totalBytesCopied()); @@ -844,7 +867,7 @@ public void testCopyWithOptions() { false, "token", 21L); EasyMock.expect(storageRpcMock.openRewrite(rpcRequest)).andReturn(rpcResponse); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); CopyWriter writer = storage.copy(request); assertEquals(42L, writer.blobSize()); assertEquals(21L, writer.totalBytesCopied()); @@ -864,7 +887,7 @@ public void testCopyWithOptionsFromBlobId() { new StorageRpc.RewriteResponse(rpcRequest, null, 42L, false, "token", 21L); EasyMock.expect(storageRpcMock.openRewrite(rpcRequest)).andReturn(rpcResponse); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); CopyWriter writer = storage.copy(request); assertEquals(42L, writer.blobSize()); assertEquals(21L, writer.totalBytesCopied()); @@ -883,7 +906,7 @@ public void testCopyMultipleRequests() { EasyMock.expect(storageRpcMock.openRewrite(rpcRequest)).andReturn(rpcResponse1); EasyMock.expect(storageRpcMock.continueRewrite(rpcResponse1)).andReturn(rpcResponse2); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); CopyWriter writer = storage.copy(request); assertEquals(42L, writer.blobSize()); assertEquals(21L, writer.totalBytesCopied()); @@ -900,7 +923,7 @@ public void testReadAllBytes() { storageRpcMock.load(BlobId.of(BUCKET_NAME1, BLOB_NAME1).toPb(), EMPTY_RPC_OPTIONS)) .andReturn(BLOB_CONTENT); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); byte[] readBytes = storage.readAllBytes(BUCKET_NAME1, BLOB_NAME1); assertArrayEquals(BLOB_CONTENT, readBytes); } @@ -911,7 +934,7 @@ public void testReadAllBytesWithOptions() { storageRpcMock.load(BlobId.of(BUCKET_NAME1, BLOB_NAME1).toPb(), BLOB_SOURCE_OPTIONS)) .andReturn(BLOB_CONTENT); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); byte[] readBytes = storage.readAllBytes(BUCKET_NAME1, BLOB_NAME1, BLOB_SOURCE_GENERATION, BLOB_SOURCE_METAGENERATION); assertArrayEquals(BLOB_CONTENT, readBytes); @@ -923,7 +946,7 @@ public void testReadAllBytesWithOptionsFromBlobId() { storageRpcMock.load(BLOB_INFO1.blobId().toPb(), BLOB_SOURCE_OPTIONS)) .andReturn(BLOB_CONTENT); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); byte[] readBytes = storage.readAllBytes(BLOB_INFO1.blobId(), BLOB_SOURCE_GENERATION_FROM_BLOB_ID, BLOB_SOURCE_METAGENERATION); assertArrayEquals(BLOB_CONTENT, readBytes); @@ -970,11 +993,10 @@ public Tuple apply(StorageObject f) { StorageRpc.BatchResponse res = new StorageRpc.BatchResponse(deleteResult, updateResult, getResult); - Capture capturedBatchRequest = Capture.newInstance(); EasyMock.expect(storageRpcMock.batch(EasyMock.capture(capturedBatchRequest))).andReturn(res); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); BatchResponse batchResponse = storage.submit(req); // Verify captured StorageRpc.BatchRequest @@ -1012,7 +1034,7 @@ public Tuple apply(StorageObject f) { @Test public void testReader() { EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); ReadChannel channel = storage.reader(BUCKET_NAME1, BLOB_NAME1); assertNotNull(channel); assertTrue(channel.isOpen()); @@ -1025,7 +1047,7 @@ public void testReaderWithOptions() throws IOException { storageRpcMock.read(BLOB_INFO2.toPb(), BLOB_SOURCE_OPTIONS, 0, DEFAULT_CHUNK_SIZE)) .andReturn(StorageRpc.Tuple.of("etag", result)); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); ReadChannel channel = storage.reader(BUCKET_NAME1, BLOB_NAME2, BLOB_SOURCE_GENERATION, BLOB_SOURCE_METAGENERATION); assertNotNull(channel); @@ -1040,7 +1062,7 @@ public void testReaderWithOptionsFromBlobId() throws IOException { storageRpcMock.read(BLOB_INFO1.blobId().toPb(), BLOB_SOURCE_OPTIONS, 0, DEFAULT_CHUNK_SIZE)) .andReturn(StorageRpc.Tuple.of("etag", result)); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); ReadChannel channel = storage.reader(BLOB_INFO1.blobId(), BLOB_SOURCE_GENERATION_FROM_BLOB_ID, BLOB_SOURCE_METAGENERATION); assertNotNull(channel); @@ -1056,7 +1078,7 @@ public void testWriter() { EasyMock.expect(storageRpcMock.open(infoWithoutHashes.toPb(), EMPTY_RPC_OPTIONS)) .andReturn("upload-id"); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); WriteChannel channel = storage.writer(infoWithHashes); assertNotNull(channel); assertTrue(channel.isOpen()); @@ -1068,7 +1090,7 @@ public void testWriterWithOptions() { EasyMock.expect(storageRpcMock.open(info.toPb(), BLOB_TARGET_OPTIONS_CREATE)) .andReturn("upload-id"); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); WriteChannel channel = storage.writer(info, BLOB_WRITE_METAGENERATION, BLOB_WRITE_NOT_EXIST, BLOB_WRITE_PREDEFINED_ACL, BLOB_WRITE_CRC2C, BLOB_WRITE_MD5_HASH); assertNotNull(channel); @@ -1154,12 +1176,11 @@ public Tuple apply(StorageObject f) { StorageRpc.BatchResponse res = new StorageRpc.BatchResponse(deleteResult, updateResult, getResult); - Capture capturedBatchRequest = Capture.newInstance(); EasyMock.expect(storageRpcMock.batch(EasyMock.capture(capturedBatchRequest))).andReturn(res); EasyMock.replay(storageRpcMock); - storage = options.service(); - List resultBlobs = storage.get(blobId1, blobId2); + initializeService(); + List resultBlobs = storage.get(blobId1, blobId2); // Verify captured StorageRpc.BatchRequest List>> capturedToGet = @@ -1197,12 +1218,11 @@ public Tuple apply(StorageObject f) { StorageRpc.BatchResponse res = new StorageRpc.BatchResponse(deleteResult, updateResult, getResult); - Capture capturedBatchRequest = Capture.newInstance(); EasyMock.expect(storageRpcMock.batch(EasyMock.capture(capturedBatchRequest))).andReturn(res); EasyMock.replay(storageRpcMock); - storage = options.service(); - List resultBlobs = storage.update(blobInfo1, blobInfo2); + initializeService(); + List resultBlobs = storage.update(blobInfo1, blobInfo2); // Verify captured StorageRpc.BatchRequest List>> capturedToUpdate = @@ -1243,7 +1263,7 @@ public Tuple apply(StorageObject f) { Capture capturedBatchRequest = Capture.newInstance(); EasyMock.expect(storageRpcMock.batch(EasyMock.capture(capturedBatchRequest))).andReturn(res); EasyMock.replay(storageRpcMock); - storage = options.service(); + initializeService(); List deleteResults = storage.delete(blobInfo1.blobId(), blobInfo2.blobId()); // Verify captured StorageRpc.BatchRequest @@ -1270,8 +1290,9 @@ public void testRetryableException() { .andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); storage = options.toBuilder().retryParams(RetryParams.defaultInstance()).build().service(); - BlobInfo readBlob = storage.get(blob); - assertEquals(BLOB_INFO1, readBlob); + initializeServiceDependentObjects(); + Blob readBlob = storage.get(blob); + assertEquals(expectedBlob1, readBlob); } @Test @@ -1282,6 +1303,7 @@ public void testNonRetryableException() { .andThrow(new StorageException(501, exceptionMessage)); EasyMock.replay(storageRpcMock); storage = options.toBuilder().retryParams(RetryParams.defaultInstance()).build().service(); + initializeServiceDependentObjects(); thrown.expect(StorageException.class); thrown.expectMessage(exceptionMessage); storage.get(blob); diff --git a/gcloud-java/README.md b/gcloud-java/README.md index a080d787d6ab..4a581d56f991 100644 --- a/gcloud-java/README.md +++ b/gcloud-java/README.md @@ -6,6 +6,7 @@ Java idiomatic client for [Google Cloud Platform][cloud-platform] services. [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java.svg) +[![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs) diff --git a/pom.xml b/pom.xml index 971cce75a89b..01e1c0d2888f 100644 --- a/pom.xml +++ b/pom.xml @@ -11,6 +11,24 @@ Java idiomatic client for Google Cloud Platform services. + + derka + Martin Derka + derka@google.com + Google + + Developer + + + + ajaykannan + Ajay Kannan + ajaykannan@google.com + Google + + Developer + + ozarov Arie Ozarov @@ -20,6 +38,15 @@ Developer + + mziccardi + Marco Ziccardi + mziccardi@google.com + Google + + Developer + + Google diff --git a/src/site/resources/index.html b/src/site/resources/index.html index 8f40cfbcd97e..0e0933e7b68c 100644 --- a/src/site/resources/index.html +++ b/src/site/resources/index.html @@ -178,8 +178,10 @@

    Examples

    • - SparkJava demo - Use gcloud-java with App Engine Managed VMs, Datastore, and SparkJava. + SparkJava demo - Uses gcloud-java with App Engine Managed VMs, Datastore, and SparkJava.
    • +
    • + Bookshelf - An App Engine app that manages a virtual bookshelf using gcloud-java libraries for Datastore and Storage.