Jclouds gce apis (gce + oauth) 1.8.1 clone with custom changes

Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/3ddce9df
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/3ddce9df
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/3ddce9df

Branch: refs/heads/master
Commit: 3ddce9dfd448b7173c3da233dfa3b67c392835bf
Parents: f9e9df9
Author: R-Rajkumar <[email protected]>
Authored: Sun Nov 30 16:12:04 2014 +0530
Committer: R-Rajkumar <[email protected]>
Committed: Sun Nov 30 16:12:04 2014 +0530

----------------------------------------------------------------------
 .../jclouds/apis/gce/1.8.1-stratos/README.txt   |   77 ++
 .../jclouds/apis/gce/1.8.1-stratos/pom.xml      |  141 +++
 .../GoogleComputeEngineApi.java                 |  185 +++
 .../GoogleComputeEngineApiMetadata.java         |  103 ++
 .../GoogleComputeEngineConstants.java           |   81 ++
 .../compute/GoogleComputeEngineService.java     |  200 +++
 .../GoogleComputeEngineServiceAdapter.java      |  439 +++++++
 ...GoogleComputeEngineServiceContextModule.java |  283 +++++
 ...ogleComputeEngineSecurityGroupExtension.java |  342 +++++
 .../functions/BuildInstanceMetadata.java        |   46 +
 .../functions/FirewallTagNamingConvention.java  |   62 +
 .../functions/FirewallToIpPermission.java       |   87 ++
 .../GoogleComputeEngineImageToImage.java        |   80 ++
 .../functions/InstanceInZoneToNodeMetadata.java |  150 +++
 .../functions/MachineTypeInZoneToHardware.java  |   95 ++
 .../functions/NetworkToSecurityGroup.java       |   82 ++
 .../functions/OrphanedGroupsFromDeadNodes.java  |   57 +
 .../compute/functions/RegionToLocation.java     |   45 +
 .../compute/functions/ZoneToLocation.java       |   45 +
 .../compute/loaders/FindNetworkOrCreate.java    |   62 +
 .../GoogleComputeEngineTemplateOptions.java     |  382 ++++++
 .../predicates/AllNodesInGroupTerminated.java   |   48 +
 ...desWithGroupEncodedIntoNameThenAddToSet.java |  183 +++
 ...DefaultLoginCredentialsForImageStrategy.java |   69 +
 ...eNodeCredentialsButOverrideFromTemplate.java |   57 +
 .../GoogleComputeEngineHttpApiModule.java       |  177 +++
 .../config/GoogleComputeEngineParserModule.java |  413 ++++++
 .../config/OAuthModuleWithoutTypeAdapters.java  |   53 +
 .../googlecomputeengine/config/UserProject.java |   33 +
 .../domain/AbstractDisk.java                    |  121 ++
 .../googlecomputeengine/domain/Address.java     |  177 +++
 .../googlecomputeengine/domain/Deprecated.java  |  195 +++
 .../googlecomputeengine/domain/Disk.java        |  123 ++
 .../googlecomputeengine/domain/Firewall.java    |  379 ++++++
 .../googlecomputeengine/domain/Image.java       |  286 +++++
 .../googlecomputeengine/domain/Instance.java    | 1187 ++++++++++++++++++
 .../domain/InstanceInZone.java                  |   52 +
 .../domain/InstanceTemplate.java                |  445 +++++++
 .../googlecomputeengine/domain/ListPage.java    |  179 +++
 .../googlecomputeengine/domain/MachineType.java |  348 +++++
 .../domain/MachineTypeInZone.java               |   52 +
 .../googlecomputeengine/domain/Metadata.java    |  139 ++
 .../googlecomputeengine/domain/Network.java     |  133 ++
 .../googlecomputeengine/domain/Operation.java   |  556 ++++++++
 .../googlecomputeengine/domain/Project.java     |  162 +++
 .../googlecomputeengine/domain/Quota.java       |  152 +++
 .../googlecomputeengine/domain/Region.java      |  175 +++
 .../googlecomputeengine/domain/Resource.java    |  283 +++++
 .../googlecomputeengine/domain/Route.java       |  433 +++++++
 .../domain/SlashEncodedIds.java                 |   83 ++
 .../googlecomputeengine/domain/Snapshot.java    |  135 ++
 .../googlecomputeengine/domain/Zone.java        |  334 +++++
 .../domain/internal/NetworkAndAddressRange.java |   91 ++
 .../features/AddressApi.java                    |  187 +++
 .../googlecomputeengine/features/DiskApi.java   |  255 ++++
 .../features/FirewallApi.java                   |  227 ++++
 .../features/GlobalOperationApi.java            |  158 +++
 .../googlecomputeengine/features/ImageApi.java  |  167 +++
 .../features/InstanceApi.java                   |  381 ++++++
 .../features/MachineTypeApi.java                |  143 +++
 .../features/NetworkApi.java                    |  204 +++
 .../features/ProjectApi.java                    |   96 ++
 .../googlecomputeengine/features/RegionApi.java |  135 ++
 .../features/RegionOperationApi.java            |  163 +++
 .../googlecomputeengine/features/RouteApi.java  |  184 +++
 .../features/SnapshotApi.java                   |  160 +++
 .../googlecomputeengine/features/ZoneApi.java   |  135 ++
 .../features/ZoneOperationApi.java              |  163 +++
 .../functions/CreateNetworkIfNeeded.java        |  100 ++
 .../functions/internal/BaseToPagedIterable.java |   66 +
 .../internal/BaseWithRegionToPagedIterable.java |   72 ++
 .../internal/BaseWithZoneToPagedIterable.java   |   72 ++
 .../functions/internal/PATCH.java               |   35 +
 .../functions/internal/ParseAddresses.java      |   67 +
 .../functions/internal/ParseDisks.java          |   67 +
 .../functions/internal/ParseFirewalls.java      |   63 +
 .../internal/ParseGlobalOperations.java         |   63 +
 .../functions/internal/ParseImages.java         |   63 +
 .../functions/internal/ParseInstances.java      |   65 +
 .../functions/internal/ParseMachineTypes.java   |   64 +
 .../functions/internal/ParseNetworks.java       |   63 +
 .../internal/ParseRegionOperations.java         |   65 +
 .../functions/internal/ParseRegions.java        |   63 +
 .../functions/internal/ParseRoutes.java         |   63 +
 .../functions/internal/ParseSnapshots.java      |   66 +
 .../functions/internal/ParseZoneOperations.java |   65 +
 .../functions/internal/ParseZones.java          |   63 +
 .../handlers/FirewallBinder.java                |   56 +
 .../GoogleComputeEngineErrorHandler.java        |   62 +
 .../handlers/InstanceBinder.java                |   65 +
 .../handlers/MetadataBinder.java                |   60 +
 .../handlers/RouteBinder.java                   |   56 +
 .../options/AttachDiskOptions.java              |  128 ++
 .../options/DeprecateOptions.java               |  126 ++
 .../options/FirewallOptions.java                |  166 +++
 .../options/ListOptions.java                    |   91 ++
 .../options/RouteOptions.java                   |  202 +++
 .../GlobalOperationDonePredicate.java           |   59 +
 .../predicates/InstancePredicates.java          |   33 +
 .../predicates/NetworkFirewallPredicates.java   |  121 ++
 .../RegionOperationDonePredicate.java           |   69 +
 .../predicates/ZoneOperationDonePredicate.java  |   68 +
 .../java/org/jclouds/oauth/v2/OAuthApi.java     |   61 +
 .../org/jclouds/oauth/v2/OAuthApiMetadata.java  |   80 ++
 .../org/jclouds/oauth/v2/OAuthConstants.java    |   78 ++
 .../jclouds/oauth/v2/config/Authentication.java |   35 +
 .../jclouds/oauth/v2/config/CredentialType.java |   42 +
 .../v2/config/OAuthAuthenticationModule.java    |   52 +
 .../oauth/v2/config/OAuthHttpApiModule.java     |   45 +
 .../jclouds/oauth/v2/config/OAuthModule.java    |  119 ++
 .../oauth/v2/config/OAuthProperties.java        |   51 +
 .../jclouds/oauth/v2/config/OAuthScopes.java    |   40 +
 .../org/jclouds/oauth/v2/domain/ClaimSet.java   |  191 +++
 .../org/jclouds/oauth/v2/domain/Header.java     |  128 ++
 .../oauth/v2/domain/OAuthCredentials.java       |  129 ++
 .../java/org/jclouds/oauth/v2/domain/Token.java |  149 +++
 .../jclouds/oauth/v2/domain/TokenRequest.java   |  131 ++
 .../oauth/v2/domain/TokenRequestFormat.java     |   45 +
 .../v2/filters/BearerTokenAuthenticator.java    |   41 +
 .../v2/filters/OAuthAuthenticationFilter.java   |   27 +
 .../oauth/v2/filters/OAuthAuthenticator.java    |   62 +
 .../oauth/v2/functions/BuildTokenRequest.java   |  135 ++
 .../jclouds/oauth/v2/functions/FetchToken.java  |   41 +
 .../v2/functions/OAuthCredentialsSupplier.java  |  125 ++
 .../v2/functions/SignOrProduceMacForToken.java  |  119 ++
 .../oauth/v2/handlers/OAuthErrorHandler.java    |   64 +
 .../oauth/v2/handlers/OAuthTokenBinder.java     |   45 +
 .../oauth/v2/json/ClaimSetTypeAdapter.java      |   59 +
 .../oauth/v2/json/HeaderTypeAdapter.java        |   52 +
 .../oauth/v2/json/JWTTokenRequestFormat.java    |   96 ++
 .../services/org.jclouds.apis.ApiMetadata       |   19 +
 .../GoogleComputeEngineApiMetadataTest.java     |   38 +
 ...eEngineAuthenticatedRestContextLiveTest.java |   33 +
 .../PageSystemExpectTest.java                   |  114 ++
 .../GoogleComputeEngineServiceExpectTest.java   |  574 +++++++++
 .../GoogleComputeEngineServiceLiveTest.java     |  133 ++
 ...uteEngineSecurityGroupExtensionLiveTest.java |   28 +
 .../functions/FirewallToIpPermissionTest.java   |   93 ++
 .../GoogleComputeEngineImageToImageTest.java    |   60 +
 .../InstanceInZoneToNodeMetadataTest.java       |  285 +++++
 .../functions/NetworkToSecurityGroupTest.java   |   94 ++
 .../OrphanedGroupsFromDeadNodesTest.java        |  136 ++
 .../loaders/FindNetworkOrCreateTest.java        |  141 +++
 .../features/AddressApiExpectTest.java          |  163 +++
 .../features/AddressApiLiveTest.java            |   71 ++
 .../features/DiskApiExpectTest.java             |  226 ++++
 .../features/DiskApiLiveTest.java               |   85 ++
 .../features/FirewallApiExpectTest.java         |  301 +++++
 .../features/FirewallApiLiveTest.java           |  164 +++
 .../features/GlobalOperationApiExpectTest.java  |  158 +++
 .../features/GlobalOperationApiLiveTest.java    |   91 ++
 .../features/ImageApiExpectTest.java            |  159 +++
 .../features/ImageApiLiveTest.java              |   74 ++
 .../features/InstanceApiExpectTest.java         |  410 ++++++
 .../features/InstanceApiLiveTest.java           |  241 ++++
 .../features/MachineTypeApiExpectTest.java      |  113 ++
 .../features/MachineTypeApiLiveTest.java        |   73 ++
 .../features/NetworkApiExpectTest.java          |  164 +++
 .../features/NetworkApiLiveTest.java            |   84 ++
 .../features/ProjectApiExpectTest.java          |   96 ++
 .../features/ProjectApiLiveTest.java            |  123 ++
 .../features/RegionApiExpectTest.java           |   94 ++
 .../features/RegionApiLiveTest.java             |   74 ++
 .../features/RegionOperationApiExpectTest.java  |  195 +++
 .../features/RegionOperationApiLiveTest.java    |   91 ++
 .../features/RouteApiExpectTest.java            |  175 +++
 .../features/RouteApiLiveTest.java              |   97 ++
 .../features/SnapshotApiExpectTest.java         |   94 ++
 .../features/SnapshotApiLiveTest.java           |   92 ++
 .../features/ZoneApiExpectTest.java             |   97 ++
 .../features/ZoneApiLiveTest.java               |   74 ++
 .../features/ZoneOperationApiExpectTest.java    |  193 +++
 .../features/ZoneOperationApiLiveTest.java      |   90 ++
 .../functions/CreateNetworkIfNeededTest.java    |  132 ++
 .../GoogleComputeEngineErrorHandlerTest.java    |   92 ++
 .../BaseGoogleComputeEngineApiExpectTest.java   |   31 +
 .../BaseGoogleComputeEngineApiLiveTest.java     |  160 +++
 .../BaseGoogleComputeEngineExpectTest.java      |  195 +++
 .../BaseGoogleComputeEngineParseTest.java       |   33 +
 ...leComputeEngineServiceContextExpectTest.java |   49 +
 ...aseGoogleComputeEngineServiceExpectTest.java |   28 +
 .../parse/ParseAddressListTest.java             |   61 +
 .../parse/ParseAddressTest.java                 |   51 +
 .../parse/ParseDiskListTest.java                |   61 +
 .../parse/ParseDiskTest.java                    |   50 +
 .../parse/ParseFirewallListTest.java            |   68 +
 .../parse/ParseFirewallTest.java                |   60 +
 .../parse/ParseImageListTest.java               |   71 ++
 .../parse/ParseImageTest.java                   |   55 +
 .../parse/ParseInstanceListTest.java            |   48 +
 .../parse/ParseInstanceSerialOutputTest.java    |   38 +
 .../parse/ParseInstanceTest.java                |   81 ++
 .../parse/ParseMachineTypeListTest.java         |   91 ++
 .../parse/ParseMachineTypeTest.java             |   56 +
 .../parse/ParseMetadataTest.java                |   45 +
 .../parse/ParseNetworkListTest.java             |   49 +
 .../parse/ParseNetworkTest.java                 |   48 +
 .../parse/ParseOperationListTest.java           |   46 +
 .../parse/ParseOperationTest.java               |   58 +
 .../parse/ParseProjectTest.java                 |   67 +
 .../parse/ParseQuotaTest.java                   |   39 +
 .../parse/ParseRegionListTest.java              |   72 ++
 .../parse/ParseRegionTest.java                  |   62 +
 .../parse/ParseRouteListTest.java               |   62 +
 .../parse/ParseRouteTest.java                   |   56 +
 .../parse/ParseSnapshotListTest.java            |   64 +
 .../parse/ParseSnapshotTest.java                |   52 +
 .../parse/ParseZoneListTest.java                |   70 ++
 .../parse/ParseZoneTest.java                    |   55 +
 .../NetworkFirewallPredicatesTest.java          |  162 +++
 .../jclouds/oauth/v2/OAuthApiMetadataTest.java  |   38 +
 .../org/jclouds/oauth/v2/OAuthTestUtils.java    |   91 ++
 .../oauth/v2/features/OAuthApiExpectTest.java   |   99 ++
 .../oauth/v2/features/OAuthApiLiveTest.java     |   80 ++
 .../functions/OAuthCredentialsFromPKTest.java   |   61 +
 .../functions/OAuthCredentialsSupplierTest.java |   55 +
 .../oauth/v2/functions/SignerFunctionTest.java  |   61 +
 .../v2/handlers/OAuthErrorHandlerTest.java      |   92 ++
 .../oauth/v2/internal/Base64UrlSafeTest.java    |   40 +
 .../v2/internal/BaseOAuthApiExpectTest.java     |   23 +
 .../oauth/v2/internal/BaseOAuthApiLiveTest.java |   56 +
 .../BaseOAuthAuthenticatedApiLiveTest.java      |  110 ++
 .../oauth/v2/internal/BaseOAuthExpectTest.java  |   26 +
 .../v2/json/JWTTokenRequestFormatTest.java      |   69 +
 .../jclouds/oauth/v2/parse/ParseTokenTest.java  |   40 +
 .../firewall_list.json                          |   37 +
 .../network_get.json                            |   10 +
 .../src/test/resources/address_get.json         |   12 +
 .../src/test/resources/address_insert.json      |    1 +
 .../src/test/resources/address_list.json        |   31 +
 .../test/resources/disk_create_snapshot.json    |    1 +
 .../src/test/resources/disk_get.json            |   10 +
 .../src/test/resources/disk_insert.json         |    1 +
 .../src/test/resources/disk_list.json           |   17 +
 .../src/test/resources/firewall_get.json        |   30 +
 .../src/test/resources/firewall_insert.json     |    1 +
 .../src/test/resources/firewall_list.json       |   58 +
 .../src/test/resources/global_operation.json    |   15 +
 .../test/resources/global_operation_list.json   |   22 +
 .../src/test/resources/image_get.json           |   13 +
 .../src/test/resources/image_insert.json        |    4 +
 .../src/test/resources/image_list.json          |   24 +
 .../src/test/resources/image_list_centos.json   |  183 +++
 .../src/test/resources/image_list_debian.json   |  400 ++++++
 .../src/test/resources/image_list_empty.json    |    6 +
 .../resources/image_list_multiple_page_1.json   |   55 +
 .../resources/image_list_multiple_page_2.json   |   47 +
 .../test/resources/image_list_single_page.json  |   50 +
 .../resources/instance_add_access_config.json   |   11 +
 .../test/resources/instance_attach_disk.json    |    6 +
 .../src/test/resources/instance_get.json        |   62 +
 .../src/test/resources/instance_insert.json     |    1 +
 .../test/resources/instance_insert_simple.json  |    1 +
 .../src/test/resources/instance_list.json       |   69 +
 .../instance_list_central1b_empty.json          |    6 +
 .../test/resources/instance_serial_port.json    |    4 +
 .../test/resources/instance_set_metadata.json   |   10 +
 .../src/test/resources/logback.xml              |   83 ++
 .../src/test/resources/machinetype.json         |   21 +
 .../src/test/resources/machinetype_list.json    |   54 +
 .../resources/machinetype_list_central1b.json   |   41 +
 .../machinetype_list_central1b_empty.json       |    6 +
 .../src/test/resources/metadata.json            |    1 +
 .../src/test/resources/network_get.json         |   10 +
 .../src/test/resources/network_insert.json      |    1 +
 .../src/test/resources/network_list.json        |   18 +
 .../src/test/resources/operation.json           |   17 +
 .../src/test/resources/operation_error.json     |   26 +
 .../src/test/resources/operation_list.json      |   24 +
 .../src/test/resources/project.json             |   69 +
 .../1.8.1-stratos/src/test/resources/quota.json |    5 +
 .../src/test/resources/region_get.json          |   60 +
 .../src/test/resources/region_list.json         |  126 ++
 .../src/test/resources/region_operation.json    |   16 +
 .../test/resources/region_operation_list.json   |   23 +
 .../src/test/resources/route_get.json           |   14 +
 .../src/test/resources/route_insert.json        |    1 +
 .../src/test/resources/route_list.json          |   34 +
 .../src/test/resources/snapshot_get.json        |   13 +
 .../src/test/resources/snapshot_list.json       |   33 +
 .../src/test/resources/tag_insert.json          |    1 +
 .../1.8.1-stratos/src/test/resources/testpk.pem |   15 +
 .../src/test/resources/tokenResponse.json       |    5 +
 .../src/test/resources/zone_get.json            |   17 +
 .../src/test/resources/zone_list.json           |   41 +
 .../src/test/resources/zone_list_short.json     |   24 +
 .../src/test/resources/zone_operation.json      |   16 +
 .../test/resources/zone_operation_error.json    |   25 +
 .../src/test/resources/zone_operation_list.json |   23 +
 289 files changed, 29334 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/3ddce9df/dependencies/jclouds/apis/gce/1.8.1-stratos/README.txt
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/README.txt 
b/dependencies/jclouds/apis/gce/1.8.1-stratos/README.txt
new file mode 100644
index 0000000..0801104
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/README.txt
@@ -0,0 +1,77 @@
+======
+Stratos GCE provider 1.8.1
+======
+
+This code in Stratos is copied from Jclouds GCE [1]
+The jclouds GCE code has 2 directories oauth & google-compute-engine
+In Stratos, these two directories are mered into one.
+
+[1] 
https://github.com/jclouds/jclouds-labs-google/tree/jclouds-labs-google-1.8.1
+
+
+
+
+======
+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>[email protected]</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/stratos/blob/3ddce9df/dependencies/jclouds/apis/gce/1.8.1-stratos/pom.xml
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/pom.xml 
b/dependencies/jclouds/apis/gce/1.8.1-stratos/pom.xml
new file mode 100644
index 0000000..34f8bc7
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/pom.xml
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.jclouds.labs</groupId>
+        <artifactId>jclouds-labs-google</artifactId>
+        <version>1.8.1</version>
+    </parent>
+
+    <!-- TODO: when out of labs, switch to org.jclouds.provider -->
+    <groupId>org.apache.stratos</groupId>
+    <artifactId>gce</artifactId>
+    <version>1.8.1-stratos</version>
+    <name>jclouds Google Compute Engine provider</name>
+    <description>jclouds components to access GoogleCompute</description>
+    <packaging>bundle</packaging>
+
+    <properties>
+        <jclouds.version>1.8.1</jclouds.version>
+        <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.api-version>v1</test.google-compute-engine.api-version>
+        <test.google-compute-engine.build-version />
+        
<test.google-compute-engine.template>imageId=debian-7-wheezy-v20131120,locationId=us-central1-a,minRam=2048</test.google-compute-engine.template>
+        
<jclouds.osgi.export>org.jclouds.googlecomputeengine*;version="${project.version}"</jclouds.osgi.export>
+        <jclouds.osgi.import>
+          org.jclouds.compute.internal;version="${jclouds.version}",
+          org.jclouds.rest.internal;version="${jclouds.version}",
+          org.jclouds*;version="${jclouds.version}",
+          *
+        </jclouds.osgi.import>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.jclouds</groupId>
+            <artifactId>jclouds-core</artifactId>
+            <version>${jclouds.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jclouds</groupId>
+            <artifactId>jclouds-compute</artifactId>
+            <version>${jclouds.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jclouds</groupId>
+            <artifactId>jclouds-compute</artifactId>
+            <version>${jclouds.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jclouds</groupId>
+            <artifactId>jclouds-core</artifactId>
+            <version>${jclouds.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jclouds.driver</groupId>
+            <artifactId>jclouds-slf4j</artifactId>
+            <version>${jclouds.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jclouds.driver</groupId>
+            <artifactId>jclouds-sshj</artifactId>
+            <version>${jclouds.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <profiles>
+        <profile>
+            <id>live</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>default-test</id>
+                                <configuration>
+                                    <skipTests>true</skipTests>
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <id>integration</id>
+                                <phase>integration-test</phase>
+                                <goals>
+                                    <goal>test</goal>
+                                </goals>
+                                <configuration>
+                                    <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.template>${test.google-compute-engine.template}</test.google-compute-engine.template>
+                                    </systemPropertyVariables>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>

http://git-wip-us.apache.org/repos/asf/stratos/blob/3ddce9df/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java
 
b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java
new file mode 100644
index 0000000..6440d91
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java
@@ -0,0 +1,185 @@
+/*
+ * 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 java.io.Closeable;
+
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+
+import org.jclouds.googlecomputeengine.features.AddressApi;
+import org.jclouds.googlecomputeengine.features.DiskApi;
+import org.jclouds.googlecomputeengine.features.FirewallApi;
+import org.jclouds.googlecomputeengine.features.GlobalOperationApi;
+import org.jclouds.googlecomputeengine.features.ImageApi;
+import org.jclouds.googlecomputeengine.features.InstanceApi;
+import org.jclouds.googlecomputeengine.features.MachineTypeApi;
+import org.jclouds.googlecomputeengine.features.NetworkApi;
+import org.jclouds.googlecomputeengine.features.ProjectApi;
+import org.jclouds.googlecomputeengine.features.RegionApi;
+import org.jclouds.googlecomputeengine.features.RegionOperationApi;
+import org.jclouds.googlecomputeengine.features.RouteApi;
+import org.jclouds.googlecomputeengine.features.SnapshotApi;
+import org.jclouds.googlecomputeengine.features.ZoneApi;
+import org.jclouds.googlecomputeengine.features.ZoneOperationApi;
+import org.jclouds.rest.annotations.Delegate;
+
+import com.google.common.annotations.Beta;
+
+
+/**
+ * Provides access to GoogleCompute.
+ * <p/>
+ *
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1";>api 
doc</a>
+ */
+@Beta
+public interface GoogleComputeEngineApi extends Closeable {
+
+   /**
+    * Provides access to Address features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   AddressApi getAddressApiForProject(@PathParam("project") String 
projectName);
+
+   /**
+    * Provides access to Disk features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   DiskApi getDiskApiForProject(@PathParam("project") String projectName);
+
+   /**
+    * Provides access to Firewall features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   FirewallApi getFirewallApiForProject(@PathParam("project") String 
projectName);
+
+   /**
+    * Provides access to Global Operation features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   GlobalOperationApi getGlobalOperationApiForProject(@PathParam("project") 
String projectName);
+
+   /**
+    * Provides access to Image features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   ImageApi getImageApiForProject(@PathParam("project") String projectName);
+
+   /**
+    * Provides access to Instance features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   InstanceApi getInstanceApiForProject(@PathParam("project") String 
projectName);
+
+   /**
+    * Provides access to MachineType features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   MachineTypeApi getMachineTypeApiForProject(@PathParam("project") String 
projectName);
+
+   /**
+    * Provides access to Network features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   NetworkApi getNetworkApiForProject(@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 getRegionApiForProject(@PathParam("project") String projectName);
+
+   /**
+    * Provides access to Region Operation features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   RegionOperationApi getRegionOperationApiForProject(@PathParam("project") 
String projectName);
+
+   /**
+    * Provides access to Route features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   RouteApi getRouteApiForProject(@PathParam("project") String projectName);
+
+   /**
+    * Provides access to Snapshot features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   SnapshotApi getSnapshotApiForProject(@PathParam("project") String 
projectName);
+
+   /**
+    * Provides access to Zone features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   ZoneApi getZoneApiForProject(@PathParam("project") String projectName);
+
+   /**
+    * Provides access to Zone Operation features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   ZoneOperationApi getZoneOperationApiForProject(@PathParam("project") String 
projectName);
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/3ddce9df/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java
 
b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java
new file mode 100644
index 0000000..544a851
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java
@@ -0,0 +1,103 @@
+/*
+ * 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 static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
+import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_PROVIDER_NAME;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
+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;
+
+import java.net.URI;
+import java.util.Properties;
+
+import org.jclouds.compute.ComputeServiceContext;
+import 
org.jclouds.googlecomputeengine.compute.config.GoogleComputeEngineServiceContextModule;
+import org.jclouds.googlecomputeengine.config.GoogleComputeEngineHttpApiModule;
+import org.jclouds.googlecomputeengine.config.GoogleComputeEngineParserModule;
+import org.jclouds.googlecomputeengine.config.OAuthModuleWithoutTypeAdapters;
+import org.jclouds.oauth.v2.config.OAuthAuthenticationModule;
+import org.jclouds.rest.internal.BaseHttpApiMetadata;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+
+/**
+ * Implementation of {@link ApiMetadata} for GoogleCompute v1 API
+ */
+public class GoogleComputeEngineApiMetadata extends 
BaseHttpApiMetadata<GoogleComputeEngineApi> {
+
+   @Override
+   public Builder toBuilder() {
+      return new Builder().fromApiMetadata(this);
+   }
+
+   public GoogleComputeEngineApiMetadata() {
+      this(new Builder());
+   }
+
+   protected GoogleComputeEngineApiMetadata(Builder builder) {
+      super(builder);
+   }
+
+   public static Properties defaultProperties() {
+      Properties properties = BaseHttpApiMetadata.defaultProperties();
+      properties.put("oauth.endpoint", 
"https://accounts.google.com/o/oauth2/token";);
+      properties.put(AUDIENCE, "https://accounts.google.com/o/oauth2/token";);
+      properties.put(SIGNATURE_OR_MAC_ALGORITHM, "RS256");
+      properties.put(PROPERTY_SESSION_INTERVAL, 3600);
+      properties.setProperty(TEMPLATE, 
"osFamily=DEBIAN,osVersionMatches=7\\..*,locationId=us-central1-a,loginUser=jclouds");
+      properties.put(OPERATION_COMPLETE_INTERVAL, 500);
+      properties.put(OPERATION_COMPLETE_TIMEOUT, 600000);
+      return properties;
+   }
+
+   public static class Builder extends 
BaseHttpApiMetadata.Builder<GoogleComputeEngineApi, Builder> {
+
+      protected Builder() {
+         id(GCE_PROVIDER_NAME)
+                 .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")
+                 
.documentation(URI.create("https://developers.google.com/compute/docs";))
+                 .version("v1")
+                 .defaultEndpoint("https://www.googleapis.com/compute/v1";)
+                 
.defaultProperties(GoogleComputeEngineApiMetadata.defaultProperties())
+                 .view(typeToken(ComputeServiceContext.class))
+                 .defaultModules(ImmutableSet.<Class<? extends 
Module>>builder()
+                         .add(GoogleComputeEngineHttpApiModule.class)
+                         .add(GoogleComputeEngineParserModule.class)
+                         .add(OAuthAuthenticationModule.class)
+                         .add(OAuthModuleWithoutTypeAdapters.class)
+                         .add(GoogleComputeEngineServiceContextModule.class)
+                         .build());
+      }
+
+      @Override
+      public GoogleComputeEngineApiMetadata build() {
+         return new GoogleComputeEngineApiMetadata(this);
+      }
+
+      @Override
+      protected Builder self() {
+         return this;
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/3ddce9df/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java
 
b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java
new file mode 100644
index 0000000..d20ff98
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java
@@ -0,0 +1,81 @@
+/*
+ * 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 org.jclouds.domain.Location;
+import org.jclouds.domain.LocationBuilder;
+import org.jclouds.domain.LocationScope;
+
+import com.google.common.annotations.Beta;
+
+public final class GoogleComputeEngineConstants {
+
+   public static final String GCE_PROVIDER_NAME = "google-compute-engine";
+
+   /**
+    * The name of the project that keeps public resources.
+    */
+   public static final String GOOGLE_PROJECT = "google";
+
+   public static final String CENTOS_PROJECT = "centos-cloud";
+
+   public static final String DEBIAN_PROJECT = "debian-cloud";
+
+   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";;
+
+   public static final String STORAGE_READONLY_SCOPE = 
"https://www.googleapis.com/auth/devstorage.read_only";;
+
+   public static final String STORAGE_WRITEONLY_SCOPE = 
"https://www.googleapis.com/auth/devstorage.write_only";;
+
+
+   /**
+    * 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";
+
+   public static final Location GOOGLE_PROVIDER_LOCATION = new 
LocationBuilder().scope(LocationScope.PROVIDER).id
+           (GCE_PROVIDER_NAME).description(GCE_PROVIDER_NAME).build();
+
+
+   /**
+    * The key we look for in instance metadata for the URI for the image the 
instance was created from.
+    */
+   public static final String GCE_IMAGE_METADATA_KEY = "jclouds-image";
+
+   /**
+    * Metadata key to check for whether we should delete an instance's boot 
disk when we delete the instance.
+    */
+   public static final String GCE_DELETE_BOOT_DISK_METADATA_KEY = 
"jclouds-delete-boot-disk";
+
+   /**
+    * The suffix we append to auto-created boot disk names.
+    */
+   public static final String GCE_BOOT_DISK_SUFFIX = "boot-disk";
+
+   private GoogleComputeEngineConstants() {
+      throw new AssertionError("intentionally unimplemented");
+   }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/3ddce9df/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java
 
b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java
new file mode 100644
index 0000000..3c140eb
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java
@@ -0,0 +1,200 @@
+/*
+ * 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.compute;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
+import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
+import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
+import static org.jclouds.util.Predicates2.retry;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Provider;
+
+import org.jclouds.Constants;
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.callables.RunScriptOnNode;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.compute.internal.BaseComputeService;
+import org.jclouds.compute.internal.PersistNodeCredentials;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
+import org.jclouds.compute.strategy.DestroyNodeStrategy;
+import org.jclouds.compute.strategy.GetImageStrategy;
+import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
+import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap;
+import org.jclouds.compute.strategy.ListNodesStrategy;
+import org.jclouds.compute.strategy.RebootNodeStrategy;
+import org.jclouds.compute.strategy.ResumeNodeStrategy;
+import org.jclouds.compute.strategy.SuspendNodeStrategy;
+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;
+import org.jclouds.googlecomputeengine.features.FirewallApi;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.scriptbuilder.functions.InitAdminAccess;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.Atomics;
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+public 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>> operationDonePredicate;
+   private final long operationCompleteCheckInterval;
+   private final long operationCompleteCheckTimeout;
+
+   @Inject
+   protected GoogleComputeEngineService(ComputeServiceContext context,
+                                        Map<String, Credentials> 
credentialStore,
+                                        @Memoized Supplier<Set<? extends 
Image>> images,
+                                        @Memoized Supplier<Set<? extends 
Hardware>> hardwareProfiles,
+                                        @Memoized Supplier<Set<? extends 
Location>> locations,
+                                        ListNodesStrategy listNodesStrategy,
+                                        GetImageStrategy getImageStrategy,
+                                        GetNodeMetadataStrategy 
getNodeMetadataStrategy,
+                                        CreateNodesInGroupThenAddToSet 
runNodesAndAddToSetStrategy,
+                                        RebootNodeStrategy rebootNodeStrategy,
+                                        DestroyNodeStrategy 
destroyNodeStrategy,
+                                        ResumeNodeStrategy resumeNodeStrategy,
+                                        SuspendNodeStrategy 
suspendNodeStrategy,
+                                        Provider<TemplateBuilder> 
templateBuilderProvider,
+                                        @Named("DEFAULT") 
Provider<TemplateOptions> templateOptionsProvider,
+                                        @Named(TIMEOUT_NODE_RUNNING) 
Predicate<AtomicReference<NodeMetadata>>
+                                                nodeRunning,
+                                        @Named(TIMEOUT_NODE_TERMINATED) 
Predicate<AtomicReference<NodeMetadata>>
+                                                nodeTerminated,
+                                        @Named(TIMEOUT_NODE_SUSPENDED)
+                                        
Predicate<AtomicReference<NodeMetadata>> nodeSuspended,
+                                        
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory,
+                                        InitAdminAccess initAdminAccess,
+                                        RunScriptOnNode.Factory 
runScriptOnNodeFactory,
+                                        PersistNodeCredentials 
persistNodeCredentials,
+                                        ComputeServiceConstants.Timeouts 
timeouts,
+                                        
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
+                                        Optional<ImageExtension> 
imageExtension,
+                                        Optional<SecurityGroupExtension> 
securityGroupExtension,
+                                        Function<Set<? extends NodeMetadata>, 
Set<String>> findOrphanedGroups,
+                                        GroupNamingConvention.Factory 
namingConvention,
+                                        GoogleComputeEngineApi api,
+                                        @UserProject Supplier<String> project,
+                                        @Named("global") 
Predicate<AtomicReference<Operation>> operationDonePredicate,
+                                        @Named(OPERATION_COMPLETE_INTERVAL) 
Long operationCompleteCheckInterval,
+                                        @Named(OPERATION_COMPLETE_TIMEOUT) 
Long operationCompleteCheckTimeout) {
+
+      super(context, credentialStore, images, hardwareProfiles, locations, 
listNodesStrategy, getImageStrategy,
+              getNodeMetadataStrategy, runNodesAndAddToSetStrategy, 
rebootNodeStrategy, destroyNodeStrategy,
+              resumeNodeStrategy, suspendNodeStrategy, 
templateBuilderProvider, templateOptionsProvider, nodeRunning,
+              nodeTerminated, nodeSuspended, initScriptRunnerFactory, 
initAdminAccess, runScriptOnNodeFactory,
+              persistNodeCredentials, timeouts, userExecutor, imageExtension, 
securityGroupExtension);
+      this.findOrphanedGroups = checkNotNull(findOrphanedGroups, "find 
orphaned groups function");
+      this.namingConvention = checkNotNull(namingConvention, "naming 
convention factory");
+      this.api = checkNotNull(api, "google compute api");
+      this.project = checkNotNull(project, "user project name");
+      this.operationDonePredicate = checkNotNull(operationDonePredicate, 
"operation completed predicate");
+      this.operationCompleteCheckInterval = 
checkNotNull(operationCompleteCheckInterval,
+              "operation completed check interval");
+      this.operationCompleteCheckTimeout = 
checkNotNull(operationCompleteCheckTimeout,
+              "operation completed check timeout");
+   }
+
+   @Override
+   protected synchronized void cleanUpIncidentalResourcesOfDeadNodes(Set<? 
extends NodeMetadata> deadNodes) {
+      Set<String> orphanedGroups = findOrphanedGroups.apply(deadNodes);
+      for (String orphanedGroup : orphanedGroups) {
+         cleanUpNetworksAndFirewallsForGroup(orphanedGroup);
+      }
+   }
+
+
+   protected void cleanUpNetworksAndFirewallsForGroup(final String groupName) {
+      String resourceName = 
namingConvention.create().sharedNameForGroup(groupName);
+      final Network network = 
api.getNetworkApiForProject(project.get()).get(resourceName);
+      FirewallApi firewallApi = api.getFirewallApiForProject(project.get());
+      Predicate<Firewall> firewallBelongsToNetwork = new Predicate<Firewall>() 
{
+         @Override
+         public boolean apply(Firewall input) {
+            return input != null && 
input.getNetwork().equals(network.getSelfLink());
+         }
+      };
+
+      Set<AtomicReference<Operation>> operations = Sets.newHashSet();
+      for (Firewall firewall : 
firewallApi.list().concat().filter(firewallBelongsToNetwork)) {
+         operations.add(new 
AtomicReference<Operation>(firewallApi.delete(firewall.getName())));
+      }
+
+      for (AtomicReference<Operation> operation : operations) {
+         retry(operationDonePredicate, operationCompleteCheckTimeout, 
operationCompleteCheckInterval,
+                 MILLISECONDS).apply(operation);
+
+         if (operation.get().getHttpError().isPresent()) {
+            HttpResponse response = operation.get().getHttpError().get();
+            logger.warn("delete orphaned firewall %s failed. Http Error Code: 
%d HttpError: %s",
+                    operation.get().getTargetId(), response.getStatusCode(), 
response.getMessage());
+         }
+      }
+
+      AtomicReference<Operation> operation = 
Atomics.newReference(api.getNetworkApiForProject(project.get()).delete(resourceName));
+
+      retry(operationDonePredicate, operationCompleteCheckTimeout, 
operationCompleteCheckInterval,
+              MILLISECONDS).apply(operation);
+
+      if (operation.get().getHttpError().isPresent()) {
+         HttpResponse response = operation.get().getHttpError().get();
+         logger.warn("delete orphaned network failed. Http Error Code: " + 
response.getStatusCode() +
+                 " HttpError: " + response.getMessage());
+      }
+   }
+
+
+   /**
+    * returns template options, except of type {@link 
org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions}.
+    */
+   @Override
+   public GoogleComputeEngineTemplateOptions templateOptions() {
+      return 
GoogleComputeEngineTemplateOptions.class.cast(super.templateOptions());
+   }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/3ddce9df/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
 
b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
new file mode 100644
index 0000000..3a26d34
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
@@ -0,0 +1,439 @@
+/*
+ * 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.compute;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Iterables.contains;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.tryFind;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.CENTOS_PROJECT;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.DEBIAN_PROJECT;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_BOOT_DISK_SUFFIX;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_DELETE_BOOT_DISK_METADATA_KEY;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_IMAGE_METADATA_KEY;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
+import static 
org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface.AccessConfig.Type;
+import static 
org.jclouds.googlecomputeengine.predicates.InstancePredicates.isBootDisk;
+import static org.jclouds.util.Predicates2.retry;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.ComputeServiceAdapter;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+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.Disk;
+import org.jclouds.googlecomputeengine.domain.Image;
+import org.jclouds.googlecomputeengine.domain.Instance;
+import org.jclouds.googlecomputeengine.domain.Instance.AttachedDisk;
+import org.jclouds.googlecomputeengine.domain.Instance.PersistentAttachedDisk;
+import org.jclouds.googlecomputeengine.domain.InstanceInZone;
+import org.jclouds.googlecomputeengine.domain.InstanceTemplate;
+import org.jclouds.googlecomputeengine.domain.InstanceTemplate.PersistentDisk;
+import 
org.jclouds.googlecomputeengine.domain.InstanceTemplate.PersistentDisk.Mode;
+import org.jclouds.googlecomputeengine.domain.MachineType;
+import org.jclouds.googlecomputeengine.domain.MachineTypeInZone;
+import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.domain.SlashEncodedIds;
+import org.jclouds.googlecomputeengine.domain.Zone;
+import org.jclouds.googlecomputeengine.features.InstanceApi;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.logging.Logger;
+
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.primitives.Ints;
+import com.google.common.util.concurrent.Atomics;
+import com.google.common.util.concurrent.UncheckedTimeoutException;
+import com.google.inject.Inject;
+
+public class GoogleComputeEngineServiceAdapter implements 
ComputeServiceAdapter<InstanceInZone, MachineTypeInZone, Image, Zone> {
+
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
+
+   private final GoogleComputeEngineApi api;
+   private final Supplier<String> userProject;
+   private final Supplier<Map<URI, ? extends Location>> zones;
+   private final Function<TemplateOptions, ImmutableMap.Builder<String, 
String>> metatadaFromTemplateOptions;
+   private final Predicate<AtomicReference<Operation>> 
retryOperationDonePredicate;
+   private final long operationCompleteCheckInterval;
+   private final long operationCompleteCheckTimeout;
+   private final FirewallTagNamingConvention.Factory 
firewallTagNamingConvention;
+
+   @Inject
+   public GoogleComputeEngineServiceAdapter(GoogleComputeEngineApi api,
+                                            @UserProject Supplier<String> 
userProject,
+                                            Function<TemplateOptions,
+                                                    
ImmutableMap.Builder<String, String>> metatadaFromTemplateOptions,
+                                            @Named("zone") 
Predicate<AtomicReference<Operation>> operationDonePredicate,
+                                            
@Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
+                                            @Named(OPERATION_COMPLETE_TIMEOUT) 
Long operationCompleteCheckTimeout,
+                                            @Memoized Supplier<Map<URI, ? 
extends Location>> zones,
+                                            
FirewallTagNamingConvention.Factory firewallTagNamingConvention) {
+      this.api = checkNotNull(api, "google compute api");
+      this.userProject = checkNotNull(userProject, "user project name");
+      this.metatadaFromTemplateOptions = 
checkNotNull(metatadaFromTemplateOptions,
+              "metadata from template options function");
+      this.operationCompleteCheckInterval = 
checkNotNull(operationCompleteCheckInterval,
+              "operation completed check interval");
+      this.operationCompleteCheckTimeout = 
checkNotNull(operationCompleteCheckTimeout,
+                                                        "operation completed 
check timeout");
+      this.retryOperationDonePredicate = retry(operationDonePredicate, 
operationCompleteCheckTimeout,
+                                               operationCompleteCheckInterval, 
TimeUnit.MILLISECONDS);
+      this.zones = checkNotNull(zones, "zones");
+      this.firewallTagNamingConvention = 
checkNotNull(firewallTagNamingConvention, "firewallTagNamingConvention");
+   }
+
+   @Override
+   public NodeAndInitialCredentials<InstanceInZone> 
createNodeWithGroupEncodedIntoName(
+           final String group, final String name, final Template template) {
+
+      checkNotNull(template, "template");
+
+      GoogleComputeEngineTemplateOptions options = 
GoogleComputeEngineTemplateOptions.class.cast(template.getOptions()).clone();
+      checkState(options.getNetwork().isPresent(), "network was not present in 
template options");
+      Hardware hardware = checkNotNull(template.getHardware(), "hardware must 
be set");
+
+      checkNotNull(hardware.getUri(), "hardware must have a URI");
+      checkNotNull(template.getImage().getUri(), "image URI is null");
+
+      // Note that the ordering is significant here - the first disk must be 
the boot disk.
+      List<PersistentDisk> disks = Lists.newArrayList();
+
+      if (!tryFind(options.getDisks(), isBootDisk()).isPresent()) {
+         Disk bootDisk = createBootDisk(template, name);
+
+         disks.add(new PersistentDisk(Mode.READ_WRITE,
+                                      bootDisk.getSelfLink(),
+                                      null,
+                                      true,
+                                      true));
+      }
+
+      disks.addAll(options.getDisks());
+
+      InstanceTemplate instanceTemplate = InstanceTemplate.builder()
+              .forMachineType(hardware.getUri());
+
+      if (options.isEnableNat()) {
+         instanceTemplate.addNetworkInterface(options.getNetwork().get(), 
Type.ONE_TO_ONE_NAT);
+      } else {
+         instanceTemplate.addNetworkInterface(options.getNetwork().get());
+      }
+
+      instanceTemplate.disks(disks);
+
+      LoginCredentials credentials = 
getFromImageAndOverrideIfRequired(template.getImage(), options);
+
+      ImmutableMap.Builder<String, String> metadataBuilder = 
metatadaFromTemplateOptions.apply(options);
+
+      metadataBuilder.put(GCE_IMAGE_METADATA_KEY, 
template.getImage().getUri().toString());
+
+      if (!options.shouldKeepBootDisk()) {
+         metadataBuilder.put(GCE_DELETE_BOOT_DISK_METADATA_KEY, 
Boolean.TRUE.toString());
+      }
+
+      instanceTemplate.metadata(metadataBuilder.build());
+      instanceTemplate.serviceAccounts(options.getServiceAccounts());
+
+      final InstanceApi instanceApi = 
api.getInstanceApiForProject(userProject.get());
+      final String zone = template.getLocation().getId();
+      Operation operation = instanceApi.createInZone(name, zone, 
instanceTemplate);
+
+      if (options.shouldBlockUntilRunning()) {
+         waitOperationDone(operation);
+      }
+
+      // some times the newly created instances are not immediately returned
+      AtomicReference<Instance> instance = Atomics.newReference();
+
+      retry(new Predicate<AtomicReference<Instance>>() {
+         @Override
+         public boolean apply(AtomicReference<Instance> input) {
+            input.set(instanceApi.getInZone(zone, name));
+            return input.get() != null;
+         }
+      }, operationCompleteCheckTimeout, operationCompleteCheckInterval, 
MILLISECONDS).apply(instance);
+
+      if (!options.getTags().isEmpty()) {
+         Operation tagsOperation = instanceApi.setTagsInZone(zone,
+                 name, options.getTags(), 
instance.get().getTags().getFingerprint());
+
+         waitOperationDone(tagsOperation);
+
+         retry(new Predicate<AtomicReference<Instance>>() {
+            @Override
+            public boolean apply(AtomicReference<Instance> input) {
+               input.set(instanceApi.getInZone(zone, name));
+               return input.get() != null;
+            }
+         }, operationCompleteCheckTimeout, operationCompleteCheckInterval, 
MILLISECONDS).apply(instance);
+      }
+
+      // Add tags for security groups
+      final FirewallTagNamingConvention naming = 
firewallTagNamingConvention.get(group);
+      Set<String> tags = 
FluentIterable.from(Ints.asList(options.getInboundPorts()))
+              .transform(new Function<Integer, String>(){
+                       @Override
+                       public String apply(Integer input) {
+                          return input != null
+                                  ? naming.name(input)
+                                  : null;
+                       }
+                    })
+              .toSet();
+      instanceApi.setTagsInZone(zone, instance.get().getName(), tags, 
instance.get().getTags().getFingerprint());
+
+      InstanceInZone instanceInZone = new InstanceInZone(instance.get(), zone);
+
+      return new NodeAndInitialCredentials<InstanceInZone>(instanceInZone, 
instanceInZone.slashEncode(), credentials);
+   }
+
+   private Disk createBootDisk(Template template, String instanceName) {
+      URI imageUri = template.getImage().getUri();
+
+      GoogleComputeEngineTemplateOptions options = 
GoogleComputeEngineTemplateOptions.class.cast(template.getOptions()).clone();
+
+      int diskSize = options.getBootDiskSize().or(10l).intValue();
+
+      String diskName = instanceName + "-" + GCE_BOOT_DISK_SUFFIX;
+
+      Operation diskOperation = api.getDiskApiForProject(userProject.get())
+                                   
.createFromImageWithSizeInZone(imageUri.toString(),
+                                                                  diskName,
+                                                                  diskSize,
+                                                                  
template.getLocation().getId());
+
+      waitOperationDone(diskOperation);
+
+      return 
api.getDiskApiForProject(userProject.get()).getInZone(template.getLocation().getId(),
+                                                                   diskName);
+   }
+
+   @Override
+   public Iterable<MachineTypeInZone> listHardwareProfiles() {
+      ImmutableSet.Builder<MachineTypeInZone> builder = ImmutableSet.builder();
+
+      for (final Location zone : zones.get().values()) {
+         builder.addAll(api.getMachineTypeApiForProject(userProject.get())
+                 .listInZone(zone.getId())
+                 .concat()
+                 .filter(new Predicate<MachineType>() {
+                    @Override
+                    public boolean apply(MachineType input) {
+                       return !input.getDeprecated().isPresent();
+                    }
+                 })
+                 .transform(new Function<MachineType, MachineTypeInZone>() {
+
+                    @Override
+                    public MachineTypeInZone apply(MachineType arg0) {
+                       return new MachineTypeInZone(arg0, arg0.getZone());
+                    }
+                 }));
+      }
+
+      return builder.build();
+   }
+
+   @Override
+   public Iterable<Image> listImages() {
+      return ImmutableSet.<Image>builder()
+              
.addAll(api.getImageApiForProject(userProject.get()).list().concat())
+              
.addAll(api.getImageApiForProject(DEBIAN_PROJECT).list().concat())
+              
.addAll(api.getImageApiForProject(CENTOS_PROJECT).list().concat())
+              .build();
+   }
+
+   @Override
+   public Image getImage(String id) {
+      return 
Objects.firstNonNull(api.getImageApiForProject(userProject.get()).get(id),
+                                  
Objects.firstNonNull(api.getImageApiForProject(DEBIAN_PROJECT).get(id),
+                                          
api.getImageApiForProject(CENTOS_PROJECT).get(id)));
+
+   }
+
+   @Override
+   public Iterable<Zone> listLocations() {
+      return api.getZoneApiForProject(userProject.get()).list().concat();
+   }
+
+   @Override
+   public InstanceInZone getNode(String name) {
+      SlashEncodedIds slashEncodedIds = SlashEncodedIds.fromSlashEncoded(name);
+
+      Instance instance = 
api.getInstanceApiForProject(userProject.get()).getInZone(slashEncodedIds.getFirstId(),
+              slashEncodedIds.getSecondId());
+
+      return instance == null ?  null : new InstanceInZone(instance, 
slashEncodedIds.getFirstId());
+   }
+
+   @Override
+   public Iterable<InstanceInZone> listNodes() {
+      return FluentIterable.from(zones.get().values()).transformAndConcat(new 
Function<Location, ImmutableSet<InstanceInZone>>() {
+         @Override
+         public ImmutableSet<InstanceInZone> apply(final Location input) {
+            return 
api.getInstanceApiForProject(userProject.get()).listInZone(input.getId()).concat()
+                    .transform(new Function<Instance, InstanceInZone>() {
+
+                       @Override
+                       public InstanceInZone apply(Instance arg0) {
+                          return new InstanceInZone(arg0, input.getId());
+                       }
+                    }).toSet();
+         }
+      }).toSet();
+   }
+
+   @Override
+   public Iterable<InstanceInZone> listNodesByIds(final Iterable<String> ids) {
+      return filter(listNodes(), new Predicate<InstanceInZone>() {
+
+         @Override
+         public boolean apply(InstanceInZone instanceInZone) {
+            return contains(ids, instanceInZone.getInstance().getName());
+         }
+      });
+   }
+
+   @Override
+   public void destroyNode(final String name) {
+      SlashEncodedIds slashEncodedIds = SlashEncodedIds.fromSlashEncoded(name);
+      String diskName = null;
+      try {
+         Instance instance = 
api.getInstanceApiForProject(userProject.get()).getInZone(slashEncodedIds.getFirstId(),
+                                                                              
slashEncodedIds.getSecondId());
+         if 
(instance.getMetadata().getItems().get(GCE_DELETE_BOOT_DISK_METADATA_KEY).equals("true"))
 {
+            Optional<AttachedDisk> disk = tryFind(instance.getDisks(), new 
Predicate<AttachedDisk>() {
+               @Override
+               public boolean apply(AttachedDisk input) {
+                  return PersistentAttachedDisk.class.isInstance(input) &&
+                         PersistentAttachedDisk.class.cast(input).isBoot();
+               }
+            });
+            if (disk.isPresent()) {
+               diskName = 
PersistentAttachedDisk.class.cast(disk.get()).getSourceDiskName();
+            }
+         }
+      } catch (Exception e) {
+         // TODO: what exception actually gets thrown here if the instance 
doesn't really exist?
+      }
+      
waitOperationDone(api.getInstanceApiForProject(userProject.get()).deleteInZone(slashEncodedIds.getFirstId(),
+              slashEncodedIds.getSecondId()));
+
+      if (diskName != null) {
+         
waitOperationDone(api.getDiskApiForProject(userProject.get()).deleteInZone(slashEncodedIds.getFirstId(),
+                                                                               
     diskName));
+      }
+
+   }
+
+   @Override
+   public void rebootNode(final String name) {
+      SlashEncodedIds slashEncodedIds = SlashEncodedIds.fromSlashEncoded(name);
+
+      
waitOperationDone(api.getInstanceApiForProject(userProject.get()).resetInZone(slashEncodedIds.getFirstId(),
+              slashEncodedIds.getSecondId()));
+   }
+
+   @Override
+   public void resumeNode(String name) {
+      throw new UnsupportedOperationException("resume is not supported by 
GCE");
+   }
+
+   @Override
+   public void suspendNode(String name) {
+      throw new UnsupportedOperationException("suspend is not supported by 
GCE");
+   }
+
+   private LoginCredentials 
getFromImageAndOverrideIfRequired(org.jclouds.compute.domain.Image image,
+                                                              
GoogleComputeEngineTemplateOptions options) {
+      LoginCredentials defaultCredentials = image.getDefaultCredentials();
+      String[] keys = defaultCredentials.getPrivateKey().split(":");
+      String publicKey = keys[0];
+      String privateKey = keys[1];
+
+      LoginCredentials.Builder credentialsBuilder = 
defaultCredentials.toBuilder();
+      credentialsBuilder.privateKey(privateKey);
+
+      // LoginCredentials from image stores the public key along with the 
private key in the privateKey field
+      // @see GoogleComputePopulateDefaultLoginCredentialsForImageStrategy
+      // so if options doesn't have a public key set we set it from the default
+      if (options.getPublicKey() == null) {
+         options.authorizePublicKey(publicKey);
+      }
+      if (options.hasLoginPrivateKeyOption()) {
+         credentialsBuilder.privateKey(options.getPrivateKey());
+      }
+      if (options.getLoginUser() != null) {
+         credentialsBuilder.identity(options.getLoginUser());
+      }
+      if (options.hasLoginPasswordOption()) {
+         credentialsBuilder.password(options.getLoginPassword());
+      }
+      if (options.shouldAuthenticateSudo() != null) {
+         credentialsBuilder.authenticateSudo(options.shouldAuthenticateSudo());
+      }
+      LoginCredentials credentials = credentialsBuilder.build();
+      options.overrideLoginCredentials(credentials);
+      return credentials;
+   }
+
+   private void waitOperationDone(Operation operation) {
+      AtomicReference<Operation> operationRef = 
Atomics.newReference(operation);
+
+      // wait for the operation to complete
+      if (!retryOperationDonePredicate.apply(operationRef)) {
+         throw new UncheckedTimeoutException("operation did not reach DONE 
state" + operationRef.get());
+      }
+
+      // check if the operation failed
+      if (operationRef.get().getHttpError().isPresent()) {
+         HttpResponse response = operationRef.get().getHttpError().get();
+         throw new IllegalStateException("operation failed. Http Error Code: " 
+ response.getStatusCode() +
+                 " HttpError: " + response.getMessage());
+      }
+   }
+
+}

Reply via email to