diff --git a/RobustaSettings.xml b/RobustaSettings.xml
deleted file mode 100644
index 8c664c57feb7..000000000000
--- a/RobustaSettings.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/gcloud-java-core/README.md b/gcloud-java-core/README.md
new file mode 100644
index 000000000000..aa8d4304f1fb
--- /dev/null
+++ b/gcloud-java-core/README.md
@@ -0,0 +1,55 @@
+Google Cloud Java Client
+==========================
+
+Java idiomatic client for [Google Cloud Platform][cloud-platform] services.
+
+[](https://travis-ci.org/GoogleCloudPlatform/gcloud-java)
+[](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master)
+
+- [Homepage] (https://googlecloudplatform.github.io/gcloud-java/)
+- [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs)
+- [Examples] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/examples/package-summary.html)
+
+This module provides common functionality and is required by the other service specific modules.
+
+Quickstart
+----------
+Add this to your pom.xml file
+```xml
+
+ com.google.gcloud
+ gcloud-java-core
+ LATEST
+
+```
+
+Contributing
+------------
+
+Contributions to this library are always welcome and highly encouraged.
+
+See [CONTRIBUTING] for more information on how to get started.
+
+Java Versions
+-------------
+
+Java 7 or above is required for using this client.
+
+Versioning
+----------
+
+This library follows [Semantic Versioning] (http://semver.org/).
+
+It is currently in major version zero (``0.y.z``), which means that anything
+may change at any time and the public API should not be considered
+stable.
+
+License
+-------
+
+Apache 2.0 - See [LICENSE] for more information.
+
+
+[CONTRIBUTING]:https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/CONTRIBUTING.md
+[LICENSE]: https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/LICENSE
+[cloud-platform]: https://cloud.google.com/
diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml
new file mode 100644
index 000000000000..78baf824c080
--- /dev/null
+++ b/gcloud-java-core/pom.xml
@@ -0,0 +1,94 @@
+
+
+ 4.0.0
+ com.google.gcloud
+ gcloud-java-core
+ jar
+ GCloud Java core
+ https://github.com/GoogleCloudPlatform/gcloud-java
+
+ Core module for the gcloud-java.
+
+
+ com.google.gcloud
+ gcloud-java-pom
+ 0.0.5
+
+
+
+ com.google.auth
+ google-auth-library-credentials
+ 0.1.0
+
+
+ com.google.auth
+ google-auth-library-oauth2-http
+ 0.1.0
+
+
+ com.google.http-client
+ google-http-client
+ 1.19.0
+ compile
+
+
+ com.google.oauth-client
+ google-oauth-client
+ 1.19.0
+ compile
+
+
+ com.google.guava
+ guava
+ 18.0
+
+
+ com.google.api-client
+ google-api-client-appengine
+ 1.20.0
+ compile
+
+
+ guava-jdk5
+ com.google.guava
+
+
+
+
+ com.google.http-client
+ google-http-client-jackson
+ 1.20.0
+ compile
+
+
+ guava-jdk5
+ com.google.guava
+
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ joda-time
+ joda-time
+ RELEASE
+ compile
+
+
+ org.json
+ json
+ 20090211
+ compile
+
+
+ org.easymock
+ easymock
+ 3.3
+ test
+
+
+
diff --git a/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java
similarity index 100%
rename from src/main/java/com/google/gcloud/AuthCredentials.java
rename to gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java
diff --git a/src/main/java/com/google/gcloud/BaseService.java b/gcloud-java-core/src/main/java/com/google/gcloud/BaseService.java
similarity index 100%
rename from src/main/java/com/google/gcloud/BaseService.java
rename to gcloud-java-core/src/main/java/com/google/gcloud/BaseService.java
diff --git a/src/main/java/com/google/gcloud/ExceptionHandler.java b/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java
similarity index 100%
rename from src/main/java/com/google/gcloud/ExceptionHandler.java
rename to gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java
diff --git a/src/main/java/com/google/gcloud/RetryHelper.java b/gcloud-java-core/src/main/java/com/google/gcloud/RetryHelper.java
similarity index 100%
rename from src/main/java/com/google/gcloud/RetryHelper.java
rename to gcloud-java-core/src/main/java/com/google/gcloud/RetryHelper.java
diff --git a/src/main/java/com/google/gcloud/RetryParams.java b/gcloud-java-core/src/main/java/com/google/gcloud/RetryParams.java
similarity index 100%
rename from src/main/java/com/google/gcloud/RetryParams.java
rename to gcloud-java-core/src/main/java/com/google/gcloud/RetryParams.java
diff --git a/src/main/java/com/google/gcloud/Service.java b/gcloud-java-core/src/main/java/com/google/gcloud/Service.java
similarity index 100%
rename from src/main/java/com/google/gcloud/Service.java
rename to gcloud-java-core/src/main/java/com/google/gcloud/Service.java
diff --git a/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java
similarity index 95%
rename from src/main/java/com/google/gcloud/ServiceOptions.java
rename to gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java
index 448b617372b0..a974a1f1912a 100644
--- a/src/main/java/com/google/gcloud/ServiceOptions.java
+++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java
@@ -25,6 +25,7 @@
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
+import com.google.common.collect.Iterables;
import com.google.gcloud.spi.ServiceRpcFactory;
import java.io.BufferedReader;
@@ -39,6 +40,7 @@
import java.net.URL;
import java.util.Locale;
import java.util.Objects;
+import java.util.ServiceLoader;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -311,4 +313,13 @@ protected boolean isEquals(ServiceOptions other) {
}
public abstract Builder toBuilder();
+
+ /**
+ * Creates a service RPC using a factory loaded by {@link ServiceLoader}.
+ */
+ protected static > R createRpc(O options,
+ Class extends ServiceRpcFactory> factoryClass) {
+ ServiceRpcFactory factory = Iterables.getFirst(ServiceLoader.load(factoryClass), null);
+ return factory == null ? null : factory.create(options);
+ }
}
diff --git a/src/main/java/com/google/gcloud/spi/ServiceRpcFactory.java b/gcloud-java-core/src/main/java/com/google/gcloud/spi/ServiceRpcFactory.java
similarity index 71%
rename from src/main/java/com/google/gcloud/spi/ServiceRpcFactory.java
rename to gcloud-java-core/src/main/java/com/google/gcloud/spi/ServiceRpcFactory.java
index a16d11217bb1..e8e67615305d 100644
--- a/src/main/java/com/google/gcloud/spi/ServiceRpcFactory.java
+++ b/gcloud-java-core/src/main/java/com/google/gcloud/spi/ServiceRpcFactory.java
@@ -1 +1 @@
-/*
* 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.spi;
import com.google.gcloud.ServiceOptions;
import java.io.Serializable;
public interface ServiceRpcFactory extends Serializable {
S create(O options);
}
\ No newline at end of file
+/*
* 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.spi;
import com.google.gcloud.ServiceOptions;
import java.io.Serializable;
/**
* A base interface for all service RPC factories.
* Loading of a factory implementation is done via {@link java.util.ServiceLoader}.
*/
public interface ServiceRpcFactory extends Serializable {
S create(O options);
}
\ No newline at end of file
diff --git a/src/test/java/com/google/gcloud/ExceptionHandlerTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/ExceptionHandlerTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/ExceptionHandlerTest.java
rename to gcloud-java-core/src/test/java/com/google/gcloud/ExceptionHandlerTest.java
diff --git a/src/test/java/com/google/gcloud/RetryHelperTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/RetryHelperTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/RetryHelperTest.java
rename to gcloud-java-core/src/test/java/com/google/gcloud/RetryHelperTest.java
diff --git a/src/test/java/com/google/gcloud/RetryParamsTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/RetryParamsTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/RetryParamsTest.java
rename to gcloud-java-core/src/test/java/com/google/gcloud/RetryParamsTest.java
diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md
new file mode 100644
index 000000000000..96d8075706e9
--- /dev/null
+++ b/gcloud-java-datastore/README.md
@@ -0,0 +1,106 @@
+Google Cloud Java Client
+==========================
+
+Java idiomatic client for [Google Cloud Platform][cloud-platform] services.
+
+[](https://travis-ci.org/GoogleCloudPlatform/gcloud-java)
+[](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master)
+
+- [Homepage] (https://googlecloudplatform.github.io/gcloud-java/)
+- [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs)
+- [Examples] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/examples/package-summary.html)
+
+This client supports [Google Cloud Datastore] (https://cloud.google.com/datastore/)
+
+
+> Note: This client is a work-in-progress, and may occasionally
+> make backwards-incompatible changes.
+
+Quickstart
+----------
+Add this to your pom.xml file
+```xml
+
+ com.google.gcloud
+ gcloud-java-datastore
+ LATEST
+
+```
+
+Google [Cloud Datastore][cloud-datastore] is a fully managed, schemaless database for
+storing non-relational data. Cloud Datastore automatically scales with
+your users and supports ACID transactions, high availability of reads and
+writes, strong consistency for reads and ancestor queries, and eventual
+consistency for all other queries.
+
+See the [Google Cloud Datastore docs][cloud-datastore-activation] for more details on how to activate
+Cloud Datastore for your project.
+
+See the ``gcloud-java`` API [datastore documentation][datastore-api] to learn how to interact
+with the Cloud Datastore using this Client Library.
+
+```java
+import com.google.gcloud.datastore.DatastoreService;
+import com.google.gcloud.datastore.DatastoreServiceFactory;
+import com.google.gcloud.datastore.DatastoreServiceOptions;
+import com.google.gcloud.datastore.DateTime;
+import com.google.gcloud.datastore.Entity;
+import com.google.gcloud.datastore.Key;
+import com.google.gcloud.datastore.KeyFactory;
+
+DatastoreServiceOptions options = DatastoreServiceOptions.builder().projectId(PROJECT_ID).build();
+DatastoreService datastore = DatastoreServiceFactory.instance().get(options);
+KeyFactory keyFactory = datastore.newKeyFactory().kind(KIND);
+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 {
+ System.out.println("Updating access_time for " + entity.getString("name"));
+ entity = Entity.builder(entity)
+ .set("access_time", DateTime.now())
+ .build();
+ datastore.update(entity);
+}
+```
+
+Contributing
+------------
+
+Contributions to this library are always welcome and highly encouraged.
+
+See [CONTRIBUTING] for more information on how to get started.
+
+Java Versions
+-------------
+
+Java 7 or above is required for using this client.
+
+Versioning
+----------
+
+This library follows [Semantic Versioning] (http://semver.org/).
+
+It is currently in major version zero (``0.y.z``), which means that anything
+may change at any time and the public API should not be considered
+stable.
+
+License
+-------
+
+Apache 2.0 - See [LICENSE] for more information.
+
+
+[CONTRIBUTING]:https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/CONTRIBUTING.md
+[LICENSE]: https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/LICENSE
+[cloud-platform]: https://cloud.google.com/
+[cloud-datastore]: https://cloud.google.com/datastore/docs
+[cloud-datastore-docs]: https://cloud.google.com/datastore/docs
+[cloud-datastore-activation]: https://cloud.google.com/datastore/docs/activate
+[datastore-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/datastore/package-summary.html
+
diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml
new file mode 100644
index 000000000000..b890e6d2b755
--- /dev/null
+++ b/gcloud-java-datastore/pom.xml
@@ -0,0 +1,47 @@
+
+
+ 4.0.0
+ com.google.gcloud
+ gcloud-java-datastore
+ jar
+ GCloud Java datastore
+ https://github.com/GoogleCloudPlatform/gcloud-java
+
+ Java idiomatic client for Google Cloud Datastore.
+
+
+ com.google.gcloud
+ gcloud-java-pom
+ 0.0.5
+
+
+
+ ${project.groupId}
+ gcloud-java-core
+ ${project.version}
+
+
+ com.google.apis
+ google-api-services-datastore-protobuf
+ v1beta2-rev1-2.1.2
+ compile
+
+
+ com.google.apis
+ google-api-services-datastore
+ v1beta2-rev23-1.19.0
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.easymock
+ easymock
+ 3.3
+ test
+
+
+
diff --git a/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java
diff --git a/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/BaseEntity.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java
diff --git a/src/main/java/com/google/gcloud/datastore/BaseKey.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/BaseKey.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java
diff --git a/src/main/java/com/google/gcloud/datastore/Batch.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Batch.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/Batch.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Batch.java
diff --git a/src/main/java/com/google/gcloud/datastore/BatchImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/BatchImpl.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java
diff --git a/src/main/java/com/google/gcloud/datastore/BatchOption.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchOption.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/BatchOption.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchOption.java
diff --git a/src/main/java/com/google/gcloud/datastore/Blob.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Blob.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/Blob.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Blob.java
diff --git a/src/main/java/com/google/gcloud/datastore/BlobValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BlobValue.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/BlobValue.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BlobValue.java
diff --git a/src/main/java/com/google/gcloud/datastore/BooleanValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BooleanValue.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/BooleanValue.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BooleanValue.java
diff --git a/src/main/java/com/google/gcloud/datastore/Cursor.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Cursor.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/Cursor.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Cursor.java
diff --git a/src/main/java/com/google/gcloud/datastore/DatastoreBatchWriter.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreBatchWriter.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/DatastoreBatchWriter.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreBatchWriter.java
diff --git a/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/DatastoreHelper.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java
diff --git a/src/main/java/com/google/gcloud/datastore/DatastoreReader.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/DatastoreReader.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java
diff --git a/src/main/java/com/google/gcloud/datastore/DatastoreReaderWriter.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReaderWriter.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/DatastoreReaderWriter.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReaderWriter.java
diff --git a/src/main/java/com/google/gcloud/datastore/DatastoreService.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreService.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/DatastoreService.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreService.java
diff --git a/src/main/java/com/google/gcloud/datastore/DatastoreServiceException.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreServiceException.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/DatastoreServiceException.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreServiceException.java
diff --git a/src/main/java/com/google/gcloud/datastore/DatastoreServiceFactory.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreServiceFactory.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/DatastoreServiceFactory.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreServiceFactory.java
diff --git a/src/main/java/com/google/gcloud/datastore/DatastoreServiceImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreServiceImpl.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/DatastoreServiceImpl.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreServiceImpl.java
diff --git a/src/main/java/com/google/gcloud/datastore/DatastoreServiceOptions.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreServiceOptions.java
similarity index 96%
rename from src/main/java/com/google/gcloud/datastore/DatastoreServiceOptions.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreServiceOptions.java
index f7b1965d0b29..e0dba7b7a982 100644
--- a/src/main/java/com/google/gcloud/datastore/DatastoreServiceOptions.java
+++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreServiceOptions.java
@@ -26,7 +26,8 @@
import com.google.gcloud.ServiceOptions;
import com.google.gcloud.spi.DatastoreRpc;
import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException;
-import com.google.gcloud.spi.ServiceRpcProvider;
+import com.google.gcloud.spi.DatastoreRpcFactory;
+import com.google.gcloud.spi.DefaultDatastoreRpc;
import java.lang.reflect.Method;
import java.util.Iterator;
@@ -185,7 +186,10 @@ DatastoreRpc datastoreRpc() {
if (serviceRpcFactory() != null) {
datastoreRpc = serviceRpcFactory().create(this);
} else {
- datastoreRpc = ServiceRpcProvider.datastore(this);
+ datastoreRpc = createRpc(this, DatastoreRpcFactory.class);
+ if (datastoreRpc == null) {
+ datastoreRpc = new DefaultDatastoreRpc(this);
+ }
}
return datastoreRpc;
}
diff --git a/src/main/java/com/google/gcloud/datastore/DatastoreWriter.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreWriter.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/DatastoreWriter.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreWriter.java
diff --git a/src/main/java/com/google/gcloud/datastore/DateTime.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/DateTime.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java
diff --git a/src/main/java/com/google/gcloud/datastore/DateTimeValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTimeValue.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/DateTimeValue.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTimeValue.java
diff --git a/src/main/java/com/google/gcloud/datastore/DoubleValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/DoubleValue.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java
diff --git a/src/main/java/com/google/gcloud/datastore/Entity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Entity.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/Entity.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Entity.java
diff --git a/src/main/java/com/google/gcloud/datastore/EntityValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/EntityValue.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java
diff --git a/src/main/java/com/google/gcloud/datastore/FullEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/FullEntity.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/FullEntity.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/FullEntity.java
diff --git a/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/GqlQuery.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java
diff --git a/src/main/java/com/google/gcloud/datastore/IncompleteKey.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/IncompleteKey.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java
diff --git a/src/main/java/com/google/gcloud/datastore/Key.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Key.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/Key.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Key.java
diff --git a/src/main/java/com/google/gcloud/datastore/KeyFactory.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/KeyFactory.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java
diff --git a/src/main/java/com/google/gcloud/datastore/KeyValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyValue.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/KeyValue.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyValue.java
diff --git a/src/main/java/com/google/gcloud/datastore/ListValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/ListValue.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java
diff --git a/src/main/java/com/google/gcloud/datastore/LongValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LongValue.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/LongValue.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LongValue.java
diff --git a/src/main/java/com/google/gcloud/datastore/NullValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/NullValue.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java
diff --git a/src/main/java/com/google/gcloud/datastore/PathElement.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/PathElement.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java
diff --git a/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/ProjectionEntity.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java
diff --git a/src/main/java/com/google/gcloud/datastore/Query.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/Query.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java
diff --git a/src/main/java/com/google/gcloud/datastore/QueryResults.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/QueryResults.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java
diff --git a/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java
diff --git a/src/main/java/com/google/gcloud/datastore/RawValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/RawValue.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java
diff --git a/src/main/java/com/google/gcloud/datastore/Serializable.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Serializable.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/Serializable.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Serializable.java
diff --git a/src/main/java/com/google/gcloud/datastore/StringValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StringValue.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/StringValue.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StringValue.java
diff --git a/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/StructuredQuery.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java
diff --git a/src/main/java/com/google/gcloud/datastore/Transaction.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Transaction.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/Transaction.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Transaction.java
diff --git a/src/main/java/com/google/gcloud/datastore/TransactionImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/TransactionImpl.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java
diff --git a/src/main/java/com/google/gcloud/datastore/TransactionOption.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionOption.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/TransactionOption.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionOption.java
diff --git a/src/main/java/com/google/gcloud/datastore/Validator.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/Validator.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java
diff --git a/src/main/java/com/google/gcloud/datastore/Value.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/Value.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java
diff --git a/src/main/java/com/google/gcloud/datastore/ValueBuilder.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/ValueBuilder.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java
diff --git a/src/main/java/com/google/gcloud/datastore/ValueMarshaller.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueMarshaller.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/ValueMarshaller.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueMarshaller.java
diff --git a/src/main/java/com/google/gcloud/datastore/ValueType.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/ValueType.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java
diff --git a/src/main/java/com/google/gcloud/datastore/package-info.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java
similarity index 100%
rename from src/main/java/com/google/gcloud/datastore/package-info.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java
diff --git a/src/main/java/com/google/gcloud/spi/DatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java
similarity index 100%
rename from src/main/java/com/google/gcloud/spi/DatastoreRpc.java
rename to gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java
diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpcFactory.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpcFactory.java
new file mode 100644
index 000000000000..952114788f01
--- /dev/null
+++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpcFactory.java
@@ -0,0 +1,28 @@
+/*
+ * 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.spi;
+
+import com.google.gcloud.datastore.DatastoreServiceOptions;
+
+/**
+ * An interface for Datastore RPC factory.
+ * Implementation will be loaded via {@link java.util.ServiceLoader}.
+ */
+public interface DatastoreRpcFactory extends
+ ServiceRpcFactory {
+}
+
diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java
new file mode 100644
index 000000000000..3d909d368bc0
--- /dev/null
+++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java
@@ -0,0 +1,151 @@
+/*
+ * 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.spi;
+
+import com.google.api.services.datastore.DatastoreV1.AllocateIdsRequest;
+import com.google.api.services.datastore.DatastoreV1.AllocateIdsResponse;
+import com.google.api.services.datastore.DatastoreV1.BeginTransactionRequest;
+import com.google.api.services.datastore.DatastoreV1.BeginTransactionResponse;
+import com.google.api.services.datastore.DatastoreV1.CommitRequest;
+import com.google.api.services.datastore.DatastoreV1.CommitResponse;
+import com.google.api.services.datastore.DatastoreV1.LookupRequest;
+import com.google.api.services.datastore.DatastoreV1.LookupResponse;
+import com.google.api.services.datastore.DatastoreV1.RollbackRequest;
+import com.google.api.services.datastore.DatastoreV1.RollbackResponse;
+import com.google.api.services.datastore.DatastoreV1.RunQueryRequest;
+import com.google.api.services.datastore.DatastoreV1.RunQueryResponse;
+import com.google.api.services.datastore.client.Datastore;
+import com.google.api.services.datastore.client.DatastoreException;
+import com.google.api.services.datastore.client.DatastoreFactory;
+import com.google.api.services.datastore.client.DatastoreOptions.Builder;
+import com.google.common.collect.ImmutableMap;
+import com.google.gcloud.datastore.DatastoreServiceOptions;
+import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class DefaultDatastoreRpc implements DatastoreRpc {
+
+ private final Datastore client;
+
+ private static final ImmutableMap STR_TO_REASON;
+ private static final ImmutableMap HTTP_STATUS_TO_REASON;
+
+ static {
+ ImmutableMap.Builder builder = ImmutableMap.builder();
+ Map httpCodes = new HashMap<>();
+ for (Reason reason : Reason.values()) {
+ builder.put(reason.name(), reason);
+ httpCodes.put(reason.httpStatus(), reason);
+ }
+ STR_TO_REASON = builder.build();
+ HTTP_STATUS_TO_REASON = ImmutableMap.copyOf(httpCodes);
+ }
+
+ public DefaultDatastoreRpc(DatastoreServiceOptions options) {
+ client = DatastoreFactory.get().create(
+ new Builder()
+ .dataset(options.projectId())
+ .host(options.host())
+ .initializer(options.httpRequestInitializer())
+ .build());
+ }
+
+ private static DatastoreRpcException translate(DatastoreException exception) {
+ String message = exception.getMessage();
+ String reasonStr = "";
+ if (message != null) {
+ try {
+ JSONObject json = new JSONObject(new JSONTokener(message));
+ JSONObject error = json.getJSONObject("error").getJSONArray("errors").getJSONObject(0);
+ reasonStr = error.getString("reason");
+ message = error.getString("message");
+ } catch (JSONException ignore) {
+ // ignore - will be converted to unknown
+ }
+ }
+ Reason reason = STR_TO_REASON.get(reasonStr);
+ if (reason == null) {
+ reason = HTTP_STATUS_TO_REASON.get(exception.getCode());
+ }
+ return reason != null
+ ? new DatastoreRpcException(reason)
+ : new DatastoreRpcException("Unknown", exception.getCode(), false, message);
+ }
+
+ @Override
+ public AllocateIdsResponse allocateIds(AllocateIdsRequest request)
+ throws DatastoreRpcException {
+ try {
+ return client.allocateIds(request);
+ } catch (DatastoreException ex) {
+ throw translate(ex);
+ }
+ }
+
+ @Override
+ public BeginTransactionResponse beginTransaction(BeginTransactionRequest request)
+ throws DatastoreRpcException {
+ try {
+ return client.beginTransaction(request);
+ } catch (DatastoreException ex) {
+ throw translate(ex);
+ }
+ }
+
+ @Override
+ public CommitResponse commit(CommitRequest request) throws DatastoreRpcException {
+ try {
+ return client.commit(request);
+ } catch (DatastoreException ex) {
+ throw translate(ex);
+ }
+ }
+
+ @Override
+ public LookupResponse lookup(LookupRequest request) throws DatastoreRpcException {
+ try {
+ return client.lookup(request);
+ } catch (DatastoreException ex) {
+ throw translate(ex);
+ }
+ }
+
+ @Override
+ public RollbackResponse rollback(RollbackRequest request) throws DatastoreRpcException {
+ try {
+ return client.rollback(request);
+ } catch (DatastoreException ex) {
+ throw translate(ex);
+ }
+ }
+
+ @Override
+ public RunQueryResponse runQuery(RunQueryRequest request) throws DatastoreRpcException {
+ try {
+ return client.runQuery(request);
+ } catch (DatastoreException ex) {
+ throw translate(ex);
+ }
+ }
+}
+
diff --git a/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/BaseEntityTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/BaseKeyTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/BlobTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/BlobTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/BlobValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobValueTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/BlobValueTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobValueTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/BooleanValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BooleanValueTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/BooleanValueTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BooleanValueTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/CursorTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/CursorTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/CursorTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/CursorTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/DatastoreServiceExceptionTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreServiceExceptionTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/DatastoreServiceExceptionTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreServiceExceptionTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/DatastoreServiceOptionsTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreServiceOptionsTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/DatastoreServiceOptionsTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreServiceOptionsTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/DatastoreServiceTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreServiceTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/DatastoreServiceTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreServiceTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/DateTimeTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/DateTimeTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/DoubleValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DoubleValueTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/DoubleValueTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DoubleValueTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/EntityTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/EntityTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/EntityValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityValueTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/EntityValueTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityValueTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/FullEntityTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/FullEntityTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/FullEntityTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/FullEntityTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/KeyTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/KeyTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/KeyValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyValueTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/KeyValueTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyValueTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/ListValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/ListValueTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java
diff --git a/src/test/java/com/google/gcloud/datastore/LongValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LongValueTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/LongValueTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LongValueTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/NullValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/NullValueTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/NullValueTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/NullValueTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/PathElementTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/PathElementTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/PathElementTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/PathElementTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/ProjectionEntityTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ProjectionEntityTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/ProjectionEntityTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ProjectionEntityTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/RawValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/RawValueTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/RawValueTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/RawValueTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/SerializationTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/StringValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StringValueTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/StringValueTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StringValueTest.java
diff --git a/src/test/java/com/google/gcloud/datastore/ValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java
similarity index 100%
rename from src/test/java/com/google/gcloud/datastore/ValueTest.java
rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java
diff --git a/src/test/resources/gcd-head.zip b/gcloud-java-datastore/src/test/resources/gcd-head.zip
similarity index 100%
rename from src/test/resources/gcd-head.zip
rename to gcloud-java-datastore/src/test/resources/gcd-head.zip
diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md
new file mode 100644
index 000000000000..59df6ced388f
--- /dev/null
+++ b/gcloud-java-examples/README.md
@@ -0,0 +1,55 @@
+Google Cloud Java Client Examples
+=================================
+
+Examples for gcloud-java (Java idiomatic client for [Google Cloud Platform][cloud-platform] services).
+
+[](https://travis-ci.org/GoogleCloudPlatform/gcloud-java)
+[](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master)
+
+- [Homepage] (https://googlecloudplatform.github.io/gcloud-java/)
+- [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs)
+- [Examples] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/examples/package-summary.html)
+
+
+Quickstart
+----------
+Add this to your pom.xml file
+```xml
+
+ com.google.gcloud
+ gcloud-java-examples
+ LATEST
+
+```
+
+
+Contributing
+------------
+
+Contributions to this library are always welcome and highly encouraged.
+
+See [CONTRIBUTING] for more information on how to get started.
+
+Java Versions
+-------------
+
+Java 7 or above is required for using this client.
+
+Versioning
+----------
+
+This library follows [Semantic Versioning] (http://semver.org/).
+
+It is currently in major version zero (``0.y.z``), which means that anything
+may change at any time and the public API should not be considered
+stable.
+
+License
+-------
+
+Apache 2.0 - See [LICENSE] for more information.
+
+
+[CONTRIBUTING]:https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/CONTRIBUTING.md
+[LICENSE]: https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/LICENSE
+[cloud-platform]: https://cloud.google.com/
diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml
new file mode 100644
index 000000000000..66d9fc9c93e3
--- /dev/null
+++ b/gcloud-java-examples/pom.xml
@@ -0,0 +1,24 @@
+
+
+ 4.0.0
+ com.google.gcloud
+ gcloud-java-examples
+ jar
+ GCloud Java examples
+ https://github.com/GoogleCloudPlatform/gcloud-java
+
+ Examples for gcloud-java.
+
+
+ com.google.gcloud
+ gcloud-java-pom
+ 0.0.5
+
+
+
+ ${project.groupId}
+ gcloud-java
+ ${project.version}
+
+
+
diff --git a/src/main/java/com/google/gcloud/examples/DatastoreExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/DatastoreExample.java
similarity index 100%
rename from src/main/java/com/google/gcloud/examples/DatastoreExample.java
rename to gcloud-java-examples/src/main/java/com/google/gcloud/examples/DatastoreExample.java
diff --git a/src/main/java/com/google/gcloud/examples/StorageExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java
similarity index 100%
rename from src/main/java/com/google/gcloud/examples/StorageExample.java
rename to gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java
diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md
new file mode 100644
index 000000000000..aa090743f5ce
--- /dev/null
+++ b/gcloud-java-storage/README.md
@@ -0,0 +1,63 @@
+Google Cloud Java Client
+==========================
+
+Java idiomatic client for [Google Cloud Platform][cloud-platform] services.
+
+[](https://travis-ci.org/GoogleCloudPlatform/gcloud-java)
+[](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master)
+
+- [Homepage] (https://googlecloudplatform.github.io/gcloud-java/)
+- [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs)
+- [Examples] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/examples/package-summary.html)
+
+This client supports the [Google Cloud Storage] (https://cloud.google.com/storage/)
+
+> Note: This client is a work-in-progress, and may occasionally
+> make backwards-incompatible changes.
+
+Quickstart
+----------
+Add this to your pom.xml file
+```xml
+
+ com.google.gcloud
+ gcloud-java-storage
+ LATEST
+
+```
+
+
+Contributing
+------------
+
+Contributions to this library are always welcome and highly encouraged.
+
+See [CONTRIBUTING] for more information on how to get started.
+
+Java Versions
+-------------
+
+Java 7 or above is required for using this client.
+
+Versioning
+----------
+
+This library follows [Semantic Versioning] (http://semver.org/).
+
+It is currently in major version zero (``0.y.z``), which means that anything
+may change at any time and the public API should not be considered
+stable.
+
+License
+-------
+
+Apache 2.0 - See [LICENSE] for more information.
+
+
+[CONTRIBUTING]:https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/CONTRIBUTING.md
+[LICENSE]: https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/LICENSE
+[cloud-platform]: https://cloud.google.com/
+
+[cloud-storage]: https://cloud.google.com/storage/
+[cloud-storage-docs]: https://cloud.google.com/storage/docs/overview
+[cloud-storage-create-bucket]: https://cloud.google.com/storage/docs/cloud-console#_creatingbuckets
diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml
new file mode 100644
index 000000000000..11cc0f02c6ac
--- /dev/null
+++ b/gcloud-java-storage/pom.xml
@@ -0,0 +1,42 @@
+
+
+ 4.0.0
+ com.google.gcloud
+ gcloud-java-storage
+ jar
+ GCloud Java storage
+ https://github.com/GoogleCloudPlatform/gcloud-java
+
+ Java idiomatic client for Google Cloud Storage.
+
+
+ com.google.gcloud
+ gcloud-java-pom
+ 0.0.5
+
+
+
+ ${project.groupId}
+ gcloud-java-core
+ ${project.version}
+
+
+ com.google.apis
+ google-api-services-storage
+ v1-rev33-1.20.0
+ compile
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.easymock
+ easymock
+ 3.3
+ test
+
+
+
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
new file mode 100644
index 000000000000..e27d837d7173
--- /dev/null
+++ b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java
@@ -0,0 +1,525 @@
+/*
+ * 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.spi;
+
+import static com.google.gcloud.spi.StorageRpc.Option.DELIMITER;
+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;
+import static com.google.gcloud.spi.StorageRpc.Option.IF_METAGENERATION_NOT_MATCH;
+import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_GENERATION_MATCH;
+import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_GENERATION_NOT_MATCH;
+import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_MATCH;
+import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_NOT_MATCH;
+import static com.google.gcloud.spi.StorageRpc.Option.MAX_RESULTS;
+import static com.google.gcloud.spi.StorageRpc.Option.PAGE_TOKEN;
+import static com.google.gcloud.spi.StorageRpc.Option.PREDEFINED_ACL;
+import static com.google.gcloud.spi.StorageRpc.Option.PREDEFINED_DEFAULT_OBJECT_ACL;
+import static com.google.gcloud.spi.StorageRpc.Option.PREFIX;
+import static com.google.gcloud.spi.StorageRpc.Option.VERSIONS;
+
+import com.google.api.client.googleapis.batch.json.JsonBatchCallback;
+import com.google.api.client.googleapis.json.GoogleJsonError;
+import com.google.api.client.googleapis.json.GoogleJsonResponseException;
+import com.google.api.client.googleapis.media.MediaHttpDownloader;
+import com.google.api.client.http.ByteArrayContent;
+import com.google.api.client.http.GenericUrl;
+import com.google.api.client.http.HttpHeaders;
+import com.google.api.client.http.HttpRequest;
+import com.google.api.client.http.HttpRequestFactory;
+import com.google.api.client.http.HttpRequestInitializer;
+import com.google.api.client.http.HttpResponse;
+import com.google.api.client.http.HttpResponseException;
+import com.google.api.client.http.HttpTransport;
+import com.google.api.client.http.json.JsonHttpContent;
+import com.google.api.client.json.JsonFactory;
+import com.google.api.client.json.jackson.JacksonFactory;
+import com.google.api.services.storage.Storage;
+import com.google.api.services.storage.Storage.Objects.Get;
+import com.google.api.services.storage.Storage.Objects.Insert;
+import com.google.api.services.storage.model.Bucket;
+import com.google.api.services.storage.model.Buckets;
+import com.google.api.services.storage.model.ComposeRequest;
+import com.google.api.services.storage.model.ComposeRequest.SourceObjects.ObjectPreconditions;
+import com.google.api.services.storage.model.Objects;
+import com.google.api.services.storage.model.StorageObject;
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.gcloud.storage.StorageServiceException;
+import com.google.gcloud.storage.StorageServiceOptions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class DefaultStorageRpc implements StorageRpc {
+
+ public static final String DEFAULT_PROJECTION = "full";
+ private final StorageServiceOptions options;
+ private final Storage storage;
+
+ // see: https://cloud.google.com/storage/docs/concepts-techniques#practices
+ private static final Set RETRYABLE_CODES = ImmutableSet.of(504, 503, 502, 500, 408);
+
+ public DefaultStorageRpc(StorageServiceOptions options) {
+ HttpTransport transport = options.httpTransportFactory().create();
+ HttpRequestInitializer initializer = options.httpRequestInitializer();
+ this.options = options;
+ storage = new Storage.Builder(transport, new JacksonFactory(), initializer)
+ .setApplicationName("gcloud-java")
+ .build();
+ // Todo: make sure nulls are being used as Data.asNull()
+ }
+
+ private static StorageServiceException translate(IOException exception) {
+ StorageServiceException translated;
+ if (exception instanceof GoogleJsonResponseException) {
+ translated = translate(((GoogleJsonResponseException) exception).getDetails());
+ } else {
+ translated = new StorageServiceException(0, exception.getMessage(), false);
+ }
+ translated.initCause(exception);
+ return translated;
+ }
+
+ private static StorageServiceException translate(GoogleJsonError exception) {
+ boolean retryable = RETRYABLE_CODES.contains(exception.getCode())
+ || "InternalError".equals(exception.getMessage());
+ return new StorageServiceException(exception.getCode(), exception.getMessage(), retryable);
+ }
+
+ @Override
+ public Bucket create(Bucket bucket, Map