Skip to content

Commit

Permalink
Remove Serializable from AuthCredentials, ServiceFactory and ServiceR…
Browse files Browse the repository at this point in the history
…pcFactory and set factories on ServiceOptions
  • Loading branch information
aozarov committed Oct 26, 2015
1 parent 6e25709 commit 8d95b0f
Show file tree
Hide file tree
Showing 37 changed files with 579 additions and 535 deletions.
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,13 @@ Here is a code snippet showing a simple usage example from within Compute/App En

```java
import com.google.gcloud.datastore.Datastore;
import com.google.gcloud.datastore.DatastoreFactory;
import com.google.gcloud.datastore.DatastoreOptions;
import com.google.gcloud.datastore.DateTime;
import com.google.gcloud.datastore.Entity;
import com.google.gcloud.datastore.Key;
import com.google.gcloud.datastore.KeyFactory;

Datastore datastore = DatastoreFactory.instance().get(DatastoreOptions.getDefaultInstance());
Datastore datastore = DatastoreOptions.getDefaultInstance().service();
KeyFactory keyFactory = datastore.newKeyFactory().kind(KIND);
Key key = keyFactory.newKey(keyName);
Entity entity = datastore.get(key);
Expand Down Expand Up @@ -106,14 +105,13 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.gcloud.storage.Blob;
import com.google.gcloud.storage.BlobId;
import com.google.gcloud.storage.Storage;
import com.google.gcloud.storage.StorageFactory;
import com.google.gcloud.storage.StorageOptions;

import java.nio.ByteBuffer;
import java.nio.channels.WritableByteChannel;

StorageOptions options = StorageOptions.builder().projectId("project").build();
Storage storage = StorageFactory.instance().get(options);
Storage storage = options.service();
BlobId blobId = BlobId.of("bucket", "blob_name");
Blob blob = Blob.load(storage, blobId);
if (blob == null) {
Expand Down
6 changes: 3 additions & 3 deletions TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ You can test against a temporary local datastore by following these steps:
.projectId(PROJECT_ID)
.host("http://localhost:8080")
.build();
Datastore localDatastore = DatastoreFactory.instance().get(options);
Datastore localDatastore = options.service();
```
3. Run your tests.

Expand All @@ -35,7 +35,7 @@ You can test against a remote datastore emulator as well. To do this, set the `
.projectId(PROJECT_ID)
.host("http://<hostname of machine>:<port>")
.build();
Datastore localDatastore = DatastoreFactory.instance().get(options);
Datastore localDatastore = options.service();
```

