You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ad...@apache.org on 2014/11/10 18:19:42 UTC
[6/6] jclouds-labs-google git commit: * Removed the need for users to
manually specify the current project name everywhere. * Documented why we
implicitly lookup project name using project id;
corrected README, pom, ApiMetadata and added tests. * I
* Removed the need for users to manually specify the current project name everywhere.
* Documented why we implicitly lookup project name using project id; corrected README, pom, ApiMetadata and added tests.
* Introduced jclouds.google-compute-engine.project-name property used to adjust the project commands affect.
* Flattened quasi-generated pagination classes into package-private members of their callers.
* Removed invalid fallbacks for lists. List responses are empty; they don't return 4xx!
* Adjusted test configuration to allow bearer token properly.
Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/commit/37e0397d
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/tree/37e0397d
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/diff/37e0397d
Branch: refs/heads/master
Commit: 37e0397d9407da694413b5c647b79f9532f10cd1
Parents: 6b5643c
Author: Adrian Cole <ac...@twitter.com>
Authored: Sun Nov 9 12:26:53 2014 -0800
Committer: Adrian Cole <ac...@twitter.com>
Committed: Mon Nov 10 09:19:14 2014 -0800
----------------------------------------------------------------------
google-compute-engine/README.md | 70 ++++++
google-compute-engine/README.txt | 63 -----
google-compute-engine/pom.xml | 26 +-
.../GoogleComputeEngineApi.java | 247 +++++++------------
.../GoogleComputeEngineApiMetadata.java | 16 +-
.../GoogleComputeEngineConstants.java | 41 ---
.../GoogleComputeEngineFallbacks.java | 18 --
.../compute/GoogleComputeEngineService.java | 11 +-
.../GoogleComputeEngineServiceAdapter.java | 25 +-
...GoogleComputeEngineServiceContextModule.java | 4 +-
...ogleComputeEngineSecurityGroupExtension.java | 36 ++-
.../functions/CreateNetworkIfNeeded.java | 15 +-
.../compute/functions/FindNetworkOrCreate.java | 9 +-
.../functions/NetworkToSecurityGroup.java | 13 +-
.../compute/functions/Resources.java | 11 +-
...desWithGroupEncodedIntoNameThenAddToSet.java | 8 +-
.../config/CurrentProject.java | 31 +++
.../GoogleComputeEngineHttpApiModule.java | 116 ++++++---
.../config/GoogleComputeEngineProperties.java | 52 ++++
.../config/GoogleComputeEngineScopes.java | 28 +++
.../googlecomputeengine/config/UserProject.java | 33 ---
.../googlecomputeengine/domain/NewInstance.java | 22 +-
.../features/AddressApi.java | 55 +++--
.../features/AggregatedListApi.java | 71 ++----
.../googlecomputeengine/features/DiskApi.java | 53 ++--
.../features/DiskTypeApi.java | 56 +++--
.../features/FirewallApi.java | 54 ++--
.../features/ForwardingRuleApi.java | 55 +++--
.../features/HttpHealthCheckApi.java | 52 ++--
.../googlecomputeengine/features/ImageApi.java | 132 ++++++++--
.../features/InstanceApi.java | 97 ++++----
.../features/MachineTypeApi.java | 51 ++--
.../features/NetworkApi.java | 52 ++--
.../features/OperationApi.java | 165 ++++++++-----
.../features/ProjectApi.java | 19 +-
.../googlecomputeengine/features/RegionApi.java | 55 +++--
.../googlecomputeengine/features/RouteApi.java | 52 ++--
.../features/SnapshotApi.java | 52 ++--
.../features/TargetPoolApi.java | 54 ++--
.../googlecomputeengine/features/ZoneApi.java | 55 +++--
.../functions/internal/AdvancingIterator.java | 48 ----
.../internal/BaseToIteratorOfListPage.java | 61 -----
.../BaseWithRegionToIteratorOfListPage.java | 67 -----
.../BaseWithZoneToIteratorOfListPage.java | 68 -----
.../functions/internal/PATCH.java | 35 ---
.../functions/internal/ParseAddresses.java | 55 -----
.../functions/internal/ParseDiskTypes.java | 55 -----
.../functions/internal/ParseDisks.java | 56 -----
.../functions/internal/ParseFirewalls.java | 55 -----
.../internal/ParseForwardingRules.java | 57 -----
.../internal/ParseGlobalOperations.java | 56 -----
.../internal/ParseHttpHealthChecks.java | 58 -----
.../functions/internal/ParseImages.java | 55 -----
.../functions/internal/ParseInstances.java | 56 -----
.../functions/internal/ParseMachineTypes.java | 56 -----
.../functions/internal/ParseNetworks.java | 55 -----
.../internal/ParseRegionOperations.java | 77 ------
.../functions/internal/ParseRegions.java | 55 -----
.../functions/internal/ParseRoutes.java | 56 -----
.../functions/internal/ParseSnapshots.java | 55 -----
.../functions/internal/ParseTargetPools.java | 60 -----
.../functions/internal/ParseZoneOperations.java | 77 ------
.../functions/internal/ParseZones.java | 56 -----
.../internal/AdvancingIterator.java | 48 ++++
.../internal/BaseArg0ToIteratorOfListPage.java | 63 +++++
.../BaseCallerArg0ToIteratorOfListPage.java | 63 +++++
.../internal/BaseToIteratorOfListPage.java | 54 ++++
.../googlecomputeengine/internal/ListPages.java | 14 ++
.../googlecomputeengine/internal/PATCH.java | 35 +++
...eEngineAuthenticatedRestContextLiveTest.java | 10 +-
.../GoogleComputeEngineServiceLiveTest.java | 22 +-
.../GoogleComputeEngineServiceMockTest.java | 19 +-
...uteEngineSecurityGroupExtensionLiveTest.java | 7 +
.../functions/CreateNetworkIfNeededTest.java | 20 +-
.../functions/FindNetworkOrCreateTest.java | 15 +-
.../functions/NetworkToSecurityGroupTest.java | 9 +-
.../UseApiToResolveProjectNameMockTest.java | 76 ++++++
.../features/AddressApiExpectTest.java | 52 ++--
.../features/AddressApiLiveTest.java | 2 +-
.../features/AggregatedListApiLiveTest.java | 2 +-
.../features/AggregatedListApiMockTest.java | 8 +-
.../features/DiskApiExpectTest.java | 62 +++--
.../features/DiskApiLiveTest.java | 10 +-
.../features/DiskTypeApiExpectTest.java | 27 +-
.../features/DiskTypeApiLiveTest.java | 2 +-
.../features/FirewallApiExpectTest.java | 54 ++--
.../features/FirewallApiLiveTest.java | 14 +-
.../features/ForwardingRuleApiExpectTest.java | 54 ++--
.../features/ForwardingRuleApiLiveTest.java | 6 +-
.../features/HttpHealthCheckApiExpectTest.java | 62 +++--
.../features/HttpHealthCheckApiLiveTest.java | 2 +-
.../features/ImageApiExpectTest.java | 146 ++++++-----
.../features/ImageApiLiveTest.java | 30 +--
.../features/InstanceApiExpectTest.java | 73 +++---
.../features/InstanceApiLiveTest.java | 20 +-
.../features/MachineTypeApiExpectTest.java | 26 +-
.../features/MachineTypeApiLiveTest.java | 2 +-
.../features/NetworkApiExpectTest.java | 52 ++--
.../features/NetworkApiLiveTest.java | 2 +-
.../features/OperationApiExpectTest.java | 140 +++++------
.../features/OperationApiLiveTest.java | 8 +-
.../features/ProjectApiExpectTest.java | 17 +-
.../features/ProjectApiLiveTest.java | 71 ++----
.../features/RegionApiExpectTest.java | 25 +-
.../features/RegionApiLiveTest.java | 2 +-
.../features/RouteApiExpectTest.java | 52 ++--
.../features/RouteApiLiveTest.java | 12 +-
.../features/SnapshotApiExpectTest.java | 28 +--
.../features/SnapshotApiLiveTest.java | 4 +-
.../features/TargetPoolApiExpectTest.java | 98 ++++----
.../features/TargetPoolApiLiveTest.java | 25 +-
.../features/ZoneApiExpectTest.java | 25 +-
.../features/ZoneApiLiveTest.java | 2 +-
.../ToIteratorOfListPageExpectTest.java | 11 +-
.../BaseGoogleComputeEngineApiLiveTest.java | 61 ++---
.../BaseGoogleComputeEngineApiMockTest.java | 17 +-
.../BaseGoogleComputeEngineExpectTest.java | 21 +-
.../internal/TestProperties.java | 58 +++++
.../parse/ParseProjectTest.java | 2 +-
.../test/resources/instance_insert_simple.json | 2 +-
.../src/test/resources/list_empty.json | 5 +
.../src/test/resources/project.json | 2 +-
122 files changed, 2160 insertions(+), 3095 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/README.md
----------------------------------------------------------------------
diff --git a/google-compute-engine/README.md b/google-compute-engine/README.md
new file mode 100644
index 0000000..47ff426
--- /dev/null
+++ b/google-compute-engine/README.md
@@ -0,0 +1,70 @@
+jclouds Google Compute Engine Provider
+======
+
+
+Authenticating into the instances:
+--------
+
+User:
+If no user is provided in GoogleComputeEngineTemplateOptions when launching an instance by default "jclouds" is used.
+
+Credential:
+
+GCE uses exclusively ssh keys to login into instances.
+In order for an instance to be sshable a public key must be installed. Public keys are installed if they are present in the project or instance's metatada.
+
+For an instance to be ssable one of the following must happen:
+1 - the project's metadata has an adequately built "sshKeys" entry and a corresponding private key is provided in GoogleComputeEngineTemplateOptions when createNodesInGroup is called.
+2 - an instance of GoogleComputeEngineTemplateOptions with an adequate public and private key is provided.
+
+NOTE: if methods 2 is chosen the global project keys will not be installed in the instance.
+
+Please refer to Google's documentation on how to form valid project wide ssh keys metadata entries.
+
+FAQ:
+--------
+
+* Q. What is the identity for GCE?
+
+A. the identity is the developer email which can be obtained from the admin GUI. Its usually something in the form: [PROJECT_ID](https://cloud.google.com/compute/docs/overview#projectids)@developer.gserviceaccount.com
+
+* Q. What is the credential for GCE
+
+A. the credential is a private key, in pem format. It can be extracted from the p12 keystore that is obtained when creating a "Service Account" (in the GUI: Google apis console > Api Access > Create another client ID > "Service Account"
+
+* Q. How to convert a p12 keystore into a pem format jclouds Google Compute Engine can handle:
+
+A.
+
+1. Convert the p12 file into pem format (it will ask for the keystore password, which is usually "notasecret"):
+ openssl pkcs12 -in <my_keystore>.p12 -out <my_keystore>.pem -nodes
+
+2. Extract only the pk and remove passphrase
+ openssl rsa -in <my_keystore>.pem -out <my_key>.pem
+
+The last file (<my_key>.pem) should contain the pk that needs to be passed to `ContextBuilder.credential()` for the provider `google-compute-engine`.
+
+
+Running the live tests:
+--------
+
+1. Place the following in your ~/.m2/settings.xml in a profile enabled when live:
+```
+ <test.google-compute-engine.identity>PROJECT_ID@developer.gserviceaccount.com</test.google-compute-engine.identity>
+ <test.google-compute-engine.credential>-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQRRbRqVDtJLN1MO/xJoKqZuphDeBh5jIKueW3aNIiWs1XFcct+h
+-- this text is literally from your <my_key>.pem
+aH7xmpHSTbbXmQkuuv+z8EKijigprd/FoJpTX1f5/R+4wQ==
+-----END RSA PRIVATE KEY-----</test.google-compute-engine.credential>
+ </properties>
+```
+Or, if using an existing OAuth Bearer Token for authentication.
+```
+ <test.google-compute-engine.identity>PROJECT_ID@developer.gserviceaccount.com</test.google-compute-engine.identity>
+ <test.google-compute-engine.credential>EXISTING_BEARER_TOKEN</test.google-compute-engine.credential>
+ <test.jclouds.oauth.credential-type>bearerTokenCredentials</test.jclouds.oauth.credential-type>
+ </properties>
+```
+
+2. mvn clean install -Plive
+
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/README.txt
----------------------------------------------------------------------
diff --git a/google-compute-engine/README.txt b/google-compute-engine/README.txt
deleted file mode 100644
index 7c23784..0000000
--- a/google-compute-engine/README.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-jclouds Google Compute Engine Provider
-======
-
-
-Authenticating into the instances:
---------
-
-User:
-If no user is provided in GoogleComputeEngineTemplateOptions when launching an instance by default "jclouds" is used.
-
-Credential:
-
-GCE uses exclusively ssh keys to login into instances.
-In order for an instance to be sshable a public key must be installed. Public keys are installed if they are present in the project or instance's metatada.
-
-For an instance to be ssable one of the following must happen:
-1 - the project's metadata has an adequately built "sshKeys" entry and a corresponding private key is provided in GoogleComputeEngineTemplateOptions when createNodesInGroup is called.
-2 - an instance of GoogleComputeEngineTemplateOptions with an adequate public and private key is provided.
-
-NOTE: if methods 2 is chosen the global project keys will not be installed in the instance.
-
-Please refer to Google's documentation on how to form valid project wide ssh keys metadata entries.
-
-FAQ:
---------
-
-* Q. What is the identity for GCE?
-
-A. the identity is the developer email which can be obtained from the admin GUI. Its usually something in the form: <my account id>@developer.gserviceaccount.com
-
-* Q. What is the credential for GCE
-
-A. the credential is a private key, in pem format. It can be extracted from the p12 keystore that is obtained when creating a "Service Account" (in the GUI: Google apis console > Api Access > Create another client ID > "Service Account"
-
-* Q. How to convert a p12 keystore into a pem format jclouds Google Compute Engine can handle:
-
-A.
-
-1. Convert the p12 file into pem format (it will ask for the keystore password, which is usually "notasecret"):
- openssl pkcs12 -in <my_keystore>.p12 -out <my_keystore>.pem -nodes
-
-2. Extract only the pk and remove passphrase
- openssl rsa -in <my_keystore>.pem -out <my_key>.pem
-
-The last file (<my_key>.pem) should contain the pk that needs to be passed to `ContextBuilder.credential()` for the provider `google-compute-engine`.
-
-
-Running the live tests:
---------
-
-1. Place the following in your ~/.m2/settings.xml in a profile enabled when live:
-```
- <test.google-compute-engine.identity>YOUR_ACCOUNT_NUMBER@developer.gserviceaccount.com</test.google-compute-engine.identity>
- <test.google-compute-engine.credential>-----BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQRRbRqVDtJLN1MO/xJoKqZuphDeBh5jIKueW3aNIiWs1XFcct+h
--- this text is literally from your <my_key>.pem
-aH7xmpHSTbbXmQkuuv+z8EKijigprd/FoJpTX1f5/R+4wQ==
------END RSA PRIVATE KEY-----</test.google-compute-engine.credential>
- </properties>
-```
-
-2. mvn clean install -Plive
-
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/pom.xml
----------------------------------------------------------------------
diff --git a/google-compute-engine/pom.xml b/google-compute-engine/pom.xml
index 3ca9004..38de821 100644
--- a/google-compute-engine/pom.xml
+++ b/google-compute-engine/pom.xml
@@ -33,10 +33,11 @@
<description>jclouds components to access GoogleCompute</description>
<properties>
- <test.google-compute-engine.identity>Email associated with the Google API client_id
- </test.google-compute-engine.identity>
- <test.google-compute-engine.credential>Private key (PKCS12 file) associated with the Google API client_id
- </test.google-compute-engine.credential>
+ <test.google-compute-engine.identity>client_email which usually looks like project_id@developer.gserviceaccount.com</test.google-compute-engine.identity>
+ <test.google-compute-engine.credential>Private key (PEM encoded PKCS12 file or literal) associated with the client_email</test.google-compute-engine.credential>
+ <!-- Add this property to use a different project, or avoid looking up the project for each test. -->
+ <test.jclouds.google-compute-engine.project-name></test.jclouds.google-compute-engine.project-name>
+ <test.jclouds.oauth.credential-type>serviceAccountCredentials</test.jclouds.oauth.credential-type>
<test.google-compute-engine.api-version>v1</test.google-compute-engine.api-version>
<test.google-compute-engine.build-version/>
<test.google-compute-engine.template>imageNameMatches=debian-7-wheezy-v[0-9]*,locationId=us-central1-a,minRam=2048</test.google-compute-engine.template>
@@ -139,17 +140,12 @@
<configuration>
<threadCount>1</threadCount>
<systemPropertyVariables>
- <test.google-compute-engine.identity>${test.google-compute-engine.identity}
- </test.google-compute-engine.identity>
- <test.google-compute-engine.credential>
- ${test.google-compute-engine.credential}
- </test.google-compute-engine.credential>
- <test.google-compute-engine.api-version>
- ${test.google-compute-engine.api-version}
- </test.google-compute-engine.api-version>
- <test.google-compute-engine.build-version>
- ${test.google-compute-engine.build-version}
- </test.google-compute-engine.build-version>
+ <test.google-compute-engine.identity>${test.google-compute-engine.identity}</test.google-compute-engine.identity>
+ <test.google-compute-engine.credential>${test.google-compute-engine.credential}</test.google-compute-engine.credential>
+ <test.jclouds.google-compute-engine.project-name>${test.jclouds.google-compute-engine.project-name}</test.jclouds.google-compute-engine.project-name>
+ <test.jclouds.oauth.credential-type>${test.jclouds.oauth.credential-type}</test.jclouds.oauth.credential-type>
+ <test.google-compute-engine.api-version>${test.google-compute-engine.api-version}</test.google-compute-engine.api-version>
+ <test.google-compute-engine.build-version>${test.google-compute-engine.build-version}</test.google-compute-engine.build-version>
<test.google-compute-engine.template>${test.google-compute-engine.template}</test.google-compute-engine.template>
</systemPropertyVariables>
</configuration>
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java
index 89d465b..4757c9d 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java
@@ -21,6 +21,7 @@ import java.io.Closeable;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
+import org.jclouds.googlecomputeengine.config.CurrentProject;
import org.jclouds.googlecomputeengine.features.AddressApi;
import org.jclouds.googlecomputeengine.features.AggregatedListApi;
import org.jclouds.googlecomputeengine.features.DiskApi;
@@ -40,171 +41,89 @@ import org.jclouds.googlecomputeengine.features.SnapshotApi;
import org.jclouds.googlecomputeengine.features.TargetPoolApi;
import org.jclouds.googlecomputeengine.features.ZoneApi;
import org.jclouds.rest.annotations.Delegate;
+import org.jclouds.rest.annotations.Endpoint;
public interface GoogleComputeEngineApi extends Closeable {
- /**
- * Provides access to Address features
- *
- * @param projectName the name of the project
- * @param region the name of the region scoping this request.
- */
- @Delegate
- @Path("/projects/{project}/regions/{region}")
- AddressApi getAddressApi(@PathParam("project") String projectName, @PathParam("region") String region);
-
- /**
- * Provides access to Aggregated list features
- *
- * @param projectName the name of the project
- */
- @Delegate
- @Path("/projects/{project}")
- AggregatedListApi aggregatedList(@PathParam("project") String projectName);
-
- /**
- * Provides access to Disk features
- *
- * @param projectName the name of the project
- * @param zone the name of the zone scoping this request.
- */
- @Delegate
- @Path("/projects/{project}/zones/{zone}")
- DiskApi getDiskApi(@PathParam("project") String projectName, @PathParam("zone") String zone);
-
- /**
- * Provides access to DiskType features
- *
- * @param projectName the name of the project
- * @param zone the name of the zone scoping this request.
- */
- @Delegate
- @Path("/projects/{project}/zones/{zone}")
- DiskTypeApi getDiskTypeApi(@PathParam("project") String projectName, @PathParam("zone") String zone);
-
- /**
- * Provides access to Firewall features
- *
- * @param projectName the name of the project
- */
- @Delegate
- @Path("/projects/{project}/global")
- FirewallApi getFirewallApi(@PathParam("project") String projectName);
-
- /**
- * Provides access to ForwardingRule features
- *
- * @param projectName the name of the project
- * @param region the name of the region scoping this request.
- */
- @Delegate
- @Path("/projects/{project}/regions/{region}")
- ForwardingRuleApi getForwardingRuleApi(@PathParam("project") String projectName, @PathParam("region") String region);
-
- /**
- * Provides access to HttpHealthCheck features
- *
- * @param projectName the name of the project
- */
- @Delegate
- @Path("/projects/{project}/global")
- HttpHealthCheckApi getHttpHealthCheckApi(@PathParam("project") String projectName);
-
- /**
- * Provides access to Image features
- *
- * @param projectName the name of the project
- */
- @Delegate
- @Path("/projects/{project}/global")
- ImageApi getImageApi(@PathParam("project") String projectName);
-
- /**
- * Provides access to Instance features
- *
- * @param projectName the name of the project
- * @param zone zone the instances are in.
- */
- @Delegate
- @Path("/projects/{project}/zones/{zone}")
- InstanceApi getInstanceApi(@PathParam("project") String projectName, @PathParam("zone") String zone);
-
- /**
- * Provides access to MachineType features
- *
- * @param projectName the name of the project
- * @param zone the name of the zone scoping this request.
- */
- @Delegate
- @Path("/projects/{project}/zones/{zone}")
- MachineTypeApi getMachineTypeApi(@PathParam("project") String projectName, @PathParam("zone") String zone);
-
- /**
- * Provides access to Network features
- *
- * @param projectName the name of the project
- */
- @Delegate
- @Path("/projects/{project}/global")
- NetworkApi getNetworkApi(@PathParam("project") String projectName);
-
- /**
- * Provides access to Operation features
- *
- * @param projectName the name of the project
- */
- @Delegate
- OperationApi getOperationApi(@PathParam("project") String projectName);
-
- /**
- * Provides access to Project features
- */
- @Delegate
- ProjectApi getProjectApi();
-
- /**
- * Provides access to Region features
- *
- * @param projectName the name of the project
- */
- @Delegate
- @Path("/projects/{project}")
- RegionApi getRegionApi(@PathParam("project") String projectName);
-
- /**
- * Provides access to Route features
- *
- * @param projectName the name of the project
- */
- @Delegate
- @Path("/projects/{project}/global")
- RouteApi getRouteApi(@PathParam("project") String projectName);
-
- /**
- * Provides access to Snapshot features
- *
- * @param projectName the name of the project
- */
- @Delegate
- @Path("/projects/{project}/global")
- SnapshotApi getSnapshotApi(@PathParam("project") String projectName);
-
- /**
- * Provides access to TargetPool features
- *
- * @param projectName the name of the project
- * @param region the name of the region scoping this request.
- */
- @Delegate
- @Path("/projects/{project}/regions/{region}")
- TargetPoolApi getTargetPoolApi(@PathParam("project") String projectName, @PathParam("region") String region);
-
- /**
- * Provides access to Zone features
- *
- * @param projectName the name of the project
- */
- @Delegate
- @Path("/projects/{project}")
- ZoneApi getZoneApi(@PathParam("project") String projectName);
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ @Path("/regions/{region}")
+ AddressApi addressesInRegion(@PathParam("region") String region);
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ AggregatedListApi aggregatedList();
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ @Path("/zones/{zone}")
+ DiskApi disksInZone(@PathParam("zone") String zone);
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ @Path("/zones/{zone}")
+ DiskTypeApi diskTypesInZone(@PathParam("zone") String zone);
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ @Path("/global")
+ FirewallApi firewalls();
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ @Path("/regions/{region}")
+ ForwardingRuleApi forwardingRulesInRegion(@PathParam("region") String region);
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ @Path("/global")
+ HttpHealthCheckApi httpHeathChecks();
+
+ @Delegate
+ ImageApi images();
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ @Path("/zones/{zone}")
+ InstanceApi instancesInZone(@PathParam("zone") String zone);
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ @Path("/zones/{zone}")
+ MachineTypeApi machineTypesInZone(@PathParam("zone") String zone);
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ @Path("/global")
+ NetworkApi networks();
+
+ @Delegate
+ OperationApi operations();
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ ProjectApi project();
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ RegionApi regions();
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ @Path("/global")
+ RouteApi routes();
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ @Path("/global")
+ SnapshotApi snapshots();
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ @Path("/regions/{region}")
+ TargetPoolApi targetPoolsInRegion(@PathParam("region") String region);
+
+ @Delegate
+ @Endpoint(CurrentProject.class)
+ ZoneApi zones();
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java
index 0c9a23c..32da0eb 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java
@@ -18,9 +18,10 @@ package org.jclouds.googlecomputeengine;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_IMAGE_PROJECTS;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
+import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineProperties.IMAGE_PROJECTS;
+import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineProperties.OPERATION_COMPLETE_INTERVAL;
+import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineProperties.OPERATION_COMPLETE_TIMEOUT;
+import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineProperties.PROJECT_NAME;
import static org.jclouds.oauth.v2.config.OAuthProperties.AUDIENCE;
import static org.jclouds.oauth.v2.config.OAuthProperties.SIGNATURE_OR_MAC_ALGORITHM;
import static org.jclouds.reflect.Reflection2.typeToken;
@@ -40,7 +41,6 @@ import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
public class GoogleComputeEngineApiMetadata extends BaseHttpApiMetadata<GoogleComputeEngineApi> {
-
@Override
public Builder toBuilder() {
return new Builder().fromApiMetadata(this);
@@ -63,7 +63,8 @@ public class GoogleComputeEngineApiMetadata extends BaseHttpApiMetadata<GoogleCo
properties.put(OPERATION_COMPLETE_INTERVAL, 500);
properties.put(OPERATION_COMPLETE_TIMEOUT, 600000);
properties.put(TEMPLATE, "osFamily=DEBIAN,osVersionMatches=7\\..*,locationId=us-central1-a,loginUser=jclouds");
- properties.put(GCE_IMAGE_PROJECTS, "centos-cloud,debian-cloud,rhel-cloud,suse-cloud,opensuse-cloud,gce-nvme,coreos-cloud");
+ properties.put(PROJECT_NAME, ""); // Defaulting to empty helps avoid temptation for optional inject!
+ properties.put(IMAGE_PROJECTS, "centos-cloud,debian-cloud,rhel-cloud,suse-cloud,opensuse-cloud,gce-nvme,coreos-cloud");
return properties;
}
@@ -72,8 +73,9 @@ public class GoogleComputeEngineApiMetadata extends BaseHttpApiMetadata<GoogleCo
protected Builder() {
id("google-compute-engine")
.name("Google Compute Engine Api")
- .identityName("Email associated with the Google API client_id")
- .credentialName("Private key literal associated with the Google API client_id")
+ .identityName("client_email which usually looks like project_id@developer.gserviceaccount.com or " //
+ + "project_id-extended_uid@developer.gserviceaccount.com")
+ .credentialName("PEM encoded P12 private key associated with client_email")
.documentation(URI.create("https://developers.google.com/compute/docs"))
.version("v1")
.defaultEndpoint("https://www.googleapis.com/compute/v1")
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java
deleted file mode 100644
index 5bce914..0000000
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.jclouds.googlecomputeengine;
-
-import com.google.common.annotations.Beta;
-
-public final class GoogleComputeEngineConstants {
-
- public static final String COMPUTE_SCOPE = "https://www.googleapis.com/auth/compute";
-
- public static final String COMPUTE_READONLY_SCOPE = "https://www.googleapis.com/auth/compute.readonly";
-
- /** The total time, in msecs, to wait for an operation to complete. */
- @Beta
- public static final String OPERATION_COMPLETE_TIMEOUT = "jclouds.google-compute-engine.operation-complete-timeout";
-
- /** The interval, in msecs, between calls to check whether an operation has completed. */
- @Beta
- public static final String OPERATION_COMPLETE_INTERVAL = "jclouds.google-compute-engine.operation-complete-interval";
-
- /** The list of projects that will be scanned looking for images. */
- @Beta
- public static final String GCE_IMAGE_PROJECTS = "jclouds.google-compute-engine.image-projects";
-
- private GoogleComputeEngineConstants() {
- }
-}
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineFallbacks.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineFallbacks.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineFallbacks.java
index 4ba6eae..105da4d 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineFallbacks.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineFallbacks.java
@@ -20,15 +20,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.in;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.primitives.Ints.asList;
-import static org.jclouds.Fallbacks.valOnNotFoundOr404;
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
-import java.util.Iterator;
-
import org.jclouds.Fallback;
-import org.jclouds.googlecomputeengine.domain.ListPage;
-
-import com.google.common.collect.Iterators;
public final class GoogleComputeEngineFallbacks {
public static class NullOn400or404 implements Fallback<Object> {
@@ -39,16 +33,4 @@ public final class GoogleComputeEngineFallbacks {
throw propagate(t);
}
}
-
- public static final class EmptyListPageOnNotFoundOr404 implements Fallback<Object> {
- @Override public ListPage<Object> createOrPropagate(Throwable t) throws Exception {
- return valOnNotFoundOr404(ListPage.create(null, null), t);
- }
- }
-
- public static final class EmptyIteratorOnNotFoundOr404 implements Fallback<Object> {
- @Override public Iterator<Object> createOrPropagate(Throwable t) throws Exception {
- return valOnNotFoundOr404(Iterators.emptyIterator(), t);
- }
- }
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java
index 9abd6e7..cd1816c 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java
@@ -57,7 +57,6 @@ import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
-import org.jclouds.googlecomputeengine.config.UserProject;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.domain.Operation;
@@ -76,7 +75,6 @@ public final class GoogleComputeEngineService extends BaseComputeService {
private final Function<Set<? extends NodeMetadata>, Set<String>> findOrphanedGroups;
private final GroupNamingConvention.Factory namingConvention;
private final GoogleComputeEngineApi api;
- private final Supplier<String> project;
private final Predicate<AtomicReference<Operation>> operationDone;
@Inject GoogleComputeEngineService(ComputeServiceContext context,
@@ -111,7 +109,6 @@ public final class GoogleComputeEngineService extends BaseComputeService {
Function<Set<? extends NodeMetadata>, Set<String>> findOrphanedGroups,
GroupNamingConvention.Factory namingConvention,
GoogleComputeEngineApi api,
- @UserProject Supplier<String> project,
Predicate<AtomicReference<Operation>> operationDone) {
super(context, credentialStore, images, hardwareProfiles, locations, listNodesStrategy, getImageStrategy,
getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
@@ -121,7 +118,6 @@ public final class GoogleComputeEngineService extends BaseComputeService {
this.findOrphanedGroups = findOrphanedGroups;
this.namingConvention = namingConvention;
this.api = api;
- this.project = project;
this.operationDone = operationDone;
}
@@ -135,8 +131,8 @@ public final class GoogleComputeEngineService extends BaseComputeService {
private void cleanUpNetworksAndFirewallsForGroup(final String groupName) {
String resourceName = namingConvention.create().sharedNameForGroup(groupName);
- Network network = api.getNetworkApi(project.get()).get(resourceName);
- FirewallApi firewallApi = api.getFirewallApi(project.get());
+ Network network = api.networks().get(resourceName);
+ FirewallApi firewallApi = api.firewalls();
for (Firewall firewall : concat(firewallApi.list())) {
if (firewall == null || !firewall.network().equals(network.selfLink())) {
@@ -152,8 +148,7 @@ public final class GoogleComputeEngineService extends BaseComputeService {
}
}
- AtomicReference<Operation> operation = Atomics
- .newReference(api.getNetworkApi(project.get()).delete(resourceName));
+ AtomicReference<Operation> operation = Atomics.newReference(api.networks().delete(resourceName));
operationDone.apply(operation);
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
index 6406c06..7f15ebb 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
@@ -21,7 +21,7 @@ import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Lists.newArrayList;
import static java.lang.String.format;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_IMAGE_PROJECTS;
+import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineProperties.IMAGE_PROJECTS;
import static org.jclouds.googlecomputeengine.domain.NewInstance.Disk;
import static org.jclouds.googlecomputeengine.internal.ListPages.concat;
@@ -45,7 +45,6 @@ import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.compute.functions.FirewallTagNamingConvention;
import org.jclouds.googlecomputeengine.compute.functions.Resources;
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
-import org.jclouds.googlecomputeengine.config.UserProject;
import org.jclouds.googlecomputeengine.domain.Image;
import org.jclouds.googlecomputeengine.domain.Instance;
import org.jclouds.googlecomputeengine.domain.MachineType;
@@ -58,7 +57,6 @@ import org.jclouds.location.suppliers.all.JustProvider;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
-import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
@@ -82,7 +80,6 @@ public final class GoogleComputeEngineServiceAdapter
private final JustProvider justProvider;
private final GoogleComputeEngineApi api;
- private final Supplier<String> userProject;
private final Resources resources;
private final Map<URI, URI> diskToSourceImage;
private final Predicate<AtomicReference<Operation>> operationDone;
@@ -91,16 +88,14 @@ public final class GoogleComputeEngineServiceAdapter
private final List<String> imageProjects;
@Inject GoogleComputeEngineServiceAdapter(JustProvider justProvider, GoogleComputeEngineApi api,
- @UserProject Supplier<String> userProject,
Predicate<AtomicReference<Operation>> operationDone,
Predicate<AtomicReference<Instance>> instanceVisible,
Map<URI, URI> diskToSourceImage,
Resources resources,
FirewallTagNamingConvention.Factory firewallTagNamingConvention,
- @Named(GCE_IMAGE_PROJECTS) String imageProjects) {
+ @Named(IMAGE_PROJECTS) String imageProjects) {
this.justProvider = justProvider;
this.api = api;
- this.userProject = userProject;
this.operationDone = operationDone;
this.instanceVisible = instanceVisible;
this.diskToSourceImage = diskToSourceImage;
@@ -128,8 +123,8 @@ public final class GoogleComputeEngineServiceAdapter
}
NewInstance newInstance = NewInstance.create(
- hardware.getUri(), // machineType
name, // name
+ hardware.getUri(), // machineType
options.network(), // network
disks, // disks
group // description
@@ -150,7 +145,7 @@ public final class GoogleComputeEngineServiceAdapter
}
String zone = template.getLocation().getId();
- InstanceApi instanceApi = api.getInstanceApi(userProject.get(), zone);
+ InstanceApi instanceApi = api.instancesInZone(zone);
Operation create = instanceApi.create(newInstance);
// We need to see the created instance so that we can access the newly created disk.
@@ -179,7 +174,7 @@ public final class GoogleComputeEngineServiceAdapter
}
@Override public Iterable<MachineType> listHardwareProfiles() {
- return filter(concat(api.aggregatedList(userProject.get()).machineTypes()), new Predicate<MachineType>() {
+ return filter(concat(api.aggregatedList().machineTypes()), new Predicate<MachineType>() {
@Override public boolean apply(MachineType input) {
return input.deprecated() == null;
}
@@ -189,24 +184,24 @@ public final class GoogleComputeEngineServiceAdapter
@Override public Iterable<Image> listImages() {
List<Iterable<Image>> images = newArrayList();
- images.add(concat(api.getImageApi(userProject.get()).list()));
+ images.add(concat(api.images().list()));
for (String project : imageProjects) {
- images.add(concat(api.getImageApi(project).list()));
+ images.add(concat(api.images().listInProject(project)));
}
return Iterables.concat(images);
}
@Override public Image getImage(String selfLink) {
- return resources.image(URI.create(checkNotNull(selfLink, "id")));
+ return api.images().get(URI.create(checkNotNull(selfLink, "id")));
}
/** Unlike EC2, you cannot default GCE instances to a region. Hence, we constrain to zones. */
@Override public Iterable<Location> listLocations() {
Location provider = justProvider.get().iterator().next();
ImmutableList.Builder<Location> zones = ImmutableList.builder();
- for (Region region : concat(api.getRegionApi(userProject.get()).list())) {
+ for (Region region : concat(api.regions().list())) {
Location regionLocation = new LocationBuilder()
.scope(LocationScope.REGION)
.id(region.name())
@@ -229,7 +224,7 @@ public final class GoogleComputeEngineServiceAdapter
}
@Override public Iterable<Instance> listNodes() {
- return concat(api.aggregatedList(userProject.get()).instances());
+ return concat(api.aggregatedList().instances());
}
@Override public Iterable<Instance> listNodesByIds(final Iterable<String> selfLinks) {
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
index 74ce1ae..47d10a9 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
@@ -20,8 +20,8 @@ import static com.google.common.base.Suppliers.memoizeWithExpiration;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
+import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineProperties.OPERATION_COMPLETE_INTERVAL;
+import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineProperties.OPERATION_COMPLETE_TIMEOUT;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
import static org.jclouds.util.Predicates2.retry;
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java
index 01892eb..f98c894 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java
@@ -19,11 +19,11 @@ package org.jclouds.googlecomputeengine.compute.extensions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
import static org.jclouds.googlecomputeengine.compute.predicates.NetworkFirewallPredicates.equalsIpPermission;
import static org.jclouds.googlecomputeengine.compute.predicates.NetworkFirewallPredicates.providesIpPermission;
import static org.jclouds.googlecomputeengine.compute.strategy.CreateNodesWithGroupEncodedIntoNameThenAddToSet.DEFAULT_INTERNAL_NETWORK_RANGE;
+import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineProperties.OPERATION_COMPLETE_INTERVAL;
+import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineProperties.OPERATION_COMPLETE_TIMEOUT;
import static org.jclouds.googlecomputeengine.internal.ListPages.concat;
import static org.jclouds.googlecomputeengine.options.ListOptions.Builder.filter;
import static org.jclouds.util.Predicates2.retry;
@@ -44,7 +44,6 @@ import org.jclouds.domain.Location;
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
import org.jclouds.googlecomputeengine.compute.functions.Resources;
-import org.jclouds.googlecomputeengine.config.UserProject;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.domain.Instance;
import org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface;
@@ -58,7 +57,6 @@ import org.jclouds.net.domain.IpProtocol;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
-import com.google.common.base.Supplier;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
@@ -72,7 +70,6 @@ public final class GoogleComputeEngineSecurityGroupExtension implements Security
private final GoogleComputeEngineApi api;
private final Resources resources;
- private final Supplier<String> userProject;
private final GroupNamingConvention.Factory namingConvention;
private final LoadingCache<NetworkAndAddressRange, Network> networkCreator;
private final Function<Network, SecurityGroup> groupConverter;
@@ -81,14 +78,13 @@ public final class GoogleComputeEngineSecurityGroupExtension implements Security
private final long operationCompleteCheckTimeout;
@Inject GoogleComputeEngineSecurityGroupExtension(GoogleComputeEngineApi api, Resources resources,
- @UserProject Supplier<String> userProject, GroupNamingConvention.Factory namingConvention,
+ GroupNamingConvention.Factory namingConvention,
LoadingCache<NetworkAndAddressRange, Network> networkCreator, Function<Network, SecurityGroup> groupConverter,
Predicate<AtomicReference<Operation>> operationDone,
@Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
@Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout) {
this.api = api;
this.resources = resources;
- this.userProject = userProject;
this.namingConvention = namingConvention;
this.networkCreator = networkCreator;
this.groupConverter = groupConverter;
@@ -99,7 +95,7 @@ public final class GoogleComputeEngineSecurityGroupExtension implements Security
@Override
public Set<SecurityGroup> listSecurityGroups() {
- return FluentIterable.from(concat(api.getNetworkApi(userProject.get()).list())).transform(groupConverter).toSet();
+ return FluentIterable.from(concat(api.networks().list())).transform(groupConverter).toSet();
}
@Override
@@ -132,7 +128,7 @@ public final class GoogleComputeEngineSecurityGroupExtension implements Security
@Override
public SecurityGroup getSecurityGroupById(String id) {
checkNotNull(id, "id");
- Network network = api.getNetworkApi(userProject.get()).get(id);
+ Network network = api.networks().get(id);
if (network == null) {
return null;
@@ -159,17 +155,17 @@ public final class GoogleComputeEngineSecurityGroupExtension implements Security
@Override
public boolean removeSecurityGroup(String id) {
checkNotNull(id, "id");
- if (api.getNetworkApi(userProject.get()).get(id) == null) {
+ if (api.networks().get(id) == null) {
return false;
}
ListOptions options = filter("network eq .*/" + id);
- FluentIterable<Firewall> fws = FluentIterable.from(concat(api.getFirewallApi(userProject.get()).list(options)));
+ FluentIterable<Firewall> fws = FluentIterable.from(concat(api.firewalls().list(options)));
for (Firewall fw : fws) {
AtomicReference<Operation> operation = Atomics
- .newReference(api.getFirewallApi(userProject.get()).delete(fw.name()));
+ .newReference(api.firewalls().delete(fw.name()));
retry(operationDone, operationCompleteCheckTimeout, operationCompleteCheckInterval, MILLISECONDS)
.apply(operation);
@@ -178,7 +174,7 @@ public final class GoogleComputeEngineSecurityGroupExtension implements Security
"Could not delete firewall, operation failed" + operation);
}
- AtomicReference<Operation> operation = Atomics.newReference(api.getNetworkApi(userProject.get()).delete(id));
+ AtomicReference<Operation> operation = Atomics.newReference(api.networks().delete(id));
retry(operationDone, operationCompleteCheckTimeout, operationCompleteCheckInterval, MILLISECONDS)
.apply(operation);
@@ -194,12 +190,12 @@ public final class GoogleComputeEngineSecurityGroupExtension implements Security
checkNotNull(group, "group");
checkNotNull(ipPermission, "ipPermission");
- checkNotNull(api.getNetworkApi(userProject.get()).get(group.getId()) == null, "network for group is null");
+ checkNotNull(api.networks().get(group.getId()) == null, "network for group is null");
ListOptions options = filter("network eq .*/" + group.getName());
if (Iterables
- .any(concat(api.getFirewallApi(userProject.get()).list(options)), providesIpPermission(ipPermission))) {
+ .any(concat(api.firewalls().list(options)), providesIpPermission(ipPermission))) {
// Permission already exists.
return group;
}
@@ -225,7 +221,7 @@ public final class GoogleComputeEngineSecurityGroupExtension implements Security
fwOptions.addAllowedRule(Firewall.Rule.create(ipPermission.getIpProtocol().value().toLowerCase(), ports));
AtomicReference<Operation> operation = Atomics.newReference(
- api.getFirewallApi(userProject.get()).createInNetwork(uniqueFwName, group.getUri(), fwOptions));
+ api.firewalls().createInNetwork(uniqueFwName, group.getUri(), fwOptions));
retry(operationDone, operationCompleteCheckTimeout, operationCompleteCheckInterval, MILLISECONDS)
.apply(operation);
@@ -255,16 +251,16 @@ public final class GoogleComputeEngineSecurityGroupExtension implements Security
checkNotNull(group, "group");
checkNotNull(ipPermission, "ipPermission");
- checkNotNull(api.getNetworkApi(userProject.get()).get(group.getId()) == null, "network for group is null");
+ checkNotNull(api.networks().get(group.getId()) == null, "network for group is null");
ListOptions options = filter("network eq .*/" + group.getName());
- FluentIterable<Firewall> fws = FluentIterable.from(concat(api.getFirewallApi(userProject.get()).list(options)));
+ FluentIterable<Firewall> fws = FluentIterable.from(concat(api.firewalls().list(options)));
for (Firewall fw : fws) {
if (equalsIpPermission(ipPermission).apply(fw)) {
AtomicReference<Operation> operation = Atomics
- .newReference(api.getFirewallApi(userProject.get()).delete(fw.name()));
+ .newReference(api.firewalls().delete(fw.name()));
retry(operationDone, operationCompleteCheckTimeout, operationCompleteCheckInterval, MILLISECONDS)
.apply(operation);
@@ -320,7 +316,7 @@ public final class GoogleComputeEngineSecurityGroupExtension implements Security
private SecurityGroup groupForTagsInNetwork(Network nw, final Collection<String> tags) {
ListOptions opts = filter("network eq .*/" + nw.name());
- List<Firewall> fws = FluentIterable.from(concat(api.getFirewallApi(userProject.get()).list(opts)))
+ List<Firewall> fws = FluentIterable.from(concat(api.firewalls().list(opts)))
.filter(new Predicate<Firewall>() {
@Override public boolean apply(final Firewall input) {
// If any of the targetTags on the firewall apply or the firewall has no target tags...
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeeded.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeeded.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeeded.java
index 338b731..7030c75 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeeded.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeeded.java
@@ -25,24 +25,19 @@ import javax.inject.Inject;
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
-import org.jclouds.googlecomputeengine.config.UserProject;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.domain.Operation;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
import com.google.common.util.concurrent.Atomics;
public final class CreateNetworkIfNeeded implements Function<NetworkAndAddressRange, Network> {
private final GoogleComputeEngineApi api;
- private final Supplier<String> userProject;
private final Predicate<AtomicReference<Operation>> operationDone;
- @Inject CreateNetworkIfNeeded(GoogleComputeEngineApi api, @UserProject Supplier<String> userProject,
- Predicate<AtomicReference<Operation>> operationDone) {
+ @Inject CreateNetworkIfNeeded(GoogleComputeEngineApi api, Predicate<AtomicReference<Operation>> operationDone) {
this.api = api;
- this.userProject = userProject;
this.operationDone = operationDone;
}
@@ -50,13 +45,13 @@ public final class CreateNetworkIfNeeded implements Function<NetworkAndAddressRa
public Network apply(NetworkAndAddressRange input) {
checkNotNull(input, "input");
- Network nw = api.getNetworkApi(userProject.get()).get(input.name());
+ Network nw = api.networks().get(input.name());
if (nw != null) {
return nw;
}
if (input.gateway() != null) {
- AtomicReference<Operation> operation = Atomics.newReference(api.getNetworkApi(userProject.get())
+ AtomicReference<Operation> operation = Atomics.newReference(api.networks()
.createInIPv4RangeWithGateway(input.name(), input.rangeIPv4(), input.gateway()));
operationDone.apply(operation);
@@ -64,13 +59,13 @@ public final class CreateNetworkIfNeeded implements Function<NetworkAndAddressRa
"Could not insert network, operation failed" + operation);
} else {
AtomicReference<Operation> operation = Atomics
- .newReference(api.getNetworkApi(userProject.get()).createInIPv4Range(input.name(), input.rangeIPv4()));
+ .newReference(api.networks().createInIPv4Range(input.name(), input.rangeIPv4()));
operationDone.apply(operation);
checkState(operation.get().httpErrorStatusCode() == null,
"Could not insert network, operation failed" + operation);
}
- return checkNotNull(api.getNetworkApi(userProject.get()).get(input.name()), "no network with name %s was found",
+ return checkNotNull(api.networks().get(input.name()), "no network with name %s was found",
input.name());
}
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreate.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreate.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreate.java
index 2f4c7a4..1137ef9 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreate.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreate.java
@@ -20,27 +20,22 @@ import javax.inject.Inject;
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
-import org.jclouds.googlecomputeengine.config.UserProject;
import org.jclouds.googlecomputeengine.domain.Network;
import com.google.common.base.Function;
-import com.google.common.base.Supplier;
import com.google.common.cache.CacheLoader;
public final class FindNetworkOrCreate extends CacheLoader<NetworkAndAddressRange, Network> {
private final GoogleComputeEngineApi api;
private final Function<NetworkAndAddressRange, Network> networkCreator;
- private final Supplier<String> userProject;
- @Inject FindNetworkOrCreate(GoogleComputeEngineApi api, Function<NetworkAndAddressRange, Network> networkCreator,
- @UserProject Supplier<String> userProject) {
+ @Inject FindNetworkOrCreate(GoogleComputeEngineApi api, Function<NetworkAndAddressRange, Network> networkCreator) {
this.api = api;
this.networkCreator = networkCreator;
- this.userProject = userProject;
}
@Override public Network load(NetworkAndAddressRange in) {
- Network network = api.getNetworkApi(userProject.get()).get(in.name());
+ Network network = api.networks().get(in.name());
if (network != null) {
return network;
} else {
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
index 1bd4811..8306f8b 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
@@ -24,32 +24,23 @@ import javax.inject.Inject;
import org.jclouds.compute.domain.SecurityGroup;
import org.jclouds.compute.domain.SecurityGroupBuilder;
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
-import org.jclouds.googlecomputeengine.config.UserProject;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.options.ListOptions;
import org.jclouds.net.domain.IpPermission;
import com.google.common.base.Function;
-import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
-/**
- * A function for transforming a GCE-specific Network into a generic
- * SecurityGroup object.
- */
public final class NetworkToSecurityGroup implements Function<Network, SecurityGroup> {
private final Function<Firewall, Iterable<IpPermission>> firewallToPerms;
private final GoogleComputeEngineApi api;
- private final Supplier<String> project;
@Inject NetworkToSecurityGroup(Function<Firewall, Iterable<IpPermission>> firewallToPerms,
- GoogleComputeEngineApi api,
- @UserProject Supplier<String> project) {
+ GoogleComputeEngineApi api) {
this.firewallToPerms = firewallToPerms;
this.api = api;
- this.project = project;
}
@Override public SecurityGroup apply(Network network) {
@@ -64,7 +55,7 @@ public final class NetworkToSecurityGroup implements Function<Network, SecurityG
ListOptions options = filter("network eq .*/" + network.name());
- for (Firewall fw : concat(api.getFirewallApi(project.get()).list(options))) {
+ for (Firewall fw : concat(api.firewalls().list(options))) {
permBuilder.addAll(firewallToPerms.apply(fw));
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/Resources.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/Resources.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/Resources.java
index 34d7d54..34ddd50 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/Resources.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/Resources.java
@@ -18,8 +18,8 @@ package org.jclouds.googlecomputeengine.compute.functions;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
+import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineScopes.COMPUTE_READONLY_SCOPE;
+import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineScopes.COMPUTE_SCOPE;
import java.net.URI;
@@ -30,7 +30,6 @@ import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
-import org.jclouds.googlecomputeengine.domain.Image;
import org.jclouds.googlecomputeengine.domain.Instance;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.domain.Operation;
@@ -47,12 +46,6 @@ import org.jclouds.rest.annotations.SkipEncoding;
@Consumes(APPLICATION_JSON)
public interface Resources {
- /** Returns an image by self-link or null if not found. */
- @Named("Images:get")
- @GET
- @OAuthScopes(COMPUTE_READONLY_SCOPE)
- @Fallback(NullOnNotFoundOr404.class) @Nullable Image image(@EndpointParam URI selfLink);
-
/** Returns an instance by self-link or null if not found. */
@Named("Instances:get")
@GET
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
index 3900c46..8c889d2 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
@@ -41,7 +41,6 @@ import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
import org.jclouds.googlecomputeengine.compute.functions.FirewallTagNamingConvention;
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
-import org.jclouds.googlecomputeengine.config.UserProject;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.domain.Firewall.Rule;
import org.jclouds.googlecomputeengine.domain.Network;
@@ -50,7 +49,6 @@ import org.jclouds.googlecomputeengine.features.FirewallApi;
import org.jclouds.googlecomputeengine.options.FirewallOptions;
import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
@@ -66,7 +64,6 @@ public final class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
public static final String DEFAULT_INTERNAL_NETWORK_RANGE = "10.0.0.0/8";
private final GoogleComputeEngineApi api;
- private final Supplier<String> userProject;
private final LoadingCache<NetworkAndAddressRange, Network> networkMap;
private final Predicate<AtomicReference<Operation>> operationDone;
private final FirewallTagNamingConvention.Factory firewallTagNamingConvention;
@@ -80,14 +77,12 @@ public final class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
GoogleComputeEngineApi api,
- @UserProject Supplier<String> userProject,
Predicate<AtomicReference<Operation>> operationDone,
LoadingCache<NetworkAndAddressRange, Network> networkMap,
FirewallTagNamingConvention.Factory firewallTagNamingConvention) {
super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor,
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
this.api = api;
- this.userProject = userProject;
this.operationDone = operationDone;
this.networkMap = networkMap;
this.firewallTagNamingConvention = firewallTagNamingConvention;
@@ -134,8 +129,7 @@ public final class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
private void getOrCreateFirewalls(GoogleComputeEngineTemplateOptions templateOptions, Network network,
FirewallTagNamingConvention naming) {
- String projectName = userProject.get();
- FirewallApi firewallApi = api.getFirewallApi(projectName);
+ FirewallApi firewallApi = api.firewalls();
List<AtomicReference<Operation>> operations = Lists.newArrayList();
for (Integer port : templateOptions.getInboundPorts()) {
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/CurrentProject.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/CurrentProject.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/CurrentProject.java
new file mode 100644
index 0000000..52d1817
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/CurrentProject.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.jclouds.googlecomputeengine.config;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+/** Associated bindings with the current <a href="https://cloud.google.com/compute/docs/projects">project</a>. */
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value = {ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
+@Qualifier
+public @interface CurrentProject {
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineHttpApiModule.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineHttpApiModule.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineHttpApiModule.java
index 4b14d7a..d37c162 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineHttpApiModule.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineHttpApiModule.java
@@ -16,32 +16,51 @@
*/
package org.jclouds.googlecomputeengine.config;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Suppliers.compose;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
+import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineProperties.PROJECT_NAME;
+import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineScopes.COMPUTE_READONLY_SCOPE;
+import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
+import java.net.URI;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
import org.jclouds.domain.Credentials;
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.domain.Project;
import org.jclouds.googlecomputeengine.handlers.GoogleComputeEngineErrorHandler;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.location.Provider;
+import org.jclouds.oauth.v2.config.OAuthScopes;
+import org.jclouds.oauth.v2.filters.OAuthAuthenticationFilter;
+import org.jclouds.providers.ProviderMetadata;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ConfiguresHttpApi;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.rest.config.HttpApiModule;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import com.google.common.base.Function;
-import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
import com.google.common.base.Supplier;
-import com.google.common.collect.Iterables;
+import com.google.common.base.Suppliers;
import com.google.inject.Provides;
@ConfiguresHttpApi
@@ -49,40 +68,79 @@ public final class GoogleComputeEngineHttpApiModule extends HttpApiModule<Google
public GoogleComputeEngineHttpApiModule() {
}
+ @Override protected void configure() {
+ super.configure();
+ bindHttpApi(binder(), UseApiToResolveProjectName.GetProject.class);
+ }
+
@Override protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(GoogleComputeEngineErrorHandler.class);
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(GoogleComputeEngineErrorHandler.class);
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(GoogleComputeEngineErrorHandler.class);
}
+ @Provides @Singleton @CurrentProject Supplier<URI> project(@Named(PROJECT_NAME) final String projectName,
+ @Provider Supplier<URI> defaultEndpoint, final UseApiToResolveProjectName useApiToResolveProjectName,
+ @Provider final Supplier<Credentials> creds, AtomicReference<AuthorizationException> authException,
+ @Named(PROPERTY_SESSION_INTERVAL) long seconds) {
+ // Try to avoid a runtime lookup by accepting a project name supplied in context overrides.
+ if (Strings.emptyToNull(projectName) != null) {
+ return Suppliers.memoizeWithExpiration(Suppliers.compose(new Function<URI, URI>() {
+ @Override public URI apply(URI input) {
+ return URI.create(String.format("%s/projects/%s", input, projectName));
+ }
+ }, defaultEndpoint), seconds, SECONDS);
+ }
+
+ // If the project name wasn't explicitly supplied, then we lookup via api.
+ // This supplier must be defensive against any auth exception.
+ return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier
+ .create(authException, compose(useApiToResolveProjectName, creds), seconds, SECONDS);
+ }
+
/**
- * Since this is caching a direct api call, we memoize, but short-circuit on any auth exception. This prevents
- * excessive errors when things occur in parallel, or as peers on a function graph.
+ * Parse the project ID from the identity, use it to lookup the project name, return the project-scoped uri.
+ *
+ * <h3>Why are we looking up the project name? We already have the project ID!</h3>
+ * <a href="https://cloud.google.com/compute/docs/overview#projectids">Documentation</a> suggests that the
+ * project name is interchangeable with the project ID, which we already have. However, in practice, using the
+ * project ID leads to problems in POST requests.
+ *
+ * <p/> For example, inserting an instance using the project ID in the instances url, but the project name in
+ * the machineType url results in an error of
+ * <pre>{@code Cross-project references for this resource type are not allowed}.</pre>
+ *
+ * <p/>Similar errors occur in POST requests to other resources including at least forwardingRules, images,
+ * targetPools.
*/
- @Provides
- @Singleton
- @UserProject Supplier<String> projectName(@Provider final Supplier<Credentials> creds,
- final GoogleComputeEngineApi api,
- AtomicReference<AuthorizationException> authException,
- @Named(PROPERTY_SESSION_INTERVAL) long seconds) {
- return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
- compose(new Function<Credentials, String>() {
- public String apply(Credentials in) {
- // ID should be of the form project_id@developer.gserviceaccount.com
- // OR (increasingly often) project_id-extended_uid@developer.gserviceaccount.com
- // where project_id is the NUMBER;
- // HERE we also accept simply "project" as the identity, if no "@" is present;
- // this is used in tests, but not sure if it is valid in the wild.
- String projectName = in.identity;
- if (projectName.indexOf("@") != -1) {
- projectName = Iterables.get(Splitter.on("@").split(projectName), 0);
- if (projectName.indexOf("-") != -1) {
- // if ID is of the form project_id-extended_uid@developer.gserviceaccount.com
- projectName = Iterables.get(Splitter.on("-").split(projectName), 0);
- }
- }
- return api.getProjectApi().get(projectName).name();
- }
- }, creds), seconds, SECONDS);
+ static final class UseApiToResolveProjectName implements Function<Credentials, URI> {
+ public static final Pattern PROJECT_NUMBER_PATTERN = Pattern.compile("^([0-9]+)[@-].*");
+
+ @SkipEncoding({ '/', '=' })
+ @RequestFilters(OAuthAuthenticationFilter.class)
+ @OAuthScopes(COMPUTE_READONLY_SCOPE)
+ @Consumes(APPLICATION_JSON)
+ interface GetProject {
+ @Named("Projects:get")
+ @GET
+ @Path("/projects/{projectNumber}") Project get(@PathParam("projectNumber") String projectNumber);
+ }
+
+ private final GetProject api;
+ private final Supplier<URI> defaultEndpoint;
+ private final String identityName;
+
+ @Inject
+ UseApiToResolveProjectName(GetProject api, @Provider Supplier<URI> defaultEndpoint, ProviderMetadata metadata) {
+ this.api = api;
+ this.defaultEndpoint = defaultEndpoint;
+ this.identityName = metadata.getApiMetadata().getIdentityName();
+ }
+
+ @Override public URI apply(Credentials in) {
+ Matcher matcher = PROJECT_NUMBER_PATTERN.matcher(in.identity);
+ checkArgument(matcher.find(), "Identity %s is malformed. Should be %s", in.identity, identityName);
+ return URI.create(defaultEndpoint.get() + "/projects/" + api.get(matcher.group(1)).name());
+ }
}
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineProperties.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineProperties.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineProperties.java
new file mode 100644
index 0000000..4f2be3d
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineProperties.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.jclouds.googlecomputeengine.config;
+
+import org.jclouds.oauth.v2.config.OAuthProperties;
+
+import com.google.common.annotations.Beta;
+
+/** Configuration properties keys used in {@link org.jclouds.ContextBuilder#overrides(java.util.Properties)}. */
+public final class GoogleComputeEngineProperties {
+
+ /**
+ * How requests are authorized using OAuth. Defaults to {@link org.jclouds.oauth.v2.config.CredentialType#SERVICE_ACCOUNT_CREDENTIALS}.
+ *
+ * @see org.jclouds.oauth.v2.config.CredentialType
+ */
+ public static final String CREDENTIAL_TYPE = OAuthProperties.CREDENTIAL_TYPE;
+
+ /**
+ * Set this property to specify the <a href="https://cloud.google.com/compute/docs/projects">project name</a> this
+ * context applies to.
+ * <p/> This is an alternative to looking up the project name at runtime.
+ */
+ public static final String PROJECT_NAME = "jclouds.google-compute-engine.project-name";
+
+ /** The total time, in msecs, to wait for an operation to complete. */
+ @Beta
+ public static final String OPERATION_COMPLETE_TIMEOUT = "jclouds.google-compute-engine.operation-complete-timeout";
+ /** The interval, in msecs, between calls to check whether an operation has completed. */
+ @Beta
+ public static final String OPERATION_COMPLETE_INTERVAL = "jclouds.google-compute-engine.operation-complete-interval";
+ /** The list of projects that will be scanned looking for images. */
+ @Beta
+ public static final String IMAGE_PROJECTS = "jclouds.google-compute-engine.image-projects";
+
+ private GoogleComputeEngineProperties() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/37e0397d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineScopes.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineScopes.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineScopes.java
new file mode 100644
index 0000000..7f5eaae
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineScopes.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.jclouds.googlecomputeengine.config;
+
+/** OAuth scopes needed for requests. */
+public final class GoogleComputeEngineScopes {
+
+ public static final String COMPUTE_SCOPE = "https://www.googleapis.com/auth/compute";
+
+ public static final String COMPUTE_READONLY_SCOPE = "https://www.googleapis.com/auth/compute.readonly";
+
+ private GoogleComputeEngineScopes() {
+ }
+}