Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Serializable from AuthCredentials, ServiceFactory and ServiceRpcFactory and set Factories in ServiceOptions #296

Merged
merged 3 commits into from
Oct 27, 2015
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>> {

This comment was marked as spam.

This comment was marked as spam.


/**
* Capture the state of this object.

This comment was marked as spam.

This comment was marked as spam.

*
* @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