Note that the remote datastore must be running before your tests are run.
Expand All @@ -52,7 +52,7 @@ Currently, there isn't an emulator for Google Cloud Storage, so an alternative i
Here is an example that uses the `RemoteGcsHelper` to create a bucket.
```java
RemoteGcsHelper gcsHelper = RemoteGcsHelper.create(PROJECT_ID, "/path/to/my/JSON/key.json");
Storage storage = StorageFactory.instance().get(gcsHelper.options());
Storage storage = gcsHelper.options().service();
String bucket = RemoteGcsHelper.generateBucketName();
storage.create(BucketInfo.of(bucket));
```
Expand Down
172 changes: 133 additions & 39 deletions gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
Expand All @@ -42,35 +40,91 @@
/**
* Credentials for accessing Google Cloud services.
*/
public abstract class AuthCredentials implements Serializable {

private static final long serialVersionUID = 236297804453464604L;
public abstract class AuthCredentials implements Restorable<AuthCredentials> {

private static class AppEngineAuthCredentials extends AuthCredentials {

private static final long serialVersionUID = 7931300552744202954L;

private static final AuthCredentials INSTANCE = new AppEngineAuthCredentials();
private static final AppEngineAuthCredentialsState STATE =
new AppEngineAuthCredentialsState();

private static class AppEngineAuthCredentialsState
implements RestorableState<AuthCredentials>, Serializable {

private static final long serialVersionUID = 3558563960848658928L;

@Override
public AuthCredentials restore() {
return INSTANCE;
}

@Override
public int hashCode() {
return getClass().getName().hashCode();
}

@Override
public boolean equals(Object obj) {
return obj instanceof AppEngineAuthCredentialsState;
}
}

@Override
protected HttpRequestInitializer httpRequestInitializer(HttpTransport transport,
Set<String> scopes) {
return new AppIdentityCredential(scopes);
}

private Object readResolve() throws ObjectStreamException {
return INSTANCE;
@Override
public RestorableState<AuthCredentials> capture() {
return STATE;
}
}

public static class ServiceAccountAuthCredentials extends AuthCredentials {

private static final long serialVersionUID = 8007708734318445901L;
private final String account;
private final PrivateKey privateKey;

private static final AuthCredentials NO_CREDENTIALS = new ServiceAccountAuthCredentials();

private static class ServiceAccountAuthCredentialsState
implements RestorableState<AuthCredentials>, Serializable {

private static final long serialVersionUID = -7302180782414633639L;

private final String account;
private final PrivateKey privateKey;

private ServiceAccountAuthCredentialsState(String account, PrivateKey privateKey) {
this.account = account;
this.privateKey = privateKey;
}

@Override
public AuthCredentials restore() {
if (account == null && privateKey == null) {
return NO_CREDENTIALS;
}
return new ServiceAccountAuthCredentials(account, privateKey);
}

@Override
public int hashCode() {
return Objects.hash(account, privateKey);
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof ServiceAccountAuthCredentialsState)) {
return false;
}
ServiceAccountAuthCredentialsState other = (ServiceAccountAuthCredentialsState) obj;
return Objects.equals(account, other.account)
&& Objects.equals(privateKey, other.privateKey);
}
}

ServiceAccountAuthCredentials(String account, PrivateKey privateKey) {
this.account = checkNotNull(account);
this.privateKey = checkNotNull(privateKey);
Expand Down Expand Up @@ -104,59 +158,94 @@ public PrivateKey privateKey() {
}

@Override
public int hashCode() {
return Objects.hash(account, privateKey);
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof ServiceAccountAuthCredentials)) {
return false;
}
ServiceAccountAuthCredentials other = (ServiceAccountAuthCredentials) obj;
return Objects.equals(account, other.account)
&& Objects.equals(privateKey, other.privateKey);
public RestorableState<AuthCredentials> capture() {
return new ServiceAccountAuthCredentialsState(account, privateKey);
}
}

private static class ComputeEngineAuthCredentials extends AuthCredentials {

private static final long serialVersionUID = -5217355402127260144L;
private ComputeCredential computeCredential;

private transient ComputeCredential computeCredential;
private static final ComputeEngineAuthCredentialsState STATE =
new ComputeEngineAuthCredentialsState();

ComputeEngineAuthCredentials() throws IOException, GeneralSecurityException {
computeCredential = getComputeCredential();
}
private static class ComputeEngineAuthCredentialsState
implements RestorableState<AuthCredentials>, Serializable {

private static final long serialVersionUID = -6168594072854417404L;

@Override
public AuthCredentials restore() {
try {
return new ComputeEngineAuthCredentials();
} catch (IOException | GeneralSecurityException e) {
throw new IllegalStateException(
"Could not restore " + ComputeEngineAuthCredentials.class.getSimpleName(), e);
}
}

@Override
public int hashCode() {
return getClass().getName().hashCode();
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
try {
computeCredential = getComputeCredential();
} catch (GeneralSecurityException e) {
throw new IOException(e);
@Override
public boolean equals(Object obj) {
return obj instanceof ComputeEngineAuthCredentialsState;
}
}

ComputeEngineAuthCredentials() throws IOException, GeneralSecurityException {
computeCredential = getComputeCredential();
}

@Override
protected HttpRequestInitializer httpRequestInitializer(HttpTransport transport,
Set<String> scopes) {
return computeCredential;
}

@Override
public RestorableState<AuthCredentials> capture() {
return STATE;
}
}

private static class ApplicationDefaultAuthCredentials extends AuthCredentials {

private static final long serialVersionUID = -8306873864136099893L;
private GoogleCredentials googleCredentials;

private transient GoogleCredentials googleCredentials;
private static final ApplicationDefaultAuthCredentialsState STATE =
new ApplicationDefaultAuthCredentialsState();

ApplicationDefaultAuthCredentials() throws IOException {
googleCredentials = GoogleCredentials.getApplicationDefault();
private static class ApplicationDefaultAuthCredentialsState
implements RestorableState<AuthCredentials>, Serializable {

private static final long serialVersionUID = -8839085552021212257L;

@Override
public AuthCredentials restore() {
try {
return new ApplicationDefaultAuthCredentials();
} catch (IOException e) {
throw new IllegalStateException(
"Could not restore " + ApplicationDefaultAuthCredentials.class.getSimpleName(), e);
}
}

@Override
public int hashCode() {
return getClass().getName().hashCode();
}

@Override
public boolean equals(Object obj) {
return obj instanceof ApplicationDefaultAuthCredentialsState;
}
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
ApplicationDefaultAuthCredentials() throws IOException {
googleCredentials = GoogleCredentials.getApplicationDefault();
}

Expand All @@ -165,6 +254,11 @@ protected HttpRequestInitializer httpRequestInitializer(HttpTransport transport,
Set<String> scopes) {
return new HttpCredentialsAdapter(googleCredentials);
}

@Override
public RestorableState<AuthCredentials> capture() {
return STATE;
}
}

protected abstract HttpRequestInitializer httpRequestInitializer(HttpTransport transport,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package com.google.gcloud;

public abstract class BaseService<OptionsT extends ServiceOptions<?, OptionsT>>
public abstract class BaseService<OptionsT extends ServiceOptions<?, ?, OptionsT>>
implements Service<OptionsT> {

private final OptionsT options;
Expand Down
15 changes: 15 additions & 0 deletions gcloud-java-core/src/main/java/com/google/gcloud/Restorable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.google.gcloud;

/**
* Implementation of this interface can persist their state and restore from it.
*/
public interface Restorable<T extends Restorable<T>> {

/**
* Capture the state of this object.
*
* @return a {@link RestorableState} instance that contains the state for this object and can
* restore it afterwards.
*/
RestorableState<T> capture();
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* Implementations of this class must implement {@link java.io.Serializable} to ensure that the
* state of a the object can be correctly serialized.
*/
public interface RestorableState<T> {
public interface RestorableState<T extends Restorable<T>> {

/**
* Returns an object whose internal state reflects the one saved in the invocation object.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@

package com.google.gcloud;

public interface Service<OptionsT extends ServiceOptions<?, OptionsT>> {
public interface Service<OptionsT extends ServiceOptions<?, ?, OptionsT>> {
OptionsT options();
}
Original file line number Diff line number Diff line change
@@ -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;

/**
* A base interface for all service factories.
*
* Implementation must provide a public no-arg constructor.
* Loading of a factory implementation is done via {@link java.util.ServiceLoader}.
*/
public interface ServiceFactory<ServiceT extends Service, ServiceOptionsT extends ServiceOptions> {

ServiceT create(ServiceOptionsT serviceOptions);
}
Loading

0 comments on commit 8d95b0f

Please sign in to comment.