Repository: jclouds-labs
Updated Branches:
  refs/heads/fix/AzureTemplateBuilderLiveTest 226633157 -> eb68333d1


Improved use of the azure blob client


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

Branch: refs/heads/fix/AzureTemplateBuilderLiveTest
Commit: eb68333d10e18d5f9f0fe35905d877b889eae98d
Parents: 2266331
Author: Ignasi Barrera <[email protected]>
Authored: Thu Oct 13 09:20:10 2016 +0200
Committer: Ignasi Barrera <[email protected]>
Committed: Thu Oct 13 09:20:10 2016 +0200

----------------------------------------------------------------------
 azurecompute-arm/README.md                      |  6 +-
 .../arm/compute/AzureComputeServiceAdapter.java | 38 ++++++----
 .../extensions/AzureComputeImageExtension.java  | 39 +++++-----
 .../functions/VirtualMachineToNodeMetadata.java | 79 ++++++++++++--------
 .../arm/functions/CleanupResources.java         | 23 ++++--
 .../azurecompute/arm/util/BlobHelper.java       | 76 ++++++++-----------
 .../arm/features/VirtualMachineApiLiveTest.java | 16 ++--
 7 files changed, 153 insertions(+), 124 deletions(-)
----------------------------------------------------------------------


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

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eb68333d/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
index d6d9267..6735afc 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
@@ -24,6 +24,7 @@ import static 
org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageE
 import static 
org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CUSTOM_IMAGE_OFFER;
 import static 
org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.decodeFieldsFromUniqueId;
 import static 
org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.encodeFieldsToUniqueIdCustom;
+import static org.jclouds.util.Closeables2.closeQuietly;
 
 import java.util.List;
 import java.util.Set;
