Refactored Azure ARM to not use Deployments

* Simplified ImageExtension
* Fixed access to deployed VMS
* Made api-version configurable for all apis"
* Fixed all feature live tests
* Fixed the AzureComputeServiceLiveTest
* Fixed the AzureTemplateBuilderLiveTest
* Fixed the AzureComputeImageExtensionLiveTest


Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/2f110387
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/2f110387
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/2f110387

Branch: refs/heads/master
Commit: 2f110387381c4778c68c2287f616193d6474bd5f
Parents: 5742745
Author: Andrea Turli <andrea.tu...@gmail.com>
Authored: Wed Sep 28 18:20:26 2016 +0200
Committer: Ignasi Barrera <n...@apache.org>
Committed: Fri Oct 14 11:43:00 2016 +0200

----------------------------------------------------------------------
 azurecompute-arm/README.md                      |   6 +-
 azurecompute-arm/pom.xml                        |   7 +-
 .../azurecompute/arm/AzureComputeApi.java       |  17 +-
 .../arm/AzureComputeProviderMetadata.java       |  68 ++-
 .../arm/compute/AzureComputeServiceAdapter.java | 348 ++++++-----
 .../AzureComputeServiceContextModule.java       | 143 +++--
 .../extensions/AzureComputeImageExtension.java  | 178 +++---
 .../functions/DeploymentToNodeMetadata.java     | 244 --------
 .../functions/DeploymentToVMDeployment.java     | 121 ----
 .../ResourceDefinitionToCustomImage.java        |  78 +++
 .../arm/compute/functions/VMImageToImage.java   |  76 +--
 .../functions/VirtualMachineToNodeMetadata.java | 279 +++++++++
 .../compute/options/AzureTemplateOptions.java   |  54 +-
 .../predicates/IsDeploymentInRegions.java       |   1 +
 ...DefaultLoginCredentialsForImageStrategy.java |  43 --
 .../CreateResourceGroupThenCreateNodes.java     |  97 +++-
 .../arm/config/AzureComputeHttpApiModule.java   |   3 -
 .../arm/config/AzureComputeProperties.java      |   9 +-
 .../azurecompute/arm/domain/VMDeployment.java   |  38 +-
 .../azurecompute/arm/domain/VMImage.java        |  43 +-
 .../azurecompute/arm/domain/VirtualMachine.java |   7 +-
 .../arm/domain/VirtualMachineInstance.java      |  51 +-
 .../arm/domain/VirtualMachineProperties.java    |  27 +-
 .../arm/features/DeploymentApi.java             |   5 +-
 .../azurecompute/arm/features/JobApi.java       |   7 +-
 .../azurecompute/arm/features/LocationApi.java  |   7 +-
 .../arm/features/NetworkInterfaceCardApi.java   |  31 +-
 .../arm/features/NetworkSecurityGroupApi.java   |  46 +-
 .../arm/features/NetworkSecurityRuleApi.java    |  38 +-
 .../azurecompute/arm/features/OSImageApi.java   |   5 +-
 .../arm/features/PublicIPAddressApi.java        |  29 +-
 .../arm/features/ResourceGroupApi.java          |  19 +-
 .../arm/features/ResourceProviderApi.java       |  24 +-
 .../arm/features/StorageAccountApi.java         |  35 +-
 .../azurecompute/arm/features/SubnetApi.java    |  33 +-
 .../azurecompute/arm/features/VMSizeApi.java    |  20 +-
 .../arm/features/VirtualMachineApi.java         |  35 +-
 .../arm/features/VirtualNetworkApi.java         |  35 +-
 .../arm/filters/ApiVersionFilter.java           |  90 +++
 .../arm/functions/CleanupResources.java         | 210 ++++---
 .../StorageProfileToStorageAccountName.java     |  38 ++
 .../azurecompute/arm/util/BlobHelper.java       |  86 ++-
 .../arm/util/DeploymentTemplateBuilder.java     | 573 -------------------
 .../azurecompute/arm/util/GetEnumValue.java     |   1 -
 .../compute/AzureComputeServiceLiveTest.java    |  76 ++-
 .../compute/AzureTemplateBuilderLiveTest.java   |  49 +-
 .../AzureComputeImageExtensionLiveTest.java     |  69 +--
 .../arm/features/DeploymentApiLiveTest.java     |  92 ++-
 .../features/DeploymentTemplateBuilderTest.java | 287 ----------
 .../NetworkSecurityGroupApiMockTest.java        |   2 -
 .../features/PublicIPAddressApiMockTest.java    |   3 +-
 .../features/ResourceProviderAPIMockTest.java   |   1 -
 .../arm/features/StorageAccountApiMockTest.java |  35 --
 .../arm/features/SubnetApiMockTest.java         |  17 +-
 .../TemplateToDeploymentTemplateLiveTest.java   | 281 ---------
 .../arm/features/VirtualMachineApiLiveTest.java |  71 +--
 .../arm/features/VirtualMachineApiMockTest.java |  47 +-
 .../arm/features/VirtualNetworkApiMockTest.java |   2 +-
 .../arm/filters/ApiVersionFilterTest.java       | 129 +++++
 .../internal/BaseAzureComputeApiMockTest.java   |  19 +-
 60 files changed, 1881 insertions(+), 2604 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/README.md
----------------------------------------------------------------------
diff --git a/azurecompute-arm/README.md b/azurecompute-arm/README.md
index b1c0916..a5a9956 100644
--- a/azurecompute-arm/README.md
+++ b/azurecompute-arm/README.md
@@ -32,8 +32,7 @@ azure ad app create --name <name> --password <password> 
--home-page <home-page>
 # Create a Service Principal
 azure ad sp create <Application-id>
 
-# Output will include a value for `Object Id`
-
+# Output will include a value for `Object Id`, to be used in the next step 
 ```
 
 Run the following commands to assign roles to the service principal
@@ -58,7 +57,8 @@ mvn -Dtest=<name of the live test> \
     -Dtest.azurecompute-arm.identity="<Application-id>" \
     -Dtest.azurecompute-arm.credential="<password>" \
     
-Dtest.azurecompute-arm.endpoint="https://management.azure.com/subscriptions/<Subscription-id>"
 \
-    
-Dtest.oauth.endpoint="https://login.microsoftonline.com/<Tenant-id>/oauth2/token"
 test
+    
-Dtest.oauth.endpoint="https://login.microsoftonline.com/<Tenant-id>/oauth2/token"
+    integration-test -Plive
 
 ```
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/pom.xml
----------------------------------------------------------------------
diff --git a/azurecompute-arm/pom.xml b/azurecompute-arm/pom.xml
index df5b835..824e552 100644
--- a/azurecompute-arm/pom.xml
+++ b/azurecompute-arm/pom.xml
@@ -46,7 +46,7 @@
     <dependency>
       <groupId>org.apache.jclouds</groupId>
       <artifactId>jclouds-compute</artifactId>
-      <version>${project.parent.version}</version>
+      <version>${project.version}</version>
     </dependency>
     <dependency>
       <groupId>com.google.auto.service</groupId>
@@ -80,11 +80,6 @@
       <groupId>org.apache.jclouds</groupId>
       <artifactId>jclouds-compute</artifactId>
       <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.jclouds</groupId>
-      <artifactId>jclouds-compute</artifactId>
-      <version>${project.version}</version>
       <type>test-jar</type>
       <scope>test</scope>
     </dependency>

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
index 42749cf..c0c0994 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
@@ -16,28 +16,27 @@
  */
 package org.jclouds.azurecompute.arm;
 
+import java.io.Closeable;
+
+import javax.ws.rs.PathParam;
+
 import org.jclouds.azurecompute.arm.features.DeploymentApi;
-import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
 import org.jclouds.azurecompute.arm.features.JobApi;
 import org.jclouds.azurecompute.arm.features.LocationApi;
 import org.jclouds.azurecompute.arm.features.NetworkInterfaceCardApi;
+import org.jclouds.azurecompute.arm.features.NetworkSecurityGroupApi;
+import org.jclouds.azurecompute.arm.features.NetworkSecurityRuleApi;
 import org.jclouds.azurecompute.arm.features.OSImageApi;
 import org.jclouds.azurecompute.arm.features.PublicIPAddressApi;
 import org.jclouds.azurecompute.arm.features.ResourceGroupApi;
 import org.jclouds.azurecompute.arm.features.ResourceProviderApi;
 import org.jclouds.azurecompute.arm.features.StorageAccountApi;
 import org.jclouds.azurecompute.arm.features.SubnetApi;
+import org.jclouds.azurecompute.arm.features.VMSizeApi;
 import org.jclouds.azurecompute.arm.features.VirtualMachineApi;
 import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
-import org.jclouds.azurecompute.arm.features.VMSizeApi;
-import org.jclouds.azurecompute.arm.features.NetworkSecurityGroupApi;
-import org.jclouds.azurecompute.arm.features.NetworkSecurityRuleApi;
 import org.jclouds.rest.annotations.Delegate;
 
