diff --git a/README.md b/README.md
index 1b9867fd198f..5ed44e91adfd 100644
--- a/README.md
+++ b/README.md
@@ -20,14 +20,22 @@ This client supports the following Google Cloud Platform services:
Quickstart
----------
-Add this to your pom.xml file
+If you are using Maven, add this to your pom.xml file
```xml
com.google.gcloudgcloud-java
- 0.0.10
+ 0.0.11
```
+If you are using Gradle, add this to your dependencies
+```Groovy
+compile 'com.google.gcloud:gcloud-java:jar:0.0.11'
+```
+If you are using SBT, add this to your dependencies
+```Scala
+libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.0.11"
+```
Example Applications
--------------------
@@ -37,6 +45,33 @@ Example Applications
- [`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
- 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
+-----------------------
+
+Most `gcloud-java` libraries require a project ID. There are multiple ways to specify this project ID.
+
+1. When using `gcloud-java` libraries from within Compute/App Engine, there's no need to specify a project ID. It is automatically inferred from the production environment.
+2. When using `gcloud-java` elsewhere, you can do one of the following:
+ * Supply the project ID when building the service options. For example, to use Datastore from a project with ID "PROJECT_ID", you can write:
+
+ ```java
+ Datastore datastore = DatastoreOptions.builder().projectId("PROJECT_ID").build().service();
+ ```
+ * Specify the environment variable `GCLOUD_PROJECT` to be your desired project ID.
+ * Set the project ID using the [Google Cloud SDK](https://cloud.google.com/sdk/?hl=en). To use the SDK, [download the SDK](https://cloud.google.com/sdk/?hl=en) if you haven't already, and set the project ID from the command line. For example:
+
+ ```
+ gcloud config set project PROJECT_ID
+ ```
+
+`gcloud-java` determines the project ID from the following sources in the listed order, stopping once it finds a value:
+
+1. Project ID supplied when building the service options
+2. Project ID specified by the environment variable `GCLOUD_PROJECT`
+3. App Engine project ID
+4. Compute Engine project ID
+5. Google Cloud SDK project ID
+
Authentication
--------------
@@ -44,8 +79,27 @@ There are multiple ways to authenticate to use Google Cloud services.
1. When using `gcloud-java` libraries from within Compute/App Engine, no additional authentication steps are necessary.
2. When using `gcloud-java` libraries elsewhere, there are two options:
- * [Generate a JSON service account key](https://cloud.google.com/storage/docs/authentication?hl=en#service_accounts). Supply a path to the downloaded JSON credentials file when building the options supplied to datastore/storage constructor.
- * If running locally for development/testing, you can use use [Google Cloud SDK](https://cloud.google.com/sdk/?hl=en). To use the SDK authentication, [download the SDK](https://cloud.google.com/sdk/?hl=en) if you haven't already. Then login using the SDK (`gcloud auth login` in command line), and set your current project using `gcloud config set project PROJECT_ID`.
+ * [Generate a JSON service account key](https://cloud.google.com/storage/docs/authentication?hl=en#service_accounts). After downloading that key, you must do one of the following:
+ * Define the environment variable GOOGLE_APPLICATION_CREDENTIALS to be the location of the key. For example:
+ ```bash
+ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/my/key.json
+ ```
+ * Supply the JSON credentials file when building the service options. For example, this Storage object has the necessary permissions to interact with your Google Cloud Storage data:
+ ```java
+ Storage storage = StorageOptions.builder()
+ .authCredentials(AuthCredentials.createForJson(new FileInputStream("/path/to/my/key.json"))
+ .build()
+ .service();
+ ```
+ * If running locally for development/testing, you can use use Google Cloud SDK. Download the SDK if you haven't already, then login using the SDK (`gcloud auth login` in command line). Be sure to set your project ID as described above.
+
+`gcloud-java` looks for credentials in the following order, stopping once it finds credentials:
+
+1. Credentials supplied when building the service options
+2. App Engine credentials
+3. Key file pointed to by the GOOGLE_APPLICATION_CREDENTIALS environment variable
+4. Google Cloud SDK credentials
+5. Compute Engine credentials
Google Cloud Datastore
----------------------
@@ -67,7 +121,7 @@ import com.google.gcloud.datastore.Entity;
import com.google.gcloud.datastore.Key;
import com.google.gcloud.datastore.KeyFactory;
-Datastore datastore = DatastoreOptions.getDefaultInstance().service();
+Datastore datastore = DatastoreOptions.defaultInstance().service();
KeyFactory keyFactory = datastore.newKeyFactory().kind(KIND);
Key key = keyFactory.newKey(keyName);
Entity entity = datastore.get(key);
diff --git a/gcloud-java-core/README.md b/gcloud-java-core/README.md
index 2a3be300f4ac..f84fb33993e7 100644
--- a/gcloud-java-core/README.md
+++ b/gcloud-java-core/README.md
@@ -12,14 +12,22 @@ This module provides common functionality required by service-specific modules o
Quickstart
----------
-Add this to your pom.xml file
+If you are using Maven, add this to your pom.xml file
```xml
com.google.gcloudgcloud-java-core
- 0.0.10
+ 0.0.11
```
+If you are using Gradle, add this to your dependencies
+```Groovy
+compile 'com.google.gcloud:gcloud-java-core:jar:0.0.11'
+```
+If you are using SBT, add this to your dependencies
+```Scala
+libraryDependencies += "com.google.gcloud" % "gcloud-java-core" % "0.0.11"
+```
Java Versions
-------------
diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml
index e849594226db..e13933bd2beb 100644
--- a/gcloud-java-core/pom.xml
+++ b/gcloud-java-core/pom.xml
@@ -11,7 +11,7 @@
com.google.gcloudgcloud-java-pom
- 0.0.11-SNAPSHOT
+ 0.0.12-SNAPSHOTgcloud-java-core
diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java
index 73c66279ea53..800fcf340689 100644
--- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java
+++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java
@@ -252,7 +252,7 @@ public boolean equals(Object obj) {
@Override
protected HttpRequestInitializer httpRequestInitializer(HttpTransport transport,
Set scopes) {
- return new HttpCredentialsAdapter(googleCredentials);
+ return new HttpCredentialsAdapter(googleCredentials.createScoped(scopes));
}
@Override
diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/BaseServiceException.java b/gcloud-java-core/src/main/java/com/google/gcloud/BaseServiceException.java
new file mode 100644
index 000000000000..cd0933426756
--- /dev/null
+++ b/gcloud-java-core/src/main/java/com/google/gcloud/BaseServiceException.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.gcloud;
+
+/**
+ * Base class for all service exceptions.
+ */
+public class BaseServiceException extends RuntimeException {
+
+ private static final long serialVersionUID = 5028833760039966178L;
+
+ private final int code;
+ private final boolean retryable;
+
+ public BaseServiceException(int code, String message, boolean retryable) {
+ super(message);
+ this.code = code;
+ this.retryable = retryable;
+ }
+
+ public BaseServiceException(int code, String message, boolean retryable, Exception cause) {
+ super(message, cause);
+ this.code = code;
+ this.retryable = retryable;
+ }
+
+ /**
+ * Returns the code associated with this exception.
+ */
+ public int code() {
+ return code;
+ }
+
+ /**
+ * Returns {@code true} when it is safe to retry the operation that caused this exception.
+ */
+ public boolean retryable() {
+ return retryable;
+ }
+}
diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java b/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java
index a0fab3dca566..c1f068594443 100644
--- a/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java
+++ b/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java
@@ -231,11 +231,11 @@ void verifyCaller(Callable> callable) {
}
}
- public Set> getRetriableExceptions() {
+ public Set> retriableExceptions() {
return retriableExceptions;
}
- public Set> getNonRetriableExceptions() {
+ public Set> nonRetriableExceptions() {
return nonRetriableExceptions;
}
@@ -262,7 +262,7 @@ boolean shouldRetry(Exception ex) {
/**
* Returns an instance which retry any checked exception and abort on any runtime exception.
*/
- public static ExceptionHandler getDefaultInstance() {
+ public static ExceptionHandler defaultInstance() {
return DEFAULT_INSTANCE;
}
diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/Page.java b/gcloud-java-core/src/main/java/com/google/gcloud/Page.java
new file mode 100644
index 000000000000..2819b56a17a0
--- /dev/null
+++ b/gcloud-java-core/src/main/java/com/google/gcloud/Page.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.gcloud;
+
+import java.util.Iterator;
+
+/**
+ * Interface for Google Cloud paginated results.
+ *
+ *
+ * Use {@code Page} to iterate through all values (also in next pages):
+ *
{@code
+ * Page page = ...; // get a Page instance
+ * Iterator iterator = page.iterateAll();
+ * while (iterator.hasNext()) {
+ * T value = iterator.next();
+ * // do something with value
+ * }}
+ *
+ * Or handle pagination explicitly:
+ *
{@code
+ * Page page = ...; // get a Page instance
+ * while (page != null) {
+ * for (T value : page.values()) {
+ * // do something with value
+ * }
+ * page = page.nextPage();
+ * }}
+ */
+public interface Page {
+
+ /**
+ * Returns the values contained in this page.
+ */
+ Iterable values();
+
+ /**
+ * Returns an iterator for all values, possibly also in the next pages. Once current page's values
+ * are traversed the iterator fetches next page, if any.
+ */
+ Iterator iterateAll();
+
+ /**
+ * Returns the cursor for the nextPage or {@code null} if no more results.
+ */
+ String nextPageCursor();
+
+ /**
+ * Returns the next page of results or {@code null} if no more result.
+ */
+ Page nextPage();
+
+}
diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/PageImpl.java b/gcloud-java-core/src/main/java/com/google/gcloud/PageImpl.java
new file mode 100644
index 000000000000..5e83b53b33a9
--- /dev/null
+++ b/gcloud-java-core/src/main/java/com/google/gcloud/PageImpl.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.gcloud;
+
+import com.google.common.collect.AbstractIterator;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Objects;
+
+/**
+ * Base implementation for Google Cloud paginated results.
+ */
+public class PageImpl implements Page, Serializable {
+
+ private static final long serialVersionUID = 3914827379823557934L;
+
+ private final String cursor;
+ private final Iterable results;
+ private final NextPageFetcher pageFetcher;
+
+ public interface NextPageFetcher extends Serializable {
+ Page nextPage();
+ }
+
+ static class PageIterator extends AbstractIterator {
+
+ private Iterator currentPageIterator;
+ private Page currentPage;
+
+ PageIterator(Page currentPage) {
+ this.currentPageIterator = currentPage.values().iterator();
+ this.currentPage = currentPage;
+ }
+
+ @Override
+ protected T computeNext() {
+ while (!currentPageIterator.hasNext()) {
+ currentPage = currentPage.nextPage();
+ if (currentPage == null) {
+ return endOfData();
+ }
+ currentPageIterator = currentPage.values().iterator();
+ }
+ return currentPageIterator.next();
+ }
+ }
+
+ /**
+ * Creates a {@code PageImpl} object. In order for the object to be serializable the {@code
+ * results} parameter must be serializable.
+ */
+ public PageImpl(NextPageFetcher pageFetcher, String cursor, Iterable results) {
+ this.pageFetcher = pageFetcher;
+ this.cursor = cursor;
+ this.results = results;
+ }
+
+ @Override
+ public Iterable values() {
+ return results == null ? Collections.EMPTY_LIST : results;
+ }
+
+ @Override
+ public Iterator iterateAll() {
+ return new PageIterator(this);
+ }
+
+ @Override
+ public String nextPageCursor() {
+ return cursor;
+ }
+
+ @Override
+ public Page nextPage() {
+ if (cursor == null || pageFetcher == null) {
+ return null;
+ }
+ return pageFetcher.nextPage();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(cursor, results);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof PageImpl)) {
+ return false;
+ }
+ PageImpl> other = (PageImpl>) obj;
+ return Objects.equals(cursor, other.cursor)
+ && Objects.equals(results, other.results);
+ }
+}
diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/RetryHelper.java b/gcloud-java-core/src/main/java/com/google/gcloud/RetryHelper.java
index 7b47209cd3ff..9b9c1f6a3124 100644
--- a/gcloud-java-core/src/main/java/com/google/gcloud/RetryHelper.java
+++ b/gcloud-java-core/src/main/java/com/google/gcloud/RetryHelper.java
@@ -194,9 +194,9 @@ private V doRetry() throws RetryHelperException {
}
exception = e;
}
- if (attemptNumber >= params.getRetryMaxAttempts()
- || attemptNumber >= params.getRetryMinAttempts()
- && stopwatch.elapsed(MILLISECONDS) >= params.getTotalRetryPeriodMillis()) {
+ if (attemptNumber >= params.retryMaxAttempts()
+ || attemptNumber >= params.retryMinAttempts()
+ && stopwatch.elapsed(MILLISECONDS) >= params.totalRetryPeriodMillis()) {
throw new RetriesExhaustedException(this + ": Too many failures, giving up", exception);
}
long sleepDurationMillis = getSleepDuration(params, attemptNumber);
@@ -215,9 +215,9 @@ private V doRetry() throws RetryHelperException {
@VisibleForTesting
static long getSleepDuration(RetryParams retryParams, int attemptsSoFar) {
- long initialDelay = retryParams.getInitialRetryDelayMillis();
- double backoffFactor = retryParams.getRetryDelayBackoffFactor();
- long maxDelay = retryParams.getMaxRetryDelayMillis();
+ long initialDelay = retryParams.initialRetryDelayMillis();
+ double backoffFactor = retryParams.retryDelayBackoffFactor();
+ long maxDelay = retryParams.maxRetryDelayMillis();
long retryDelay = getExponentialValue(initialDelay, backoffFactor, maxDelay, attemptsSoFar);
return (long) ((random() / 2.0 + .75) * retryDelay);
}
@@ -228,8 +228,8 @@ private static long getExponentialValue(long initialDelay, double backoffFactor,
}
public static V runWithRetries(Callable callable) throws RetryHelperException {
- return runWithRetries(callable, RetryParams.getDefaultInstance(),
- ExceptionHandler.getDefaultInstance());
+ return runWithRetries(callable, RetryParams.defaultInstance(),
+ ExceptionHandler.defaultInstance());
}
public static V runWithRetries(Callable callable, RetryParams params,
diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/RetryParams.java b/gcloud-java-core/src/main/java/com/google/gcloud/RetryParams.java
index 461dbac77ff2..ab3644c6d747 100644
--- a/gcloud-java-core/src/main/java/com/google/gcloud/RetryParams.java
+++ b/gcloud-java-core/src/main/java/com/google/gcloud/RetryParams.java
@@ -38,8 +38,8 @@
* {@code RetryParams}, first create a {@link RetryParams.Builder}. The builder is mutable and each
* of the parameters can be set (any unset parameters will fallback to the defaults). The
* {@code Builder} can be then used to create an immutable {@code RetryParams} object. For default
- * {@code RetryParams} use {@link #getDefaultInstance}. Default settings are subject to change
- * release to release. If you require specific settings, explicitly create an instance of
+ * {@code RetryParams} use {@link #defaultInstance}. Default settings are subject to change release
+ * to release. If you require specific settings, explicitly create an instance of
* {@code RetryParams} with all the required settings.
*
* @see RetryHelper
@@ -91,12 +91,12 @@ private Builder() {
retryDelayBackoffFactor = DEFAULT_RETRY_DELAY_BACKOFF_FACTOR;
totalRetryPeriodMillis = DEFAULT_TOTAL_RETRY_PERIOD_MILLIS;
} else {
- retryMinAttempts = retryParams.getRetryMinAttempts();
- retryMaxAttempts = retryParams.getRetryMaxAttempts();
- initialRetryDelayMillis = retryParams.getInitialRetryDelayMillis();
- maxRetryDelayMillis = retryParams.getMaxRetryDelayMillis();
- retryDelayBackoffFactor = retryParams.getRetryDelayBackoffFactor();
- totalRetryPeriodMillis = retryParams.getTotalRetryPeriodMillis();
+ retryMinAttempts = retryParams.retryMinAttempts();
+ retryMaxAttempts = retryParams.retryMaxAttempts();
+ initialRetryDelayMillis = retryParams.initialRetryDelayMillis();
+ maxRetryDelayMillis = retryParams.maxRetryDelayMillis();
+ retryDelayBackoffFactor = retryParams.retryDelayBackoffFactor();
+ totalRetryPeriodMillis = retryParams.totalRetryPeriodMillis();
}
}
@@ -201,7 +201,7 @@ private RetryParams(Builder builder) {
/**
* Returns an instance with the default parameters.
*/
- public static RetryParams getDefaultInstance() {
+ public static RetryParams defaultInstance() {
return DEFAULT_INSTANCE;
}
@@ -216,14 +216,14 @@ public static RetryParams noRetries() {
/**
* Returns the retryMinAttempts. Default value is {@value #DEFAULT_RETRY_MIN_ATTEMPTS}.
*/
- public int getRetryMinAttempts() {
+ public int retryMinAttempts() {
return retryMinAttempts;
}
/**
* Returns the retryMaxAttempts. Default value is {@value #DEFAULT_RETRY_MAX_ATTEMPTS}.
*/
- public int getRetryMaxAttempts() {
+ public int retryMaxAttempts() {
return retryMaxAttempts;
}
@@ -231,14 +231,14 @@ public int getRetryMaxAttempts() {
* Returns the initialRetryDelayMillis. Default value is
* {@value #DEFAULT_INITIAL_RETRY_DELAY_MILLIS}.
*/
- public long getInitialRetryDelayMillis() {
+ public long initialRetryDelayMillis() {
return initialRetryDelayMillis;
}
/**
* Returns the maxRetryDelayMillis. Default values is {@value #DEFAULT_MAX_RETRY_DELAY_MILLIS}.
*/
- public long getMaxRetryDelayMillis() {
+ public long maxRetryDelayMillis() {
return maxRetryDelayMillis;
}
@@ -246,7 +246,7 @@ public long getMaxRetryDelayMillis() {
* Returns the maxRetryDelayBackoffFactor. Default values is
* {@value #DEFAULT_RETRY_DELAY_BACKOFF_FACTOR}.
*/
- public double getRetryDelayBackoffFactor() {
+ public double retryDelayBackoffFactor() {
return retryDelayBackoffFactor;
}
@@ -254,7 +254,7 @@ public double getRetryDelayBackoffFactor() {
* Returns the totalRetryPeriodMillis. Default value is
* {@value #DEFAULT_TOTAL_RETRY_PERIOD_MILLIS}.
*/
- public long getTotalRetryPeriodMillis() {
+ public long totalRetryPeriodMillis() {
return totalRetryPeriodMillis;
}
diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java
index 1be1f16115ad..0793470ade83 100644
--- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java
+++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java
@@ -17,7 +17,7 @@
package com.google.gcloud;
import static com.google.common.base.MoreObjects.firstNonNull;
-import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.api.client.extensions.appengine.http.UrlFetchTransport;
@@ -30,6 +30,7 @@
import java.io.BufferedReader;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
@@ -305,7 +306,13 @@ public B readTimeout(int readTimeout) {
protected ServiceOptions(Class extends ServiceFactory> serviceFactoryClass,
Class extends ServiceRpcFactory> rpcFactoryClass,
Builder builder) {
- projectId = checkNotNull(builder.projectId != null ? builder.projectId : defaultProject());
+ projectId = builder.projectId != null ? builder.projectId : defaultProject();
+ if (projectIdRequired()) {
+ checkArgument(
+ projectId != null,
+ "A project ID is required for this service but could not be determined from the builder or "
+ + "the environment. Please set a project ID using the builder.");
+ }
host = firstNonNull(builder.host, defaultHost());
httpTransportFactory = firstNonNull(builder.httpTransportFactory,
getFromServiceLoader(HttpTransportFactory.class, DefaultHttpTransportFactory.INSTANCE));
@@ -324,6 +331,16 @@ protected ServiceOptions(Class extends ServiceFactory> ser
clock = firstNonNull(builder.clock, Clock.defaultClock());
}
+ /**
+ * Returns whether a service requires a project ID. This method may be overridden in
+ * service-specific Options objects.
+ *
+ * @return true if a project ID is required to use the service, false if not.
+ */
+ protected boolean projectIdRequired() {
+ return true;
+ }
+
private static AuthCredentials defaultAuthCredentials() {
// Consider App Engine. This will not be needed once issue #21 is fixed.
if (appEngineAppId() != null) {
@@ -387,8 +404,18 @@ protected static String googleCloudProjectId() {
} else {
configDir = new File(System.getProperty("user.home"), ".config/gcloud");
}
- try (BufferedReader reader =
- new BufferedReader(new FileReader(new File(configDir, "properties")))) {
+ FileReader fileReader;
+ try {
+ fileReader = new FileReader(new File(configDir, "configurations/config_default"));
+ } catch (FileNotFoundException newConfigFileNotFoundEx) {
+ try {
+ fileReader = new FileReader(new File(configDir, "properties"));
+ } catch (FileNotFoundException oldConfigFileNotFoundEx) {
+ // return null if we can't find config file
+ return null;
+ }
+ }
+ try (BufferedReader reader = new BufferedReader(fileReader)) {
String line;
String section = null;
Pattern projectPattern = Pattern.compile("^project\\s*=\\s*(.*)$");
@@ -451,6 +478,8 @@ public ServiceRpcT rpc() {
/**
* Returns the project id.
+ *
+ * Return value can be null (for services that don't require a project id).
*/
public String projectId() {
return projectId;
diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/BaseServiceExceptionTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/BaseServiceExceptionTest.java
new file mode 100644
index 000000000000..f30fd3abfb79
--- /dev/null
+++ b/gcloud-java-core/src/test/java/com/google/gcloud/BaseServiceExceptionTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.gcloud;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * Tests for {@link BaseServiceException}.
+ */
+public class BaseServiceExceptionTest {
+
+ private final int code = 1;
+ private final String message = "some message";
+ private final boolean retryable = true;
+
+ @Test
+ public void testBaseServiceException() {
+ BaseServiceException serviceException = new BaseServiceException(code, message, retryable);
+ assertEquals(serviceException.code(), code);
+ assertEquals(serviceException.getMessage(), message);
+ assertEquals(serviceException.getCause(), null);
+
+ Exception cause = new RuntimeException();
+ serviceException = new BaseServiceException(code, message, retryable, cause);
+ assertEquals(serviceException.code(), code);
+ assertEquals(serviceException.getMessage(), message);
+ assertEquals(serviceException.getCause(), cause);
+ }
+}
diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/ExceptionHandlerTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/ExceptionHandlerTest.java
index c182515dbb16..cedc995ddbd0 100644
--- a/gcloud-java-core/src/test/java/com/google/gcloud/ExceptionHandlerTest.java
+++ b/gcloud-java-core/src/test/java/com/google/gcloud/ExceptionHandlerTest.java
@@ -82,7 +82,7 @@ public Object call() throws Error {
}
// using default exception handler (retry upon any non-runtime exceptions)
- ExceptionHandler handler = ExceptionHandler.getDefaultInstance();
+ ExceptionHandler handler = ExceptionHandler.defaultInstance();
assertValidCallable(new A(), handler);
assertValidCallable(new B(), handler);
assertValidCallable(new C(), handler);
diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/PageImplTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/PageImplTest.java
new file mode 100644
index 000000000000..fb289186de8d
--- /dev/null
+++ b/gcloud-java-core/src/test/java/com/google/gcloud/PageImplTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.gcloud;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.collect.ImmutableList;
+
+import org.junit.Test;
+
+import java.util.Collections;
+
+public class PageImplTest {
+
+ private static final ImmutableList VALUES = ImmutableList.of("1", "2");
+ private static final ImmutableList NEXT_VALUES = ImmutableList.of("3", "4");
+ private static final ImmutableList ALL_VALUES = ImmutableList.builder()
+ .addAll(VALUES)
+ .addAll(NEXT_VALUES)
+ .build();
+
+ @Test
+ public void testPage() {
+ final PageImpl nextResult = new PageImpl<>(null, "c", NEXT_VALUES);
+ PageImpl.NextPageFetcher fetcher = new PageImpl.NextPageFetcher() {
+ @Override
+ public PageImpl nextPage() {
+ return nextResult;
+ }
+ };
+ PageImpl result = new PageImpl<>(fetcher, "c", VALUES);
+ assertEquals(nextResult, result.nextPage());
+ assertEquals("c", result.nextPageCursor());
+ assertEquals(VALUES, result.values());
+ }
+
+ @Test
+ public void testIterateAll() {
+ final PageImpl nextResult = new PageImpl<>(null, "c", NEXT_VALUES);
+ PageImpl.NextPageFetcher fetcher = new PageImpl.NextPageFetcher() {
+ @Override
+ public PageImpl nextPage() {
+ return nextResult;
+ }
+ };
+ PageImpl result = new PageImpl<>(fetcher, "c", VALUES);
+ assertEquals(ALL_VALUES, ImmutableList.copyOf(result.iterateAll()));
+ }
+}
diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/RetryHelperTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/RetryHelperTest.java
index dfd933bcae46..9a7cc2104f4a 100644
--- a/gcloud-java-core/src/test/java/com/google/gcloud/RetryHelperTest.java
+++ b/gcloud-java-core/src/test/java/com/google/gcloud/RetryHelperTest.java
@@ -118,13 +118,13 @@ public void testTriesAtLeastMinTimes() {
@Override public Integer call() throws IOException {
timesCalled++;
assertEquals(timesCalled, RetryHelper.getContext().getAttemptNumber());
- assertEquals(10, RetryHelper.getContext().getRetryParams().getRetryMaxAttempts());
+ assertEquals(10, RetryHelper.getContext().getRetryParams().retryMaxAttempts());
if (timesCalled <= timesToFail) {
throw new IOException();
}
return timesCalled;
}
- }, params, ExceptionHandler.getDefaultInstance());
+ }, params, ExceptionHandler.defaultInstance());
assertEquals(timesToFail + 1, attempted);
assertNull(RetryHelper.getContext());
}
diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/RetryParamsTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/RetryParamsTest.java
index d1d5e3c076d8..eae44693929b 100644
--- a/gcloud-java-core/src/test/java/com/google/gcloud/RetryParamsTest.java
+++ b/gcloud-java-core/src/test/java/com/google/gcloud/RetryParamsTest.java
@@ -41,15 +41,15 @@ public class RetryParamsTest {
@Test
public void testDefaults() {
- RetryParams params1 = RetryParams.getDefaultInstance();
+ RetryParams params1 = RetryParams.defaultInstance();
RetryParams params2 = RetryParams.builder().build();
for (RetryParams params : Arrays.asList(params1, params2)) {
- assertEquals(DEFAULT_INITIAL_RETRY_DELAY_MILLIS, params.getInitialRetryDelayMillis());
- assertEquals(DEFAULT_MAX_RETRY_DELAY_MILLIS, params.getMaxRetryDelayMillis());
- assertEquals(DEFAULT_RETRY_DELAY_BACKOFF_FACTOR, params.getRetryDelayBackoffFactor(), 0);
- assertEquals(DEFAULT_RETRY_MAX_ATTEMPTS, params.getRetryMaxAttempts());
- assertEquals(DEFAULT_RETRY_MIN_ATTEMPTS, params.getRetryMinAttempts());
- assertEquals(DEFAULT_TOTAL_RETRY_PERIOD_MILLIS, params.getTotalRetryPeriodMillis());
+ assertEquals(DEFAULT_INITIAL_RETRY_DELAY_MILLIS, params.initialRetryDelayMillis());
+ assertEquals(DEFAULT_MAX_RETRY_DELAY_MILLIS, params.maxRetryDelayMillis());
+ assertEquals(DEFAULT_RETRY_DELAY_BACKOFF_FACTOR, params.retryDelayBackoffFactor(), 0);
+ assertEquals(DEFAULT_RETRY_MAX_ATTEMPTS, params.retryMaxAttempts());
+ assertEquals(DEFAULT_RETRY_MIN_ATTEMPTS, params.retryMinAttempts());
+ assertEquals(DEFAULT_TOTAL_RETRY_PERIOD_MILLIS, params.totalRetryPeriodMillis());
}
}
@@ -65,12 +65,12 @@ public void testSetAndCopy() {
RetryParams params1 = builder.build();
RetryParams params2 = new RetryParams.Builder(params1).build();
for (RetryParams params : Arrays.asList(params1, params2)) {
- assertEquals(101, params.getInitialRetryDelayMillis());
- assertEquals(102, params.getMaxRetryDelayMillis());
- assertEquals(103, params.getRetryDelayBackoffFactor(), 0);
- assertEquals(107, params.getRetryMinAttempts());
- assertEquals(108, params.getRetryMaxAttempts());
- assertEquals(109, params.getTotalRetryPeriodMillis());
+ assertEquals(101, params.initialRetryDelayMillis());
+ assertEquals(102, params.maxRetryDelayMillis());
+ assertEquals(103, params.retryDelayBackoffFactor(), 0);
+ assertEquals(107, params.retryMinAttempts());
+ assertEquals(108, params.retryMaxAttempts());
+ assertEquals(109, params.totalRetryPeriodMillis());
}
}
@@ -79,19 +79,19 @@ public void testBadSettings() {
RetryParams.Builder builder = RetryParams.builder();
builder.initialRetryDelayMillis(-1);
builder = assertFailure(builder);
- builder.maxRetryDelayMillis(RetryParams.getDefaultInstance().getInitialRetryDelayMillis() - 1);
+ builder.maxRetryDelayMillis(RetryParams.defaultInstance().initialRetryDelayMillis() - 1);
builder = assertFailure(builder);
builder.retryDelayBackoffFactor(-1);
builder = assertFailure(builder);
builder.retryMinAttempts(-1);
builder = assertFailure(builder);
- builder.retryMaxAttempts(RetryParams.getDefaultInstance().getRetryMinAttempts() - 1);
+ builder.retryMaxAttempts(RetryParams.defaultInstance().retryMinAttempts() - 1);
builder = assertFailure(builder);
builder.totalRetryPeriodMillis(-1);
builder = assertFailure(builder);
// verify that it is OK for min and max to be equal
- builder.retryMaxAttempts(RetryParams.getDefaultInstance().getRetryMinAttempts());
- builder.maxRetryDelayMillis(RetryParams.getDefaultInstance().getInitialRetryDelayMillis());
+ builder.retryMaxAttempts(RetryParams.defaultInstance().retryMinAttempts());
+ builder.maxRetryDelayMillis(RetryParams.defaultInstance().initialRetryDelayMillis());
builder.build();
}
diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md
index bbcdd9d8857c..6d9fc0e8c4d6 100644
--- a/gcloud-java-datastore/README.md
+++ b/gcloud-java-datastore/README.md
@@ -15,14 +15,22 @@ Java idiomatic client for [Google Cloud Datastore] (https://cloud.google.com/dat
Quickstart
----------
-Add this to your pom.xml file
+If you are using Maven, add this to your pom.xml file
```xml
com.google.gcloudgcloud-java-datastore
- 0.0.10
+ 0.0.11
```
+If you are using Gradle, add this to your dependencies
+```Groovy
+compile 'com.google.gcloud:gcloud-java-datastore:jar:0.0.11'
+```
+If you are using SBT, add this to your dependencies
+```Scala
+libraryDependencies += "com.google.gcloud" % "gcloud-java-datastore" % "0.0.11"
+```
Example Application
--------------------
@@ -58,7 +66,7 @@ import com.google.gcloud.datastore.Entity;
import com.google.gcloud.datastore.Key;
import com.google.gcloud.datastore.KeyFactory;
-Datastore datastore = DatastoreOptions.getDefaultInstance().service();
+Datastore datastore = DatastoreOptions.defaultInstance().service();
KeyFactory keyFactory = datastore.newKeyFactory().kind(KIND);
Key key = keyFactory.newKey(keyName);
Entity entity = datastore.get(key);
diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml
index c7c57d91ae1d..b58e9e0ffc74 100644
--- a/gcloud-java-datastore/pom.xml
+++ b/gcloud-java-datastore/pom.xml
@@ -11,7 +11,7 @@
com.google.gcloudgcloud-java-pom
- 0.0.11-SNAPSHOT
+ 0.0.12-SNAPSHOTgcloud-java-datastore
diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java
index 562578a26428..dded1d11875e 100644
--- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java
+++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java
@@ -18,6 +18,7 @@
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableMap;
+import com.google.gcloud.BaseServiceException;
import com.google.gcloud.RetryHelper;
import com.google.gcloud.RetryHelper.RetryHelperException;
import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException;
@@ -26,21 +27,21 @@
import java.util.HashMap;
import java.util.Map;
-public class DatastoreException extends RuntimeException {
+public class DatastoreException extends BaseServiceException {
- private static final long serialVersionUID = 8170357898917041899L;
- private static final ImmutableMap REASON_TO_CODE;
- private static final ImmutableMap HTTP_TO_CODE;
+ private static final long serialVersionUID = -2336749234060754893L;
+ private static final ImmutableMap REASON_TO_ERROR;
+ private static final ImmutableMap HTTP_TO_ERROR;
- private final Code code;
+ private final DatastoreError error;
/**
- * An error code to represent the failure.
+ * Represents Datastore errors.
*
* @see Google Cloud
* Datastore error codes
*/
- public enum Code {
+ public enum DatastoreError {
ABORTED(Reason.ABORTED),
DEADLINE_EXCEEDED(Reason.DEADLINE_EXCEEDED),
@@ -57,29 +58,25 @@ public enum Code {
private final String description;
private final int httpStatus;
- Code(Reason reason) {
+ DatastoreError(Reason reason) {
this(reason.retryable(), reason.description(), reason.httpStatus());
}
- Code(boolean retryable, String description, int httpStatus) {
+ DatastoreError(boolean retryable, String description, int httpStatus) {
this.retryable = retryable;
this.description = description;
this.httpStatus = httpStatus;
}
- public String description() {
+ String description() {
return description;
}
- public int httpStatus() {
+ int httpStatus() {
return httpStatus;
}
- /**
- * Returns {@code true} if this exception is transient and the same request could be retried.
- * For any retry it is highly recommended to apply an exponential backoff.
- */
- public boolean retryable() {
+ boolean retryable() {
return retryable;
}
@@ -89,30 +86,31 @@ DatastoreException translate(DatastoreRpcException exception, String message) {
}
static {
- ImmutableMap.Builder builder = ImmutableMap.builder();
- Map httpCodes = new HashMap<>();
- for (Code code : Code.values()) {
- builder.put(code.name(), code);
- httpCodes.put(code.httpStatus(), code);
+ ImmutableMap.Builder builder = ImmutableMap.builder();
+ Map httpCodes = new HashMap<>();
+ for (DatastoreError error : DatastoreError.values()) {
+ builder.put(error.name(), error);
+ httpCodes.put(error.httpStatus(), error);
}
- REASON_TO_CODE = builder.build();
- HTTP_TO_CODE = ImmutableMap.copyOf(httpCodes);
+ REASON_TO_ERROR = builder.build();
+ HTTP_TO_ERROR = ImmutableMap.copyOf(httpCodes);
}
- public DatastoreException(Code code, String message, Exception cause) {
- super(MoreObjects.firstNonNull(message, code.description), cause);
- this.code = code;
+ public DatastoreException(DatastoreError error, String message, Exception cause) {
+ super(error.httpStatus(), MoreObjects.firstNonNull(message, error.description),
+ error.retryable(), cause);
+ this.error = error;
}
- public DatastoreException(Code code, String message) {
- this(code, message, null);
+ public DatastoreException(DatastoreError error, String message) {
+ this(error, message, null);
}
/**
- * Returns the code associated with this exception.
+ * Returns the DatastoreError associated with this exception.
*/
- public Code code() {
- return code;
+ public DatastoreError datastoreError() {
+ return error;
}
static DatastoreException translateAndThrow(RetryHelperException ex) {
@@ -122,35 +120,36 @@ static DatastoreException translateAndThrow(RetryHelperException ex) {
if (ex instanceof RetryHelper.RetryInterruptedException) {
RetryHelper.RetryInterruptedException.propagate();
}
- throw new DatastoreException(Code.UNKNOWN, ex.getMessage(), ex);
+ throw new DatastoreException(DatastoreError.UNKNOWN, ex.getMessage(), ex);
}
/**
- * Translate DatastoreException to DatastoreException based on their
+ * Translate DatastoreRpcExceptions to DatastoreExceptions based on their
* HTTP error codes. This method will always throw a new DatastoreException.
*
* @throws DatastoreException every time
*/
static DatastoreException translateAndThrow(DatastoreRpcException exception) {
String message = exception.getMessage();
- Code code = REASON_TO_CODE.get(exception.reason());
- if (code == null) {
- code = MoreObjects.firstNonNull(HTTP_TO_CODE.get(exception.httpStatus()), Code.UNKNOWN);
+ DatastoreError error = REASON_TO_ERROR.get(exception.reason());
+ if (error == null) {
+ error = MoreObjects.firstNonNull(
+ HTTP_TO_ERROR.get(exception.httpStatus()), DatastoreError.UNKNOWN);
}
- throw code.translate(exception, message);
+ throw error.translate(exception, message);
}
/**
- * Throw a DatastoreException with {@code FAILED_PRECONDITION} code and the {@code message}
+ * Throw a DatastoreException with {@code FAILED_PRECONDITION} error and the {@code message}
* in a nested exception.
*
* @throws DatastoreException every time
*/
static DatastoreException throwInvalidRequest(String massage, Object... params) {
- throw new DatastoreException(Code.FAILED_PRECONDITION, String.format(massage, params));
+ throw new DatastoreException(DatastoreError.FAILED_PRECONDITION, String.format(massage, params));
}
static DatastoreException propagateUserException(Exception ex) {
- throw new DatastoreException(Code.UNKNOWN, ex.getMessage(), ex);
+ throw new DatastoreException(DatastoreError.UNKNOWN, ex.getMessage(), ex);
}
}
diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java
index 5338c03a6d56..ee15393a8048 100644
--- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java
+++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java
@@ -171,6 +171,13 @@ public String namespace() {
return namespace;
}
+ /**
+ * Returns a default {@code DatastoreOptions} instance.
+ */
+ public static DatastoreOptions defaultInstance() {
+ return builder().build();
+ }
+
private static String defaultNamespace() {
try {
Class> clazz = Class.forName("com.google.appengine.api.NamespaceManager");
diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java
index a64a3531c19d..9ad836b15a4e 100644
--- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java
+++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java
@@ -19,7 +19,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
-import com.google.gcloud.datastore.DatastoreException.Code;
+import com.google.gcloud.datastore.DatastoreException.DatastoreError;
import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException;
import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason;
@@ -28,16 +28,16 @@
public class DatastoreExceptionTest {
@Test
- public void testCode() throws Exception {
+ public void testDatastoreError() throws Exception {
for (Reason reason : Reason.values()) {
- Code code = Code.valueOf(reason.name());
- assertEquals(reason.retryable(), code.retryable());
- assertEquals(reason.description(), code.description());
- assertEquals(reason.httpStatus(), code.httpStatus());
+ DatastoreError error = DatastoreError.valueOf(reason.name());
+ assertEquals(reason.retryable(), error.retryable());
+ assertEquals(reason.description(), error.description());
+ assertEquals(reason.httpStatus(), error.httpStatus());
}
- DatastoreException exception = new DatastoreException(Code.ABORTED, "bla");
- assertEquals(Code.ABORTED, exception.code());
+ DatastoreException exception = new DatastoreException(DatastoreError.ABORTED, "bla");
+ assertEquals(DatastoreError.ABORTED, exception.datastoreError());
}
@Test
@@ -47,7 +47,7 @@ public void testTranslateAndThrow() throws Exception {
DatastoreException.translateAndThrow(new DatastoreRpcException(reason));
fail("Exception expected");
} catch (DatastoreException ex) {
- assertEquals(reason.name(), ex.code().name());
+ assertEquals(reason.name(), ex.datastoreError().name());
}
}
}
@@ -58,7 +58,7 @@ public void testThrowInvalidRequest() throws Exception {
DatastoreException.throwInvalidRequest("message %s %d", "a", 1);
fail("Exception expected");
} catch (DatastoreException ex) {
- assertEquals(Code.FAILED_PRECONDITION, ex.code());
+ assertEquals(DatastoreError.FAILED_PRECONDITION, ex.datastoreError());
assertEquals("message a 1", ex.getMessage());
}
}
diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java
index f639ca3fdac0..162104c0dd84 100644
--- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java
+++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java
@@ -197,7 +197,7 @@ public void testTransactionWithRead() {
transaction.commit();
fail("Expecting a failure");
} catch (DatastoreException expected) {
- assertEquals(DatastoreException.Code.ABORTED, expected.code());
+ assertEquals(DatastoreException.DatastoreError.ABORTED, expected.datastoreError());
}
}
@@ -225,7 +225,7 @@ public void testTransactionWithQuery() {
transaction.commit();
fail("Expecting a failure");
} catch (DatastoreException expected) {
- assertEquals(DatastoreException.Code.ABORTED, expected.code());
+ assertEquals(DatastoreException.DatastoreError.ABORTED, expected.datastoreError());
}
}
@@ -625,7 +625,7 @@ private Datastore createDatastoreForDeferredLookup() throws DatastoreRpcExceptio
EasyMock.replay(rpcFactoryMock, rpcMock);
DatastoreOptions options =
this.options.toBuilder()
- .retryParams(RetryParams.getDefaultInstance())
+ .retryParams(RetryParams.defaultInstance())
.serviceRpcFactory(rpcFactoryMock)
.build();
return options.service();
@@ -738,7 +738,7 @@ public void testRetryableException() throws Exception {
.andReturn(responsePb);
EasyMock.replay(rpcFactoryMock, rpcMock);
DatastoreOptions options = this.options.toBuilder()
- .retryParams(RetryParams.getDefaultInstance())
+ .retryParams(RetryParams.defaultInstance())
.serviceRpcFactory(rpcFactoryMock)
.build();
Datastore datastore = options.service();
@@ -784,7 +784,7 @@ public void testRuntimeException() throws Exception {
.andThrow(new RuntimeException(exceptionMessage));
EasyMock.replay(rpcFactoryMock, rpcMock);
DatastoreOptions options = this.options.toBuilder()
- .retryParams(RetryParams.getDefaultInstance())
+ .retryParams(RetryParams.defaultInstance())
.serviceRpcFactory(rpcFactoryMock)
.build();
Datastore datastore = options.service();
diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java
index 1ad690938ef5..32e14fb47ea0 100644
--- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java
+++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java
@@ -143,7 +143,7 @@ public void testServiceOptions() throws Exception {
options = options.toBuilder()
.namespace("ns1")
- .retryParams(RetryParams.getDefaultInstance())
+ .retryParams(RetryParams.defaultInstance())
.authCredentials(AuthCredentials.noCredentials())
.force(true)
.build();
diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md
index 366acd5de929..bc738de41b51 100644
--- a/gcloud-java-examples/README.md
+++ b/gcloud-java-examples/README.md
@@ -12,14 +12,22 @@ Examples for gcloud-java (Java idiomatic client for [Google Cloud Platform][clou
Quickstart
----------
-Add this to your pom.xml file
+If you are using Maven, add this to your pom.xml file
```xml
com.google.gcloudgcloud-java-examples
- 0.0.10
+ 0.0.11
```
+If you are using Gradle, add this to your dependencies
+```Groovy
+compile 'com.google.gcloud:gcloud-java-examples:jar:0.0.11'
+```
+If you are using SBT, add this to your dependencies
+```Scala
+libraryDependencies += "com.google.gcloud" % "gcloud-java-examples" % "0.0.11"
+```
To run examples from your command line:
diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml
index 55548e756be3..c461846acab2 100644
--- a/gcloud-java-examples/pom.xml
+++ b/gcloud-java-examples/pom.xml
@@ -11,7 +11,7 @@
com.google.gcloudgcloud-java-pom
- 0.0.11-SNAPSHOT
+ 0.0.12-SNAPSHOTgcloud-java-examples
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/StorageExample.java
index fb207023203f..0e7d6bbbf3ea 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/StorageExample.java
@@ -52,6 +52,7 @@
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -213,8 +214,9 @@ String parse(String... args) {
public void run(Storage storage, String bucketName) {
if (bucketName == null) {
// list buckets
- for (BucketInfo b : storage.list()) {
- System.out.println(b);
+ Iterator bucketInfoIterator = storage.list().iterateAll();
+ while (bucketInfoIterator.hasNext()) {
+ System.out.println(bucketInfoIterator.next());
}
} else {
// list a bucket's blobs
@@ -223,8 +225,9 @@ public void run(Storage storage, String bucketName) {
System.out.println("No such bucket");
return;
}
- for (Blob b : bucket.list()) {
- System.out.println(b.info());
+ Iterator blobIterator = bucket.list().iterateAll();
+ while (blobIterator.hasNext()) {
+ System.out.println(blobIterator.next().info());
}
}
}
@@ -542,7 +545,7 @@ public static void main(String... args) throws Exception {
return;
}
StorageOptions.Builder optionsBuilder =
- StorageOptions.builder().retryParams(RetryParams.getDefaultInstance());
+ StorageOptions.builder().retryParams(RetryParams.defaultInstance());
StorageAction action;
String actionName;
if (args.length >= 2 && !ACTIONS.containsKey(args[0])) {
diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md
index 717fd1f1f3e4..f2b99388ff0f 100644
--- a/gcloud-java-storage/README.md
+++ b/gcloud-java-storage/README.md
@@ -15,14 +15,22 @@ Java idiomatic client for [Google Cloud Storage] (https://cloud.google.com/stora
Quickstart
----------
-Add this to your pom.xml file
+If you are using Maven, add this to your pom.xml file
```xml
com.google.gcloudgcloud-java-storage
- 0.0.10
+ 0.0.11
```
+If you are using Gradle, add this to your dependencies
+```Groovy
+compile 'com.google.gcloud:gcloud-java-storage:jar:0.0.11'
+```
+If you are using SBT, add this to your dependencies
+```Scala
+libraryDependencies += "com.google.gcloud" % "gcloud-java-storage" % "0.0.11"
+```
Example Application
-------------------
diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml
index 82b67277f4fe..ef3ddec79816 100644
--- a/gcloud-java-storage/pom.xml
+++ b/gcloud-java-storage/pom.xml
@@ -11,7 +11,7 @@
com.google.gcloudgcloud-java-pom
- 0.0.11-SNAPSHOT
+ 0.0.12-SNAPSHOTgcloud-java-storage
diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java
index 70cad8c7773e..b1e188f1d1fb 100644
--- a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java
+++ b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java
@@ -15,6 +15,7 @@
package com.google.gcloud.spi;
import static com.google.gcloud.spi.StorageRpc.Option.DELIMITER;
+import static com.google.gcloud.spi.StorageRpc.Option.FIELDS;
import static com.google.gcloud.spi.StorageRpc.Option.IF_GENERATION_MATCH;
import static com.google.gcloud.spi.StorageRpc.Option.IF_GENERATION_NOT_MATCH;
import static com.google.gcloud.spi.StorageRpc.Option.IF_METAGENERATION_MATCH;
@@ -150,6 +151,7 @@ public Tuple> list(Map