You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2015/04/06 23:00:27 UTC

[1/3] jclouds-labs git commit: [JCLOUDS-849] All tests are green in Azure

Repository: jclouds-labs
Updated Branches:
  refs/heads/master aac957447 -> b9036f5af


[JCLOUDS-849] All tests are green in Azure


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

Branch: refs/heads/master
Commit: d3ff98a0caeb020843ea38bea27c55714dd48bb1
Parents: aac9574
Author: fmartelli <fa...@gmail.com>
Authored: Tue Mar 17 18:17:00 2015 +0100
Committer: Ignasi Barrera <na...@apache.org>
Committed: Mon Apr 6 22:48:47 2015 +0200

----------------------------------------------------------------------
 .../AzureManagementApiMetadata.java             |   7 +-
 .../compute/AzureComputeServiceAdapter.java     | 262 ++++++++++++-------
 .../AzureComputeServiceContextModule.java       |   5 +
 .../AzureComputeSecurityGroupExtension.java     |  15 +-
 .../functions/DeploymentToNodeMetadata.java     |  88 +++++--
 .../compute/functions/OSImageToImage.java       |   9 +
 ...ServiceAndVirtualNetworkThenCreateNodes.java |   7 -
 .../AzureAdaptingComputeServiceStrategies.java  |  70 +++++
 .../jclouds/azurecompute/domain/Deployment.java | 134 +++++++---
 .../suppliers/KeyStoreSupplier.java             |  60 +++--
 .../util/ConflictManagementPredicate.java       |   6 +-
 .../azurecompute/xml/DeploymentHandler.java     |   2 +-
 .../jclouds/azurecompute/xml/RoleHandler.java   |   1 +
 .../azurecompute/xml/RoleInstanceHandler.java   |  15 +-
 .../AzureComputeProviderMetadataLive.java       |   2 +-
 .../AzureComputeServiceAdapterLiveTest.java     |  67 ++---
 .../AzureComputeServiceContextLiveTest.java     |  36 +--
 .../compute/AzureComputeServiceLiveTest.java    |  57 ++++
 ...reComputeSecurityGroupExtensionLiveTest.java |  41 ++-
 .../features/DeploymentApiLiveTest.java         |   6 +-
 .../features/VirtualMachineApiLiveTest.java     |   2 +-
 .../internal/BaseAzureComputeApiLiveTest.java   |   6 +-
 .../azurecompute/xml/DeploymentHandlerTest.java |   7 +-
 23 files changed, 630 insertions(+), 275 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/main/java/org/jclouds/azurecompute/AzureManagementApiMetadata.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/AzureManagementApiMetadata.java b/azurecompute/src/main/java/org/jclouds/azurecompute/AzureManagementApiMetadata.java
