From 55e65af862349ec34603225b15d3c5706de76dec Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Sep 2015 12:34:35 +0200 Subject: [PATCH 1/3] Add ServiceFactory interface, extending Serializable. Add factory getter to Service contract. Update all services accordingly. --- .../java/com/google/gcloud/BaseService.java | 15 ++++++++-- .../main/java/com/google/gcloud/Service.java | 5 +++- .../com/google/gcloud/ServiceFactory.java | 28 +++++++++++++++++++ .../google/gcloud/datastore/Datastore.java | 3 +- .../gcloud/datastore/DatastoreFactory.java | 6 ++-- .../gcloud/datastore/DatastoreImpl.java | 6 ++-- .../com/google/gcloud/storage/Storage.java | 2 +- .../google/gcloud/storage/StorageFactory.java | 6 ++-- .../google/gcloud/storage/StorageImpl.java | 6 ++-- 9 files changed, 61 insertions(+), 16 deletions(-) create mode 100644 gcloud-java-core/src/main/java/com/google/gcloud/ServiceFactory.java diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/BaseService.java b/gcloud-java-core/src/main/java/com/google/gcloud/BaseService.java index 982d3058295c..70c0a7792956 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/BaseService.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/BaseService.java @@ -16,17 +16,26 @@ package com.google.gcloud; -public abstract class BaseService> - implements Service { +public abstract class BaseService< + OptionsT extends ServiceOptions, + ServiceFactoryT extends ServiceFactory> + implements Service { private final OptionsT options; + private final ServiceFactoryT factory; - protected BaseService(OptionsT options) { + protected BaseService(OptionsT options, ServiceFactoryT factory) { this.options = options; + this.factory = factory; } @Override public OptionsT options() { return options; } + + @Override + public ServiceFactoryT factory() { + return factory; + } } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/Service.java b/gcloud-java-core/src/main/java/com/google/gcloud/Service.java index 19759fb20e21..fb541ab9f85b 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/Service.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/Service.java @@ -16,6 +16,9 @@ package com.google.gcloud; -public interface Service> { +public interface Service< + OptionsT extends ServiceOptions, + ServiceFactoryT extends ServiceFactory> { OptionsT options(); + ServiceFactoryT factory(); } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceFactory.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceFactory.java new file mode 100644 index 000000000000..8387008ff70b --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceFactory.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; + +import java.io.Serializable; + +public interface ServiceFactory< + ServiceT extends Service, + OptionsT extends ServiceOptions> + extends Serializable { + + public ServiceT get(OptionsT options); + +} diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java index 870ed8d9474f..61948e544c2d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java @@ -23,7 +23,8 @@ /** * An interface for Google Cloud Datastore. */ -public interface Datastore extends Service, DatastoreReaderWriter { +public interface Datastore extends Service, + DatastoreReaderWriter { /** * Returns a new Datastore transaction. diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java index a64fab3715f1..bc24278d6ff8 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java @@ -16,16 +16,17 @@ package com.google.gcloud.datastore; +import com.google.gcloud.ServiceFactory; /** * A base class for Datastore factories. */ -public abstract class DatastoreFactory { +public abstract class DatastoreFactory implements ServiceFactory { private static final DatastoreFactory INSTANCE = new DatastoreFactory() { @Override public Datastore get(DatastoreOptions options) { - return new DatastoreImpl(options); + return new DatastoreImpl(options, this); } }; @@ -39,5 +40,6 @@ public static DatastoreFactory instance() { /** * Returns a {@code Datastore} service for the given options. */ + @Override public abstract Datastore get(DatastoreOptions options); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index 6f2454c62167..6fb8d0507433 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -43,7 +43,7 @@ import java.util.concurrent.Callable; -final class DatastoreImpl extends BaseService +final class DatastoreImpl extends BaseService implements Datastore { private static final Interceptor EXCEPTION_HANDLER_INTERCEPTOR = @@ -72,8 +72,8 @@ public RetryResult beforeEval(Exception exception) { private final DatastoreRpc datastoreRpc; private final RetryParams retryParams; - DatastoreImpl(DatastoreOptions options) { - super(options); + DatastoreImpl(DatastoreOptions options, DatastoreFactory factory) { + super(options, factory); this.datastoreRpc = options.datastoreRpc(); retryParams = MoreObjects.firstNonNull(options.retryParams(), RetryParams.noRetries()); } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index e3cfbc195860..2586208c5141 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -38,7 +38,7 @@ * * @see Google Cloud Storage */ -public interface Storage extends Service { +public interface Storage extends Service { enum PredefinedAcl { AUTHENTICATED_READ("authenticatedRead"), diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java index e269f0c9d92b..27a55ca4e95c 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java @@ -16,16 +16,17 @@ package com.google.gcloud.storage; +import com.google.gcloud.ServiceFactory; /** * A base class for Storage factories. */ -public abstract class StorageFactory { +public abstract class StorageFactory implements ServiceFactory { private static final StorageFactory INSTANCE = new StorageFactory() { @Override public Storage get(StorageOptions options) { - return new StorageImpl(options); + return new StorageImpl(options, this); } }; @@ -39,5 +40,6 @@ public static StorageFactory instance() { /** * Returns a {@code Storage} service for the given options. */ + @Override public abstract Storage get(StorageOptions options); } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java index f59c6c670969..56b6b8a20cfc 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java @@ -64,7 +64,7 @@ import java.util.Set; import java.util.concurrent.Callable; -final class StorageImpl extends BaseService implements Storage { +final class StorageImpl extends BaseService implements Storage { private static final Interceptor EXCEPTION_HANDLER_INTERCEPTOR = new Interceptor() { @@ -90,8 +90,8 @@ public RetryResult beforeEval(Exception exception) { private final StorageRpc storageRpc; - StorageImpl(StorageOptions options) { - super(options); + StorageImpl(StorageOptions options, StorageFactory factory) { + super(options, factory); storageRpc = options.storageRpc(); // todo: configure timeouts - https://developers.google.com/api-client-library/java/google-api-java-client/errors // todo: provide rewrite - https://cloud.google.com/storage/docs/json_api/v1/objects/rewrite From 09e03e0f364b35ac52677f078cfe7c332bf87352 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Sep 2015 12:35:35 +0200 Subject: [PATCH 2/3] Add tests for factory() getter and factory serialization. --- .../java/com/google/gcloud/datastore/DatastoreTest.java | 5 +++++ .../com/google/gcloud/datastore/SerializationTest.java | 7 +++++++ .../java/com/google/gcloud/storage/SerializationTest.java | 7 +++++++ 3 files changed, 19 insertions(+) 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 156f9684f8ba..45026d38cb7b 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 @@ -134,6 +134,11 @@ public void testGetOptions() { assertSame(options, datastore.options()); } + @Test + public void testGetFactory() { + assertSame(DatastoreFactory.instance(), datastore.factory()); + } + @Test public void testNewTransactionCommit() { Transaction transaction = datastore.newTransaction(); 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 5f3bfc036fa2..3f24164373b4 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 @@ -40,6 +40,7 @@ public class SerializationTest { + private static final DatastoreFactory DATASTORE_FACTORY = DatastoreFactory.instance(); private static final IncompleteKey INCOMPLETE_KEY1 = IncompleteKey.builder("ds", "k").ancestors(PathElement.of("p", 1)).build(); private static final Key KEY1 = Key.builder("ds", "k", "n").build(); @@ -131,6 +132,12 @@ public class SerializationTest { .put(ValueType.RAW_VALUE, RAW_VALUE) .build(); + @Test + public void testStorageFactory() throws Exception { + DatastoreFactory serializedCopy = serializeAndDeserialize(DATASTORE_FACTORY); + assertNotSame(DATASTORE_FACTORY, serializedCopy); + } + @Test public void testServiceOptions() throws Exception { DatastoreOptions options = DatastoreOptions.builder() diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index 81342e4b5748..984e9eb818fd 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -35,6 +35,7 @@ public class SerializationTest { + private static final StorageFactory STORAGE_FACTORY = StorageFactory.instance(); private static final Acl.Domain ACL_DOMAIN = new Acl.Domain("domain"); private static final Acl.Group ACL_GROUP = new Acl.Group("group"); private static final Acl.Project ACL_PROJECT_ = new Acl.Project(ProjectRole.VIEWERS, "pid"); @@ -65,6 +66,12 @@ public class SerializationTest { private static final Storage.BucketTargetOption BUCKET_TARGET_OPTIONS = Storage.BucketTargetOption.metagenerationNotMatch(); + @Test + public void testStorageFactory() throws Exception { + StorageFactory serializedCopy = serializeAndDeserialize(STORAGE_FACTORY); + assertNotSame(STORAGE_FACTORY, serializedCopy); + } + @Test public void testServiceOptions() throws Exception { StorageOptions options = StorageOptions.builder() From 0d2446e28487e84056dd080c8853d7a0aca4abfe Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Sep 2015 14:19:51 +0200 Subject: [PATCH 3/3] Add serialVersionUID and readResolve method to service factories. Updated tests. --- .../gcloud/datastore/DatastoreFactory.java | 20 ++++++++++++++----- .../gcloud/datastore/SerializationTest.java | 3 ++- .../google/gcloud/storage/StorageFactory.java | 10 ++++++++++ .../gcloud/storage/SerializationTest.java | 3 ++- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java index bc24278d6ff8..91d9706756f6 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java @@ -17,18 +17,28 @@ package com.google.gcloud.datastore; import com.google.gcloud.ServiceFactory; +import java.io.ObjectStreamException; /** * A base class for Datastore factories. */ public abstract class DatastoreFactory implements ServiceFactory { + private static final long serialVersionUID = 5037190305022535983L; + private static final DatastoreFactory INSTANCE = new DatastoreFactory() { - @Override - public Datastore get(DatastoreOptions options) { - return new DatastoreImpl(options, this); - } - }; + + private static final long serialVersionUID = 5893914895344559491L; + + @Override + public Datastore get(DatastoreOptions options) { + return new DatastoreImpl(options, this); + } + + private Object readResolve() throws ObjectStreamException { + return INSTANCE; + } + }; /** * Returns the default factory instance. 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 3f24164373b4..410fe07c961f 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 @@ -135,7 +135,8 @@ public class SerializationTest { @Test public void testStorageFactory() throws Exception { DatastoreFactory serializedCopy = serializeAndDeserialize(DATASTORE_FACTORY); - assertNotSame(DATASTORE_FACTORY, serializedCopy); + assertEquals(DATASTORE_FACTORY, serializedCopy); + assertEquals(DATASTORE_FACTORY.hashCode(), serializedCopy.hashCode()); } @Test diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java index 27a55ca4e95c..f058079e45e9 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java @@ -17,17 +17,27 @@ package com.google.gcloud.storage; import com.google.gcloud.ServiceFactory; +import java.io.ObjectStreamException; /** * A base class for Storage factories. */ public abstract class StorageFactory implements ServiceFactory { + private static final long serialVersionUID = 1866883249985063753L; + private static final StorageFactory INSTANCE = new StorageFactory() { + + private static final long serialVersionUID = -7985210081064222485L; + @Override public Storage get(StorageOptions options) { return new StorageImpl(options, this); } + + private Object readResolve() throws ObjectStreamException { + return INSTANCE; + } }; /** diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index 984e9eb818fd..8fd6d3d80d7a 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -69,7 +69,8 @@ public class SerializationTest { @Test public void testStorageFactory() throws Exception { StorageFactory serializedCopy = serializeAndDeserialize(STORAGE_FACTORY); - assertNotSame(STORAGE_FACTORY, serializedCopy); + assertEquals(STORAGE_FACTORY, serializedCopy); + assertEquals(STORAGE_FACTORY.hashCode(), serializedCopy.hashCode()); } @Test