From e063bc5707ae1cac53f8d2ec0d3d971dd94e617e Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 6 Nov 2015 18:10:50 -0800 Subject: [PATCH 1/7] Auth cleanup --- README.md | 6 +- .../com/google/gcloud/AuthCredentials.java | 113 +----------------- .../com/google/gcloud/ServiceOptions.java | 35 +++--- .../gcloud/datastore/SerializationTest.java | 24 ++-- .../gcloud/storage/SerializationTest.java | 22 ++-- 5 files changed, 45 insertions(+), 155 deletions(-) diff --git a/README.md b/README.md index 9ba994d572c1..0833de90dfde 100644 --- a/README.md +++ b/README.md @@ -96,9 +96,9 @@ There are multiple ways to authenticate to use Google Cloud services. `gcloud-java` looks for credentials in the following order, stopping once it finds credentials: 1. Credentials supplied when building the service options -2. App Engine credentials -3. Key file pointed to by the GOOGLE_APPLICATION_CREDENTIALS environment variable -4. Google Cloud SDK credentials +2. Key file pointed to by the GOOGLE_APPLICATION_CREDENTIALS environment variable +3. Google Cloud SDK credentials +4. App Engine credentials 5. Compute Engine credentials Google Cloud Datastore diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index 73c66279ea53..990d30eca618 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -19,12 +19,8 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.googleapis.compute.ComputeCredential; -import com.google.api.client.googleapis.extensions.appengine.auth.oauth2.AppIdentityCredential; -import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; 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.api.client.json.jackson.JacksonFactory; import com.google.auth.http.HttpCredentialsAdapter; import com.google.auth.oauth2.GoogleCredentials; @@ -32,7 +28,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.Serializable; -import java.security.GeneralSecurityException; import java.security.PrivateKey; import java.util.Objects; import java.util.Set; @@ -42,45 +37,6 @@ */ public abstract class AuthCredentials implements Restorable { - private static class AppEngineAuthCredentials extends AuthCredentials { - - private static final AuthCredentials INSTANCE = new AppEngineAuthCredentials(); - private static final AppEngineAuthCredentialsState STATE = - new AppEngineAuthCredentialsState(); - - private static class AppEngineAuthCredentialsState - implements RestorableState, 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 scopes) { - return new AppIdentityCredential(scopes); - } - - @Override - public RestorableState capture() { - return STATE; - } - } - public static class ServiceAccountAuthCredentials extends AuthCredentials { private final String account; @@ -163,55 +119,6 @@ public RestorableState capture() { } } - private static class ComputeEngineAuthCredentials extends AuthCredentials { - - private ComputeCredential computeCredential; - - private static final ComputeEngineAuthCredentialsState STATE = - new ComputeEngineAuthCredentialsState(); - - private static class ComputeEngineAuthCredentialsState - implements RestorableState, 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(); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof ComputeEngineAuthCredentialsState; - } - } - - ComputeEngineAuthCredentials() throws IOException, GeneralSecurityException { - computeCredential = getComputeCredential(); - } - - @Override - protected HttpRequestInitializer httpRequestInitializer(HttpTransport transport, - Set scopes) { - return computeCredential; - } - - @Override - public RestorableState capture() { - return STATE; - } - } - private static class ApplicationDefaultAuthCredentials extends AuthCredentials { private GoogleCredentials googleCredentials; @@ -264,21 +171,12 @@ public RestorableState capture() { protected abstract HttpRequestInitializer httpRequestInitializer(HttpTransport transport, Set scopes); - public static AuthCredentials createForAppEngine() { - return AppEngineAuthCredentials.INSTANCE; - } - - public static AuthCredentials createForComputeEngine() - throws IOException, GeneralSecurityException { - return new ComputeEngineAuthCredentials(); - } - /** * Returns the Application Default Credentials. * *

Returns the Application Default Credentials which are credentials that identify and * authorize the whole application. This is the built-in service account if running on - * Google Compute Engine or the credentials file can be read from the path in the environment + * Google App/Compute Engine or the credentials file can be read from the path in the environment * variable GOOGLE_APPLICATION_CREDENTIALS. *

* @@ -327,13 +225,4 @@ public static ServiceAccountAuthCredentials createForJson(InputStream jsonCreden public static AuthCredentials noCredentials() { return ServiceAccountAuthCredentials.NO_CREDENTIALS; } - - static ComputeCredential getComputeCredential() throws IOException, GeneralSecurityException { - NetHttpTransport transport = GoogleNetHttpTransport.newTrustedTransport(); - // Try to connect using Google Compute Engine service account credentials. - ComputeCredential credential = new ComputeCredential(transport, new JacksonFactory()); - // Force token refresh to detect if we are running on Google Compute Engine. - credential.refreshToken(); - return credential; - } } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index 898897833287..876317162add 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -21,10 +21,13 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.google.api.client.extensions.appengine.http.UrlFetchTransport; +import com.google.api.client.googleapis.compute.ComputeCredential; +import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; import com.google.api.client.http.HttpRequest; 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.api.client.json.jackson.JacksonFactory; import com.google.common.collect.Iterables; import com.google.gcloud.spi.ServiceRpcFactory; @@ -41,6 +44,7 @@ import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.URL; +import java.security.GeneralSecurityException; import java.util.Enumeration; import java.util.Locale; import java.util.Objects; @@ -111,12 +115,22 @@ public HttpTransport create() { } // Consider Compute try { - return AuthCredentials.getComputeCredential().getTransport(); + return getComputeHttpTransport(); } catch (Exception e) { // Maybe not on GCE } return new NetHttpTransport(); } + + private static HttpTransport getComputeHttpTransport() + throws IOException, GeneralSecurityException { + NetHttpTransport transport = GoogleNetHttpTransport.newTrustedTransport(); + // Try to connect using Google Compute Engine service account credentials. + ComputeCredential credential = new ComputeCredential(transport, new JacksonFactory()); + // Force token refresh to detect if we are running on Google Compute Engine. + credential.refreshToken(); + return transport; + } } /** @@ -326,28 +340,11 @@ protected ServiceOptions(Class> ser } private static AuthCredentials defaultAuthCredentials() { - // Consider App Engine. This will not be needed once issue #21 is fixed. - if (appEngineAppId() != null) { - try { - return AuthCredentials.createForAppEngine(); - } catch (Exception ignore) { - // Maybe not on App Engine - } - } - try { return AuthCredentials.createApplicationDefaults(); } catch (Exception ex) { - // fallback to old-style - } - - // Consider old-style Compute. This will not be needed once issue #21 is fixed. - try { - return AuthCredentials.createForComputeEngine(); - } catch (Exception ignore) { - // Maybe not on GCE + return AuthCredentials.noCredentials(); } - return AuthCredentials.noCredentials(); } protected static String appEngineAppId() { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 1ad690938ef5..89da268562b3 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 @@ -133,20 +133,22 @@ public class SerializationTest { @Test public void testServiceOptions() throws Exception { - DatastoreOptions options = DatastoreOptions.builder() - .authCredentials(AuthCredentials.createForAppEngine()) - .normalizeDataset(false) - .projectId("ds1") - .build(); + DatastoreOptions options = + DatastoreOptions.builder() + .authCredentials(AuthCredentials.createApplicationDefaults()) + .normalizeDataset(false) + .projectId("ds1") + .build(); DatastoreOptions serializedCopy = serializeAndDeserialize(options); assertEquals(options, serializedCopy); - options = options.toBuilder() - .namespace("ns1") - .retryParams(RetryParams.getDefaultInstance()) - .authCredentials(AuthCredentials.noCredentials()) - .force(true) - .build(); + options = + options.toBuilder() + .namespace("ns1") + .retryParams(RetryParams.getDefaultInstance()) + .authCredentials(AuthCredentials.noCredentials()) + .force(true) + .build(); serializedCopy = serializeAndDeserialize(options); assertEquals(options, serializedCopy); } 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 a125a64df6d6..e8481a2f0d90 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 @@ -73,19 +73,21 @@ public class SerializationTest { @Test public void testServiceOptions() throws Exception { - StorageOptions options = StorageOptions.builder() - .projectId("p1") - .authCredentials(AuthCredentials.createForAppEngine()) - .build(); + StorageOptions options = + StorageOptions.builder() + .projectId("p1") + .authCredentials(AuthCredentials.createApplicationDefaults()) + .build(); StorageOptions serializedCopy = serializeAndDeserialize(options); assertEquals(options, serializedCopy); - options = options.toBuilder() - .projectId("p2") - .retryParams(RetryParams.getDefaultInstance()) - .authCredentials(AuthCredentials.noCredentials()) - .pathDelimiter(":") - .build(); + options = + options.toBuilder() + .projectId("p2") + .retryParams(RetryParams.getDefaultInstance()) + .authCredentials(AuthCredentials.noCredentials()) + .pathDelimiter(":") + .build(); serializedCopy = serializeAndDeserialize(options); assertEquals(options, serializedCopy); } From 9394d2819d2c92dc3421d986846c101d5e65f7ac Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 6 Nov 2015 19:10:24 -0800 Subject: [PATCH 2/7] Remove DefaultAuthCredentials from serialization tests, since there are no default auth credentials on Travis --- .../test/java/com/google/gcloud/datastore/SerializationTest.java | 1 - .../test/java/com/google/gcloud/storage/SerializationTest.java | 1 - 2 files changed, 2 deletions(-) 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 89da268562b3..129122c8643d 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,6 @@ public class SerializationTest { public void testServiceOptions() throws Exception { DatastoreOptions options = DatastoreOptions.builder() - .authCredentials(AuthCredentials.createApplicationDefaults()) .normalizeDataset(false) .projectId("ds1") .build(); 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 e8481a2f0d90..a0bfa0213796 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 @@ -76,7 +76,6 @@ public void testServiceOptions() throws Exception { StorageOptions options = StorageOptions.builder() .projectId("p1") - .authCredentials(AuthCredentials.createApplicationDefaults()) .build(); StorageOptions serializedCopy = serializeAndDeserialize(options); assertEquals(options, serializedCopy); From 607460518d477a235ebcd8afd155b5c35c220fd2 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 9 Nov 2015 08:19:46 -0800 Subject: [PATCH 3/7] Modify project id lookup order and revert style changes --- README.md | 4 +- .../com/google/gcloud/ServiceOptions.java | 67 ++++++++++--------- .../gcloud/datastore/SerializationTest.java | 22 +++--- .../gcloud/storage/SerializationTest.java | 20 +++--- 4 files changed, 55 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 0833de90dfde..9cdee74ee8f8 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,8 @@ Most `gcloud-java` libraries require a project ID. There are multiple ways to s 1. Project ID supplied when building the service options 2. Project ID specified by the environment variable `GCLOUD_PROJECT` 3. App Engine project ID -4. Compute Engine project ID -5. Google Cloud SDK project ID +4. Google Cloud SDK project ID +5. Compute Engine project ID Authentication -------------- diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index 876317162add..298a1223acac 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -364,19 +364,6 @@ protected String defaultProject() { } protected static String googleCloudProjectId() { - try { - URL url = new URL("http://metadata/computeMetadata/v1/project/project-id"); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestProperty("X-Google-Metadata-Request", "True"); - InputStream input = connection.getInputStream(); - if (connection.getResponseCode() == 200) { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, UTF_8))) { - return reader.readLine(); - } - } - } catch (IOException ignore) { - // ignore - } File configDir; if (System.getenv().containsKey("CLOUDSDK_CONFIG")) { configDir = new File(System.getenv("CLOUDSDK_CONFIG")); @@ -385,38 +372,52 @@ protected static String googleCloudProjectId() { } else { configDir = new File(System.getProperty("user.home"), ".config/gcloud"); } - FileReader fileReader; + FileReader fileReader = null; try { fileReader = new FileReader(new File(configDir, "configurations/config_default")); } catch (FileNotFoundException newConfigFileNotFoundEx) { try { fileReader = new FileReader(new File(configDir, "properties")); } catch (FileNotFoundException oldConfigFileNotFoundEx) { - // return null if we can't find config file - return null; + // ignore } } - try (BufferedReader reader = new BufferedReader(fileReader)) { - String line; - String section = null; - Pattern projectPattern = Pattern.compile("^project\\s*=\\s*(.*)$"); - Pattern sectionPattern = Pattern.compile("^\\[(.*)\\]$"); - while ((line = reader.readLine()) != null) { - if (line.isEmpty() || line.startsWith(";")) { - continue; - } - line = line.trim(); - Matcher matcher = sectionPattern.matcher(line); - if (matcher.matches()) { - section = matcher.group(1); - } else if (section == null || section.equals("core")) { - matcher = projectPattern.matcher(line); + if (fileReader != null) { + try (BufferedReader reader = new BufferedReader(fileReader)) { + String line; + String section = null; + Pattern projectPattern = Pattern.compile("^project\\s*=\\s*(.*)$"); + Pattern sectionPattern = Pattern.compile("^\\[(.*)\\]$"); + while ((line = reader.readLine()) != null) { + if (line.isEmpty() || line.startsWith(";")) { + continue; + } + line = line.trim(); + Matcher matcher = sectionPattern.matcher(line); if (matcher.matches()) { - return matcher.group(1); + section = matcher.group(1); + } else if (section == null || section.equals("core")) { + matcher = projectPattern.matcher(line); + if (matcher.matches()) { + return matcher.group(1); + } } } + } catch (IOException ex) { + // ignore } - } catch (IOException ex) { + } + try { + URL url = new URL("http://metadata/computeMetadata/v1/project/project-id"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestProperty("X-Google-Metadata-Request", "True"); + InputStream input = connection.getInputStream(); + if (connection.getResponseCode() == 200) { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, UTF_8))) { + return reader.readLine(); + } + } + } catch (IOException ignore) { // ignore } // return null if can't determine 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 129122c8643d..48259f7a1395 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 @@ -133,21 +133,19 @@ public class SerializationTest { @Test public void testServiceOptions() throws Exception { - DatastoreOptions options = - DatastoreOptions.builder() - .normalizeDataset(false) - .projectId("ds1") - .build(); + DatastoreOptions options = DatastoreOptions.builder() + .normalizeDataset(false) + .projectId("ds1") + .build(); DatastoreOptions serializedCopy = serializeAndDeserialize(options); assertEquals(options, serializedCopy); - options = - options.toBuilder() - .namespace("ns1") - .retryParams(RetryParams.getDefaultInstance()) - .authCredentials(AuthCredentials.noCredentials()) - .force(true) - .build(); + options = options.toBuilder() + .namespace("ns1") + .retryParams(RetryParams.getDefaultInstance()) + .authCredentials(AuthCredentials.noCredentials()) + .force(true) + .build(); serializedCopy = serializeAndDeserialize(options); assertEquals(options, serializedCopy); } 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 a0bfa0213796..6ed8046e35a2 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 @@ -73,20 +73,18 @@ public class SerializationTest { @Test public void testServiceOptions() throws Exception { - StorageOptions options = - StorageOptions.builder() - .projectId("p1") - .build(); + StorageOptions options = StorageOptions.builder() + .projectId("p1") + .build(); StorageOptions serializedCopy = serializeAndDeserialize(options); assertEquals(options, serializedCopy); - options = - options.toBuilder() - .projectId("p2") - .retryParams(RetryParams.getDefaultInstance()) - .authCredentials(AuthCredentials.noCredentials()) - .pathDelimiter(":") - .build(); + options = options.toBuilder() + .projectId("p2") + .retryParams(RetryParams.getDefaultInstance()) + .authCredentials(AuthCredentials.noCredentials()) + .pathDelimiter(":") + .build(); serializedCopy = serializeAndDeserialize(options); assertEquals(options, serializedCopy); } From a5607774aee109dea6de6202a8f9ffb6652bcb6f Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 18 Nov 2015 15:28:48 -0800 Subject: [PATCH 4/7] Use version auth library verison 0.3.1 to avoid NPE --- gcloud-java-core/pom.xml | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index e849594226db..ea10f5145800 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -20,12 +20,29 @@ com.google.auth google-auth-library-credentials - 0.1.0 + 0.3.1 com.google.auth google-auth-library-oauth2-http - 0.1.0 + 0.3.1 + + + com.google.guava + guava-jdk5 + + + + + com.google.auth + google-auth-library-appengine + 0.3.1 + + + com.google.guava + guava-jdk5 + + com.google.http-client From 539ac61bfc31a544bb6ebf5a29d680bbaf618110 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 23 Nov 2015 13:09:42 -0800 Subject: [PATCH 5/7] Add back AppEngineCredentials --- README.md | 6 +-- gcloud-java-core/pom.xml | 11 ----- .../com/google/gcloud/AuthCredentials.java | 46 ++++++++++++++++++- .../com/google/gcloud/ServiceOptions.java | 9 ++++ .../gcloud/datastore/SerializationTest.java | 1 + .../gcloud/storage/SerializationTest.java | 1 + 6 files changed, 59 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index ccdd18c31052..c697796f0a4f 100644 --- a/README.md +++ b/README.md @@ -96,9 +96,9 @@ There are multiple ways to authenticate to use Google Cloud services. `gcloud-java` looks for credentials in the following order, stopping once it finds credentials: 1. Credentials supplied when building the service options -2. Key file pointed to by the GOOGLE_APPLICATION_CREDENTIALS environment variable -3. Google Cloud SDK credentials -4. App Engine credentials +2. App Engine credentials +3. Key file pointed to by the GOOGLE_APPLICATION_CREDENTIALS environment variable +4. Google Cloud SDK credentials 5. Compute Engine credentials Google Cloud Datastore diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index e2ac0ddd81b6..c0248004d335 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -33,17 +33,6 @@ - - com.google.auth - google-auth-library-appengine - 0.3.1 - - - com.google.guava - guava-jdk5 - - - com.google.http-client google-http-client diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index 09cdcc16f7de..3303e4f8a652 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; +import com.google.api.client.googleapis.extensions.appengine.auth.oauth2.AppIdentityCredential; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.HttpTransport; import com.google.api.client.json.jackson.JacksonFactory; @@ -38,6 +39,45 @@ */ public abstract class AuthCredentials implements Restorable { + private static class AppEngineAuthCredentials extends AuthCredentials { + + private static final AuthCredentials INSTANCE = new AppEngineAuthCredentials(); + private static final AppEngineAuthCredentialsState STATE = + new AppEngineAuthCredentialsState(); + + private static class AppEngineAuthCredentialsState + implements RestorableState, 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 scopes) { + return new AppIdentityCredential(scopes); + } + + @Override + public RestorableState capture() { + return STATE; + } + } + public static class ServiceAccountAuthCredentials extends AuthCredentials { private final String account; @@ -181,12 +221,16 @@ public RestorableState capture() { protected abstract HttpRequestInitializer httpRequestInitializer(HttpTransport transport, Set scopes); + public static AuthCredentials createForAppEngine() { + return AppEngineAuthCredentials.INSTANCE; + } + /** * Returns the Application Default Credentials. * *

Returns the Application Default Credentials which are credentials that identify and * authorize the whole application. This is the built-in service account if running on - * Google App/Compute Engine or the credentials file can be read from the path in the environment + * Google Compute Engine or the credentials file can be read from the path in the environment * variable GOOGLE_APPLICATION_CREDENTIALS. *

* diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index e5dba231d3ff..a5601e35a6db 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -356,6 +356,15 @@ protected boolean projectIdRequired() { } private static AuthCredentials defaultAuthCredentials() { + // Consider App Engine. + if (appEngineAppId() != null) { + try { + return AuthCredentials.createForAppEngine(); + } catch (Exception ignore) { + // Maybe not on App Engine + } + } + try { return AuthCredentials.createApplicationDefaults(); } catch (Exception ex) { 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 8fba8de8866b..32e14fb47ea0 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -134,6 +134,7 @@ public class SerializationTest { @Test public void testServiceOptions() throws Exception { DatastoreOptions options = DatastoreOptions.builder() + .authCredentials(AuthCredentials.createForAppEngine()) .normalizeDataset(false) .projectId("ds1") .build(); 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 a1b647fbba07..2d80191aeb2d 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 @@ -75,6 +75,7 @@ public class SerializationTest { public void testServiceOptions() throws Exception { StorageOptions options = StorageOptions.builder() .projectId("p1") + .authCredentials(AuthCredentials.createForAppEngine()) .build(); StorageOptions serializedCopy = serializeAndDeserialize(options); assertEquals(options, serializedCopy); From 2ef47e869450d14d4a1153bcbff17e1c9c36ea60 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 24 Nov 2015 13:20:16 -0800 Subject: [PATCH 6/7] Use NetHttpTransport when running on Compute --- .../com/google/gcloud/ServiceOptions.java | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index a5601e35a6db..25fda29c363d 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -21,13 +21,10 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.google.api.client.extensions.appengine.http.UrlFetchTransport; -import com.google.api.client.googleapis.compute.ComputeCredential; -import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; import com.google.api.client.http.HttpRequest; 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.api.client.json.jackson.JacksonFactory; import com.google.common.collect.Iterables; import com.google.gcloud.spi.ServiceRpcFactory; @@ -44,7 +41,6 @@ import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.URL; -import java.security.GeneralSecurityException; import java.util.Enumeration; import java.util.Locale; import java.util.Objects; @@ -113,24 +109,8 @@ public HttpTransport create() { // Maybe not on App Engine } } - // Consider Compute - try { - return getComputeHttpTransport(); - } catch (Exception e) { - // Maybe not on GCE - } return new NetHttpTransport(); } - - private static HttpTransport getComputeHttpTransport() - throws IOException, GeneralSecurityException { - NetHttpTransport transport = GoogleNetHttpTransport.newTrustedTransport(); - // Try to connect using Google Compute Engine service account credentials. - ComputeCredential credential = new ComputeCredential(transport, new JacksonFactory()); - // Force token refresh to detect if we are running on Google Compute Engine. - credential.refreshToken(); - return transport; - } } /** From f87a394379e3ecb662370da5dc5e2b0ddfa4a91f Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 24 Nov 2015 18:40:22 -0800 Subject: [PATCH 7/7] Fix dependency on two different versions of the GoogleCredential class --- gcloud-java-datastore/pom.xml | 6 ++++++ gcloud-java-storage/pom.xml | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index f2743c8e2af1..4bf5caab2ff8 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -27,6 +27,12 @@ google-api-services-datastore-protobuf v1beta2-rev1-2.1.2 compile + + + com.google.api-client + google-api-client + +
junit diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index b592200243ef..3e0b6a9490a8 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -32,6 +32,10 @@ com.google.guava guava-jdk5 + + com.google.api-client + google-api-client +