-import com.google.inject.Provides;
-import javax.ws.rs.PathParam;
-import java.io.Closeable;
-
 /**
  * The Azure Resource Manager API is a REST API for managing your services and 
deployments.
  * <p>
@@ -165,6 +164,4 @@ public interface AzureComputeApi extends Closeable {
    @Delegate
    ResourceProviderApi getResourceProviderApi();
 
-   @Provides
-   DeploymentTemplateBuilder.Factory deploymentTemplateFactory();
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
index 460df67..a434079 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
@@ -17,31 +17,47 @@
 package org.jclouds.azurecompute.arm;
 
 
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.API_VERSION_PREFIX;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_DATADISKSIZE;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_SUBNET_ADDRESS_PREFIX;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_VNET_ADDRESS_SPACE_PREFIX;
 import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
 import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_INITIAL_PERIOD;
 import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.STORAGE_API_VERSION;
 import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_FORMAT;
 import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_VNET_ADDRESS_SPACE_PREFIX;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_SUBNET_ADDRESS_PREFIX;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_DATADISKSIZE;
-
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_IMAGE_LOGIN;
-
+import static 
org.jclouds.compute.config.ComputeServiceProperties.IMAGE_AUTHENTICATE_SUDO;
+import static 
org.jclouds.compute.config.ComputeServiceProperties.IMAGE_LOGIN_USER;
+import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
+import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
 import static 
org.jclouds.oauth.v2.config.CredentialType.CLIENT_CREDENTIALS_SECRET;
-import static org.jclouds.oauth.v2.config.OAuthProperties.RESOURCE;
 import static org.jclouds.oauth.v2.config.OAuthProperties.CREDENTIAL_TYPE;
+import static org.jclouds.oauth.v2.config.OAuthProperties.RESOURCE;
 
 import java.net.URI;
 import java.util.Properties;
+
 import org.jclouds.azurecompute.arm.domain.Region;
+import org.jclouds.azurecompute.arm.features.DeploymentApi;
+import org.jclouds.azurecompute.arm.features.LocationApi;
+import org.jclouds.azurecompute.arm.features.NetworkInterfaceCardApi;
+import org.jclouds.azurecompute.arm.features.NetworkSecurityGroupApi;
+import org.jclouds.azurecompute.arm.features.NetworkSecurityRuleApi;
+import org.jclouds.azurecompute.arm.features.OSImageApi;
+import org.jclouds.azurecompute.arm.features.PublicIPAddressApi;
+import org.jclouds.azurecompute.arm.features.ResourceGroupApi;
+import org.jclouds.azurecompute.arm.features.ResourceProviderApi;
+import org.jclouds.azurecompute.arm.features.StorageAccountApi;
+import org.jclouds.azurecompute.arm.features.SubnetApi;
+import org.jclouds.azurecompute.arm.features.VMSizeApi;
+import org.jclouds.azurecompute.arm.features.VirtualMachineApi;
+import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
+import org.jclouds.compute.config.ComputeServiceProperties;
 import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.providers.internal.BaseProviderMetadata;
-import org.jclouds.compute.config.ComputeServiceProperties;
-
-import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
 
 import com.google.auto.service.AutoService;
 
@@ -72,13 +88,37 @@ public class AzureComputeProviderMetadata extends 
BaseProviderMetadata {
       properties.setProperty(TCP_RULE_REGEXP, "tcp_\\d{1,5}-\\d{1,5}");
       properties.put(RESOURCE, "https://management.azure.com/";);
       properties.put(CREDENTIAL_TYPE, CLIENT_CREDENTIALS_SECRET.toString());
-      properties.put(RESOURCE_GROUP_NAME, "jcloudsgroup");
+      properties.put(RESOURCE_GROUP_NAME, "jclouds");
       properties.put(DEFAULT_VNET_ADDRESS_SPACE_PREFIX, "10.0.0.0/16");
       properties.put(DEFAULT_SUBNET_ADDRESS_PREFIX, "10.0.0.0/24");
       properties.put(DEFAULT_DATADISKSIZE, "100");
       properties.put(IMAGE_PUBLISHERS, "Canonical,RedHat");
-      properties.put(DEFAULT_IMAGE_LOGIN, "jclouds:Password1!");
+      // Default credentials for all images
+      properties.put(IMAGE_LOGIN_USER, "jclouds:Password12345!");
+      properties.put(IMAGE_AUTHENTICATE_SUDO, "true");
+      properties.put(TEMPLATE, 
"imageNameMatches=UbuntuServer,osVersionMatches=1[45]\\.[01][04]\\.[0-9]-LTS");
       properties.put(TIMEOUT_NODE_TERMINATED, 60 * 10 * 1000);
+      // Api versions used in each API
+      properties.put(API_VERSION_PREFIX + DeploymentApi.class.getSimpleName(), 
"2016-02-01");
+      properties.put(API_VERSION_PREFIX + LocationApi.class.getSimpleName(), 
"2015-11-01");
+      properties.put(API_VERSION_PREFIX + 
NetworkInterfaceCardApi.class.getSimpleName(), "2015-06-15");
+      properties.put(API_VERSION_PREFIX + 
NetworkSecurityGroupApi.class.getSimpleName(), "2016-03-30");
+      properties.put(API_VERSION_PREFIX + 
NetworkSecurityRuleApi.class.getSimpleName(), "2016-03-30");
+      properties.put(API_VERSION_PREFIX + OSImageApi.class.getSimpleName(), 
"2015-06-15");
+      properties.put(API_VERSION_PREFIX + 
PublicIPAddressApi.class.getSimpleName(), "2015-06-15");
+      properties.put(API_VERSION_PREFIX + 
ResourceGroupApi.class.getSimpleName(), "2015-01-01");
+      properties.put(API_VERSION_PREFIX + 
ResourceProviderApi.class.getSimpleName(), "2015-01-01");
+      properties.put(API_VERSION_PREFIX + 
StorageAccountApi.class.getSimpleName(), STORAGE_API_VERSION);
+      properties.put(API_VERSION_PREFIX + SubnetApi.class.getSimpleName(), 
"2015-06-15");
+      properties.put(API_VERSION_PREFIX + 
VirtualNetworkApi.class.getSimpleName(), "2015-06-15");
+      properties.put(API_VERSION_PREFIX + VMSizeApi.class.getSimpleName(), 
"2015-06-15");
+      properties.put(API_VERSION_PREFIX + 
VirtualMachineApi.class.getSimpleName(), "2015-06-15");
+      properties.put(API_VERSION_PREFIX + "GetVirtualMachine", "2016-03-30");
+      properties.put(API_VERSION_PREFIX + "GetVirtualMachineInstance", 
"2016-03-30");
+      properties.put(API_VERSION_PREFIX + "CreateVirtualMachine", 
"2016-03-30");
+      properties.put(API_VERSION_PREFIX + "ListVirtualMachines", "2015-06-15");
+      properties.put(API_VERSION_PREFIX + "DeleteVirtualMachine", 
"2016-03-30");
+      
       return properties;
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
index 61807a9..0e2ed64 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
@@ -17,164 +17,139 @@
 package org.jclouds.azurecompute.arm.compute;
 
 import static com.google.common.base.Preconditions.checkState;
-import static java.lang.String.format;
-import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.jclouds.util.Predicates2.retry;
+import static com.google.common.collect.Iterables.contains;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.find;
+import static 
org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CONTAINER_NAME;
+import static 
org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CUSTOM_IMAGE_OFFER;
+import static 
org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.decodeFieldsFromUniqueId;
+import static 
org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.encodeFieldsToUniqueIdCustom;
+import static org.jclouds.util.Closeables2.closeQuietly;
 
-import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 
-import javax.annotation.Resource;
 import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Singleton;
 
 import org.jclouds.azurecompute.arm.AzureComputeApi;
 import 
org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
-import org.jclouds.azurecompute.arm.compute.functions.DeploymentToVMDeployment;
-import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage;
-import org.jclouds.azurecompute.arm.compute.predicates.IsDeploymentInRegions;
-import org.jclouds.azurecompute.arm.domain.Deployment;
-import org.jclouds.azurecompute.arm.domain.DeploymentBody;
-import org.jclouds.azurecompute.arm.domain.DeploymentProperties;
+import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
+import org.jclouds.azurecompute.arm.domain.DataDisk;
+import org.jclouds.azurecompute.arm.domain.HardwareProfile;
+import org.jclouds.azurecompute.arm.domain.IdReference;
+import org.jclouds.azurecompute.arm.domain.ImageReference;
+import org.jclouds.azurecompute.arm.domain.IpConfiguration;
+import org.jclouds.azurecompute.arm.domain.IpConfigurationProperties;
 import org.jclouds.azurecompute.arm.domain.Location;
+import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
+import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCardProperties;
+import org.jclouds.azurecompute.arm.domain.NetworkProfile;
+import org.jclouds.azurecompute.arm.domain.OSDisk;
+import org.jclouds.azurecompute.arm.domain.OSProfile;
 import org.jclouds.azurecompute.arm.domain.Offer;
+import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
+import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties;
 import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData;
 import org.jclouds.azurecompute.arm.domain.SKU;
+import org.jclouds.azurecompute.arm.domain.StorageProfile;
 import org.jclouds.azurecompute.arm.domain.StorageService;
-import org.jclouds.azurecompute.arm.domain.VMDeployment;
+import org.jclouds.azurecompute.arm.domain.StorageService.Status;
+import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
+import org.jclouds.azurecompute.arm.domain.VHD;
 import org.jclouds.azurecompute.arm.domain.VMHardware;
 import org.jclouds.azurecompute.arm.domain.VMImage;
 import org.jclouds.azurecompute.arm.domain.VMSize;
-import org.jclouds.azurecompute.arm.domain.Value;
 import org.jclouds.azurecompute.arm.domain.Version;
-import org.jclouds.azurecompute.arm.features.DeploymentApi;
+import org.jclouds.azurecompute.arm.domain.VirtualMachine;
+import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
 import org.jclouds.azurecompute.arm.features.OSImageApi;
+import org.jclouds.azurecompute.arm.features.PublicIPAddressApi;
 import org.jclouds.azurecompute.arm.functions.CleanupResources;
 import org.jclouds.azurecompute.arm.util.BlobHelper;
-import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
 import org.jclouds.compute.ComputeServiceAdapter;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.OsFamily;
 import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.reference.ComputeServiceConstants;
-import org.jclouds.domain.LoginCredentials;
 import org.jclouds.location.Region;
-import org.jclouds.logging.Logger;
 
 import com.google.common.base.Function;
+import com.google.common.base.Objects;
 import com.google.common.base.Predicate;
 import com.google.common.base.Splitter;
 import com.google.common.base.Supplier;
-import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-import com.google.common.net.UrlEscapers;
 
 /**
  * Defines the connection between the {@link AzureComputeApi} implementation 
and the jclouds
  * {@link org.jclouds.compute.ComputeService}.
  */
 @Singleton