@@ -205,11 +206,17 @@ public class AzureComputeServiceAdapter implements 
ComputeServiceAdapter<Virtual
       for (StorageService storage : storages) {
          String name = storage.name();
          StorageService storageService = 
api.getStorageAccountApi(azureGroup).get(name);
-         if (storageService != null && Status.Succeeded == 
storageService.storageServiceProperties().provisioningState()) {
+         if (storageService != null
+               && Status.Succeeded == 
storageService.storageServiceProperties().provisioningState()) {
             String key = 
api.getStorageAccountApi(azureGroup).getKeys(name).key1();
-            List<VMImage> images = BlobHelper.getImages(CONTAINER_NAME, 
azureGroup, storage.name(), key,
-                  CUSTOM_IMAGE_OFFER, storage.location());
-            osImages.addAll(images);
+            BlobHelper blobHelper = new BlobHelper(storage.name(), key);
+            try {
+               List<VMImage> images = blobHelper.getImages(CONTAINER_NAME, 
azureGroup, CUSTOM_IMAGE_OFFER,
+                     storage.location());
+               osImages.addAll(images);
+            } finally {
+               closeQuietly(blobHelper);
+            }
          }
       }
       
@@ -222,16 +229,21 @@ public class AzureComputeServiceAdapter implements 
ComputeServiceAdapter<Virtual
       if (image.custom()) {
          VMImage customImage = null;
          String key = 
api.getStorageAccountApi(azureGroup).getKeys(image.storage()).key1();
-         if (BlobHelper.customImageExists(image.storage(), key)) {
-            List<VMImage> customImagesInStorage = 
BlobHelper.getImages(CONTAINER_NAME, azureGroup, image.storage(), key,
-                  CUSTOM_IMAGE_OFFER, image.location());
-            customImage = find(customImagesInStorage, new Predicate<VMImage>() 
{
-               @Override public boolean apply(VMImage input) {
-                  return id.equals(encodeFieldsToUniqueIdCustom(input));
-               }
-            }, null);
+         BlobHelper blobHelper = new BlobHelper(image.storage(), key);
+         try {
+            if (blobHelper.customImageExists()) {
+               List<VMImage> customImagesInStorage = 
blobHelper.getImages(CONTAINER_NAME, azureGroup,
+                     CUSTOM_IMAGE_OFFER, image.location());
+               customImage = find(customImagesInStorage, new 
Predicate<VMImage>() {
+                  @Override
+                  public boolean apply(VMImage input) {
+                     return id.equals(encodeFieldsToUniqueIdCustom(input));
+                  }
+               }, null);
+            }
+         } finally {
+            closeQuietly(blobHelper);
          }
-         
          return customImage;
       }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eb68333d/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
index 5817e9e..99c9c6c 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
@@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkState;
 import static 
org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.decodeFieldsFromUniqueId;
 import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
 import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
+import static org.jclouds.util.Closeables2.closeQuietly;
 
 import java.net.URI;
 import java.util.List;
@@ -73,8 +74,7 @@ public class AzureComputeImageExtension implements 
ImageExtension {
          @Named(TIMEOUT_NODE_SUSPENDED) Predicate<String> 
nodeSuspendedPredicate,
          AzureComputeConstants azureComputeConstants,
          @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService 
userExecutor,
-         ResourceDefinitionToCustomImage.Factory resourceDefinitionToImage,
-         CleanupResources cleanupResources) {
+         ResourceDefinitionToCustomImage.Factory resourceDefinitionToImage, 
CleanupResources cleanupResources) {
       this.api = api;
       this.imageAvailablePredicate = imageAvailablePredicate;
       this.nodeSuspendedPredicate = nodeSuspendedPredicate;
@@ -114,7 +114,7 @@ public class AzureComputeImageExtension implements 
ImageExtension {
             checkState(definitions.size() == 1,
                   "Expected one resource definition after creating the image 
but %s were returned", definitions.size());
 
-            Image image =  resourceDefinitionToImage.create(id, 
name).apply(definitions.get(0));
+            Image image = resourceDefinitionToImage.create(id, 
name).apply(definitions.get(0));
             logger.debug(">> created %s", image);
             return image;
          }
@@ -125,23 +125,28 @@ public class AzureComputeImageExtension implements 
ImageExtension {
    public boolean deleteImage(String id) {
       VMImage image = decodeFieldsFromUniqueId(id);
       checkArgument(image.custom(), "Only custom images can be deleted");
-      
+
       logger.debug(">> deleting image %s", id);
 
       StorageServiceKeys keys = 
api.getStorageAccountApi(image.group()).getKeys(image.storage());
-      // This removes now all the images in this storage. At least in theory,
-      // there should be just one and if there is
-      // more, they should be copies of each other.
-      // TODO: Reuse the blobstore context in these two calls
-      BlobHelper.deleteContainerIfExists(image.storage(), keys.key1(), 
"system");
-      boolean result = !BlobHelper.customImageExists(image.storage(), 
keys.key1());
-
-      if (!BlobHelper.hasContainers(image.storage(), keys.key1())) {
-         logger.debug(">> storage account is empty after deleting the custom 
image. Deleting the storage account...");
-         api.getStorageAccountApi(image.group()).delete(image.storage());
-         cleanupResources.deleteResourceGroupIfEmpty(image.group());
-      }
+      BlobHelper blobHelper = new BlobHelper(image.storage(), keys.key1());
+      
+      try {
+         // This removes now all the images in this storage. At least in 
theory,
+         // there should be just one and if there is
+         // more, they should be copies of each other.
+         blobHelper.deleteContainerIfExists("system");
+         boolean result = !blobHelper.customImageExists();
+
+         if (!blobHelper.hasContainers()) {
+            logger.debug(">> storage account is empty after deleting the 
custom image. Deleting the storage account...");
+            api.getStorageAccountApi(image.group()).delete(image.storage());
+            cleanupResources.deleteResourceGroupIfEmpty(image.group());
+         }
 
-      return result;
+         return result;
+      } finally {
+         closeQuietly(blobHelper);
+      }
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eb68333d/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java
index de373b5..0929bd4 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java
@@ -23,6 +23,7 @@ import static com.google.common.collect.Iterables.tryFind;
 import static 
org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CONTAINER_NAME;
 import static 
org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CUSTOM_IMAGE_OFFER;
 import static 
org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.encodeFieldsToUniqueId;
+import static org.jclouds.util.Closeables2.closeQuietly;
 
 import java.net.URI;
 import java.util.List;
@@ -71,17 +72,20 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 
-public class VirtualMachineToNodeMetadata  implements Function<VirtualMachine, 
NodeMetadata> {
+public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, 
NodeMetadata> {
 
    @Resource
    @Named(ComputeServiceConstants.COMPUTE_LOGGER)
    protected Logger logger = Logger.NULL;
-   
-   // When using the Deployment API to deploy an ARM template, the deployment 
goes through
-   // stages.  Accepted -> Running -> Succeeded.  Only when the deployment has 
SUCCEEDED is
+
+   // When using the Deployment API to deploy an ARM template, the deployment
+   // goes through
+   // stages. Accepted -> Running -> Succeeded. Only when the deployment has
+   // SUCCEEDED is
    // the resource deployed using the template actually ready.
    //
-   // To get details about the resource(s) deployed via template, one needs to 
query the
+   // To get details about the resource(s) deployed via template, one needs to
+   // query the
    // various resources after the deployment has "SUCCEEDED".
    private static final Function<VirtualMachineProperties.ProvisioningState, 
NodeMetadata.Status> PROVISIONINGSTATE_TO_NODESTATUS = Functions
          .forMap(
@@ -97,7 +101,7 @@ public class VirtualMachineToNodeMetadata  implements 
Function<VirtualMachine, N
                      .put(VirtualMachineProperties.ProvisioningState.FAILED, 
NodeMetadata.Status.ERROR)
                      
.put(VirtualMachineProperties.ProvisioningState.UNRECOGNIZED, 
NodeMetadata.Status.UNRECOGNIZED)
                      .build(), NodeMetadata.Status.UNRECOGNIZED);
-   
+
    private static final Function<VirtualMachineStatus.PowerState, 
NodeMetadata.Status> POWERSTATE_TO_NODESTATUS = Functions
          .forMap(
                ImmutableMap.<PowerState, NodeMetadata.Status> builder()
@@ -105,7 +109,7 @@ public class VirtualMachineToNodeMetadata  implements 
Function<VirtualMachine, N
                      .put(PowerState.STOPPED, NodeMetadata.Status.SUSPENDED)
                      .put(PowerState.UNRECOGNIZED, 
NodeMetadata.Status.UNRECOGNIZED).build(),
                NodeMetadata.Status.UNRECOGNIZED);
-   
+
    private final String azureGroup;
    private final AzureComputeApi api;
    private final GroupNamingConvention nodeNamingConvention;
@@ -119,8 +123,7 @@ public class VirtualMachineToNodeMetadata  implements 
Function<VirtualMachine, N
    VirtualMachineToNodeMetadata(AzureComputeApi api, 
GroupNamingConvention.Factory namingConvention,
          Supplier<Map<String, ? extends Image>> images, Supplier<Map<String, ? 
extends Hardware>> hardwares,
          @Memoized Supplier<Set<? extends Location>> locations, Map<String, 
Credentials> credentialStore,
-         final AzureComputeConstants azureComputeConstants,
-         Function<VMImage, Image> vmImageToImge) {
+         final AzureComputeConstants azureComputeConstants, Function<VMImage, 
Image> vmImageToImge) {
       this.api = api;
       this.nodeNamingConvention = namingConvention.createWithoutPrefix();
       this.images = checkNotNull(images, "images cannot be null");
@@ -130,6 +133,7 @@ public class VirtualMachineToNodeMetadata  implements 
Function<VirtualMachine, N
       this.azureGroup = azureComputeConstants.azureResourceGroup();
       this.vmImageToImge = vmImageToImge;
    }
+
    @Override
    public NodeMetadata apply(VirtualMachine virtualMachine) {
       NodeMetadataBuilder builder = new NodeMetadataBuilder();
@@ -139,20 +143,24 @@ public class VirtualMachineToNodeMetadata  implements 
Function<VirtualMachine, N
       builder.hostname(virtualMachine.name());
       String group = 
this.nodeNamingConvention.extractGroup(virtualMachine.name());
       builder.group(group);
-      
+
       ProvisioningState provisioningState = 
virtualMachine.properties().provisioningState();
       if (ProvisioningState.SUCCEEDED.equals(provisioningState)) {
-         // If the provisioning succeeded, we need to query the *real* status 
of the VM
-         VirtualMachineInstance instanceDetails = 
api.getVirtualMachineApi(azureGroup).getInstanceDetails(virtualMachine.name());
+         // If the provisioning succeeded, we need to query the *real* status 
of
+         // the VM
+         VirtualMachineInstance instanceDetails = 
api.getVirtualMachineApi(azureGroup).getInstanceDetails(
+               virtualMachine.name());
          
builder.status(POWERSTATE_TO_NODESTATUS.apply(instanceDetails.powerState()));
-         
builder.backendStatus(Joiner.on(',').join(transform(instanceDetails.statuses(), 
new Function<VirtualMachineStatus, String>() {
-            @Override public String apply(VirtualMachineStatus input) {
-               return input.code();
-            }
-         })));
+         builder.backendStatus(Joiner.on(',').join(
+               transform(instanceDetails.statuses(), new 
Function<VirtualMachineStatus, String>() {
+                  @Override
+                  public String apply(VirtualMachineStatus input) {
+                     return input.code();
+                  }
+               })));
       } else {
          
builder.status(PROVISIONINGSTATE_TO_NODESTATUS.apply(provisioningState));
-         builder.backendStatus(provisioningState.name());   
+         builder.backendStatus(provisioningState.name());
       }
 
       Credentials credentials = credentialStore.get("node#" + 
virtualMachine.name());
@@ -200,7 +208,7 @@ public class VirtualMachineToNodeMetadata  implements 
Function<VirtualMachine, N
       String resourceGroup = 
Iterables.get(Splitter.on("/").split(networkInterfaceCardIdReference.id()), 4);
       String nicName = 
Iterables.getLast(Splitter.on("/").split(networkInterfaceCardIdReference.id()));
       return api.getNetworkInterfaceCardApi(resourceGroup).get(nicName);
-      
+
    }
 
    private Iterable<String> getPublicIpAddresses(List<IdReference> 
idReferences) {
@@ -211,7 +219,8 @@ public class VirtualMachineToNodeMetadata  implements 
Function<VirtualMachine, N
          for (IpConfiguration ipConfiguration : 
networkInterfaceCard.properties().ipConfigurations()) {
             if (ipConfiguration.properties().publicIPAddress() != null) {
                String publicIpId = 
ipConfiguration.properties().publicIPAddress().id();
-               
publicIpAddresses.add(api.getPublicIPAddressApi(resourceGroup).get(Iterables.getLast(Splitter.on("/").split(publicIpId))).properties().ipAddress());
+               publicIpAddresses.add(api.getPublicIPAddressApi(resourceGroup)
+                     
.get(Iterables.getLast(Splitter.on("/").split(publicIpId))).properties().ipAddress());
             }
          }
       }
@@ -229,25 +238,31 @@ public class VirtualMachineToNodeMetadata  implements 
Function<VirtualMachine, N
 
    protected Optional<? extends Image> findImage(final StorageProfile 
storageProfile, String locatioName) {
       if (storageProfile.imageReference() != null) {
-         return 
Optional.fromNullable(images.get().get(encodeFieldsToUniqueId(false, 
locatioName, storageProfile.imageReference())));
+         return Optional.fromNullable(images.get().get(
+               encodeFieldsToUniqueId(false, locatioName, 
storageProfile.imageReference())));
       } else {
          String storageAccountNameURI = storageProfile.osDisk().vhd().uri();
          String storageAccountName = 
Iterables.get(Splitter.on(".").split(URI.create(storageAccountNameURI).getHost()),
                0);
          StorageServiceKeys keys = 
api.getStorageAccountApi(azureGroup).getKeys(storageAccountName);
+         BlobHelper blobHelper = new BlobHelper(storageAccountName, 
keys.key1());
 
-         // Custom image. Let's find it by uri
-         List<VMImage> customImagesInStorage = 
BlobHelper.getImages(CONTAINER_NAME, azureGroup, storageAccountName,
-               keys.key1(), CUSTOM_IMAGE_OFFER, locatioName);
-         Optional<VMImage> customImage = tryFind(customImagesInStorage, new 
Predicate<VMImage>() {
-            @Override
-            public boolean apply(VMImage input) {
-               return 
input.vhd1().equals(storageProfile.osDisk().image().uri());
-            }
-         });
+         try {
+            // Custom image. Let's find it by uri
+            List<VMImage> customImagesInStorage = 
blobHelper.getImages(CONTAINER_NAME, azureGroup, CUSTOM_IMAGE_OFFER,
+                  locatioName);
+            Optional<VMImage> customImage = tryFind(customImagesInStorage, new 
Predicate<VMImage>() {
+               @Override
+               public boolean apply(VMImage input) {
+                  return 
input.vhd1().equals(storageProfile.osDisk().image().uri());
+               }
+            });
 
-         return customImage.isPresent() ? 
Optional.of(vmImageToImge.apply(customImage.get())) : Optional
-               .<Image> absent();
+            return customImage.isPresent() ? 
Optional.of(vmImageToImge.apply(customImage.get())) : Optional
+                  .<Image> absent();
+         } finally {
+            closeQuietly(blobHelper);
+         }
       }
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eb68333d/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/CleanupResources.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/CleanupResources.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/CleanupResources.java
index 5fda879..e0f0b54 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/CleanupResources.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/CleanupResources.java
@@ -21,6 +21,7 @@ import static com.google.common.base.Predicates.notNull;
 import static com.google.common.collect.Iterables.filter;
 import static com.google.common.collect.Iterables.transform;
 import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
+import static org.jclouds.util.Closeables2.closeQuietly;
 
 import java.net.URI;
 import java.util.List;
@@ -80,6 +81,9 @@ public class CleanupResources implements Function<String, 
Boolean> {
             "virtualMachine must not be null");
 
       boolean vmDeleted = deleteVirtualMachine(group, virtualMachine);
+      
+      // We don't delete the network here, as it is global to the resource
+      // group. It will be deleted when the resource group is deleted
 
       for (String nicName : getNetworkCardInterfaceNames(virtualMachine)) {
          NetworkInterfaceCard nic = 
api.getNetworkInterfaceCardApi(group).get(nicName);
@@ -101,13 +105,18 @@ public class CleanupResources implements Function<String, 
Boolean> {
 
       // Remove the virtual machine files
       logger.debug(">> deleting virtual machine disk storage...");
-      BlobHelper.deleteContainerIfExists(storageAccountName, keys.key1(), 
"vhds");
-
-      if (!BlobHelper.customImageExists(storageAccountName, keys.key1())) {
-         logger.debug(">> deleting storage account %s...", storageAccountName);
-         api.getStorageAccountApi(group).delete(storageAccountName);
-      } else {
-         logger.debug(">> the storage account contains custom images. Will not 
delete it!");
+      BlobHelper blobHelper = new BlobHelper(storageAccountName, keys.key1());
+      try {
+         blobHelper.deleteContainerIfExists("vhds");
+
+         if (!blobHelper.customImageExists()) {
+            logger.debug(">> deleting storage account %s...", 
storageAccountName);
+            api.getStorageAccountApi(group).delete(storageAccountName);
+         } else {
+            logger.debug(">> the storage account contains custom images. Will 
not delete it!");
+         }
+      } finally {
+         closeQuietly(blobHelper);
       }
 
       deleteResourceGroupIfEmpty(group);

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eb68333d/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/BlobHelper.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/BlobHelper.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/BlobHelper.java
index 2124901..b42ea5e 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/BlobHelper.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/BlobHelper.java
@@ -18,6 +18,8 @@ package org.jclouds.azurecompute.arm.util;
 
 import static org.jclouds.util.Closeables2.closeQuietly;
 
+import java.io.Closeable;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -28,68 +30,54 @@ import org.jclouds.azureblob.domain.ContainerProperties;
 import org.jclouds.azureblob.domain.ListBlobsResponse;
 import org.jclouds.azurecompute.arm.domain.VMImage;
 
-public class BlobHelper {
+public class BlobHelper implements Closeable {
 
-   public static void deleteContainerIfExists(String storage, String key, 
String containerName) {
-      final AzureBlobClient azureBlob = 
ContextBuilder.newBuilder("azureblob").credentials(storage, key)
-            .buildApi(AzureBlobClient.class);
+   private final String storageAccount;
+   private final AzureBlobClient azureBlob;
 
-      try {
-         azureBlob.deleteContainer(containerName);
-      } finally {
-         closeQuietly(azureBlob);
-      }
-   }
-   
-   public static boolean hasContainers(String storage, String key) {
-      final AzureBlobClient azureBlob = 
ContextBuilder.newBuilder("azureblob").credentials(storage, key)
+   public BlobHelper(String storageAccount, String key) {
+      this.storageAccount = storageAccount;
+      this.azureBlob = 
ContextBuilder.newBuilder("azureblob").credentials(storageAccount, key)
             .buildApi(AzureBlobClient.class);
+   }
 
-      try {
-         return !azureBlob.listContainers().isEmpty();
-      } finally {
-         closeQuietly(azureBlob);
-      }
+   @Override
+   public void close() throws IOException {
+      closeQuietly(azureBlob);
    }
 
-   public static boolean customImageExists(String storage, String key) {
-      final AzureBlobClient azureBlob = 
ContextBuilder.newBuilder("azureblob").credentials(storage, key)
-            .buildApi(AzureBlobClient.class);
+   public void deleteContainerIfExists(String containerName) {
+      azureBlob.deleteContainer(containerName);
+   }
 
-      try {
-         return azureBlob.containerExists("system");
-      } finally {
-         closeQuietly(azureBlob);
-      }
+   public boolean hasContainers() {
+      return !azureBlob.listContainers().isEmpty();
    }
 
-   public static List<VMImage> getImages(String containerName, String group, 
String storageAccountName, String key,
-         String offer, String location) {
-      final AzureBlobClient azureBlob = 
ContextBuilder.newBuilder("azureblob").credentials(storageAccountName, key)
-            .buildApi(AzureBlobClient.class);
+   public boolean customImageExists() {
+      return azureBlob.containerExists("system");
+   }
 
+   public List<VMImage> getImages(String containerName, String group, String 
offer, String location) {
       List<VMImage> list = new ArrayList<VMImage>();
 
-      try {
-         ContainerProperties systemContainer = 
azureBlob.getContainerProperties("system");
-         if (systemContainer != null) {
-            ListBlobsResponse blobList = 
azureBlob.listBlobs(systemContainer.getName());
-            for (BlobProperties blob : blobList) {
-               String name = blob.getName();
+      ContainerProperties systemContainer = 
azureBlob.getContainerProperties("system");
+      if (systemContainer != null) {
+         ListBlobsResponse blobList = 
azureBlob.listBlobs(systemContainer.getName());
+         for (BlobProperties blob : blobList) {
+            String name = blob.getName();
 
-               if (name.contains("-osDisk")) {
-                  String imageName = name.substring(name.lastIndexOf('/') + 1, 
name.indexOf("-osDisk"));
-                  String imageUrl = blob.getUrl().toString();
+            if (name.contains("-osDisk")) {
+               String imageName = name.substring(name.lastIndexOf('/') + 1, 
name.indexOf("-osDisk"));
+               String imageUrl = blob.getUrl().toString();
 
-                  
list.add(VMImage.customImage().group(group).storage(storageAccountName).vhd1(imageUrl).name(imageName)
-                        .offer(offer).location(location).build());
-               }
+               
list.add(VMImage.customImage().group(group).storage(storageAccount).vhd1(imageUrl).name(imageName)
+                     .offer(offer).location(location).build());
             }
          }
-      } finally {
-         closeQuietly(azureBlob);
       }
 
       return list;
    }
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eb68333d/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java
 
b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java
index 9cc6089..0973693 100644
--- 
a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java
+++ 
b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java
@@ -56,7 +56,6 @@ import org.testng.annotations.Test;
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
-import com.google.gson.internal.LinkedTreeMap;
 
 @Test(groups = "live", testName = "VirtualMachineApiLiveTest")
 public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
@@ -183,6 +182,7 @@ public class VirtualMachineApiLiveTest extends 
BaseAzureComputeApiLiveTest {
       api().generalize(vmName);
    }
 
+   @SuppressWarnings("unchecked")
    @Test(dependsOnMethods = "testGeneralize")
    public void testCapture() throws IllegalStateException {
       URI uri = api().capture(vmName, vmName, vmName);
@@ -191,17 +191,17 @@ public class VirtualMachineApiLiveTest extends 
BaseAzureComputeApiLiveTest {
          List<ResourceDefinition> definitions = 
api.getJobApi().captureStatus(uri);
          if (definitions != null) {
             for (ResourceDefinition definition : definitions) {
-               LinkedTreeMap<String, String> properties = 
(LinkedTreeMap<String, String>) definition.properties();
+               Map<String, String> properties = (Map<String, String>) 
definition.properties();
                Object storageObject = properties.get("storageProfile");
-               LinkedTreeMap<String, String> properties2 = 
(LinkedTreeMap<String, String>) storageObject;
+               Map<String, String> properties2 = (Map<String, String>) 
storageObject;
                Object osDiskObject = properties2.get("osDisk");
-               LinkedTreeMap<String, String> osProperties = 
(LinkedTreeMap<String, String>) osDiskObject;
+               Map<String, String> osProperties = (Map<String, String>) 
osDiskObject;
                Object dataDisksObject = properties2.get("dataDisks");
-               ArrayList<Object> dataProperties = (ArrayList<Object>) 
dataDisksObject;
-               LinkedTreeMap<String, String> datadiskObject = 
(LinkedTreeMap<String, String>) dataProperties.get(0);
+               List<Object> dataProperties = (List<Object>) dataDisksObject;
+               Map<String, String> datadiskObject = (Map<String, String>) 
dataProperties.get(0);
 
-               Assert.assertNotNull(osProperties.get("name"));
-               Assert.assertNotNull(datadiskObject.get("name"));
+               assertNotNull(osProperties.get("name"));
+               assertNotNull(datadiskObject.get("name"));
             }
          }
       }

Reply via email to