index 6bafad1..ebd0c74 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/AzureManagementApiMetadata.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/AzureManagementApiMetadata.java
@@ -49,7 +49,12 @@ public class AzureManagementApiMetadata extends BaseHttpApiMetadata<AzureCompute
    }
 
    public static Properties defaultProperties() {
-      return BaseHttpApiMetadata.defaultProperties();
+      final Properties properties = BaseHttpApiMetadata.defaultProperties();
+      // Sometimes SSH Authentication failure happens in Azure.
+      // It seems that the authorized key is injected after ssh has been started.  
+      properties.setProperty("jclouds.ssh.max-retries", "15");
+      properties.setProperty("jclouds.ssh.retry-auth", "true");
+      return properties;
    }
 
    public static class Builder extends BaseHttpApiMetadata.Builder<AzureComputeApi, Builder> {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/main/java/org/jclouds/azurecompute/compute/AzureComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/AzureComputeServiceAdapter.java b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/AzureComputeServiceAdapter.java
index ea44308..ac343a3 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/AzureComputeServiceAdapter.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/AzureComputeServiceAdapter.java
@@ -19,7 +19,6 @@ package org.jclouds.azurecompute.compute;
 import static com.google.common.base.Predicates.notNull;
 import static java.lang.String.format;
 import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.jclouds.azurecompute.domain.Deployment.InstanceStatus.READY_ROLE;
 import static org.jclouds.util.Predicates2.retry;
 
 import java.net.URI;
@@ -36,13 +35,16 @@ import org.jclouds.azurecompute.compute.config.AzureComputeServiceContextModule.
 import org.jclouds.azurecompute.config.AzureComputeProperties;
 import org.jclouds.azurecompute.domain.CloudService;
 import org.jclouds.azurecompute.domain.Deployment;
-import org.jclouds.azurecompute.domain.Deployment.RoleInstance;
 import org.jclouds.azurecompute.domain.DeploymentParams;
 import org.jclouds.azurecompute.domain.DeploymentParams.ExternalEndpoint;
 import org.jclouds.azurecompute.domain.Location;
 import org.jclouds.azurecompute.domain.OSImage;
 import org.jclouds.azurecompute.domain.RoleSize;
+import org.jclouds.azurecompute.domain.Deployment.RoleInstance;
+import org.jclouds.azurecompute.domain.Role;
+import org.jclouds.azurecompute.compute.functions.OSImageToImage;
 import org.jclouds.azurecompute.options.AzureComputeTemplateOptions;
+import org.jclouds.azurecompute.util.ConflictManagementPredicate;
 import org.jclouds.compute.ComputeServiceAdapter;
 import org.jclouds.compute.domain.OsFamily;
 import org.jclouds.compute.domain.Template;
@@ -60,8 +62,8 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 
 /**
- * defines the connection between the {@link AzureComputeApi} implementation and the jclouds
- * {@link org.jclouds.compute.ComputeService}
+ * Defines the connection between the {@link AzureComputeApi} implementation and the jclouds
+ * {@link org.jclouds.compute.ComputeService}.
  */
 @Singleton
 public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Deployment, RoleSize, OSImage, Location> {
@@ -72,7 +74,7 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Deploym
 
    @Resource
    @Named(ComputeServiceConstants.COMPUTE_LOGGER)
-   protected Logger logger = Logger.NULL;
+   private Logger logger = Logger.NULL;
 
    private final AzureComputeApi api;
 
@@ -108,7 +110,8 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Deploym
       final String subnetName = templateOptions.getSubnetName().get();
 
       logger.debug("Creating a cloud service with name '%s', label '%s' in location '%s'", name, name, location);
-      String createCloudServiceRequestId = api.getCloudServiceApi().createWithLabelInLocation(name, name, location);
+      final String createCloudServiceRequestId =
+              api.getCloudServiceApi().createWithLabelInLocation(name, name, location);
       if (!operationSucceededPredicate.apply(createCloudServiceRequestId)) {
          final String message = generateIllegalStateExceptionMessage(
                  createCloudServiceRequestId, azureComputeConstants.operationTimeout());
@@ -119,7 +122,7 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Deploym
 
       final OSImage.Type os = template.getImage().getOperatingSystem().getFamily() == OsFamily.WINDOWS
               ? OSImage.Type.WINDOWS : OSImage.Type.LINUX;
-      Set<ExternalEndpoint> externalEndpoints = Sets.newHashSet();
+      final Set<ExternalEndpoint> externalEndpoints = Sets.newHashSet();
       for (int inboundPort : inboundPorts) {
          externalEndpoints.add(ExternalEndpoint.inboundTcpToLocalPort(inboundPort, inboundPort));
       }
@@ -128,7 +131,7 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Deploym
               .os(os)
               .username(loginUser)
               .password(loginPassword)
-              .sourceImageName(Splitter.on('/').split(template.getImage().getId()).iterator().next())
+              .sourceImageName(OSImageToImage.fromGeoName(template.getImage().getId())[0])
               .mediaLink(createMediaLink(storageAccountName, name))
               .size(RoleSize.Type.fromString(template.getHardware().getName()))
               .externalEndpoints(externalEndpoints)
@@ -137,42 +140,37 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Deploym
               .build();
 
       logger.debug("Creating a deployment with params '%s' ...", params);
-      String createDeploymentRequestId = api.getDeploymentApiForService(name).create(params);
-      if (!operationSucceededPredicate.apply(createDeploymentRequestId)) {
-         final String message = generateIllegalStateExceptionMessage(
-                 createCloudServiceRequestId, azureComputeConstants.operationTimeout());
-         logger.warn(message);
-         logger.debug("Deleting cloud service (%s) ...", name);
-         deleteCloudService(name);
-         logger.debug("Cloud service (%s) deleted.", name);
-      }
-      logger.info("Deployment created with operation id: %s", createDeploymentRequestId);
+      retry(new ConflictManagementPredicate() {
+
+         @Override
+         protected String operation() {
+            return api.getDeploymentApiForService(name).create(params);
+         }
+      }, 30 * 60, 1, SECONDS).apply(name);
 
+      final Set<Deployment> deployments = Sets.newHashSet();
       if (!retry(new Predicate<String>() {
          @Override
-         public boolean apply(String name) {
-            return FluentIterable.from(api.getDeploymentApiForService(name).get(name).roleInstanceList())
-                    .allMatch(new Predicate<RoleInstance>() {
-                       @Override
-                       public boolean apply(RoleInstance input) {
-                          return input != null && input.instanceStatus() == READY_ROLE;
-                       }
-                    });
+         public boolean apply(final String name) {
+            final Deployment deployment = api.getDeploymentApiForService(name).get(name);
+            if (deployment != null) {
+               deployments.add(deployment);
+            }
+            return !deployments.isEmpty();
          }
       }, 30 * 60, 1, SECONDS).apply(name)) {
-         logger.warn("Instances %s of %s has not reached the status %s within %sms so it will be destroyed.",
-                 Iterables.toString(api.getDeploymentApiForService(name).get(name).roleInstanceList()), name,
-                 READY_ROLE, azureComputeConstants.operationTimeout());
-         api.getDeploymentApiForService(group).delete(name);
+         final String message = format("Deployment %s was not created within %sms so it will be destroyed.",
+                 name, azureComputeConstants.operationTimeout());
+         logger.warn(message);
+
+         api.getDeploymentApiForService(name).delete(name);
          api.getCloudServiceApi().delete(name);
-         throw new IllegalStateException(format("Deployment %s is being destroyed as its instanceStatus didn't reach "
-                 + "status %s after %ss. Please, try by increasing `jclouds.azure.operation-timeout` and "
-                 + " try again", name, READY_ROLE, 30 * 60));
-      }
 
-      Deployment deployment = api.getDeploymentApiForService(name).get(name);
+         throw new IllegalStateException(message);
+      }
 
-      return new NodeAndInitialCredentials<Deployment>(deployment, deployment.name(),
+      final Deployment deployment = deployments.iterator().next();
+      return new NodeAndInitialCredentials<Deployment>(deployment, name,
               LoginCredentials.builder().user(loginUser).password(loginPassword).build());
    }
 
@@ -189,7 +187,7 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Deploym
 
    @Override
    public Iterable<OSImage> listImages() {
-      List<OSImage> osImages = Lists.newArrayList();
+      final List<OSImage> osImages = Lists.newArrayList();
       for (OSImage osImage : api.getOSImageApi().list()) {
          if (osImage.location() == null) {
             osImages.add(OSImage.create(
@@ -208,10 +206,10 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Deploym
          } else {
             for (String actualLocation : Splitter.on(';').split(osImage.location())) {
                osImages.add(OSImage.create(
-                       osImage.name() + "/" + actualLocation,
+                       OSImageToImage.toGeoName(osImage.name(), actualLocation),
                        actualLocation,
                        osImage.affinityGroup(),
-                       osImage.label() + "/" + actualLocation,
+                       osImage.label(),
                        osImage.description(),
                        osImage.category(),
                        osImage.os(),
@@ -228,12 +226,30 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Deploym
 
    @Override
    public OSImage getImage(final String id) {
-      return Iterables.find(api.getOSImageApi().list(), new Predicate<OSImage>() {
+      final String[] idParts = OSImageToImage.fromGeoName(id);
+      final OSImage image = Iterables.find(api.getOSImageApi().list(), new Predicate<OSImage>() {
          @Override
-         public boolean apply(OSImage input) {
-            return input.name().equals(id);
+         public boolean apply(final OSImage input) {
+            return idParts[0].equals(input.name());
          }
       });
+
+      return image == null
+              ? null
+              : idParts[1] == null
+                      ? image
+                      : OSImage.create(
+                              id,
+                              idParts[1],
+                              image.affinityGroup(),
+                              image.label(),
+                              image.description(),
+                              image.category(),
+                              image.os(),
+                              image.publisherName(),
+                              image.mediaLink(),
+                              image.logicalSizeInGB(),
+                              image.eula());
    }
 
    @Override
@@ -243,97 +259,165 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Deploym
 
    @Override
    public Deployment getNode(final String id) {
-      return FluentIterable.from(api.getCloudServiceApi().list())
-              .transform(new Function<CloudService, Deployment>() {
+      return FluentIterable.from(api.getCloudServiceApi().list()).
+              transform(new Function<CloudService, Deployment>() {
                  @Override
                  public Deployment apply(final CloudService input) {
-                    return api.getDeploymentApiForService(input.name()).get(id);
+                    final Deployment deployment = api.getDeploymentApiForService(input.name()).get(id);
+                    return deployment == null || deployment.roleInstanceList().isEmpty()
+                            ? null
+                            : FluentIterable.from(deployment.roleInstanceList()).allMatch(
+                                    new Predicate<RoleInstance>() {
+                                       @Override
+                                       public boolean apply(final RoleInstance input) {
+                                          return input != null && !input.instanceStatus().isTransient();
+                                       }
+                                    })
+                                    ? deployment
+                                    : null;
                  }
-              })
-              .firstMatch(notNull())
-              .orNull();
+              }).
+              firstMatch(notNull()).
+              orNull();
    }
 
-   @Override
-   public void destroyNode(final String id) {
-      CloudService cloudService = api.getCloudServiceApi().get(id);
-      if (cloudService != null) {
-         // TODO detach disk before deleting node
+   private void trackRequest(final String requestId) {
+      if (!operationSucceededPredicate.apply(requestId)) {
+         final String message = generateIllegalStateExceptionMessage(
+                 requestId, azureComputeConstants.operationTimeout());
+         logger.warn(message);
+         throw new IllegalStateException(message);
+      }
+   }
+
+   private List<CloudService> getCloudServicesForDeployment(final String id) {
+      return FluentIterable.from(api.getCloudServiceApi().list()).filter(new Predicate<CloudService>() {
+
+         @Override
+         public boolean apply(final CloudService input) {
+            final Deployment deployment =
+                    input.status() == CloudService.Status.DELETING || input.status() == CloudService.Status.DELETED
+                            ? null
+                            : api.getDeploymentApiForService(input.name()).get(id);
+            return deployment != null && deployment.status() != Deployment.Status.DELETING;
+         }
+      }).toList();
+   }
+
+   public Deployment internalDestroyNode(final String id) {
+      Deployment deployment = null;
+
+      for (CloudService cloudService : getCloudServicesForDeployment(id)) {
+         final List<Deployment> nodes = Lists.newArrayList();
+         retry(new Predicate<String>() {
+            @Override
+            public boolean apply(final String input) {
+               final Deployment deployment = getNode(id);
+               if (deployment != null) {
+                  nodes.add(deployment);
+               }
+               return !nodes.isEmpty();
+            }
+         }, 30 * 60, 1, SECONDS).apply(id);
+
+         if (!nodes.isEmpty()) {
+            deployment = nodes.iterator().next();
+         }
 
          final String cloudServiceName = cloudService.name();
          logger.debug("Deleting deployment(%s) of cloud service (%s)", id, cloudServiceName);
-         deleteDeployment(id, cloudServiceName);
-         logger.debug("Deployment (%s) deleted in cloud service (%s).", id, cloudServiceName);
+         retry(new ConflictManagementPredicate(operationSucceededPredicate) {
+
+            @Override
+            protected String operation() {
+               return api.getDeploymentApiForService(cloudServiceName).delete(id);
+            }
+         }, 30 * 60, 1, SECONDS).apply(id);
 
          logger.debug("Deleting cloud service (%s) ...", cloudServiceName);
-         deleteCloudService(cloudServiceName);
+         trackRequest(api.getCloudServiceApi().delete(cloudServiceName));
          logger.debug("Cloud service (%s) deleted.", cloudServiceName);
+
+         if (deployment != null) {
+            for (Role role : deployment.roleList()) {
+               final Role.OSVirtualHardDisk disk = role.osVirtualHardDisk();
+               if (disk != null) {
+                  retry(new ConflictManagementPredicate(operationSucceededPredicate) {
+
+                     @Override
+                     protected String operation() {
+                        return api.getDiskApi().delete(disk.diskName());
+                     }
+                  }, 30 * 60, 1, SECONDS).apply(id);
+               }
+            }
+         }
       }
+
+      return deployment;
+   }
+
+   @Override
+   public void destroyNode(final String id) {
+      internalDestroyNode(id);
    }
 
    @Override
    public void rebootNode(final String id) {
-      throw new UnsupportedOperationException();
+      final CloudService cloudService = api.getCloudServiceApi().get(id);
+      if (cloudService != null) {
+         logger.debug("Restarting %s ...", id);
+         trackRequest(api.getVirtualMachineApiForDeploymentInService(id, cloudService.name()).restart(id));
+         logger.debug("Restarted %s", id);
+      }
    }
 
    @Override
    public void resumeNode(final String id) {
-      throw new UnsupportedOperationException();
+      final CloudService cloudService = api.getCloudServiceApi().get(id);
+      if (cloudService != null) {
+         logger.debug("Resuming %s ...", id);
+         trackRequest(api.getVirtualMachineApiForDeploymentInService(id, cloudService.name()).start(id));
+         logger.debug("Resumed %s", id);
+      }
    }
 
    @Override
    public void suspendNode(final String id) {
-      throw new UnsupportedOperationException();
+      final CloudService cloudService = api.getCloudServiceApi().get(id);
+      if (cloudService != null) {
+         logger.debug("Suspending %s ...", id);
+         trackRequest(api.getVirtualMachineApiForDeploymentInService(id, cloudService.name()).shutdown(id));
+         logger.debug("Suspended %s", id);
+      }
    }
 
    @Override
    public Iterable<Deployment> listNodes() {
-      Set<Deployment> deployments = FluentIterable.from(api.getCloudServiceApi().list())
-              .transform(new Function<CloudService, Deployment>() {
+      return FluentIterable.from(api.getCloudServiceApi().list()).
+              transform(new Function<CloudService, Deployment>() {
                  @Override
-                 public Deployment apply(CloudService cloudService) {
+                 public Deployment apply(final CloudService cloudService) {
                     return api.getDeploymentApiForService(cloudService.name()).get(cloudService.name());
                  }
-              })
-              .filter(notNull())
-              .toSet();
-      return deployments;
+              }).
+              filter(notNull()).
+              toSet();
    }
 
    @Override
    public Iterable<Deployment> listNodesByIds(final Iterable<String> ids) {
       return Iterables.filter(listNodes(), new Predicate<Deployment>() {
          @Override
-         public boolean apply(Deployment input) {
+         public boolean apply(final Deployment input) {
             return Iterables.contains(ids, input.name());
          }
       });
    }
 
    @VisibleForTesting
-   public static URI createMediaLink(String storageServiceName, String diskName) {
+   public static URI createMediaLink(final String storageServiceName, final String diskName) {
       return URI.create(
               String.format("https://%s.blob.core.windows.net/vhds/disk-%s.vhd", storageServiceName, diskName));
    }
-
-   private void deleteCloudService(final String name) {
-      String deleteCloudServiceId = api.getCloudServiceApi().delete(name);
-      if (!operationSucceededPredicate.apply(deleteCloudServiceId)) {
-         final String deleteMessage = generateIllegalStateExceptionMessage(
-                 deleteCloudServiceId, azureComputeConstants.operationTimeout());
-         logger.warn(deleteMessage);
-         throw new IllegalStateException(deleteMessage);
-      }
-   }
-
-   private void deleteDeployment(final String id, final String cloudServiceName) {
-      String deleteDeploymentId = api.getDeploymentApiForService(cloudServiceName).delete(id);
-      if (!operationSucceededPredicate.apply(deleteDeploymentId)) {
-         final String deleteMessage = generateIllegalStateExceptionMessage(
-                 deleteDeploymentId, azureComputeConstants.operationTimeout());
-         logger.warn(deleteMessage);
-         throw new IllegalStateException(deleteMessage);
-      }
-   }
-
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/main/java/org/jclouds/azurecompute/compute/config/AzureComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/config/AzureComputeServiceContextModule.java b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/config/AzureComputeServiceContextModule.java
index ca7a290..e129ada 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/config/AzureComputeServiceContextModule.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/config/AzureComputeServiceContextModule.java
@@ -35,6 +35,7 @@ import org.jclouds.azurecompute.compute.functions.OSImageToImage;
 import org.jclouds.azurecompute.compute.functions.RoleSizeToHardware;
 import org.jclouds.azurecompute.compute.strategy.GetOrCreateStorageServiceAndVirtualNetworkThenCreateNodes;
 import org.jclouds.azurecompute.compute.strategy.UseNodeCredentialsButOverrideFromTemplate;
+import org.jclouds.azurecompute.compute.strategy.impl.AzureAdaptingComputeServiceStrategies;
 import org.jclouds.azurecompute.domain.Deployment;
 import org.jclouds.azurecompute.domain.Location;
 import org.jclouds.azurecompute.domain.OSImage;
@@ -49,6 +50,7 @@ import org.jclouds.compute.extensions.SecurityGroupExtension;
 import org.jclouds.compute.options.TemplateOptions;
 import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
 import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
+import org.jclouds.compute.strategy.impl.AdaptingComputeServiceStrategies;
 import org.jclouds.util.Predicates2;
 
 import com.google.common.base.Function;
@@ -65,6 +67,7 @@ public class AzureComputeServiceContextModule
    @Override
    protected void configure() {
       super.configure();
+
       bind(new TypeLiteral<ComputeServiceAdapter<Deployment, RoleSize, OSImage, Location>>() {
       }).to(AzureComputeServiceAdapter.class);
       bind(new TypeLiteral<Function<OSImage, org.jclouds.compute.domain.Image>>() {
@@ -73,6 +76,8 @@ public class AzureComputeServiceContextModule
       }).to(RoleSizeToHardware.class);
       bind(new TypeLiteral<Function<Deployment, NodeMetadata>>() {
       }).to(DeploymentToNodeMetadata.class);
+      bind(new TypeLiteral<AdaptingComputeServiceStrategies<Deployment, RoleSize, OSImage, Location>>() {
+      }).to(AzureAdaptingComputeServiceStrategies.class);
 
       bind(PrioritizeCredentialsFromTemplate.class).to(UseNodeCredentialsButOverrideFromTemplate.class);
       bind(new TypeLiteral<Function<Location, org.jclouds.domain.Location>>() {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/main/java/org/jclouds/azurecompute/compute/extensions/AzureComputeSecurityGroupExtension.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/extensions/AzureComputeSecurityGroupExtension.java b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/extensions/AzureComputeSecurityGroupExtension.java
index 278effb..f6bab8f 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/extensions/AzureComputeSecurityGroupExtension.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/extensions/AzureComputeSecurityGroupExtension.java
@@ -109,7 +109,7 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio
       final Deployment deployment = api.getDeploymentApiForService(name).get(name);
       final String virtualNetworkName = deployment.virtualNetworkName();
 
-      final List<String> subnetNames = FluentIterable.from(deployment.roles())
+      final List<String> subnetNames = FluentIterable.from(deployment.roleList())
               .transformAndConcat(new Function<Role, Iterable<Role.ConfigurationSet>>() {
                  @Override
                  public Iterable<Role.ConfigurationSet> apply(final Role input) {
@@ -153,7 +153,7 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio
       checkNotNull(location, "location");
 
       final NetworkSecurityGroup networkSecurityGroup = NetworkSecurityGroup.create(name, name, location.getId(), null);
-      String createNSGRequestId = api.getNetworkSecurityGroupApi().create(networkSecurityGroup);
+      final String createNSGRequestId = api.getNetworkSecurityGroupApi().create(networkSecurityGroup);
       if (!operationSucceededPredicate.apply(createNSGRequestId)) {
          final String message = generateIllegalStateExceptionMessage(
                  createNSGRequestId, azureComputeConstants.operationTimeout());
@@ -181,7 +181,7 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio
                final String virtualNetworkName = virtualNetworkSite.name();
                final String subnetName = subnet.name();
                if (virtualNetworkName != null && subnetName != null) {
-                  NetworkSecurityGroup networkSecurityGroupAppliedToSubnet = api.getNetworkSecurityGroupApi()
+                  final NetworkSecurityGroup networkSecurityGroupAppliedToSubnet = api.getNetworkSecurityGroupApi()
                           .getNetworkSecurityGroupAppliedToSubnet(virtualNetworkName, subnetName);
                   if (networkSecurityGroupAppliedToSubnet != null) {
                      if (!networkSecurityGroupAppliedToSubnet.name().equals(id)) {
@@ -228,7 +228,7 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio
          final Deployment deployment = api.getDeploymentApiForService(service.name()).get(service.name());
          if (deployment != null && deployment.status() != Status.DELETING) {
             for (Deployment.VirtualIP vip : Iterables.filter(deployment.virtualIPs(), Predicates.notNull())) {
-               for (final Role role : deployment.roles()) {
+               for (final Role role : deployment.roleList()) {
                   for (Role.ConfigurationSet configurationSet : role.configurationSets()) {
                      if (ipPermission.getFromPort() < ipPermission.getToPort()) {
                         for (int i = ipPermission.getFromPort(); i <= ipPermission.getToPort(); i++) {
@@ -315,7 +315,7 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio
          final Deployment deployment = api.getDeploymentApiForService(service.name()).get(service.name());
          if (deployment != null && deployment.status() != Status.DELETING) {
             for (Deployment.VirtualIP vip : Iterables.filter(deployment.virtualIPs(), Predicates.notNull())) {
-               for (final Role role : deployment.roles()) {
+               for (final Role role : deployment.roleList()) {
                   for (Role.ConfigurationSet configurationSet : role.configurationSets()) {
                      for (int i = ipPermission.getFromPort(); i <= ipPermission.getToPort(); i++) {
                         final String name = NetworkSecurityGroups.createRuleName(
@@ -450,8 +450,9 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio
       final String destinationPortRange = ipPermission.getFromPort() == ipPermission.getToPort()
               ? String.valueOf(ipPermission.getToPort())
               : String.format("%s-%s", ipPermission.getFromPort(), ipPermission.getToPort());
-      final String destinationAddressPrefix
-              = ipPermission.getCidrBlocks().isEmpty() || Iterables.get(ipPermission.getCidrBlocks(), 0).equals("0.0.0.0/0")
+      final String destinationAddressPrefix =
+              ipPermission.getCidrBlocks().isEmpty()
+              || Iterables.get(ipPermission.getCidrBlocks(), 0).equals("0.0.0.0/0")
                       ? "*"
                       : Iterables.get(ipPermission.getCidrBlocks(), 0);
       final String setRuleToNSGRequestId = api.getNetworkSecurityGroupApi().

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/DeploymentToNodeMetadata.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/DeploymentToNodeMetadata.java b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/DeploymentToNodeMetadata.java
index 297bba6..cfe1ece 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/DeploymentToNodeMetadata.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/DeploymentToNodeMetadata.java
@@ -21,33 +21,63 @@ import java.util.Set;
 
 import javax.inject.Inject;
 
+import org.jclouds.azurecompute.AzureComputeApi;
 import org.jclouds.azurecompute.domain.Deployment;
 import org.jclouds.azurecompute.domain.Deployment.RoleInstance;
+import org.jclouds.azurecompute.domain.CloudService;
 import org.jclouds.collect.Memoized;
 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 org.jclouds.location.predicates.LocationPredicates;
 
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import com.google.common.base.Supplier;
+import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Sets;
 
 public class DeploymentToNodeMetadata implements Function<Deployment, NodeMetadata> {
 
-   private static final Map<Deployment.Status, NodeMetadata.Status> serverStateToNodeStatus
-           = ImmutableMap.<Deployment.Status, NodeMetadata.Status>builder()
-           .put(Deployment.Status.DELETING, NodeMetadata.Status.PENDING)
-           .put(Deployment.Status.SUSPENDED_TRANSITIONING, NodeMetadata.Status.PENDING)
-           .put(Deployment.Status.RUNNING_TRANSITIONING, NodeMetadata.Status.PENDING)
-           .put(Deployment.Status.DEPLOYING, NodeMetadata.Status.PENDING)
-           .put(Deployment.Status.STARTING, NodeMetadata.Status.PENDING)
-           .put(Deployment.Status.SUSPENDED, NodeMetadata.Status.SUSPENDED)
-           .put(Deployment.Status.RUNNING, NodeMetadata.Status.RUNNING)
-           .put(Deployment.Status.UNRECOGNIZED, NodeMetadata.Status.UNRECOGNIZED).build();
+   private static final Map<Deployment.InstanceStatus, NodeMetadata.Status> INSTANCESTATUS_TO_NODESTATUS =
+           ImmutableMap.<Deployment.InstanceStatus, NodeMetadata.Status>builder().
+           put(Deployment.InstanceStatus.BUSY_ROLE, NodeMetadata.Status.PENDING).
+           put(Deployment.InstanceStatus.CREATING_ROLE, NodeMetadata.Status.PENDING).
+           put(Deployment.InstanceStatus.CREATING_VM, NodeMetadata.Status.PENDING).
+           put(Deployment.InstanceStatus.CYCLING_ROLE, NodeMetadata.Status.PENDING).
+           put(Deployment.InstanceStatus.DELETING_VM, NodeMetadata.Status.PENDING).
+           put(Deployment.InstanceStatus.FAILED_STARTING_ROLE, NodeMetadata.Status.ERROR).
+           put(Deployment.InstanceStatus.FAILED_STARTING_VM, NodeMetadata.Status.ERROR).
+           put(Deployment.InstanceStatus.PREPARING, NodeMetadata.Status.PENDING).
+           put(Deployment.InstanceStatus.READY_ROLE, NodeMetadata.Status.RUNNING).
+           put(Deployment.InstanceStatus.RESTARTING_ROLE, NodeMetadata.Status.PENDING).
+           put(Deployment.InstanceStatus.STARTING_ROLE, NodeMetadata.Status.PENDING).
+           put(Deployment.InstanceStatus.STARTING_VM, NodeMetadata.Status.PENDING).
+           put(Deployment.InstanceStatus.STOPPED_DEALLOCATED, NodeMetadata.Status.SUSPENDED).
+           put(Deployment.InstanceStatus.STOPPED_VM, NodeMetadata.Status.SUSPENDED).
+           put(Deployment.InstanceStatus.STOPPING_ROLE, NodeMetadata.Status.PENDING).
+           put(Deployment.InstanceStatus.STOPPING_VM, NodeMetadata.Status.PENDING).
+           put(Deployment.InstanceStatus.ROLE_STATE_UNKNOWN, NodeMetadata.Status.UNRECOGNIZED).
+           put(Deployment.InstanceStatus.UNRECOGNIZED, NodeMetadata.Status.UNRECOGNIZED).
+           build();
+
+   private static final Map<Deployment.Status, NodeMetadata.Status> STATUS_TO_NODESTATUS =
+           ImmutableMap.<Deployment.Status, NodeMetadata.Status>builder().
+           put(Deployment.Status.DELETING, NodeMetadata.Status.PENDING).
+           put(Deployment.Status.SUSPENDED_TRANSITIONING, NodeMetadata.Status.PENDING).
+           put(Deployment.Status.RUNNING_TRANSITIONING, NodeMetadata.Status.PENDING).
+           put(Deployment.Status.DEPLOYING, NodeMetadata.Status.PENDING).
+           put(Deployment.Status.STARTING, NodeMetadata.Status.PENDING).
+           put(Deployment.Status.SUSPENDED, NodeMetadata.Status.SUSPENDED).
+           put(Deployment.Status.RUNNING, NodeMetadata.Status.RUNNING).
+           put(Deployment.Status.UNRECOGNIZED, NodeMetadata.Status.UNRECOGNIZED).
+           build();
+
+   private final AzureComputeApi api;
 
    private final Supplier<Set<? extends Location>> locations;
 
@@ -60,15 +90,18 @@ public class DeploymentToNodeMetadata implements Function<Deployment, NodeMetada
    private final Map<String, Credentials> credentialStore;
 
    @Inject
-   DeploymentToNodeMetadata(@Memoized Supplier<Set<? extends Location>> locations,
+   DeploymentToNodeMetadata(
+           AzureComputeApi api,
+           @Memoized Supplier<Set<? extends Location>> locations,
            GroupNamingConvention.Factory namingConvention, OSImageToImage osImageToImage,
            RoleSizeToHardware roleSizeToHardware, Map<String, Credentials> credentialStore) {
 
       this.nodeNamingConvention = namingConvention.createWithoutPrefix();
-      this.locations = locations;
+      this.locations = Preconditions.checkNotNull(locations, "locations");
       this.osImageToImage = osImageToImage;
       this.roleSizeToHardware = roleSizeToHardware;
       this.credentialStore = credentialStore;
+      this.api = api;
    }
 
    @Override
@@ -78,12 +111,21 @@ public class DeploymentToNodeMetadata implements Function<Deployment, NodeMetada
       builder.providerId(from.name());
       builder.name(from.name());
       builder.hostname(getHostname(from));
+      builder.group(nodeNamingConvention.groupInUniqueNameOrNull(getHostname(from)));
+
+      // TODO: CloudService name is required (see JCLOUDS-849): waiting for JCLOUDS-853.
+      final CloudService cloudService = api.getCloudServiceApi().get(from.name());
+      if (cloudService != null) {
+         builder.location(FluentIterable.from(locations.get()).
+                 firstMatch(LocationPredicates.idEquals(cloudService.location())).
+                 orNull());
+      }
+
       /* TODO
        if (from.getDatacenter() != null) {
        builder.location(from(locations.get()).firstMatch(
        LocationPredicates.idEquals(from.getDatacenter().getId() + "")).orNull());
        }
-       builder.group(nodeNamingConvention.groupInUniqueNameOrNull(from.getHostname()));
        builder.hardware(roleSizeToHardware.apply(from.instanceSize()));
        Image image = osImageToImage.apply(from);
        if (image != null) {
@@ -92,8 +134,14 @@ public class DeploymentToNodeMetadata implements Function<Deployment, NodeMetada
        }
        */
       if (from.status() != null) {
-         builder.status(serverStateToNodeStatus.get(from.status()));
+         final Optional<RoleInstance> roleInstance = tryFindFirstRoleInstanceInDeployment(from);
+         if (roleInstance.isPresent()) {
+            builder.status(INSTANCESTATUS_TO_NODESTATUS.get(roleInstance.get().instanceStatus()));
+         } else {
+            builder.status(STATUS_TO_NODESTATUS.get(from.status()));
+         }
       }
+
       final Set<String> publicIpAddresses = Sets.newLinkedHashSet();
       if (from.virtualIPs() != null) {
          for (Deployment.VirtualIP virtualIP : from.virtualIPs()) {
@@ -104,7 +152,9 @@ public class DeploymentToNodeMetadata implements Function<Deployment, NodeMetada
       final Set<String> privateIpAddresses = Sets.newLinkedHashSet();
       if (from.roleInstanceList() != null) {
          for (RoleInstance roleInstance : from.roleInstanceList()) {
-            privateIpAddresses.add(roleInstance.ipAddress());
+            if (roleInstance.ipAddress() != null) {
+               privateIpAddresses.add(roleInstance.ipAddress());
+            }
          }
          builder.privateAddresses(privateIpAddresses);
       }
@@ -112,10 +162,10 @@ public class DeploymentToNodeMetadata implements Function<Deployment, NodeMetada
    }
 
    private String getHostname(final Deployment from) {
-      final Optional<RoleInstance> roleInstanceOptional = tryFindFirstRoleInstanceInDeployment(from);
-      return roleInstanceOptional.isPresent()
-              ? roleInstanceOptional.get().hostname()
-              : from.name();
+      final Optional<RoleInstance> roleInstance = tryFindFirstRoleInstanceInDeployment(from);
+      return !roleInstance.isPresent() || roleInstance.get().hostname() == null
+              ? from.name()
+              : roleInstance.get().hostname();
    }
 
    private Optional<RoleInstance> tryFindFirstRoleInstanceInDeployment(final Deployment deployment) {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/OSImageToImage.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/OSImageToImage.java b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/OSImageToImage.java
index 2088418..bfee989 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/OSImageToImage.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/OSImageToImage.java
@@ -90,6 +90,15 @@ public class OSImageToImage implements Function<OSImage, Image> {
               build();
    }
 
+   public static String toGeoName(final String name, final String location) {
+      return name + "/" + location;
+   }
+
+   public static String[] fromGeoName(final String geoName) {
+      final String[] parts = checkNotNull(geoName, "geoName").split("/");
+      return (parts.length == 1) ? new String[]{geoName, null} : parts;
+   }
+
    public static Function<OSImage, OperatingSystem.Builder> osFamily() {
       return new Function<OSImage, OperatingSystem.Builder>() {
          @Override

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/GetOrCreateStorageServiceAndVirtualNetworkThenCreateNodes.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/GetOrCreateStorageServiceAndVirtualNetworkThenCreateNodes.java b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/GetOrCreateStorageServiceAndVirtualNetworkThenCreateNodes.java
index 6f70229..5a8c681 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/GetOrCreateStorageServiceAndVirtualNetworkThenCreateNodes.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/GetOrCreateStorageServiceAndVirtualNetworkThenCreateNodes.java
@@ -28,7 +28,6 @@ import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.atomic.AtomicReference;
 
-import javax.annotation.Resource;
 import javax.inject.Named;
 import javax.inject.Singleton;
 
@@ -43,12 +42,10 @@ import org.jclouds.compute.config.CustomizationResponse;
 import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.domain.Template;
 import org.jclouds.compute.functions.GroupNamingConvention;
-import org.jclouds.compute.reference.ComputeServiceConstants;
 import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
 import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory;
 import org.jclouds.compute.strategy.ListNodesStrategy;
 import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
-import org.jclouds.logging.Logger;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
@@ -77,10 +74,6 @@ public class GetOrCreateStorageServiceAndVirtualNetworkThenCreateNodes
 
    private static final String DEFAULT_SUBNET_ADDRESS_PREFIX = "10.0.0.0/23";
 
-   @Resource
-   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
-   protected Logger logger = Logger.NULL;
-
    private final AzureComputeApi api;
 
    private final Predicate<String> operationSucceededPredicate;

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/impl/AzureAdaptingComputeServiceStrategies.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/impl/AzureAdaptingComputeServiceStrategies.java b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/impl/AzureAdaptingComputeServiceStrategies.java
new file mode 100644
index 0000000..c99f3a4
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/impl/AzureAdaptingComputeServiceStrategies.java
@@ -0,0 +1,70 @@
+/*
+ * 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.compute.strategy.impl;
+
+import com.google.common.base.Function;
+import java.util.Map;
+import javax.inject.Inject;
+import org.jclouds.azurecompute.compute.AzureComputeServiceAdapter;
+import org.jclouds.azurecompute.domain.Deployment;
+import org.jclouds.azurecompute.domain.Location;
+import org.jclouds.azurecompute.domain.OSImage;
+import org.jclouds.azurecompute.domain.RoleSize;
+import org.jclouds.compute.ComputeServiceAdapter;
+import org.jclouds.compute.config.ComputeServiceAdapterContextModule.AddDefaultCredentialsToImage;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
+import org.jclouds.compute.strategy.impl.AdaptingComputeServiceStrategies;
+import org.jclouds.domain.Credentials;
+
+public class AzureAdaptingComputeServiceStrategies
+        extends AdaptingComputeServiceStrategies<Deployment, RoleSize, OSImage, Location> {
+
+   private final AzureComputeServiceAdapter client;
+
+   private final Function<Deployment, NodeMetadata> nodeMetadataAdapter;
+
+   @Inject
+   public AzureAdaptingComputeServiceStrategies(
+           final Map<String, Credentials> credentialStore,
+           final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate,
+           final ComputeServiceAdapter<Deployment, RoleSize, OSImage, Location> client,
+           final Function<Deployment, NodeMetadata> nodeMetadataAdapter,
+           final Function<OSImage, Image> imageAdapter,
+           final AddDefaultCredentialsToImage addDefaultCredentialsToImage) {
+
+      super(credentialStore,
+              prioritizeCredentialsFromTemplate,
+              client,
+              nodeMetadataAdapter,
+              imageAdapter,
+              addDefaultCredentialsToImage);
+
+      this.client = (AzureComputeServiceAdapter) client;
+      this.nodeMetadataAdapter = nodeMetadataAdapter;
+   }
+
+   @Override
+   public NodeMetadata destroyNode(final String id) {
+      final Deployment node = client.internalDestroyNode(id);
+      return node == null
+              ? null
+              : nodeMetadataAdapter.apply(node);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Deployment.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Deployment.java b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Deployment.java
index 4fe0e49..617d3df 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Deployment.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Deployment.java
@@ -47,20 +47,26 @@ public abstract class Deployment {
 
    public enum Status {
 
-      RUNNING,
-      SUSPENDED,
-      RUNNING_TRANSITIONING,
-      SUSPENDED_TRANSITIONING,
-      STARTING,
-      SUSPENDING,
-      DEPLOYING,
-      DELETING,
-      UNRECOGNIZED;
+      RUNNING("Running"),
+      SUSPENDED("Suspended"),
+      RUNNING_TRANSITIONING("RunningTransitioning"),
+      SUSPENDED_TRANSITIONING("SuspendedTransitioning"),
+      STARTING("Starting"),
+      SUSPENDING("Suspending"),
+      DEPLOYING("Deploying"),
+      DELETING("Deleting"),
+      UNRECOGNIZED("");
+
+      private final String key;
+
+      private Status(final String key) {
+         this.key = key;
+      }
 
       public static Status fromString(final String text) {
          if (text != null) {
             for (Status status : Status.values()) {
-               if (text.equalsIgnoreCase(status.name())) {
+               if (text.equalsIgnoreCase(status.key)) {
                   return status;
                }
             }
@@ -71,37 +77,51 @@ public abstract class Deployment {
 
    public enum InstanceStatus {
 
-      CREATING_VM,
-      STARTING_VM,
-      CREATING_ROLE,
-      STARTING_ROLE,
-      READY_ROLE,
-      BUSY_ROLE,
-      STOPPING_ROLE,
-      STOPPING_VM,
-      DELETING_VM,
-      STOPPED_VM,
-      RESTARTING_ROLE,
-      CYCLING_ROLE,
-      FAILED_STARTING_ROLE,
-      FAILED_STARTING_VM,
-      UNRESPONSIVE_ROLE,
-      STOPPED_DEALLOCATED,
-      PREPARING,
-      /**
-       * Unknown to Azure.
-       */
-      UNKNOWN,
+      ROLE_STATE_UNKNOWN("RoleStateUnknown"),
+      CREATING_VM("CreatingVM"),
+      STARTING_VM("StartingVM"),
+      CREATING_ROLE("CreatingRole"),
+      STARTING_ROLE("StartingRole"),
+      READY_ROLE("ReadyRole", false),
+      BUSY_ROLE("BusyRole"),
+      STOPPING_ROLE("StoppingRole"),
+      STOPPING_VM("StoppingVM"),
+      STOPPED_DEALLOCATED("StoppedDeallocated", false),
+      PREPARING("Preparing"),
+      DELETING_VM("DeletingVM"),
+      STOPPED_VM("StoppedVM", false),
+      RESTARTING_ROLE("RestartingRole"),
+      CYCLING_ROLE("CyclingRole"),
+      FAILED_STARTING_ROLE("FailedStartingRole", false),
+      FAILED_STARTING_VM("FailedStartingVM", false),
+      UNRESPONSIVE_ROLE("UnresponsiveRole"),
+      PROVISIONING("Provisioning"),
       /**
        * Not parsable into one of the above.
        */
-      UNRECOGNIZED;
+      UNRECOGNIZED("");
+
+      private final String key;
+
+      private final boolean _transient;
+
+      private InstanceStatus(final String key) {
+         this(key, true);
+      }
+
+      private InstanceStatus(final String key, final boolean _transient) {
+         this.key = key;
+         this._transient = _transient;
+      }
+
+      public boolean isTransient() {
+         return _transient;
+      }
 
       public static InstanceStatus fromString(final String text) {
          if (text != null) {
             for (InstanceStatus status : InstanceStatus.values()) {
-               // Azure isn't exactly upper-camel, as some states end in VM, not Vm.
-               if (text.replace("V_M", "VM").equalsIgnoreCase(status.name())) {
+               if (text.equalsIgnoreCase(status.key)) {
                   return status;
                }
             }
@@ -110,6 +130,36 @@ public abstract class Deployment {
       }
    }
 
+   public enum PowerState {
+
+      STARTING("Starting"),
+      STARTED("Started"),
+      STOPPING("Stopping"),
+      STOPPED("Stopped"),
+      UNKNOWN("Unknown"),
+      /**
+       * Not parsable into one of the above.
+       */
+      UNRECOGNIZED("");
+
+      private final String key;
+
+      private PowerState(final String key) {
+         this.key = key;
+      }
+
+      public static PowerState fromString(final String text) {
+         if (text != null) {
+            for (PowerState state : PowerState.values()) {
+               if (text.equalsIgnoreCase(state.key)) {
+                  return state;
+               }
+            }
+         }
+         return UNRECOGNIZED;
+      }
+   }
+
    @AutoValue
    public abstract static class VirtualIP {
 
@@ -159,11 +209,13 @@ public abstract class Deployment {
 
       public abstract InstanceStatus instanceStatus();
 
+      public abstract PowerState powerState();
+
       @Nullable // null value in case of StoppedDeallocated
-      public abstract int instanceUpgradeDomain();
+      public abstract Integer instanceUpgradeDomain();
 
       @Nullable // null value in case of StoppedDeallocated
-      public abstract int instanceFaultDomain();
+      public abstract Integer instanceFaultDomain();
 
       @Nullable // null value in case of StoppedDeallocated
       public abstract RoleSize.Type instanceSize();
@@ -181,12 +233,12 @@ public abstract class Deployment {
       }
 
       public static RoleInstance create(final String roleName, final String instanceName,
-              final InstanceStatus instanceStatus, final int instanceUpgradeDomain,
-              final int instanceFaultDomain, final RoleSize.Type instanceSize,
+              final InstanceStatus instanceStatus, final PowerState powerState, final Integer instanceUpgradeDomain,
+              final Integer instanceFaultDomain, final RoleSize.Type instanceSize,
               final String ipAddress, final String hostname, final List<InstanceEndpoint> instanceEndpoints) {
 
-         return new AutoValue_Deployment_RoleInstance(roleName, instanceName, instanceStatus, instanceUpgradeDomain,
-                 instanceFaultDomain, instanceSize, ipAddress, hostname,
+         return new AutoValue_Deployment_RoleInstance(roleName, instanceName, instanceStatus, powerState,
+                 instanceUpgradeDomain, instanceFaultDomain, instanceSize, ipAddress, hostname,
                  instanceEndpoints == null ? null : copyOf(instanceEndpoints));
       }
    }
@@ -245,7 +297,7 @@ public abstract class Deployment {
    public abstract List<RoleInstance> roleInstanceList();
 
    @Nullable
-   public abstract List<Role> roles();
+   public abstract List<Role> roleList();
 
    @Nullable
    public abstract String virtualNetworkName();

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/KeyStoreSupplier.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/KeyStoreSupplier.java b/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/KeyStoreSupplier.java
index 9089f5f..99efc0b 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/KeyStoreSupplier.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/KeyStoreSupplier.java
@@ -83,39 +83,41 @@ public class KeyStoreSupplier implements Supplier<KeyStore> {
             } finally {
                stream.close();
             }
-         } else { // cert is PEM encoded, containing private key and certs
+         } else { 
+            keyStore.load(null);
 
             // split in private key and certs
             final int privateKeyBeginIdx = cert.indexOf("-----BEGIN PRIVATE KEY");
             final int privateKeyEndIdx = cert.indexOf("-----END PRIVATE KEY");
-            final String pemPrivateKey = cert.substring(privateKeyBeginIdx, privateKeyEndIdx + 26);
-
-            final StringBuilder pemCerts = new StringBuilder();
-            int certsBeginIdx = 0;
-
-            do {
-               certsBeginIdx = cert.indexOf("-----BEGIN CERTIFICATE", certsBeginIdx);
-
-               if (certsBeginIdx >= 0) {
-                  final int certsEndIdx = cert.indexOf("-----END CERTIFICATE", certsBeginIdx) + 26;
-                  pemCerts.append(cert.substring(certsBeginIdx, certsEndIdx));
-                  certsBeginIdx = certsEndIdx;
-               }
-            } while (certsBeginIdx != -1);
-
-            // parse private key
-            final KeySpec keySpec = Pems.privateKeySpec(ByteSource.wrap(pemPrivateKey.getBytes(Charsets.UTF_8)));
-            final PrivateKey privateKey = crypto.rsaKeyFactory().generatePrivate(keySpec);
-
-            // populate keystore with private key and certs
-            final CertificateFactory cf = CertificateFactory.getInstance("X.509");
-            @SuppressWarnings("unchecked")
-            final Collection<Certificate> certs = (Collection<Certificate>) cf.generateCertificates(
-                    new ByteArrayInputStream(pemCerts.toString().getBytes(Charsets.UTF_8)));
-            keyStore.load(null);
-            keyStore.setKeyEntry("dummy", privateKey, keyStorePassword.toCharArray(),
-                    certs.toArray(new java.security.cert.Certificate[0]));
-
+            // cert is PEM encoded, containing private key and certs
+            if (privateKeyBeginIdx != -1 && privateKeyEndIdx != -1) {
+               final String pemPrivateKey = cert.substring(privateKeyBeginIdx, privateKeyEndIdx + 26);
+
+               final StringBuilder pemCerts = new StringBuilder();
+               int certsBeginIdx = 0;
+
+               do {
+                  certsBeginIdx = cert.indexOf("-----BEGIN CERTIFICATE", certsBeginIdx);
+
+                  if (certsBeginIdx >= 0) {
+                     final int certsEndIdx = cert.indexOf("-----END CERTIFICATE", certsBeginIdx) + 26;
+                     pemCerts.append(cert.substring(certsBeginIdx, certsEndIdx));
+                     certsBeginIdx = certsEndIdx;
+                  }
+               } while (certsBeginIdx != -1);
+
+               // parse private key
+               final KeySpec keySpec = Pems.privateKeySpec(ByteSource.wrap(pemPrivateKey.getBytes(Charsets.UTF_8)));
+               final PrivateKey privateKey = crypto.rsaKeyFactory().generatePrivate(keySpec);
+
+               // populate keystore with private key and certs
+               final CertificateFactory cf = CertificateFactory.getInstance("X.509");
+               @SuppressWarnings("unchecked")
+               final Collection<Certificate> certs = (Collection<Certificate>) cf.generateCertificates(
+                       new ByteArrayInputStream(pemCerts.toString().getBytes(Charsets.UTF_8)));
+               keyStore.setKeyEntry("dummy", privateKey, keyStorePassword.toCharArray(),
+                       certs.toArray(new java.security.cert.Certificate[0]));
+            }
          }
          return keyStore;
       } catch (NoSuchAlgorithmException e) {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/main/java/org/jclouds/azurecompute/util/ConflictManagementPredicate.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/util/ConflictManagementPredicate.java b/azurecompute/src/main/java/org/jclouds/azurecompute/util/ConflictManagementPredicate.java
index 422072c..4949130 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/util/ConflictManagementPredicate.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/util/ConflictManagementPredicate.java
@@ -41,6 +41,10 @@ public abstract class ConflictManagementPredicate implements Predicate<String> {
 
    private boolean raiseException = false;
 
+   public ConflictManagementPredicate() {
+      this(null);
+   }
+
    /**
     * Constructor.
     *
@@ -88,7 +92,7 @@ public abstract class ConflictManagementPredicate implements Predicate<String> {
             return true;
          }
 
-         final boolean res = operationSucceeded.apply(requestId);
+         final boolean res = operationSucceeded == null ? true : operationSucceeded.apply(requestId);
          if (!res && raiseException) {
             final String message = generateIllegalStateExceptionMessage(requestId, timeout);
             logger.warn(message);

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DeploymentHandler.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DeploymentHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DeploymentHandler.java
index 6f4133f..c53d0ab 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DeploymentHandler.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DeploymentHandler.java
@@ -131,7 +131,7 @@ public final class DeploymentHandler extends ParseSax.HandlerForGeneratedRequest
       } else if (qName.equals("Status")) {
          String statusText = currentOrNull(currentText);
          if (status == null && statusText != null) {
-            status = Status.fromString(UPPER_CAMEL.to(UPPER_UNDERSCORE, statusText));
+            status = Status.fromString(statusText);
          }
       } else if (qName.equals("Label")) {
          String labelText = currentOrNull(currentText);

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/main/java/org/jclouds/azurecompute/xml/RoleHandler.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/RoleHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/RoleHandler.java
index 8650ac6..9b77b1e 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/RoleHandler.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/RoleHandler.java
@@ -169,6 +169,7 @@ public class RoleHandler extends ParseSax.HandlerForGeneratedRequestWithResult<R
          }
       } else if (qName.equals("ResourceExtensionReferences")) {
          inResourceExtensionReference = false;
+      } else if (qName.equals("ResourceExtensionReference")) {
          resourceExtensionReferences.add(resourceExtensionReferenceHandler.getResult());
       } else if (inResourceExtensionReference) {
          resourceExtensionReferenceHandler.endElement(ignoredUri, ignoredName, qName);

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/main/java/org/jclouds/azurecompute/xml/RoleInstanceHandler.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/RoleInstanceHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/RoleInstanceHandler.java
index 641e34c..8589960 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/RoleInstanceHandler.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/RoleInstanceHandler.java
@@ -16,14 +16,13 @@
  */
 package org.jclouds.azurecompute.xml;
 
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
 import static org.jclouds.util.SaxUtils.currentOrNull;
 
 import java.util.List;
 
 import org.jclouds.azurecompute.domain.Deployment.InstanceEndpoint;
 import org.jclouds.azurecompute.domain.Deployment.InstanceStatus;
+import org.jclouds.azurecompute.domain.Deployment.PowerState;
 import org.jclouds.azurecompute.domain.Deployment.RoleInstance;
 import org.jclouds.azurecompute.domain.RoleSize;
 import org.jclouds.http.functions.ParseSax;
@@ -39,6 +38,8 @@ public class RoleInstanceHandler extends ParseSax.HandlerForGeneratedRequestWith
 
    private InstanceStatus instanceStatus;
 
+   private PowerState powerState;
+
    private Integer instanceUpgradeDomain;
 
    private Integer instanceFaultDomain;
@@ -68,6 +69,7 @@ public class RoleInstanceHandler extends ParseSax.HandlerForGeneratedRequestWith
    private void resetState() {
       roleName = instanceName = ipAddress = hostname = null;
       instanceStatus = null;
+      powerState = null;
       instanceUpgradeDomain = instanceFaultDomain = null;
       instanceSize = null;
       instanceEndpoints = Lists.newArrayList();
@@ -77,8 +79,8 @@ public class RoleInstanceHandler extends ParseSax.HandlerForGeneratedRequestWith
 
    @Override
    public RoleInstance getResult() {
-      RoleInstance result = RoleInstance.create(roleName, instanceName, instanceStatus, instanceUpgradeDomain,
-              instanceFaultDomain, instanceSize, ipAddress, hostname, instanceEndpoints);
+      RoleInstance result = RoleInstance.create(roleName, instanceName, instanceStatus, powerState,
+              instanceUpgradeDomain, instanceFaultDomain, instanceSize, ipAddress, hostname, instanceEndpoints);
       resetState(); // handler is called in a loop.
       return result;
    }
@@ -96,8 +98,9 @@ public class RoleInstanceHandler extends ParseSax.HandlerForGeneratedRequestWith
       } else if (qName.equals("InstanceName")) {
          instanceName = currentOrNull(currentText);
       } else if (qName.equals("InstanceStatus")) {
-         String instanceStatusText = currentOrNull(currentText);
-         instanceStatus = InstanceStatus.fromString(UPPER_CAMEL.to(UPPER_UNDERSCORE, instanceStatusText));
+         instanceStatus = InstanceStatus.fromString(currentOrNull(currentText));
+      } else if (qName.equals("PowerState")) {
+         powerState = PowerState.fromString(currentOrNull(currentText));
       } else if (qName.equals("InstanceUpgradeDomain")) {
          String upgradeDomain = currentOrNull(currentText);
          if (upgradeDomain != null) {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/test/java/org/jclouds/azurecompute/AzureComputeProviderMetadataLive.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/AzureComputeProviderMetadataLive.java b/azurecompute/src/test/java/org/jclouds/azurecompute/AzureComputeProviderMetadataLive.java
index 180c0af..86bda72 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/AzureComputeProviderMetadataLive.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/AzureComputeProviderMetadataLive.java
@@ -41,7 +41,7 @@ public class AzureComputeProviderMetadataLive extends AzureComputeProviderMetada
 
    public static Properties defaultProperties() {
       Properties properties = AzureManagementApiMetadata.defaultProperties();
-      properties.setProperty(TEMPLATE, "osFamily=UBUNTU,loginUser=jclouds");
+      properties.setProperty(TEMPLATE, "osFamily=UBUNTU,osVersionMatches=.*14\\.10.*,loginUser=jclouds");
       properties.setProperty(OPERATION_TIMEOUT, "" + 600 * 1000);
       properties.setProperty(OPERATION_POLL_INITIAL_PERIOD, "" + 5);
       properties.setProperty(OPERATION_POLL_MAX_PERIOD, "" + 15);

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/test/java/org/jclouds/azurecompute/compute/AzureComputeServiceAdapterLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/compute/AzureComputeServiceAdapterLiveTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/compute/AzureComputeServiceAdapterLiveTest.java
index 8d347e6..fcdf2bc 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/compute/AzureComputeServiceAdapterLiveTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/compute/AzureComputeServiceAdapterLiveTest.java
@@ -22,14 +22,25 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
 
-import java.util.List;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import com.google.common.net.HostAndPort;
+import com.google.common.net.InetAddresses;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+
+import java.util.Arrays;
 import java.util.Properties;
 import java.util.Random;
+import java.util.Set;
 
 import org.jclouds.azurecompute.AzureComputeApi;
 import org.jclouds.azurecompute.domain.Deployment;
 import org.jclouds.azurecompute.domain.RoleSize;
 import org.jclouds.azurecompute.internal.BaseAzureComputeApiLiveTest;
+import org.jclouds.azurecompute.options.AzureComputeTemplateOptions;
 import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
 import org.jclouds.compute.domain.ExecResponse;
 import org.jclouds.compute.domain.Template;
@@ -37,21 +48,10 @@ import org.jclouds.compute.domain.TemplateBuilder;
 import org.jclouds.ssh.SshClient;
 import org.jclouds.ssh.SshClient.Factory;
 import org.jclouds.sshj.config.SshjSshClientModule;
-import org.jclouds.azurecompute.domain.Role;
-import org.jclouds.azurecompute.options.AzureComputeTemplateOptions;
 
 import org.testng.annotations.Test;
 import org.testng.annotations.AfterGroups;
 
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.net.HostAndPort;
-import com.google.common.net.InetAddresses;
-import com.google.inject.Injector;
-import com.google.inject.Module;
-import java.util.Arrays;
-import org.jclouds.azurecompute.util.ConflictManagementPredicate;
-
 @Test(groups = "live", singleThreaded = true, testName = "AzureComputeServiceAdapterLiveTest")
 public class AzureComputeServiceAdapterLiveTest extends BaseAzureComputeApiLiveTest {
 
@@ -111,40 +111,41 @@ public class AzureComputeServiceAdapterLiveTest extends BaseAzureComputeApiLiveT
          deployment = adapter.createNodeWithGroupEncodedIntoName(groupName, name, template);
          assertEquals(deployment.getNode().name(), name);
          assertEquals(deployment.getNodeId(), deployment.getNode().name());
-         assert InetAddresses.isInetAddress(deployment.getNode().virtualIPs().get(0).address()) : deployment;
 
-         SshClient client = sshFactory.create(
-                 HostAndPort.fromParts(deployment.getNode().virtualIPs().get(0).address(), 22),
+         // wait for node to start...
+         final Set<Deployment> nodes = Sets.newHashSet();
+         retry(new Predicate<String>() {
+
+            @Override
+            public boolean apply(final String input) {
+               final Deployment node = adapter.getNode(input);
+               if (node != null) {
+                  nodes.add(node);
+               }
+               return !nodes.isEmpty();
+            }
+         }, 600, 30, 30, SECONDS).apply(name);
+
+         assertFalse(nodes.isEmpty());
+         final Deployment node = nodes.iterator().next();
+         assert InetAddresses.isInetAddress(node.virtualIPs().get(0).address()) : deployment;
+
+         final SshClient client = sshFactory.create(
+                 HostAndPort.fromParts(node.virtualIPs().get(0).address(), 22),
                  deployment.getCredentials());
          client.connect();
-         ExecResponse hello = client.exec("echo hello");
+         final ExecResponse hello = client.exec("echo hello");
          assertEquals(hello.getOutput().trim(), "hello");
       } finally {
          if (deployment != null) {
-            final List<Role> roles = api.getDeploymentApiForService(deployment.getNodeId()).
-                    get(deployment.getNodeId()).roles();
-
             adapter.destroyNode(deployment.getNodeId());
-
-            for (Role role : roles) {
-               final Role.OSVirtualHardDisk disk = role.osVirtualHardDisk();
-               if (disk != null) {
-                  retry(new ConflictManagementPredicate(operationSucceeded) {
-
-                     @Override
-                     protected String operation() {
-                        return api.getDiskApi().delete(disk.diskName());
-                     }
-                  }, 600, 30, 30, SECONDS).apply(disk.diskName());
-               }
-            }
          }
       }
    }
 
    @Test
    public void testListHardwareProfiles() {
-      Iterable<RoleSize> roleSizes = adapter.listHardwareProfiles();
+      final Iterable<RoleSize> roleSizes = adapter.listHardwareProfiles();
       assertFalse(Iterables.isEmpty(roleSizes));
 
       for (RoleSize roleSize : roleSizes) {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/test/java/org/jclouds/azurecompute/compute/AzureComputeServiceContextLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/compute/AzureComputeServiceContextLiveTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/compute/AzureComputeServiceContextLiveTest.java
index 990fba6..f73fd2b 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/compute/AzureComputeServiceContextLiveTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/compute/AzureComputeServiceContextLiveTest.java
@@ -21,10 +21,19 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.jclouds.util.Predicates2.retry;
 
 import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.reflect.TypeToken;
+import com.google.inject.Module;
+
+import java.util.Arrays;
 import java.util.Random;
 import java.util.Set;
 
 import org.jclouds.azurecompute.options.AzureComputeTemplateOptions;
+import org.jclouds.azurecompute.AzureComputeApi;
+import org.jclouds.azurecompute.compute.config.AzureComputeServiceContextModule;
+import org.jclouds.azurecompute.internal.BaseAzureComputeApiLiveTest;
+import org.jclouds.azurecompute.util.ConflictManagementPredicate;
 import org.jclouds.compute.RunNodesException;
 import org.jclouds.compute.domain.ExecResponse;
 import org.jclouds.compute.domain.NodeMetadata;
@@ -34,16 +43,6 @@ import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
 import org.jclouds.ssh.SshClient;
 import org.jclouds.sshj.config.SshjSshClientModule;
 
-import com.google.common.collect.Iterables;
-import com.google.common.reflect.TypeToken;
-import com.google.inject.Module;
-import java.util.Arrays;
-import java.util.List;
-import org.jclouds.azurecompute.AzureComputeApi;
-import org.jclouds.azurecompute.compute.config.AzureComputeServiceContextModule;
-import org.jclouds.azurecompute.domain.Role;
-import org.jclouds.azurecompute.internal.BaseAzureComputeApiLiveTest;
-import org.jclouds.azurecompute.util.ConflictManagementPredicate;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
@@ -122,7 +121,7 @@ public class AzureComputeServiceContextLiveTest extends BaseComputeServiceContex
       templateBuilder.imageId(BaseAzureComputeApiLiveTest.IMAGE_NAME);
       templateBuilder.hardwareId("BASIC_A0");
       templateBuilder.locationId(BaseAzureComputeApiLiveTest.LOCATION);
-      Template tmp = templateBuilder.build();
+      final Template tmp = templateBuilder.build();
 
       // test passing custom options
       final AzureComputeTemplateOptions options = tmp.getOptions().as(AzureComputeTemplateOptions.class);
@@ -145,22 +144,7 @@ public class AzureComputeServiceContextLiveTest extends BaseComputeServiceContex
          assertThat(hello.getOutput().trim()).isEqualTo("hello");
       } finally {
          if (node != null) {
-            final List<Role> roles = api.getDeploymentApiForService(node.getId()).get(node.getId()).roles();
-
             view.getComputeService().destroyNode(node.getId());
-
-            for (Role role : roles) {
-               final Role.OSVirtualHardDisk disk = role.osVirtualHardDisk();
-               if (disk != null) {
-                  retry(new ConflictManagementPredicate(operationSucceeded) {
-
-                     @Override
-                     protected String operation() {
-                        return api.getDiskApi().delete(disk.diskName());
-                     }
-                  }, 600, 30, 30, SECONDS).apply(disk.diskName());
-               }
-            }
          }
       }
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/test/java/org/jclouds/azurecompute/compute/AzureComputeServiceLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/compute/AzureComputeServiceLiveTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/compute/AzureComputeServiceLiveTest.java
new file mode 100644
index 0000000..e9b4f29
--- /dev/null
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/compute/AzureComputeServiceLiveTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.compute;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.internal.BaseComputeServiceLiveTest;
+import org.jclouds.sshj.config.SshjSshClientModule;
+import org.testng.annotations.Test;
+
+@Test(groups = {"integration", "live"}, singleThreaded = true, testName = "AzureComputeServiceLiveTest")
+public class AzureComputeServiceLiveTest extends BaseComputeServiceLiveTest {
+
+   public AzureComputeServiceLiveTest() {
+      super();
+      provider = "azurecompute";
+   }
+
+   @Override
+   protected void checkUserMetadataContains(final NodeMetadata node, final ImmutableMap<String, String> userMetadata) {
+      // Azure doe not support user metadata
+   }
+
+   @Override
+   protected void checkTagsInNodeEquals(final NodeMetadata node, final ImmutableSet<String> tags) {
+      // Azure does not support tags
+   }
+
+   @Override
+   public void testOptionToNotBlock() throws Exception {
+      // this is 30 seconds by default, but Azure will take anyway longer because we need to wait for a non-null
+      // Deployment object to be returned: see the end of AzureComputeServiceAdapter#createNodeWithGroupEncodedIntoName
+      nonBlockDurationSeconds = 120;
+      super.testOptionToNotBlock();
+   }
+
+   @Override
+   protected Module getSshModule() {
+      return new SshjSshClientModule();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/test/java/org/jclouds/azurecompute/compute/extensions/AzureComputeSecurityGroupExtensionLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/compute/extensions/AzureComputeSecurityGroupExtensionLiveTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/compute/extensions/AzureComputeSecurityGroupExtensionLiveTest.java
index b5bc3a5..50a88c0 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/compute/extensions/AzureComputeSecurityGroupExtensionLiveTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/compute/extensions/AzureComputeSecurityGroupExtensionLiveTest.java
@@ -16,12 +16,21 @@
  */
 package org.jclouds.azurecompute.compute.extensions;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.inject.Module;
+
 import org.jclouds.compute.extensions.internal.BaseSecurityGroupExtensionLiveTest;
 import org.jclouds.sshj.config.SshjSshClientModule;
-import org.testng.annotations.Test;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
 
-import com.google.common.collect.ImmutableSet;
-import com.google.inject.Module;
+import org.testng.annotations.Test;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
 
 /**
  * Live test for AzureCompute {@link org.jclouds.compute.extensions.SecurityGroupExtension} implementation.
@@ -44,4 +53,30 @@ public class AzureComputeSecurityGroupExtensionLiveTest extends BaseSecurityGrou
       return new SshjSshClientModule();
    }
 
+   @BeforeClass(groups = {"integration", "live"})
+   public void setup() {
+      final ComputeService computeService = view.getComputeService();
+
+      final Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
+      if (securityGroupExtension.isPresent()) {
+         final Optional<SecurityGroup> group = Iterables.tryFind(securityGroupExtension.get().listSecurityGroups(),
+                 new Predicate<SecurityGroup>() {
+                    @Override
+                    public boolean apply(final SecurityGroup input) {
+                       return input.getId().equals(secGroupName);
+                    }
+                 });
+
+         if (group.isPresent()) {
+            securityGroupExtension.get().removeSecurityGroup(group.get().getId());
+         }
+      }
+   }
+
+   @AfterClass(groups = {"integration", "live"}, alwaysRun = true)
+   @Override
+   protected void tearDownContext() {
+      super.tearDownContext();
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiLiveTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiLiveTest.java
index 7c8d865..183beda 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiLiveTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiLiveTest.java
@@ -96,7 +96,7 @@ public class DeploymentApiLiveTest extends BaseAzureComputeApiLiveTest {
               .virtualNetworkName(virtualNetworkSite.name())
               .externalEndpoint(DeploymentParams.ExternalEndpoint.inboundTcpToLocalPort(22, 22))
               .build();
-      String requestId = api().create(params);
+      final String requestId = api().create(params);
       assertTrue(operationSucceeded.apply(requestId), requestId);
 
       deployment = api().get(DEPLOYMENT);
@@ -106,7 +106,7 @@ public class DeploymentApiLiveTest extends BaseAzureComputeApiLiveTest {
       assertThat(deployment.status()).isEqualTo(Deployment.Status.RUNNING);
       assertThat(deployment.label()).isEqualTo(DEPLOYMENT);
       assertThat(deployment.slot()).isEqualTo(Deployment.Slot.PRODUCTION);
-      assertThat(deployment.roles().size()).isEqualTo(1);
+      assertThat(deployment.roleList().size()).isEqualTo(1);
       assertThat(deployment.roleInstanceList().size()).isEqualTo(1);
       assertThat(deployment.virtualNetworkName()).isEqualTo(virtualNetworkSite.name());
 
@@ -120,7 +120,7 @@ public class DeploymentApiLiveTest extends BaseAzureComputeApiLiveTest {
 
    @Test(dependsOnMethods = "testGet")
    public void testDelete() {
-      final List<Role> roles = api.getDeploymentApiForService(cloudService.name()).get(DEPLOYMENT).roles();
+      final List<Role> roles = api.getDeploymentApiForService(cloudService.name()).get(DEPLOYMENT).roleList();
 
       retry(new ConflictManagementPredicate(operationSucceeded) {
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/test/java/org/jclouds/azurecompute/features/VirtualMachineApiLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/features/VirtualMachineApiLiveTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/features/VirtualMachineApiLiveTest.java
index 76bd2b7..a207bf7 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/features/VirtualMachineApiLiveTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/features/VirtualMachineApiLiveTest.java
@@ -161,7 +161,7 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
    @AfterClass(alwaysRun = true)
    public void cleanup() {
       if (cloudService != null && api.getDeploymentApiForService(cloudService.name()).get(DEPLOYMENT) != null) {
-         final List<Role> roles = api.getDeploymentApiForService(cloudService.name()).get(DEPLOYMENT).roles();
+         final List<Role> roles = api.getDeploymentApiForService(cloudService.name()).get(DEPLOYMENT).roleList();
 
          retry(new ConflictManagementPredicate(operationSucceeded) {
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/test/java/org/jclouds/azurecompute/internal/BaseAzureComputeApiLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/internal/BaseAzureComputeApiLiveTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/internal/BaseAzureComputeApiLiveTest.java
index 1ad8cda..3d57bd9 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/internal/BaseAzureComputeApiLiveTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/internal/BaseAzureComputeApiLiveTest.java
@@ -53,11 +53,11 @@ public class BaseAzureComputeApiLiveTest extends AbstractAzureComputeApiLiveTest
 
    public static final String DEFAULT_SUBNET_ADDRESS_SPACE = "10.0.0.0/23";
 
-   public static final String VIRTUAL_NETWORK_NAME = "jclouds-vnetsite";
+   public static final String VIRTUAL_NETWORK_NAME = "jclouds-virtual-network";
 
-   public static final String DEFAULT_SUBNET_NAME = "jclouds-subnet";
+   public static final String DEFAULT_SUBNET_NAME = "jclouds-1";
 
-   public static final String LOCATION = "West Europe";
+   public static final String LOCATION = "South Central US";
 
    public static final String IMAGE_NAME =
            "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_1-LTS-amd64-server-20150123-en-us-30GB";

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/d3ff98a0/azurecompute/src/test/java/org/jclouds/azurecompute/xml/DeploymentHandlerTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/xml/DeploymentHandlerTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/xml/DeploymentHandlerTest.java
index 8af313e..0b24069 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/xml/DeploymentHandlerTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/xml/DeploymentHandlerTest.java
@@ -16,8 +16,6 @@
  */
 package org.jclouds.azurecompute.xml;
 
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
 import static org.testng.Assert.assertEquals;
 
 import java.io.InputStream;
@@ -43,7 +41,7 @@ import com.google.common.collect.ImmutableList;
 public class DeploymentHandlerTest extends BaseHandlerTest {
 
    private InstanceStatus parseInstanceStatus(final String instanceStatus) {
-      return InstanceStatus.fromString(UPPER_CAMEL.to(UPPER_UNDERSCORE, instanceStatus));
+      return InstanceStatus.fromString(instanceStatus);
    }
 
    /**
@@ -51,7 +49,7 @@ public class DeploymentHandlerTest extends BaseHandlerTest {
     * <a href="http://msdn.microsoft.com/en-us/library/azure/ee460804.aspx#RoleInstanceList">here</a>.
     */
    public void parseInstanceStatus_Recognized() {
-      assertEquals(parseInstanceStatus("Unknown"), InstanceStatus.UNKNOWN);
+      assertEquals(parseInstanceStatus("RoleStateUnknown"), InstanceStatus.ROLE_STATE_UNKNOWN);
       assertEquals(parseInstanceStatus("CreatingVM"), InstanceStatus.CREATING_VM);
       assertEquals(parseInstanceStatus("StartingVM"), InstanceStatus.STARTING_VM);
       assertEquals(parseInstanceStatus("CreatingRole"), InstanceStatus.CREATING_ROLE);
@@ -103,6 +101,7 @@ public class DeploymentHandlerTest extends BaseHandlerTest {
                               "node1855162607153993262-b26", // roleName
                               "node1855162607153993262-b26", // instanceName
                               InstanceStatus.READY_ROLE, //instanceStatus
+                              Deployment.PowerState.STARTED,
                               0,
                               0,
                               RoleSize.Type.BASIC_A0,


[3/3] jclouds-labs git commit: [JCLOUDS-838] Introducing InMemoryKeyManager for PEM-encoded certificate and private key

Posted by na...@apache.org.
[JCLOUDS-838] Introducing InMemoryKeyManager for PEM-encoded certificate and private key

Conflicts:
	azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/KeyStoreSupplier.java


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

Branch: refs/heads/master
Commit: b9036f5afcdfde0011291fef3e046f977925b518
Parents: ab6993f
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Mar 13 12:00:15 2015 +0100
Committer: Ignasi Barrera <na...@apache.org>
Committed: Mon Apr 6 22:54:43 2015 +0200

----------------------------------------------------------------------
 .../config/AzureComputeHttpApiModule.java       |   9 +-
 .../suppliers/DelegatingSSLContextSupplier.java |  91 ++++++++++++
 .../suppliers/FileBasedKeyManagersSupplier.java |  64 +++++++++
 .../suppliers/InMemoryKeyManagersSupplier.java  | 136 ++++++++++++++++++
 .../suppliers/KeyStoreSupplier.java             | 137 -------------------
 .../suppliers/SSLContextWithKeysSupplier.java   |  86 ------------
 6 files changed, 293 insertions(+), 230 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/b9036f5a/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeHttpApiModule.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeHttpApiModule.java b/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeHttpApiModule.java
index 4c5961c..779de7f 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeHttpApiModule.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeHttpApiModule.java
@@ -16,13 +16,11 @@
  */
 package org.jclouds.azurecompute.config;
 
-import java.security.KeyStore;
 import javax.net.ssl.SSLContext;
 
 import org.jclouds.azurecompute.AzureComputeApi;
 import org.jclouds.azurecompute.handlers.AzureComputeErrorHandler;
-import org.jclouds.azurecompute.suppliers.KeyStoreSupplier;
-import org.jclouds.azurecompute.suppliers.SSLContextWithKeysSupplier;
+import org.jclouds.azurecompute.suppliers.DelegatingSSLContextSupplier;
 import org.jclouds.http.HttpErrorHandler;
 import org.jclouds.http.annotation.ClientError;
 import org.jclouds.http.annotation.Redirection;
@@ -60,10 +58,7 @@ public class AzureComputeHttpApiModule extends HttpApiModule<AzureComputeApi> {
       install(new AzureComputeParserModule());
       super.configure();
       bind(new TypeLiteral<Supplier<SSLContext>>() {
-      }).to(new TypeLiteral<SSLContextWithKeysSupplier>() {
-      });
-      bind(new TypeLiteral<Supplier<KeyStore>>() {
-      }).to(new TypeLiteral<KeyStoreSupplier>() {
+      }).to(new TypeLiteral<DelegatingSSLContextSupplier>() {
       });
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/b9036f5a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/DelegatingSSLContextSupplier.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/DelegatingSSLContextSupplier.java b/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/DelegatingSSLContextSupplier.java
new file mode 100644
index 0000000..3570b0a
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/DelegatingSSLContextSupplier.java
@@ -0,0 +1,91 @@
+/*
+ * 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.suppliers;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Throwables.propagate;
+
+import com.google.common.base.Supplier;
+import java.io.File;
+import java.security.SecureRandom;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import org.jclouds.crypto.Crypto;
+import org.jclouds.domain.Credentials;
+import org.jclouds.http.HttpUtils;
+import org.jclouds.http.config.SSLModule.TrustAllCerts;
+import org.jclouds.location.Provider;
+
+/**
+ * This supplier handles two different types of authentication: PKCS12 and PEM.
+ * <br/>
+ * Out of the {@link Credentials} instance:
+ * <ol>
+ * <li><tt>PKCS12</tt>: where {@link Credentials#identity} is keystore path and {@link Credentials#credential} is
+ * keystore password</li>
+ * <li><tt>PEM</tt>: where {@link Credentials#identity} is PEM-encoded certificate content and
+ * {@link Credentials#credential} is PEM-encoded private key</li>
+ * </ol>
+ */
+@Singleton
+public class DelegatingSSLContextSupplier implements Supplier<SSLContext> {
+
+   private final Crypto crypto;
+
+   private final TrustManager[] trustManager;
+
+   private final Supplier<Credentials> creds;
+
+   @Inject
+   DelegatingSSLContextSupplier(
+           Crypto crypto, @Provider Supplier<Credentials> creds, HttpUtils utils, TrustAllCerts trustAllCerts) {
+
+      this.crypto = crypto;
+      this.trustManager = utils.trustAllCerts() ? new TrustManager[]{trustAllCerts} : null;
+      this.creds = creds;
+   }
+
+   @Override
+   public SSLContext get() {
+      final Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
+      final String identity = checkNotNull(currentCreds.identity, "credential supplier returned null identity");
+      final String credential = checkNotNull(currentCreds.credential, "credential supplier returned null credential");
+
+      final File pkcs12File = new File(identity);
+
+      final KeyManager[] keyManagers = pkcs12File.isFile()
+              ? // identity is path to PKCS12 file, credential holds keystore password
+              new FileBasedKeyManagersSupplier(pkcs12File, credential.toCharArray()).get()
+              : // identity is PEM-encoded certificate content, credentials PEM-encoded private key
+              new InMemoryKeyManagersSupplier(crypto, identity).get();
+
+      if (keyManagers == null) {
+         throw new IllegalStateException("Could not setup any viable authentication method");
+      }
+
+      try {
+         final SSLContext sslContext = SSLContext.getInstance("TLS");
+         sslContext.init(keyManagers, trustManager, new SecureRandom());
+         return sslContext;
+      } catch (Exception e) {
+         throw propagate(e);
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/b9036f5a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/FileBasedKeyManagersSupplier.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/FileBasedKeyManagersSupplier.java b/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/FileBasedKeyManagersSupplier.java
new file mode 100644
index 0000000..e388184
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/FileBasedKeyManagersSupplier.java
@@ -0,0 +1,64 @@
+/*
+ * 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.suppliers;
+
+import com.google.common.base.Supplier;
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.KeyStore;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import org.jclouds.util.Closeables2;
+
+import static com.google.common.base.Throwables.propagate;
+
+class FileBasedKeyManagersSupplier implements Supplier<KeyManager[]> {
+
+   private final File pkcs12File;
+
+   private final char[] credential;
+
+   public FileBasedKeyManagersSupplier(final File pkcs12File, final char[] credential) {
+      this.pkcs12File = pkcs12File;
+      this.credential = credential;
+   }
+
+   @Override
+   public KeyManager[] get() {
+      KeyManager[] keyManagers = null;
+
+      FileInputStream stream = null;
+      try {
+         stream = new FileInputStream(pkcs12File);
+
+         final KeyStore keyStore = KeyStore.getInstance("PKCS12");
+         keyStore.load(stream, credential);
+
+         final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
+         keyManagerFactory.init(keyStore, credential);
+
+         keyManagers = keyManagerFactory.getKeyManagers();
+      } catch (Exception e) {
+         propagate(e);
+      } finally {
+         Closeables2.closeQuietly(stream);
+      }
+
+      return keyManagers;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/b9036f5a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/InMemoryKeyManagersSupplier.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/InMemoryKeyManagersSupplier.java b/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/InMemoryKeyManagersSupplier.java
new file mode 100644
index 0000000..d96fcd8
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/InMemoryKeyManagersSupplier.java
@@ -0,0 +1,136 @@
+/*
+ * 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.suppliers;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Supplier;
+import com.google.common.io.ByteSource;
+import java.io.ByteArrayInputStream;
+import java.net.Socket;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.KeySpec;
+import java.util.Collection;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.X509ExtendedKeyManager;
+import org.jclouds.crypto.Crypto;
+import org.jclouds.crypto.Pems;
+
+import static com.google.common.base.Throwables.propagate;
+
+class InMemoryKeyManagersSupplier implements Supplier<KeyManager[]> {
+
+   private final Crypto crypto;
+
+   private final String identity;
+
+   public InMemoryKeyManagersSupplier(final Crypto crypto, final String identity) {
+      this.crypto = crypto;
+      this.identity = identity;
+   }
+
+   @Override
+   public KeyManager[] get() {
+      KeyManager[] keyManagers = null;
+
+      try {
+         // split in private key and certs
+         final int privateKeyBeginIdx = identity.indexOf("-----BEGIN PRIVATE KEY");
+         final int privateKeyEndIdx = identity.indexOf("-----END PRIVATE KEY");
+         final String pemPrivateKey = identity.substring(privateKeyBeginIdx, privateKeyEndIdx + 26);
+
+         final StringBuilder pemCerts = new StringBuilder();
+         int certsBeginIdx = 0;
+         do {
+            certsBeginIdx = identity.indexOf("-----BEGIN CERTIFICATE", certsBeginIdx);
+            if (certsBeginIdx >= 0) {
+               final int certsEndIdx = identity.indexOf("-----END CERTIFICATE", certsBeginIdx) + 26;
+               pemCerts.append(identity.substring(certsBeginIdx, certsEndIdx));
+               certsBeginIdx = certsEndIdx;
+            }
+         } while (certsBeginIdx != -1);
+
+         // parse private key
+         final KeySpec keySpec = Pems.privateKeySpec(ByteSource.wrap(pemPrivateKey.getBytes(Charsets.UTF_8)));
+         final PrivateKey privateKey = crypto.rsaKeyFactory().generatePrivate(keySpec);
+
+         // parse cert(s)
+         @SuppressWarnings("unchecked")
+         final Collection<Certificate> certs = (Collection<Certificate>) CertificateFactory.getInstance("X.509").
+                 generateCertificates(new ByteArrayInputStream(pemCerts.toString().getBytes(Charsets.UTF_8)));
+
+         if (certs.isEmpty()) {
+            throw new IllegalStateException("Could not find any valid certificate");
+         }
+
+         final X509Certificate certificate = (X509Certificate) certs.iterator().next();
+
+         keyManagers = new KeyManager[]{new InMemoryKeyManager(certificate, privateKey)};
+      } catch (Exception e) {
+         propagate(e);
+      }
+
+      return keyManagers;
+   }
+
+   private static class InMemoryKeyManager extends X509ExtendedKeyManager {
+
+      private static final String DEFAULT_ALIAS = "azure";
+
+      private final X509Certificate certificate;
+
+      private final PrivateKey privateKey;
+
+      public InMemoryKeyManager(final X509Certificate certificate, final PrivateKey privateKey) {
+         this.certificate = certificate;
+         this.privateKey = privateKey;
+      }
+
+      @Override
+      public String chooseClientAlias(final String[] keyType, final Principal[] issuers, final Socket socket) {
+         return DEFAULT_ALIAS;
+      }
+
+      @Override
+      public String chooseServerAlias(final String keyType, final Principal[] issuers, final Socket socket) {
+         return DEFAULT_ALIAS;
+      }
+
+      @Override
+      public X509Certificate[] getCertificateChain(final String alias) {
+         return new X509Certificate[]{certificate};
+      }
+
+      @Override
+      public String[] getClientAliases(final String keyType, final Principal[] issuers) {
+         return new String[]{DEFAULT_ALIAS};
+      }
+
+      @Override
+      public PrivateKey getPrivateKey(final String alias) {
+         return privateKey;
+      }
+
+      @Override
+      public String[] getServerAliases(final String keyType, final Principal[] issuers) {
+         return new String[]{DEFAULT_ALIAS};
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/b9036f5a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/KeyStoreSupplier.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/KeyStoreSupplier.java b/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/KeyStoreSupplier.java
deleted file mode 100644
index 99efc0b..0000000
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/KeyStoreSupplier.java
+++ /dev/null
@@ -1,137 +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.suppliers;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Throwables.propagate;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.util.Collection;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import org.jclouds.crypto.Crypto;
-import org.jclouds.crypto.Pems;
-import org.jclouds.domain.Credentials;
-import org.jclouds.location.Provider;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Supplier;
-import com.google.common.io.ByteSource;
-
-/**
- * TODO this code needs to be completely refactored. It needs to stop using KeyStore of at all possible and definitely
- * the local filesystem. Please look at oauth for examples on how to do this via PEMs.
- */
-@Deprecated
-@Singleton
-public class KeyStoreSupplier implements Supplier<KeyStore> {
-
-   private final Crypto crypto;
-
-   private final Supplier<Credentials> creds;
-
-   @Inject
-   KeyStoreSupplier(Crypto crypto, @Provider Supplier<Credentials> creds) {
-      this.crypto = crypto;
-      this.creds = creds;
-   }
-
-   @Override
-   public KeyStore get() {
-      final Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
-      final String cert = checkNotNull(currentCreds.identity,
-              "credential supplier returned null identity (should be cert)");
-      final String keyStorePassword = checkNotNull(currentCreds.credential,
-              "credential supplier returned null credential (should be keyStorePassword)");
-      try {
-         final KeyStore keyStore = KeyStore.getInstance("PKCS12");
-
-         final File certFile = new File(checkNotNull(cert));
-         if (certFile.isFile()) { // cert is path to pkcs12 file
-            final FileInputStream stream = new FileInputStream(certFile);
-            try {
-               keyStore.load(stream, keyStorePassword.toCharArray());
-            } finally {
-               stream.close();
-            }
-         } else { 
-            keyStore.load(null);
-
-            // split in private key and certs
-            final int privateKeyBeginIdx = cert.indexOf("-----BEGIN PRIVATE KEY");
-            final int privateKeyEndIdx = cert.indexOf("-----END PRIVATE KEY");
-            // cert is PEM encoded, containing private key and certs
-            if (privateKeyBeginIdx != -1 && privateKeyEndIdx != -1) {
-               final String pemPrivateKey = cert.substring(privateKeyBeginIdx, privateKeyEndIdx + 26);
-
-               final StringBuilder pemCerts = new StringBuilder();
-               int certsBeginIdx = 0;
-
-               do {
-                  certsBeginIdx = cert.indexOf("-----BEGIN CERTIFICATE", certsBeginIdx);
-
-                  if (certsBeginIdx >= 0) {
-                     final int certsEndIdx = cert.indexOf("-----END CERTIFICATE", certsBeginIdx) + 26;
-                     pemCerts.append(cert.substring(certsBeginIdx, certsEndIdx));
-                     certsBeginIdx = certsEndIdx;
-                  }
-               } while (certsBeginIdx != -1);
-
-               // parse private key
-               final KeySpec keySpec = Pems.privateKeySpec(ByteSource.wrap(pemPrivateKey.getBytes(Charsets.UTF_8)));
-               final PrivateKey privateKey = crypto.rsaKeyFactory().generatePrivate(keySpec);
-
-               // populate keystore with private key and certs
-               final CertificateFactory cf = CertificateFactory.getInstance("X.509");
-               @SuppressWarnings("unchecked")
-               final Collection<Certificate> certs = (Collection<Certificate>) cf.generateCertificates(
-                       new ByteArrayInputStream(pemCerts.toString().getBytes(Charsets.UTF_8)));
-               keyStore.setKeyEntry("dummy", privateKey, keyStorePassword.toCharArray(),
-                       certs.toArray(new java.security.cert.Certificate[0]));
-            }
-         }
-         return keyStore;
-      } catch (NoSuchAlgorithmException e) {
-         throw propagate(e);
-      } catch (KeyStoreException e) {
-         throw propagate(e);
-      } catch (CertificateException e) {
-         throw propagate(e);
-      } catch (FileNotFoundException e) {
-         throw propagate(e);
-      } catch (IOException e) {
-         throw propagate(e);
-      } catch (InvalidKeySpecException e) {
-         throw propagate(e);
-      }
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/b9036f5a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/SSLContextWithKeysSupplier.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/SSLContextWithKeysSupplier.java b/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/SSLContextWithKeysSupplier.java
deleted file mode 100644
index 1987792..0000000
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/suppliers/SSLContextWithKeysSupplier.java
+++ /dev/null
@@ -1,86 +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.suppliers;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Throwables.propagate;
-
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-
-import org.jclouds.domain.Credentials;
-import org.jclouds.http.HttpUtils;
-import org.jclouds.http.config.SSLModule.TrustAllCerts;
-import org.jclouds.location.Provider;
-
-import com.google.common.base.Supplier;
-
-/**
- * TODO this code needs to be completely refactored. It needs to stop using KeyStore of at all possible and definitely
- * the local filesystem. Please look at oauth for examples on how to do this via PEMs.
- */
-@Deprecated
-@Singleton
-public class SSLContextWithKeysSupplier implements Supplier<SSLContext> {
-
-   private final Supplier<KeyStore> keyStore;
-
-   private final TrustManager[] trustManager;
-
-   private final Supplier<Credentials> creds;
-
-   @Inject
-   SSLContextWithKeysSupplier(Supplier<KeyStore> keyStore, @Provider Supplier<Credentials> creds, HttpUtils utils,
-           TrustAllCerts trustAllCerts) {
-      this.keyStore = keyStore;
-      this.trustManager = utils.trustAllCerts() ? new TrustManager[]{trustAllCerts} : null;
-      this.creds = creds;
-   }
-
-   @Override
-   public SSLContext get() {
-      final Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
-      final String keyStorePassword = checkNotNull(currentCreds.credential,
-              "credential supplier returned null credential (should be keyStorePassword)");
-      KeyManagerFactory kmf;
-      try {
-         kmf = KeyManagerFactory.getInstance("SunX509");
-         kmf.init(keyStore.get(), keyStorePassword.toCharArray());
-         final SSLContext sc = SSLContext.getInstance("TLS");
-         sc.init(kmf.getKeyManagers(), trustManager, new SecureRandom());
-         return sc;
-      } catch (NoSuchAlgorithmException e) {
-         throw propagate(e);
-      } catch (UnrecoverableKeyException e) {
-         throw propagate(e);
-      } catch (KeyStoreException e) {
-         throw propagate(e);
-      } catch (KeyManagementException e) {
-         throw propagate(e);
-      }
-   }
-}


[2/3] jclouds-labs git commit: [JCLOUDS-849] Explicitly setting default test image location to West Europe

Posted by na...@apache.org.
[JCLOUDS-849] Explicitly setting default test image location to West Europe


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

Branch: refs/heads/master
Commit: ab6993fbd89c80f0947fd3ec1df58f4626feccac
Parents: d3ff98a
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Mar 30 12:01:49 2015 +0200
Committer: Ignasi Barrera <na...@apache.org>
Committed: Mon Apr 6 22:48:51 2015 +0200

----------------------------------------------------------------------
 .../jclouds/azurecompute/AzureComputeProviderMetadataLive.java   | 4 +++-
 .../azurecompute/internal/BaseAzureComputeApiLiveTest.java       | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ab6993fb/azurecompute/src/test/java/org/jclouds/azurecompute/AzureComputeProviderMetadataLive.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/AzureComputeProviderMetadataLive.java b/azurecompute/src/test/java/org/jclouds/azurecompute/AzureComputeProviderMetadataLive.java
index 86bda72..2786c63 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/AzureComputeProviderMetadataLive.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/AzureComputeProviderMetadataLive.java
@@ -25,6 +25,7 @@ import com.google.auto.service.AutoService;
 import java.net.URI;
 import java.util.Properties;
 import org.jclouds.azurecompute.config.AzureComputeProperties;
+import org.jclouds.azurecompute.internal.BaseAzureComputeApiLiveTest;
 import org.jclouds.providers.ProviderMetadata;
 
 @AutoService(ProviderMetadata.class)
@@ -41,7 +42,8 @@ public class AzureComputeProviderMetadataLive extends AzureComputeProviderMetada
 
    public static Properties defaultProperties() {
       Properties properties = AzureManagementApiMetadata.defaultProperties();
-      properties.setProperty(TEMPLATE, "osFamily=UBUNTU,osVersionMatches=.*14\\.10.*,loginUser=jclouds");
+      properties.setProperty(TEMPLATE, "osFamily=UBUNTU,osVersionMatches=.*14\\.10.*,loginUser=jclouds,"
+              + "locationId=" + BaseAzureComputeApiLiveTest.LOCATION);
       properties.setProperty(OPERATION_TIMEOUT, "" + 600 * 1000);
       properties.setProperty(OPERATION_POLL_INITIAL_PERIOD, "" + 5);
       properties.setProperty(OPERATION_POLL_MAX_PERIOD, "" + 15);

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ab6993fb/azurecompute/src/test/java/org/jclouds/azurecompute/internal/BaseAzureComputeApiLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/internal/BaseAzureComputeApiLiveTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/internal/BaseAzureComputeApiLiveTest.java
index 3d57bd9..5ad992f 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/internal/BaseAzureComputeApiLiveTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/internal/BaseAzureComputeApiLiveTest.java
@@ -57,7 +57,7 @@ public class BaseAzureComputeApiLiveTest extends AbstractAzureComputeApiLiveTest
 
    public static final String DEFAULT_SUBNET_NAME = "jclouds-1";
 
-   public static final String LOCATION = "South Central US";
+   public static final String LOCATION = "West Europe";
 
    public static final String IMAGE_NAME =
            "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_1-LTS-amd64-server-20150123-en-us-30GB";