-public class AzureComputeServiceAdapter implements 
ComputeServiceAdapter<VMDeployment, VMHardware, VMImage, Location> {
+public class AzureComputeServiceAdapter implements 
ComputeServiceAdapter<VirtualMachine, VMHardware, VMImage, Location> {
 
-   private String azureGroup;
-   protected final CleanupResources cleanupResources;
-
-   @Resource
-   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
-   private Logger logger = Logger.NULL;
+   private final String azureGroup;
+   private final CleanupResources cleanupResources;
    private final AzureComputeApi api;
    private final AzureComputeConstants azureComputeConstants;
    private final Supplier<Set<String>> regionIds;
-   private final IsDeploymentInRegions isDeploymentInRegions;
-   private final DeploymentToVMDeployment deploymentToVMDeployment;
+   private final Predicate<String> publicIpAvailable;
 
    @Inject
    AzureComputeServiceAdapter(final AzureComputeApi api, final 
AzureComputeConstants azureComputeConstants,
          CleanupResources cleanupResources, @Region Supplier<Set<String>> 
regionIds,
-         IsDeploymentInRegions isDeploymentInRegions, DeploymentToVMDeployment 
deploymentToVMDeployment) {
+         @Named("PublicIpAvailable") Predicate<String> publicIpAvailable) {
       this.api = api;
       this.azureComputeConstants = azureComputeConstants;
       this.azureGroup = azureComputeConstants.azureResourceGroup();
-
-      logger.debug("AzureComputeServiceAdapter set azuregroup to: " + 
azureGroup);
-
       this.cleanupResources = cleanupResources;
       this.regionIds = regionIds;
-      this.isDeploymentInRegions = isDeploymentInRegions;
-      this.deploymentToVMDeployment = deploymentToVMDeployment;
+      this.publicIpAvailable = publicIpAvailable;
    }
 
    @Override
-   public NodeAndInitialCredentials<VMDeployment> 
createNodeWithGroupEncodedIntoName(
+   public NodeAndInitialCredentials<VirtualMachine> 
createNodeWithGroupEncodedIntoName(
            final String group, final String name, final Template template) {
 
-      DeploymentTemplateBuilder deploymentTemplateBuilder = 
api.deploymentTemplateFactory().create(group, name, template);
-
-      final String loginUser = 
DeploymentTemplateBuilder.getLoginUserUsername();
-      final String loginPassword = 
DeploymentTemplateBuilder.getLoginPassword();
-
-      DeploymentBody deploymentTemplateBody =  
deploymentTemplateBuilder.getDeploymentTemplate();
-
-      DeploymentProperties properties = 
DeploymentProperties.create(deploymentTemplateBody);
-
-      final String deploymentTemplate = 
UrlEscapers.urlFormParameterEscaper().escape(deploymentTemplateBuilder.getDeploymentTemplateJson(properties));
-
-      logger.debug("Deployment created with name: %s group: %s", name, group);
-
-
-      final Set<VMDeployment> deployments = Sets.newHashSet();
-
-      final DeploymentApi deploymentApi = api.getDeploymentApi(azureGroup);
-
-      if (!retry(new Predicate<String>() {
-         @Override
-         public boolean apply(final String name) {
-            Deployment deployment = deploymentApi.create(name, 
deploymentTemplate);
-
-            if (deployment != null) {
-               VMDeployment vmDeployment = VMDeployment.create(deployment);
-               deployments.add(vmDeployment);
-            } else {
-               logger.debug("Failed to create deployment!");
-            }
-            return !deployments.isEmpty();
-         }
-      }, azureComputeConstants.operationTimeout(), 1, SECONDS).apply(name)) {
-         final String illegalStateExceptionMessage = format("Deployment %s was 
not created within %sms so it will be destroyed.",
-                 name, azureComputeConstants.operationTimeout());
-         logger.warn(illegalStateExceptionMessage);
-         destroyNode(name);
-         throw new IllegalStateException(illegalStateExceptionMessage);
-      }
-      final VMDeployment deployment = deployments.iterator().next();
-      NodeAndInitialCredentials<VMDeployment> credential;
-      if (template.getOptions().getPublicKey() != null){
-         String privateKey = template.getOptions().getPrivateKey();
-         credential = new NodeAndInitialCredentials<VMDeployment>(deployment, 
name,
-                 
LoginCredentials.builder().user(loginUser).privateKey(privateKey).authenticateSudo(true).build());
-      } else {
-         credential = new NodeAndInitialCredentials<VMDeployment>(deployment, 
name,
-                 
LoginCredentials.builder().user(loginUser).password(loginPassword).authenticateSudo(true).build());
-      }
-      return credential;
+      AzureTemplateOptions templateOptions = 
template.getOptions().as(AzureTemplateOptions.class);
+
+      // TODO Store group apart from the name to be able to identify nodes 
with custom names in the configured group
+      // TODO ARM specific options
+      // TODO user metadata and tags
+      // TODO network ids => create one nic in each network
+      // TODO inbound ports
+      
+      String locationName = template.getLocation().getId();
+      String subnetId = templateOptions.getSubnetId();
+      NetworkInterfaceCard nic = createNetworkInterfaceCard(subnetId, name, 
locationName); 
+      StorageProfile storageProfile = createStorageProfile(name, 
template.getImage(), templateOptions.getBlob());
+      HardwareProfile hardwareProfile = 
HardwareProfile.builder().vmSize(template.getHardware().getId()).build();
+      OSProfile osProfile = createOsProfile(name, template);
+      NetworkProfile networkProfile = 
NetworkProfile.builder().networkInterfaces(ImmutableList.of(IdReference.create(nic.id()))).build();
+      VirtualMachineProperties virtualMachineProperties = 
VirtualMachineProperties.builder()
+              .licenseType(null) // TODO
+              .availabilitySet(null) // TODO
+              .hardwareProfile(hardwareProfile)
+              .storageProfile(storageProfile)
+              .osProfile(osProfile)
+              .networkProfile(networkProfile)
+              .build();
+
+      VirtualMachine virtualMachine = 
api.getVirtualMachineApi(azureGroup).create(name, 
template.getLocation().getId(), virtualMachineProperties);
+
+      // Safe to pass null credentials here, as jclouds will default populate 
the node with the default credentials from the image, or the ones in the 
options, if provided.
+      return new NodeAndInitialCredentials<VirtualMachine>(virtualMachine, 
name, null);
    }
 
    @Override
    public Iterable<VMHardware> listHardwareProfiles() {
-
       final List<VMHardware> hwProfiles = Lists.newArrayList();
-      final List<String> locationIds = Lists.newArrayList();
-
-      Iterable<Location> locations = listLocations();
-      for (Location location : locations){
-         locationIds.add(location.name());
-
+      for (Location location : listLocations()) {
          Iterable<VMSize> vmSizes = api.getVMSizeApi(location.name()).list();
-
          for (VMSize vmSize : vmSizes){
             VMHardware hwProfile = VMHardware.create(
                     vmSize.name(),
@@ -188,22 +163,8 @@ public class AzureComputeServiceAdapter implements 
ComputeServiceAdapter<VMDeplo
             hwProfiles.add(hwProfile);
          }
       }
-
-      checkAndSetHwAvailability(hwProfiles, Sets.newHashSet(locationIds));
-
       return hwProfiles;
    }
-   private void checkAndSetHwAvailability(List<VMHardware> hwProfiles, 
Collection<String> locations) {
-      Multimap<String, String> hwMap = ArrayListMultimap.create();
-      for (VMHardware hw : hwProfiles) {
-         hwMap.put(hw.name(), hw.location());
-      }
-
-      /// TODO
-      //      for (VMHardware hw : hwProfiles) {
-      //         hw.globallyAvailable() = 
hwMap.get(hw.name()).containsAll(locations);
-      //      }
-   }
 
    private List<VMImage> getImagesFromPublisher(String publisherName, String 
location) {
       List<VMImage> osImagesRef = Lists.newArrayList();
@@ -216,7 +177,8 @@ public class AzureComputeServiceAdapter implements 
ComputeServiceAdapter<VMDeplo
          for (SKU sku : skuList) {
             Iterable<Version> versionList = 
osImageApi.listVersions(publisherName, offer.name(), sku.name());
             for (Version version : versionList) {
-               VMImage vmImage = VMImage.create(publisherName, offer.name(), 
sku.name(), version.name(), location);
+               VMImage vmImage = 
VMImage.azureImage().publisher(publisherName).offer(offer.name()).sku(sku.name())
+                     .version(version.name()).location(location).build();
                osImagesRef.add(vmImage);
             }
          }
@@ -235,7 +197,6 @@ public class AzureComputeServiceAdapter implements 
ComputeServiceAdapter<VMDeplo
 
    @Override
    public Iterable<VMImage> listImages() {
-
       final List<VMImage> osImages = Lists.newArrayList();
 
       for (Location location : listLocations()){
@@ -245,24 +206,51 @@ public class AzureComputeServiceAdapter implements 
ComputeServiceAdapter<VMDeplo
       List<StorageService> storages = 
api.getStorageAccountApi(azureGroup).list();
       for (StorageService storage : storages) {
          String name = storage.name();
-         String key = 
api.getStorageAccountApi(azureGroup).getKeys(name).key1();
-            List<VMImage> images = BlobHelper.getImages("jclouds", azureGroup, 
storage.name(), key,
-                  "custom", storage.location());
-            osImages.addAll(images);
+         StorageService storageService = 
api.getStorageAccountApi(azureGroup).get(name);
+         if (storageService != null
+               && Status.Succeeded == 
storageService.storageServiceProperties().provisioningState()) {
+            String key = 
api.getStorageAccountApi(azureGroup).getKeys(name).key1();
+            BlobHelper blobHelper = new BlobHelper(storage.name(), key);
+            try {
+               List<VMImage> images = blobHelper.getImages(CONTAINER_NAME, 
azureGroup, CUSTOM_IMAGE_OFFER,
+                     storage.location());
+               osImages.addAll(images);
+            } finally {
+               closeQuietly(blobHelper);
+            }
+         }
       }
+      
       return osImages;
    }
 
    @Override
    public VMImage getImage(final String id) {
-      VMImage image = VMImageToImage.decodeFieldsFromUniqueId(id);
+      VMImage image = decodeFieldsFromUniqueId(id);
       if (image.custom()) {
-         String key = 
api.getStorageAccountApi(azureGroup).getKeys(image.storage()).key1();
-         if (BlobHelper.customImageExists(image.storage(), key))
-            return image;
-         else
+         VMImage customImage = null;
+         StorageServiceKeys keys = 
api.getStorageAccountApi(azureGroup).getKeys(image.storage());
+         if (keys == null) {
+            // If the storage account for the image does not exist, it means 
the image was deleted
             return null;
-
+         }
+         
+         BlobHelper blobHelper = new BlobHelper(image.storage(), keys.key1());
+         try {
+            if (blobHelper.customImageExists()) {
+               List<VMImage> customImagesInStorage = 
blobHelper.getImages(CONTAINER_NAME, azureGroup,
+                     CUSTOM_IMAGE_OFFER, image.location());
+               customImage = find(customImagesInStorage, new 
Predicate<VMImage>() {
+                  @Override
+                  public boolean apply(VMImage input) {
+                     return id.equals(encodeFieldsToUniqueIdCustom(input));
+                  }
+               }, null);
+            }
+         } finally {
+            closeQuietly(blobHelper);
+         }
+         return customImage;
       }
 
       String location = image.location();
@@ -273,7 +261,8 @@ public class AzureComputeServiceAdapter implements 
ComputeServiceAdapter<VMDeplo
       OSImageApi osImageApi = api.getOSImageApi(location);
       List<Version> versions = osImageApi.listVersions(publisher, offer, sku);
       if (!versions.isEmpty()) {
-         return VMImage.create(publisher, offer, sku, versions.get(0).name(), 
location);
+         return 
VMImage.azureImage().publisher(publisher).offer(offer).sku(sku).version(versions.get(0).name())
+               .location(location).build();
       }
       return null;
    }
@@ -313,13 +302,8 @@ public class AzureComputeServiceAdapter implements 
ComputeServiceAdapter<VMDeplo
    }
 
    @Override
-   public VMDeployment getNode(final String id) {
-      Deployment deployment = api.getDeploymentApi(azureGroup).get(id);
-      if (deployment == null) return null;
-      if (isDeploymentInRegions.apply(deployment)) {
-         return deploymentToVMDeployment.apply(deployment);
-      }
-      return null;
+   public VirtualMachine getNode(final String id) {
+      return api.getVirtualMachineApi(azureGroup).get(id);
    }
 
    @Override
@@ -343,29 +327,99 @@ public class AzureComputeServiceAdapter implements 
ComputeServiceAdapter<VMDeplo
    }
 
    @Override
-   public Iterable<VMDeployment> listNodes() {
-      return FluentIterable.from(api.getDeploymentApi(azureGroup).list())
-              .filter(isDeploymentInRegions)
-              .filter(new Predicate<Deployment>() {
-                 @Override
-                 public boolean apply(Deployment deployment) {
-                    Value storageAccountNameValue = 
deployment.properties().parameters().get("storageAccountName");
-                    String storageAccountName = 
storageAccountNameValue.value();
-                    String key = 
api.getStorageAccountApi(azureGroup).getKeys(storageAccountName).key1();
-                    return !BlobHelper.customImageExists(storageAccountName, 
key);
-                 }
-              })
-              .transform(deploymentToVMDeployment)
-              .toList();
+   public Iterable<VirtualMachine> listNodes() {
+      return api.getVirtualMachineApi(azureGroup).list();
    }
 
    @Override
-   public Iterable<VMDeployment> listNodesByIds(final Iterable<String> ids) {
-      return Iterables.filter(listNodes(), new Predicate<VMDeployment>() {
+   public Iterable<VirtualMachine> listNodesByIds(final Iterable<String> ids) {
+      return filter(listNodes(), new Predicate<VirtualMachine>() {
          @Override
-         public boolean apply(final VMDeployment input) {
-            return Iterables.contains(ids, input.deployment().name());
+         public boolean apply(VirtualMachine virtualMachine) {
+            return contains(ids, virtualMachine.id());
          }
       });
    }
+
+
+   private OSProfile createOsProfile(String computerName, Template template) {
+      String defaultLoginUser = 
template.getImage().getDefaultCredentials().getUser();
+      String defaultLoginPassword = 
template.getImage().getDefaultCredentials().getOptionalPassword().get();
+      String adminUsername = 
Objects.firstNonNull(template.getOptions().getLoginUser(), defaultLoginUser);
+      String adminPassword = 
Objects.firstNonNull(template.getOptions().getLoginPassword(), 
defaultLoginPassword);
+      OSProfile.Builder builder = 
OSProfile.builder().adminUsername(adminUsername).computerName(computerName);
+      // prefer public key over password
+      if (template.getOptions().getPublicKey() != null) {
+         OSProfile.LinuxConfiguration linuxConfiguration = 
OSProfile.LinuxConfiguration.create("true",
+                 OSProfile.LinuxConfiguration.SSH.create(ImmutableList.of(
+                         OSProfile.LinuxConfiguration.SSH.SSHPublicKey.create(
+                                 
String.format("/home/%s/.ssh/authorized_keys", adminUsername),
+                                 template.getOptions().getPublicKey())
+                 ))
+         );
+         builder.linuxConfiguration(linuxConfiguration);
+      } else {
+         builder.adminPassword(adminPassword);
+      }
+      return builder.build();
+   }
+
+   private NetworkInterfaceCard createNetworkInterfaceCard(String subnetId, 
String name, String locationName) {
+      final PublicIPAddressApi ipApi = api.getPublicIPAddressApi(azureGroup);
+
+      PublicIPAddressProperties properties =
+              PublicIPAddressProperties.builder()
+                      .publicIPAllocationMethod("Static")
+                      .idleTimeoutInMinutes(4)
+                      .build();
+
+      String publicIpAddressName = "public-address-" + name;
+      PublicIPAddress ip = ipApi.createOrUpdate(publicIpAddressName, 
locationName, ImmutableMap.of("jclouds", name), properties);
+      
+      checkState(publicIpAvailable.apply(publicIpAddressName),
+            "Public IP was not provisioned in the configured timeout");
+
+      final NetworkInterfaceCardProperties networkInterfaceCardProperties =
+              NetworkInterfaceCardProperties.builder()
+                      .ipConfigurations(ImmutableList.of(
+                              IpConfiguration.builder()
+                                      .name("ipConfig-" + name)
+                                      
.properties(IpConfigurationProperties.builder()
+                                              
.privateIPAllocationMethod("Dynamic")
+                                              
.publicIPAddress(IdReference.create(ip.id()))
+                                              
.subnet(IdReference.create(subnetId))
+                                              .build())
+                                      .build()))
+                      .build();
+
+      String networkInterfaceCardName = "jc-nic-" + name;
+      return 
api.getNetworkInterfaceCardApi(azureGroup).createOrUpdate(networkInterfaceCardName,
 locationName, networkInterfaceCardProperties, ImmutableMap.of("jclouds", 
name));
+   }
+
+   private StorageProfile createStorageProfile(String name, Image image, 
String blob) {
+      VMImage imageRef = decodeFieldsFromUniqueId(image.getId());
+      ImageReference imageReference = null;
+      VHD sourceImage = null;
+      String osType = null;
+      
+      if (!imageRef.custom()) {
+         imageReference = ImageReference.builder()
+               .publisher(image.getProviderId())
+               .offer(image.getName())
+               .sku(image.getVersion())
+               .version("latest")
+               .build();
+      } else {
+         sourceImage = VHD.create(image.getProviderId());
+
+         // TODO: read the ostype from the image blob
+         OsFamily osFamily = image.getOperatingSystem().getFamily();
+         osType = osFamily == OsFamily.WINDOWS ? "Windows" : "Linux";
+      }
+      
+      VHD vhd = VHD.create(blob + "vhds/" + name + ".vhd");
+      OSDisk osDisk = OSDisk.create(osType, name, vhd, "ReadWrite", 
"FromImage", sourceImage);
+      
+      return StorageProfile.create(imageReference, osDisk, 
ImmutableList.<DataDisk>of());
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
index 6033f42..24f02ea 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
@@ -16,10 +16,27 @@
  */
 package org.jclouds.azurecompute.arm.compute.config;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_DATADISKSIZE;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_SUBNET_ADDRESS_PREFIX;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_VNET_ADDRESS_SPACE_PREFIX;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_INITIAL_PERIOD;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_FORMAT;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
+import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
+import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
+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.util.Predicates2.retry;
+
 import java.net.URI;
 import java.util.List;
 
-import javax.annotation.Resource;
 import javax.inject.Named;
 import javax.inject.Singleton;
 
@@ -27,19 +44,21 @@ import org.jclouds.azurecompute.arm.AzureComputeApi;
 import org.jclouds.azurecompute.arm.compute.AzureComputeService;
 import org.jclouds.azurecompute.arm.compute.AzureComputeServiceAdapter;
 import 
org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension;
-import org.jclouds.azurecompute.arm.compute.functions.DeploymentToNodeMetadata;
 import org.jclouds.azurecompute.arm.compute.functions.LocationToLocation;
+import 
org.jclouds.azurecompute.arm.compute.functions.ResourceDefinitionToCustomImage;
 import org.jclouds.azurecompute.arm.compute.functions.VMHardwareToHardware;
 import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage;
+import 
org.jclouds.azurecompute.arm.compute.functions.VirtualMachineToNodeMetadata;
 import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
-import 
org.jclouds.azurecompute.arm.compute.strategy.AzurePopulateDefaultLoginCredentialsForImageStrategy;
 import 
org.jclouds.azurecompute.arm.compute.strategy.CreateResourceGroupThenCreateNodes;
 import org.jclouds.azurecompute.arm.domain.Location;
+import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
 import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
-import org.jclouds.azurecompute.arm.domain.VMDeployment;
 import org.jclouds.azurecompute.arm.domain.VMHardware;
 import org.jclouds.azurecompute.arm.domain.VMImage;
+import org.jclouds.azurecompute.arm.domain.VirtualMachine;
 import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
+import 
org.jclouds.azurecompute.arm.domain.VirtualMachineInstance.VirtualMachineStatus.PowerState;
 import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
 import org.jclouds.compute.ComputeService;
 import org.jclouds.compute.ComputeServiceAdapter;
@@ -47,13 +66,12 @@ import 
org.jclouds.compute.config.ComputeServiceAdapterContextModule;
 import org.jclouds.compute.domain.Hardware;
 import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.functions.NodeAndTemplateOptionsToStatement;
+import 
org.jclouds.compute.functions.NodeAndTemplateOptionsToStatementWithoutPublicKey;
 import org.jclouds.compute.options.TemplateOptions;
-import org.jclouds.compute.reference.ComputeServiceConstants;
 import org.jclouds.compute.reference.ComputeServiceConstants.PollPeriod;
 import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
 import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
-import 
org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
-import org.jclouds.logging.Logger;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Function;
@@ -61,53 +79,37 @@ import com.google.common.base.Predicate;
 import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.TypeLiteral;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_DATADISKSIZE;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_IMAGE_LOGIN;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_SUBNET_ADDRESS_PREFIX;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_VNET_ADDRESS_SPACE_PREFIX;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_INITIAL_PERIOD;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_FORMAT;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
-import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
-import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
-import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
-import static org.jclouds.util.Predicates2.retry;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
 
 public class AzureComputeServiceContextModule
-        extends ComputeServiceAdapterContextModule<VMDeployment, VMHardware, 
VMImage, Location> {
-
-   @Resource
-   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
-   protected Logger logger = Logger.NULL;
+        extends ComputeServiceAdapterContextModule<VirtualMachine, VMHardware, 
VMImage, Location> {
 
    @Override
    protected void configure() {
       super.configure();
-      bind(new TypeLiteral<ComputeServiceAdapter<VMDeployment, VMHardware, 
VMImage, Location>>() {
+      
+      bind(new TypeLiteral<ComputeServiceAdapter<VirtualMachine, VMHardware, 
VMImage, Location>>() {
       }).to(AzureComputeServiceAdapter.class);
+      
       bind(new TypeLiteral<Function<VMImage, 
org.jclouds.compute.domain.Image>>() {
       }).to(VMImageToImage.class);
       bind(new TypeLiteral<Function<VMHardware, Hardware>>() {
       }).to(VMHardwareToHardware.class);
-      bind(new TypeLiteral<Function<VMDeployment, NodeMetadata>>() {
-      }).to(DeploymentToNodeMetadata.class);
+      bind(new TypeLiteral<Function<VirtualMachine, NodeMetadata>>() {
+      }).to(VirtualMachineToNodeMetadata.class);
       bind(new TypeLiteral<Function<Location, org.jclouds.domain.Location>>() {
       }).to(LocationToLocation.class);
       bind(ComputeService.class).to(AzureComputeService.class);
-      install(new LocationsFromComputeServiceAdapterModule<VMDeployment, 
VMHardware, VMImage, Location>() {
+      
+      install(new LocationsFromComputeServiceAdapterModule<VirtualMachine, 
VMHardware, VMImage, Location>() {
       });
+      
+      install(new 
FactoryModuleBuilder().build(ResourceDefinitionToCustomImage.Factory.class));
 
       bind(TemplateOptions.class).to(AzureTemplateOptions.class);
-      
bind(PopulateDefaultLoginCredentialsForImageStrategy.class).to(AzurePopulateDefaultLoginCredentialsForImageStrategy.class);
-      
//bind(TemplateOptionsToStatement.class).to(TemplateOptionsToStatementWithoutPublicKey.class);
+      
bind(NodeAndTemplateOptionsToStatement.class).to(NodeAndTemplateOptionsToStatementWithoutPublicKey.class);
       
bind(CreateNodesInGroupThenAddToSet.class).to(CreateResourceGroupThenCreateNodes.class);
+      
       bind(new TypeLiteral<ImageExtension>() {
       }).to(AzureComputeImageExtension.class);
    }
@@ -143,10 +145,6 @@ public class AzureComputeServiceContextModule
       @Inject
       private String azureImagePublishersProperty;
 
-      @Named(DEFAULT_IMAGE_LOGIN)
-      @Inject
-      private String azureDefaultImageLoginProperty;
-
       @Named(DEFAULT_VNET_ADDRESS_SPACE_PREFIX)
       @Inject
       private String azureDefaultVnetAddressPrefixProperty;
@@ -171,10 +169,6 @@ public class AzureComputeServiceContextModule
          return azureImagePublishersProperty;
       }
 
-      public String azureDefaultImageLogin() {
-         return azureDefaultImageLoginProperty;
-      }
-
       public String azureDefaultVnetAddressPrefixProperty() {
          return azureDefaultVnetAddressPrefixProperty;
       }
@@ -205,6 +199,14 @@ public class AzureComputeServiceContextModule
    }
 
    @Provides
+   @com.google.inject.name.Named(TIMEOUT_NODE_RUNNING)
+   protected Predicate<String> provideVirtualMachineRunningPredicate(final 
AzureComputeApi api, final 
AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants, 
Timeouts timeouts, PollPeriod pollPeriod) {
+      String azureGroup = azureComputeConstants.azureResourceGroup();
+      return retry(new VirtualMachineInStatePredicate(api, azureGroup, 
PowerState.RUNNING), timeouts.nodeRunning,
+              pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+   }
+   
+   @Provides
    @Named(TIMEOUT_NODE_TERMINATED)
    protected Predicate<URI> provideNodeTerminatedPredicate(final 
AzureComputeApi api, Timeouts timeouts, PollPeriod pollPeriod) {
       return retry(new ActionDonePredicate(api), timeouts.nodeTerminated, 
pollPeriod.pollInitialPeriod,
@@ -230,7 +232,17 @@ public class AzureComputeServiceContextModule
    protected Predicate<String> provideNodeSuspendedPredicate(final 
AzureComputeApi api, final 
AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
                                                              Timeouts 
timeouts, PollPeriod pollPeriod) {
       String azureGroup = azureComputeConstants.azureResourceGroup();
-      return retry(new NodeSuspendedPredicate(api, azureGroup), 
timeouts.nodeSuspended, pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+      return retry(new VirtualMachineInStatePredicate(api, azureGroup, 
PowerState.STOPPED), timeouts.nodeTerminated,
+              pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+   }
+   
+   @Provides
+   @Named("PublicIpAvailable")
+   protected Predicate<String> providePublicIpAvailablePredicate(final 
AzureComputeApi api, final 
AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
+                                                             Timeouts 
timeouts, PollPeriod pollPeriod) {
+      String azureGroup = azureComputeConstants.azureResourceGroup();
+      return retry(new PublicIpAvailablePredicate(api, azureGroup), 
azureComputeConstants.operationTimeout(),
+            azureComputeConstants.operationPollInitialPeriod(), 
azureComputeConstants.operationPollMaxPeriod());
    }
 
    @VisibleForTesting
@@ -269,30 +281,45 @@ public class AzureComputeServiceContextModule
    }
 
    @VisibleForTesting
-   static class NodeSuspendedPredicate implements Predicate<String> {
+   static class VirtualMachineInStatePredicate implements Predicate<String> {
 
       private final AzureComputeApi api;
       private final String azureGroup;
+      private final PowerState powerState;
 
-      public NodeSuspendedPredicate(AzureComputeApi api, String azureGroup) {
+      public VirtualMachineInStatePredicate(AzureComputeApi api, String 
azureGroup, PowerState powerState) {
          this.api = checkNotNull(api, "api must not be null");
          this.azureGroup = checkNotNull(azureGroup, "azuregroup must not be 
null");
+         this.powerState = checkNotNull(powerState, "powerState must not be 
null");
       }
 
       @Override
       public boolean apply(String name) {
          checkNotNull(name, "name cannot be null");
-         String status = "";
-         VirtualMachineInstance virtualMachineInstance = 
api.getVirtualMachineApi(this.azureGroup).getInstanceDetails(name);
-         if (virtualMachineInstance == null) return false;
-         List<VirtualMachineInstance.VirtualMachineStatus> statuses = 
virtualMachineInstance.statuses();
-         for (int c = 0; c < statuses.size(); c++) {
-            if (statuses.get(c).code().substring(0, 10).equals("PowerState")) {
-               status = statuses.get(c).displayStatus();
-               break;
-            }
-         }
-         return status.equals("VM stopped");
+         VirtualMachineInstance vmInstance = 
api.getVirtualMachineApi(this.azureGroup).getInstanceDetails(name);
+         if (vmInstance == null) return false;
+         return powerState == vmInstance.powerState();
       }
    }
+   
+   @VisibleForTesting
+   static class PublicIpAvailablePredicate implements Predicate<String> {
+
+      private final AzureComputeApi api;
+      private final String azureGroup;
+
+      public PublicIpAvailablePredicate(AzureComputeApi api, String 
azureGroup) {
+         this.api = checkNotNull(api, "api must not be null");
+         this.azureGroup = checkNotNull(azureGroup, "azuregroup must not be 
null");
+      }
+
+      @Override
+      public boolean apply(String name) {
+         checkNotNull(name, "name cannot be null");
+         PublicIPAddress publicIp = 
api.getPublicIPAddressApi(azureGroup).get(name);
+         if (publicIp == null) return false;
+         return 
publicIp.properties().provisioningState().equalsIgnoreCase("Succeeded");
+      }
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
index 786c17a..99c9c6c 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
@@ -16,141 +16,137 @@
  */
 package org.jclouds.azurecompute.arm.compute.extensions;
 
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.UncheckedTimeoutException;
-import com.google.gson.internal.LinkedTreeMap;
-import com.google.inject.Inject;
-import com.google.inject.name.Named;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+import static 
org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.decodeFieldsFromUniqueId;
+import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
+import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
+import static org.jclouds.util.Closeables2.closeQuietly;
+
+import java.net.URI;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import javax.annotation.Resource;
+
 import org.jclouds.Constants;
-import org.jclouds.View;
 import org.jclouds.azurecompute.arm.AzureComputeApi;
-import 
org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
-import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage;
+import 
org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
+import 
org.jclouds.azurecompute.arm.compute.functions.ResourceDefinitionToCustomImage;
 import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
 import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
 import org.jclouds.azurecompute.arm.domain.VMImage;
-import org.jclouds.azurecompute.arm.domain.VirtualMachine;
-import static java.lang.String.format;
+import org.jclouds.azurecompute.arm.functions.CleanupResources;
 import org.jclouds.azurecompute.arm.util.BlobHelper;
 import org.jclouds.compute.domain.CloneImageTemplate;
 import org.jclouds.compute.domain.Image;
 import org.jclouds.compute.domain.ImageTemplate;
 import org.jclouds.compute.domain.ImageTemplateBuilder;
 import org.jclouds.compute.extensions.ImageExtension;
-import 
org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
 
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
+import com.google.common.base.Predicate;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
 
-import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
-import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
+public class AzureComputeImageExtension implements ImageExtension {
+   public static final String CONTAINER_NAME = "jclouds";
+   public static final String CUSTOM_IMAGE_OFFER = "custom";
 
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
 
-public class AzureComputeImageExtension implements ImageExtension {
    private final AzureComputeApi api;
-   private final ListeningExecutorService userExecutor;
-   private final Supplier<View> blobstore = null;
    private final String group;
+   private final ListeningExecutorService userExecutor;
    private final Predicate<URI> imageAvailablePredicate;
    private final Predicate<String> nodeSuspendedPredicate;
-   private final AzureComputeConstants azureComputeConstants;
-   private final VMImageToImage imageReferenceToImage;
-   public static final String CONTAINER_NAME = "jclouds";
-   public static final String CUSTOM_IMAGE_PREFIX = "#";
+   private final ResourceDefinitionToCustomImage.Factory 
resourceDefinitionToImage;
+   private final CleanupResources cleanupResources;
 
    @Inject
    AzureComputeImageExtension(AzureComputeApi api,
-                              @Named(TIMEOUT_IMAGE_AVAILABLE) Predicate<URI> 
imageAvailablePredicate,
-                              @Named(TIMEOUT_NODE_SUSPENDED) Predicate<String> 
nodeSuspendedPredicate,
-                              final 
AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
-                              @Named(Constants.PROPERTY_USER_THREADS) 
ListeningExecutorService userExecutor,
-                              VMImageToImage imageReferenceToImage) {
-      this.userExecutor = userExecutor;
-      this.group = azureComputeConstants.azureResourceGroup();
-      this.imageReferenceToImage = imageReferenceToImage;
+         @Named(TIMEOUT_IMAGE_AVAILABLE) Predicate<URI> 
imageAvailablePredicate,
+         @Named(TIMEOUT_NODE_SUSPENDED) Predicate<String> 
nodeSuspendedPredicate,
+         AzureComputeConstants azureComputeConstants,
+         @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService 
userExecutor,
+         ResourceDefinitionToCustomImage.Factory resourceDefinitionToImage, 
CleanupResources cleanupResources) {
+      this.api = api;
       this.imageAvailablePredicate = imageAvailablePredicate;
       this.nodeSuspendedPredicate = nodeSuspendedPredicate;
-      this.azureComputeConstants = azureComputeConstants;
-      this.api = api;
+      this.group = azureComputeConstants.azureResourceGroup();
+      this.userExecutor = userExecutor;
+      this.resourceDefinitionToImage = resourceDefinitionToImage;
+      this.cleanupResources = cleanupResources;
    }
 
    @Override
    public ImageTemplate buildImageTemplateFromNode(String name, String id) {
-      String nameLowerCase = name.toLowerCase();
-      return new 
ImageTemplateBuilder.CloneImageTemplateBuilder().nodeId(id).name(nameLowerCase).build();
+      return new 
ImageTemplateBuilder.CloneImageTemplateBuilder().nodeId(id).name(name.toLowerCase()).build();
    }
 
    @Override
    public ListenableFuture<Image> createImage(ImageTemplate template) {
-
-
       final CloneImageTemplate cloneTemplate = (CloneImageTemplate) template;
       final String id = cloneTemplate.getSourceNodeId();
       final String name = cloneTemplate.getName();
-      final String storageAccountName = id.replaceAll("[^A-Za-z0-9 ]", "") + 
"stor";
 
+      logger.debug(">> stopping node %s...", id);
       api.getVirtualMachineApi(group).stop(id);
-      if (nodeSuspendedPredicate.apply(id)) {
-         return userExecutor.submit(new Callable<Image>() {
-            @Override
-            public Image call() throws Exception {
-               api.getVirtualMachineApi(group).generalize(id);
-
-               final String[] disks = new String[2];
-               URI uri = api.getVirtualMachineApi(group).capture(id, 
cloneTemplate.getName(), CONTAINER_NAME);
-               if (uri != null) {
-                  if (imageAvailablePredicate.apply(uri)) {
-                     List<ResourceDefinition> definitions = 
api.getJobApi().captureStatus(uri);
-                     if (definitions != null) {
-                        for (ResourceDefinition definition : definitions) {
-                           LinkedTreeMap<String, String> properties = 
(LinkedTreeMap<String, String>) definition.properties();
-                           Object storageObject = 
properties.get("storageProfile");
-                           LinkedTreeMap<String, String> properties2 = 
(LinkedTreeMap<String, String>) storageObject;
-                           Object osDiskObject = properties2.get("osDisk");
-                           LinkedTreeMap<String, String> osProperties = 
(LinkedTreeMap<String, String>) osDiskObject;
-                           Object dataDisksObject = 
properties2.get("dataDisks");
-                           ArrayList<Object> dataProperties = 
(ArrayList<Object>) dataDisksObject;
-                           LinkedTreeMap<String, String> datadiskObject = 
(LinkedTreeMap<String, String>) dataProperties.get(0);
-
-                           disks[0] = osProperties.get("name");
-                           disks[1] = datadiskObject.get("name");
-
-                           VirtualMachine vm = 
api.getVirtualMachineApi(group).get(id);
-                           final VMImage ref = VMImage.create(group, 
storageAccountName, disks[0], disks[1], name, "custom", vm.location());
-                           return imageReferenceToImage.apply(ref);
-                        }
-                     }
-                  }
-               }
-               throw new UncheckedTimeoutException("Image was not created 
within the time limit: "
-                     + cloneTemplate.getName());
-            }
-         });
-      } else {
-         final String illegalStateExceptionMessage = format("Node %s was not 
suspended within %sms.",
-               id, azureComputeConstants.operationTimeout());
-         throw new IllegalStateException(illegalStateExceptionMessage);
-      }
+      checkState(nodeSuspendedPredicate.apply(id), "Node %s was not suspended 
within the configured time limit", id);
+
+      return userExecutor.submit(new Callable<Image>() {
+         @Override
+         public Image call() throws Exception {
+            logger.debug(">> generalizing virtal machine %s...", id);
+            api.getVirtualMachineApi(group).generalize(id);
+
+            logger.debug(">> capturing virtual machine %s to container %s...", 
id, CONTAINER_NAME);
+            URI uri = api.getVirtualMachineApi(group).capture(id, 
cloneTemplate.getName(), CONTAINER_NAME);
+            checkState(uri != null && imageAvailablePredicate.apply(uri),
+                  "Image %s was not created within the configured time limit", 
cloneTemplate.getName());
+
+            List<ResourceDefinition> definitions = 
api.getJobApi().captureStatus(uri);
+            checkState(definitions.size() == 1,
+                  "Expected one resource definition after creating the image 
but %s were returned", definitions.size());
+
+            Image image = resourceDefinitionToImage.create(id, 
name).apply(definitions.get(0));
+            logger.debug(">> created %s", image);
+            return image;
+         }
+      });
    }
 
    @Override
    public boolean deleteImage(String id) {
+      VMImage image = decodeFieldsFromUniqueId(id);
+      checkArgument(image.custom(), "Only custom images can be deleted");
 
-      VMImage image = VMImageToImage.decodeFieldsFromUniqueId(id);
-      if (image.custom()) {
-         StorageServiceKeys keys = 
api.getStorageAccountApi(image.group()).getKeys(image.storage());
+      logger.debug(">> deleting image %s", id);
 
-         // This removes now all the images in this storage. At least in 
theory, there should be just one and if there is
+      StorageServiceKeys keys = 
api.getStorageAccountApi(image.group()).getKeys(image.storage());
+      BlobHelper blobHelper = new BlobHelper(image.storage(), keys.key1());
+      
+      try {
+         // This removes now all the images in this storage. At least in 
theory,
+         // there should be just one and if there is
          // more, they should be copies of each other.
-         BlobHelper.deleteContainerIfExists(image.storage(), keys.key1(), 
"system");
-         return !BlobHelper.customImageExists(image.storage(), keys.key1());
+         blobHelper.deleteContainerIfExists("system");
+         boolean result = !blobHelper.customImageExists();
+
+         if (!blobHelper.hasContainers()) {
+            logger.debug(">> storage account is empty after deleting the 
custom image. Deleting the storage account...");
+            api.getStorageAccountApi(image.group()).delete(image.storage());
+            cleanupResources.deleteResourceGroupIfEmpty(image.group());
+         }
+
+         return result;
+      } finally {
+         closeQuietly(blobHelper);
       }
-
-      return false;
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToNodeMetadata.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToNodeMetadata.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToNodeMetadata.java
deleted file mode 100644
index 532e786..0000000
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToNodeMetadata.java
+++ /dev/null
@@ -1,244 +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.azurecompute.arm.compute.functions;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.inject.Inject;
-
-import com.google.common.collect.Sets;
-import org.jclouds.azurecompute.arm.AzureComputeApi;
-import org.jclouds.azurecompute.arm.domain.ComputeNode;
-import org.jclouds.azurecompute.arm.domain.Deployment;
-import org.jclouds.azurecompute.arm.domain.ImageReference;
-import org.jclouds.azurecompute.arm.domain.IpConfiguration;
-import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
-import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
-import org.jclouds.azurecompute.arm.domain.VMDeployment;
-import org.jclouds.azurecompute.arm.domain.VMHardware;
-import org.jclouds.azurecompute.arm.domain.VMImage;
-import org.jclouds.azurecompute.arm.domain.VMSize;
-import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
-import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
-import org.jclouds.azurecompute.arm.util.GetEnumValue;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.NodeMetadataBuilder;
-import org.jclouds.compute.functions.GroupNamingConvention;
-import org.jclouds.domain.Credentials;
-import org.jclouds.domain.Location;
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableMap;
-import org.jclouds.domain.LoginCredentials;
-import org.jclouds.compute.domain.Image;
-import org.jclouds.compute.domain.Hardware;
-
-public class DeploymentToNodeMetadata implements Function<VMDeployment, 
NodeMetadata> {
-
-   public static final String JCLOUDS_DEFAULT_USERNAME = "root";
-   public static final String AZURE_LOGIN_USERNAME = 
DeploymentTemplateBuilder.getLoginUserUsername();
-   public static final String AZURE_LOGIN_PASSWORD = 
DeploymentTemplateBuilder.getLoginPassword();
-
-   private static final Map<ComputeNode.Status, NodeMetadata.Status> 
INSTANCESTATUS_TO_NODESTATUS =
-           ImmutableMap.<ComputeNode.Status, NodeMetadata.Status>builder().
-                   put(ComputeNode.Status.GOOD, NodeMetadata.Status.RUNNING).
-                   put(ComputeNode.Status.BAD, NodeMetadata.Status.ERROR).
-                   put(ComputeNode.Status.UNRECOGNIZED, 
NodeMetadata.Status.UNRECOGNIZED).
-                   build();
-
-   // When using the Deployment API to deploy an ARM template, the deployment 
goes through
-   // stages.  Accepted -> Running -> Succeeded.  Only when the deployment has 
SUCCEEDED is
-   // the resource deployed using the template actually ready.
-   //
-   // To get details about the resource(s) deployed via template, one needs to 
query the
-   // various resources after the deployment has "SUCCEEDED".
-   private static final Map<Deployment.ProvisioningState, NodeMetadata.Status> 
STATUS_TO_NODESTATUS =
-           ImmutableMap.<Deployment.ProvisioningState, 
NodeMetadata.Status>builder().
-                   put(Deployment.ProvisioningState.ACCEPTED, 
NodeMetadata.Status.PENDING).
-                   put(Deployment.ProvisioningState.READY, 
NodeMetadata.Status.PENDING).
-                   put(Deployment.ProvisioningState.RUNNING, 
NodeMetadata.Status.PENDING).
-                   put(Deployment.ProvisioningState.CANCELED, 
NodeMetadata.Status.TERMINATED).
-                   put(Deployment.ProvisioningState.FAILED, 
NodeMetadata.Status.ERROR).
-                   put(Deployment.ProvisioningState.DELETED, 
NodeMetadata.Status.TERMINATED).
-                   put(Deployment.ProvisioningState.SUCCEEDED, 
NodeMetadata.Status.RUNNING).
-                   put(Deployment.ProvisioningState.UNRECOGNIZED, 
NodeMetadata.Status.UNRECOGNIZED).
-                   build();
-
-   public static Deployment.ProvisioningState 
provisioningStateFromString(final String text) {
-      return (Deployment.ProvisioningState) 
GetEnumValue.fromValueOrDefault(text, 
Deployment.ProvisioningState.UNRECOGNIZED);
-   }
-
-   private final AzureComputeApi api;
-
-   private final LocationToLocation locationToLocation;
-
-   private final GroupNamingConvention nodeNamingConvention;
-
-   private final VMImageToImage vmImageToImage;
-
-   private final VMHardwareToHardware vmHardwareToHardware;
-
-   private final Map<String, Credentials> credentialStore;
-
-   @Inject
-   DeploymentToNodeMetadata(
-           AzureComputeApi api,
-           LocationToLocation locationToLocation,
-           GroupNamingConvention.Factory namingConvention, VMImageToImage 
vmImageToImage,
-           VMHardwareToHardware vmHardwareToHardware, Map<String, Credentials> 
credentialStore) {
-
-      this.nodeNamingConvention = namingConvention.createWithoutPrefix();
-      this.locationToLocation = locationToLocation;
-      this.vmImageToImage = vmImageToImage;
-      this.vmHardwareToHardware = vmHardwareToHardware;
-      this.credentialStore = credentialStore;
-      this.api = api;
-   }
-
-   @Override
-   public NodeMetadata apply(final VMDeployment from) {
-      final NodeMetadataBuilder builder = new NodeMetadataBuilder();
-      final Deployment deployment = from.deployment();
-      builder.id(deployment.name());
-      builder.providerId(deployment.name());
-      builder.name(deployment.name());
-      String group =  
this.nodeNamingConvention.extractGroup(deployment.name());
-      builder.group(group);
-      if (from.tags() != null)
-         builder.tags(from.tags());
-      if (from.userMetaData() != null)
-         builder.userMetadata(from.userMetaData());
-
-      NodeMetadata.Status status = 
STATUS_TO_NODESTATUS.get(provisioningStateFromString(deployment.properties().provisioningState()));
-      if (status == NodeMetadata.Status.RUNNING && from.vm() != null && 
from.vm().statuses() != null) {
-         List<VirtualMachineInstance.VirtualMachineStatus> statuses = 
from.vm().statuses();
-         for (int c = 0; c < statuses.size(); c++) {
-            if (statuses.get(c).code().substring(0, 10).equals("PowerState")) {
-               if (statuses.get(c).displayStatus().equals("VM running")) {
-                  status = NodeMetadata.Status.RUNNING;
-               } else if (statuses.get(c).displayStatus().equals("VM 
stopped")) {
-                  status = NodeMetadata.Status.SUSPENDED;
-               }
-               break;
-            }
-         }
-      }
-
-      builder.status(status);
-
-      if (from.vm() != null) {
-         builder.hostname(deployment.name() + "pc");
-      }
-
-      Credentials credentials = credentialStore.get("node#" + 
from.deployment().name());
-      if (credentials != null && 
credentials.identity.equals(JCLOUDS_DEFAULT_USERNAME)) {
-         credentials = new Credentials(AZURE_LOGIN_USERNAME, 
credentials.credential);
-      }
-      else if (credentials == null) {
-         String username = AZURE_LOGIN_USERNAME;
-         String password = AZURE_LOGIN_PASSWORD;
-         if (username == null) {
-            username = "jclouds";
-         }
-         if (password == null) {
-            password = "Password1!";
-         }
-
-         credentials = new Credentials(username, password);
-      }
-      builder.credentials(LoginCredentials.fromCredentials(credentials));
-
-      final Set<String> publicIpAddresses = Sets.newLinkedHashSet();
-      if (from.ipAddressList() != null) {
-         for (int c = 0; c < from.ipAddressList().size(); c++) {
-            PublicIPAddress ip = from.ipAddressList().get(c);
-            if (ip != null && ip.properties() != null && 
ip.properties().ipAddress() != null)
-            {
-               publicIpAddresses.add(ip.properties().ipAddress());
-               break;
-            }
-         }
-         if (publicIpAddresses.size() > 0)
-            builder.publicAddresses(publicIpAddresses);
-      }
-      final Set<String> privateIpAddresses = Sets.newLinkedHashSet();
-      if (from.networkInterfaceCards() != null) {
-         for (NetworkInterfaceCard nic : from.networkInterfaceCards()) {
-            if (nic != null && nic.properties() != null && 
nic.properties().ipConfigurations() != null) {
-               for (IpConfiguration ip : nic.properties().ipConfigurations()) {
-                  if (ip != null && ip.properties() != null && 
ip.properties().privateIPAddress() != null) {
-                     
privateIpAddresses.add(ip.properties().privateIPAddress());
-                  }
-               }
-            }
-         }
-         if (!privateIpAddresses.isEmpty()) {
-            builder.privateAddresses(privateIpAddresses);
-         }
-      }
-
-      org.jclouds.azurecompute.arm.domain.Location myLocation = null;
-      if (from.virtualMachine() != null) {
-         String locationName = from.virtualMachine().location();
-         List<org.jclouds.azurecompute.arm.domain.Location> locations = 
api.getLocationApi().list();
-
-         for (org.jclouds.azurecompute.arm.domain.Location location : 
locations) {
-            if (location.name().equals(locationName)) {
-               myLocation = location;
-               break;
-            }
-         }
-         Location jLocation = this.locationToLocation.apply(myLocation);
-         builder.location(jLocation);
-
-         ImageReference imageReference = 
from.virtualMachine().properties().storageProfile().imageReference();
-
-         if (imageReference != null) {
-            VMImage vmImage = VMImage.create(imageReference.publisher(), 
imageReference.offer(), imageReference.sku(),
-                    imageReference.version(), locationName);
-            Image image = vmImageToImage.apply(vmImage);
-            builder.imageId(image.getId());
-         }
-
-         VMSize myVMSize = null;
-         String vmSizeName = 
from.virtualMachine().properties().hardwareProfile().vmSize();
-         List<VMSize> vmSizes = api.getVMSizeApi(locationName).list();
-         for (VMSize vmSize : vmSizes) {
-            if (vmSize.name().equals(vmSizeName)) {
-               myVMSize = vmSize;
-               break;
-            }
-         }
-
-         VMHardware hwProfile = VMHardware.create(
-                 myVMSize.name(),
-                 myVMSize.numberOfCores(),
-                 myVMSize.osDiskSizeInMB(),
-                 myVMSize.resourceDiskSizeInMB(),
-                 myVMSize.memoryInMB(),
-                 myVMSize.maxDataDiskCount(),
-                 locationName,
-                 false);
-
-         Hardware hardware = vmHardwareToHardware.apply(hwProfile);
-         builder.hardware(hardware);
-      }
-
-      return builder.build();
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToVMDeployment.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToVMDeployment.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToVMDeployment.java
deleted file mode 100644
index 31f1a58..0000000
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToVMDeployment.java
+++ /dev/null
@@ -1,121 +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.azurecompute.arm.compute.functions;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import org.jclouds.azurecompute.arm.AzureComputeApi;
-import 
org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
-import org.jclouds.azurecompute.arm.domain.Deployment;
-import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
-import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
-import org.jclouds.azurecompute.arm.domain.VMDeployment;
-import org.jclouds.azurecompute.arm.domain.VirtualMachine;
-import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
-
-import com.google.common.base.Function;
-
-/**
- * Converts an Deployment into a VMDeployment.
- */
-@Singleton
-public class DeploymentToVMDeployment implements Function<Deployment, 
VMDeployment> {
-
-   private final AzureComputeServiceContextModule.AzureComputeConstants 
azureComputeConstants;
-
-   private final AzureComputeApi api;
-
-   @Inject
-   DeploymentToVMDeployment(AzureComputeApi api, final 
AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants) {
-      this.api = api;
-      this.azureComputeConstants = azureComputeConstants;
-   }
-
-   @Override
-   public VMDeployment apply(final Deployment deployment) {
-      String id = deployment.id();
-      List<PublicIPAddress> ipAddressList = getIPAddresses(deployment);
-      List<NetworkInterfaceCard> networkInterfaceCards = 
getNetworkInterfaceCards(deployment);
-      VirtualMachine vm = 
api.getVirtualMachineApi(azureComputeConstants.azureResourceGroup()).get(id);
-      VirtualMachineInstance vmInstanceDetails = 
api.getVirtualMachineApi(azureComputeConstants.azureResourceGroup()).getInstanceDetails(id);
-      Map<String, String> userMetaData = null;
-      Iterable<String> tags = null;
-      if (vm != null && vm.tags() != null) {
-         userMetaData = vm.tags();
-         String tagString = userMetaData.get("tags");
-         tags = Arrays.asList(tagString.split(","));
-      }
-      return VMDeployment.create(deployment, ipAddressList, vmInstanceDetails, 
vm, networkInterfaceCards, userMetaData, tags);
-   }
-
-   private List<PublicIPAddress> getIPAddresses(Deployment deployment) {
-      List<PublicIPAddress> list = new ArrayList<PublicIPAddress>();
-      String resourceGroup = getResourceGroupFromId(deployment.id());
-
-      if (deployment.properties() != null && 
deployment.properties().dependencies() != null) {
-         List<Deployment.Dependency> dependencies = 
deployment.properties().dependencies();
-         for (int d = 0; d < dependencies.size(); d++) {
-            if 
(dependencies.get(d).resourceType().equals("Microsoft.Network/networkInterfaces"))
 {
-               List<Deployment.Dependency> dependsOn = 
dependencies.get(d).dependsOn();
-               for (int e = 0; e < dependsOn.size(); e++) {
-                  if 
(dependsOn.get(e).resourceType().equals("Microsoft.Network/publicIPAddresses")) 
{
-                     String resourceName = dependsOn.get(e).resourceName();
-                     PublicIPAddress ip = 
api.getPublicIPAddressApi(resourceGroup).get(resourceName);
-                     list.add(ip);
-                     break;
-                  }
-               }
-            }
-         }
-      }
-      return list;
-   }
-
-   private String getResourceGroupFromId(String id) {
-      String searchStr = "/resourceGroups/";
-      int indexStart = id.lastIndexOf(searchStr) + searchStr.length();
-      searchStr = "/providers/";
-      int indexEnd = id.lastIndexOf(searchStr);
-
-      String resourceGroup = id.substring(indexStart, indexEnd);
-      return resourceGroup;
-   }
-
-   private List<NetworkInterfaceCard> getNetworkInterfaceCards(Deployment 
deployment) {
-      List<NetworkInterfaceCard> result = new 
ArrayList<NetworkInterfaceCard>();
-
-      String resourceGroup = getResourceGroupFromId(deployment.id());
-
-      if (deployment.properties() != null && 
deployment.properties().dependencies() != null) {
-         for (Deployment.Dependency dependency : 
deployment.properties().dependencies()) {
-            if 
(dependency.resourceType().equals("Microsoft.Network/networkInterfaces")) {
-               String resourceName = dependency.resourceName();
-               NetworkInterfaceCard nic = 
api.getNetworkInterfaceCardApi(resourceGroup).get(resourceName);
-               result.add(nic);
-            }
-         }
-      }
-      return result;
-   }
-
-}

Reply via email to