You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by an...@apache.org on 2016/10/04 08:24:07 UTC

[2/2] jclouds-labs git commit: fix Cleanup resources

fix Cleanup resources


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

Branch: refs/heads/fix/AzureTemplateBuilderLiveTest
Commit: 84ed11fcef5ba2ad4e0ff1e597d6b7f69661aa86
Parents: 21403be
Author: Andrea Turli <an...@gmail.com>
Authored: Tue Oct 4 10:23:52 2016 +0200
Committer: Andrea Turli <an...@gmail.com>
Committed: Tue Oct 4 10:23:52 2016 +0200

----------------------------------------------------------------------
 .../arm/compute/AzureComputeServiceAdapter.java |  54 +----
 .../AzureComputeServiceContextModule.java       |  35 ++-
 .../arm/functions/CleanupResources.java         | 213 +++++++++++--------
 3 files changed, 161 insertions(+), 141 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/84ed11fc/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 36534ae..c990f6c 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
@@ -29,10 +29,8 @@ import javax.inject.Singleton;
 
 import org.jclouds.azurecompute.arm.AzureComputeApi;
 import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
-import org.jclouds.azurecompute.arm.compute.functions.DeploymentToVMDeployment;
 import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage;
 import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
-import org.jclouds.azurecompute.arm.compute.predicates.IsDeploymentInRegions;
 import org.jclouds.azurecompute.arm.domain.DataDisk;
 import org.jclouds.azurecompute.arm.domain.HardwareProfile;
 import org.jclouds.azurecompute.arm.domain.IdReference;
@@ -88,6 +86,7 @@ import com.google.common.collect.Sets;
 
 import static com.google.common.base.Preconditions.checkState;
 import static org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CUSTOM_IMAGE_PREFIX;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
 import static org.jclouds.util.Predicates2.retry;
 
 /**
@@ -106,23 +105,22 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
    private final AzureComputeApi api;
    private final AzureComputeConstants azureComputeConstants;
    private final Supplier<Set<String>> regionIds;
-   private final IsDeploymentInRegions isDeploymentInRegions;
-   private final DeploymentToVMDeployment deploymentToVMDeployment;
+   private final Predicate<String> nodeRunningPredicate;
 
    @Inject
    AzureComputeServiceAdapter(final AzureComputeApi api, final AzureComputeConstants azureComputeConstants,
          CleanupResources cleanupResources, @Region Supplier<Set<String>> regionIds,
-         IsDeploymentInRegions isDeploymentInRegions, DeploymentToVMDeployment deploymentToVMDeployment) {
+                              @Named(TIMEOUT_NODE_RUNNING) Predicate<String> nodeRunningPredicate) {
       this.api = api;
       this.azureComputeConstants = azureComputeConstants;
+      // TODO remove this constant, use `group`
       this.azureGroup = azureComputeConstants.azureResourceGroup();
 
       logger.debug("AzureComputeServiceAdapter set azuregroup to: " + azureGroup);
 
       this.cleanupResources = cleanupResources;
       this.regionIds = regionIds;
-      this.isDeploymentInRegions = isDeploymentInRegions;
-      this.deploymentToVMDeployment = deploymentToVMDeployment;
+      this.nodeRunningPredicate = nodeRunningPredicate;
    }
 
    @Override
@@ -177,7 +175,7 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
       String networkInterfaceCardName = "jc-nic-" + name;
       NetworkInterfaceCard nic = api.getNetworkInterfaceCardApi(azureGroup).createOrUpdate(networkInterfaceCardName, locationName, networkInterfaceCardProperties, ImmutableMap.of("jclouds", "livetest"));
       
-      // StorageAccount
+      // TODO move storageAccount to CreateResourceGroupThenCreateNodes
       String storageAccountName = null;
       String imageName = template.getImage().getName();
       if (imageName.startsWith(CUSTOM_IMAGE_PREFIX)) {
@@ -227,46 +225,8 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
       VirtualMachine virtualMachine = api.getVirtualMachineApi(azureGroup).create(name, template.getLocation().getId(), virtualMachineProperties);
 
       //Poll until resource is ready to be used
-      retry(new Predicate<String>() {
-         @Override
-         public boolean apply(String name) {
-            return api.getVirtualMachineApi(azureGroup).get(name).properties().provisioningState() != VirtualMachineProperties.ProvisioningState.SUCCEEDED;
-         }
-      }, 60 * 20 * 1000).apply(name);
-
-      VirtualMachineProperties.ProvisioningState status = api.getVirtualMachineApi(azureGroup).get(name).properties().provisioningState();
-      /*
-      DeploymentTemplateBuilder deploymentTemplateBuilder = api.deploymentTemplateFactory().create(group, name, template);
-      DeploymentBody deploymentTemplateBody = deploymentTemplateBuilder.getDeploymentTemplate();
-      DeploymentProperties properties = DeploymentProperties.create(deploymentTemplateBody);
-      final String deploymentTemplate = UrlEscapers.urlFormParameterEscaper().escape(deploymentTemplateBuilder.getDeploymentTemplateJson(properties));
-
-      logger.debug("Deployment created with name: %s group: %s", name, group);
-
-      Deployment deployment = api.getDeploymentApi(azureGroup).create(name, deploymentTemplate);
-      if (!retry(new Predicate<String>() {
-         @Override
-         public boolean apply(final String name) {
-            Deployment deployment = api.getDeploymentApi(azureGroup).get(name);
-            if (deployment == null) return false;
-            Deployment.ProvisioningState state = Deployment.ProvisioningState.fromValue(deployment.properties().provisioningState());
-            if (state == Deployment.ProvisioningState.FAILED) {
-               logger.error(String.format("Deployment %s failed", deployment));
-               cleanupResources.apply(name);
-               throw new IllegalStateException(String.format("Deployment %s failed", deployment));
-            }
-            return state == Deployment.ProvisioningState.SUCCEEDED;
-         }
-      }, azureComputeConstants.operationTimeout(), 1, SECONDS).apply(deployment.name())) {
-         final String illegalStateExceptionMessage = format("Deployment %s was not created within %sms so it will be destroyed.",
-                 name, azureComputeConstants.operationTimeout());
-         logger.warn(illegalStateExceptionMessage);
-         cleanupResources.apply(name);
-         throw new IllegalStateException(illegalStateExceptionMessage);
-      }
+      nodeRunningPredicate.apply(virtualMachine.name());
 
-      VMDeployment vmDeployment = deploymentToVMDeployment.apply(api.getDeploymentApi(azureGroup).get(name));
-*/      
       // Safe to pass null credentials here, as jclouds will default populate the node with the default credentials from the image, or the ones in the options, if provided.
       return new NodeAndInitialCredentials<VirtualMachine>(virtualMachine, name, null);
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/84ed11fc/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
index 21d5062..34319d0 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
@@ -75,6 +75,7 @@ import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RUL
 import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
 import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
 import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
 import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
 import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
 import static org.jclouds.util.Predicates2.retry;
@@ -95,10 +96,6 @@ public class AzureComputeServiceContextModule
       }).to(VMImageToImage.class);
       bind(new TypeLiteral<Function<VMHardware, Hardware>>() {
       }).to(VMHardwareToHardware.class);
-      /*
-      bind(new TypeLiteral<Function<VMDeployment, NodeMetadata>>() {
-      }).to(DeploymentToNodeMetadata.class);
-      */
       bind(new TypeLiteral<Function<VirtualMachine, NodeMetadata>>() {
       }).to(VirtualMachineToNodeMetadata.class);
       bind(new TypeLiteral<Function<Location, org.jclouds.domain.Location>>() {
@@ -199,6 +196,13 @@ public class AzureComputeServiceContextModule
    }
 
    @Provides
+   @com.google.inject.name.Named(TIMEOUT_NODE_RUNNING)
+   protected Predicate<String> provideVirtualMachineRunningPredicate(final AzureComputeApi api, String resourceGroupName, Timeouts timeouts, PollPeriod pollPeriod) {
+      return retry(new VirtualMachineInStatePredicate(api, resourceGroupName, VirtualMachineInstance.VirtualMachineStatus.create("PowerState/running", "Info", "VM running", null)), timeouts.nodeRunning,
+              pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+   }
+   
+   @Provides
    @Named(TIMEOUT_NODE_TERMINATED)
    protected Predicate<URI> provideNodeTerminatedPredicate(final AzureComputeApi api, Timeouts timeouts, PollPeriod pollPeriod) {
       return retry(new ActionDonePredicate(api), timeouts.nodeTerminated, pollPeriod.pollInitialPeriod,
@@ -263,6 +267,29 @@ public class AzureComputeServiceContextModule
    }
 
    @VisibleForTesting
+   static class VirtualMachineInStatePredicate implements Predicate<String> {
+
+      private final AzureComputeApi api;
+      private final String azureGroup;
+      private final VirtualMachineInstance.VirtualMachineStatus status;
+
+      public VirtualMachineInStatePredicate(AzureComputeApi api, String azureGroup, VirtualMachineInstance.VirtualMachineStatus status) {
+         this.api = checkNotNull(api, "api must not be null");
+         this.azureGroup = checkNotNull(azureGroup, "azuregroup must not be null");
+         this.status = status;
+      }
+
+      @Override
+      public boolean apply(String name) {
+         checkNotNull(name, "name cannot be null");
+         VirtualMachineInstance virtualMachineInstance = api.getVirtualMachineApi(this.azureGroup).getInstanceDetails(name);
+         if (virtualMachineInstance == null) return false;
+         List<VirtualMachineInstance.VirtualMachineStatus> statuses = virtualMachineInstance.statuses();
+         return status.equals("VM stopped");
+      }
+   }
+
+   @VisibleForTesting
    static class NodeSuspendedPredicate implements Predicate<String> {
 
       private final AzureComputeApi api;

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/84ed11fc/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 7290f8d..e035ba6 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
@@ -16,7 +16,11 @@
  */
 package  org.jclouds.azurecompute.arm.functions;
 
+import autovalue.shaded.com.google.common.common.collect.Lists;
+
 import java.net.URI;
+import java.util.List;
+import java.util.Map;
 
 import javax.annotation.Resource;
 import javax.inject.Inject;
@@ -24,133 +28,162 @@ import javax.inject.Named;
 import javax.inject.Singleton;
 
 import org.jclouds.azurecompute.arm.AzureComputeApi;
-import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
 import org.jclouds.azurecompute.arm.domain.IdReference;
-import org.jclouds.azurecompute.arm.domain.IpConfiguration;
-import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
+import org.jclouds.azurecompute.arm.domain.ResourceGroup;
+import org.jclouds.azurecompute.arm.domain.Subnet;
 import org.jclouds.azurecompute.arm.domain.VirtualMachine;
+import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
 import org.jclouds.compute.reference.ComputeServiceConstants;
 import org.jclouds.logging.Logger;
 
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
 
+import static com.google.common.base.Preconditions.checkNotNull;
 import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
-import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
 
 @Singleton
 public class CleanupResources implements Function<String, Boolean> {
 
-   private final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants;
    @Resource
    @Named(ComputeServiceConstants.COMPUTE_LOGGER)
    protected Logger logger = Logger.NULL;
 
    protected final AzureComputeApi api;
-   private Predicate<URI> nodeTerminated;
    private Predicate<URI> resourceDeleted;
 
    @Inject
-   public CleanupResources(AzureComputeApi azureComputeApi,
-                           AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
-                           @Named(TIMEOUT_NODE_TERMINATED) Predicate<URI> nodeTerminated,
-                           @Named(TIMEOUT_RESOURCE_DELETED) Predicate<URI> resourceDeleted) {
-      this.azureComputeConstants = azureComputeConstants;
+   public CleanupResources(AzureComputeApi azureComputeApi, @Named(TIMEOUT_RESOURCE_DELETED) Predicate<URI> resourceDeleted) {
       this.api = azureComputeApi;
-      this.nodeTerminated = nodeTerminated;
       this.resourceDeleted = resourceDeleted;
    }
 
    @Override
-   public Boolean apply(String id) {
-
+   public Boolean apply(final String id) {
       logger.debug("Destroying %s ...", id);
-      String storageAccountName = id.replaceAll("[^A-Za-z0-9 ]", "") + "stor";
-      String group = azureComputeConstants.azureResourceGroup();
 
-      VirtualMachine vm = api.getVirtualMachineApi(group).get(id);
-
-      if (vm != null) {
-         URI uri = api.getVirtualMachineApi(group).delete(id);
-         nodeTerminated.apply(uri);
+      Map<String, VirtualMachine> resourceGroupNamesAndVirtualMachines = getResourceGroupNamesAndVirtualMachines(id);
+      if (resourceGroupNamesAndVirtualMachines.isEmpty()) return true;
+      String group = checkNotNull(resourceGroupNamesAndVirtualMachines.entrySet().iterator().next().getKey(), "resourceGroup name must not be null");
+      VirtualMachine virtualMachine = checkNotNull(resourceGroupNamesAndVirtualMachines.get(group), "virtualMachine must not be null");
+      boolean vmDeleted = deleteVirtualMachine(group, virtualMachine);
+      // delete networkCardInterfaces
+      List<String> nics = getNetworkCardInterfaceNames(virtualMachine);
+      for (String nicName : nics) {
+         URI nicDeletionURI = api.getNetworkInterfaceCardApi(group).delete(nicName);
+         // todo is a collection!
+         boolean nicDeleted = resourceDeleted.apply(nicDeletionURI);
+      }
+      // delete virtual networks
+      for (VirtualNetwork virtualNetwork : api.getVirtualNetworkApi(group).list()) {
+         for (Subnet subnet : virtualNetwork.properties().subnets()) {
+            // delete subnets
+            api.getSubnetApi(group, virtualNetwork.name()).delete(subnet.name());
+         }
+         // todo is a collection!
+         boolean virtualNetworkDeleted = api.getVirtualNetworkApi(group).delete(virtualNetwork.name());
+      }
+      // delete storage account
+      String storageAccountNameURI = virtualMachine.properties().storageProfile().osDisk().vhd().uri();
+      boolean storageAccountDeleted = api.getStorageAccountApi(group).delete(Iterables.get(Splitter.on(".").split(URI.create(storageAccountNameURI).getHost()), 0));
+
+      // delete resource group if empty
+      if (api.getVirtualMachineApi(group).list().isEmpty() &&
+              api.getVirtualNetworkApi(group).list().isEmpty() &&
+              api.getStorageAccountApi(group).list().isEmpty() &&
+              api.getNetworkInterfaceCardApi(group).list().isEmpty()) {
+         boolean resourceGroupDeleted = resourceDeleted.apply(api.getResourceGroupApi().delete(group));
+      }
+      return vmDeleted;
+   }
 
-         for (IdReference idReference : vm.properties().networkProfile().networkInterfaces()) {
-            String nicName = Iterables.getLast(Splitter.on("/").split(idReference.id()));
-            NetworkInterfaceCard networkInterfaceCard = api.getNetworkInterfaceCardApi(group).get(nicName);
+   private List<String> getNetworkCardInterfaceNames(VirtualMachine virtualMachine) {
+      List<String> nics = Lists.newArrayList();
+      for (IdReference idReference : virtualMachine.properties().networkProfile().networkInterfaces()) {
+         nics.add(Iterables.getLast(Splitter.on("/").split(idReference.id())));
+      }
+      return nics;
+   }
 
-            api.getNetworkInterfaceCardApi(group).delete(nicName);
-            // TODO waitForJob
+   private boolean deleteVirtualMachine(String group, VirtualMachine virtualMachine) {
+      return resourceDeleted.apply(api.getVirtualMachineApi(group).delete(virtualMachine.name()));
+   }
 
-            for (IpConfiguration ipConfiguration : networkInterfaceCard.properties().ipConfigurations()) {
-               if (ipConfiguration.properties().publicIPAddress() != null) {
-                  String publicIpId = ipConfiguration.properties().publicIPAddress().id();
-                  String publicIpAddressName = Iterables.getLast(Splitter.on("/").split(publicIpId));
-                  // TODO deallocate first?
-                  api.getPublicIPAddressApi(group).delete(publicIpAddressName);
-                  // TODO waitForJob
-               }
-            }
+   private Map<String, VirtualMachine> getResourceGroupNamesAndVirtualMachines(String id) {
+      for (ResourceGroup resourceGroup : api.getResourceGroupApi().list()) {
+         String group = resourceGroup.name();
+         VirtualMachine virtualMachine = api.getVirtualMachineApi(group).get(id);
+         if (virtualMachine != null) {
+            return ImmutableMap.of(group, virtualMachine);
          }
       }
-      return true;
+      return Maps.newHashMap();
    }
 }
-         /*
-         if (uri != null) {
-            boolean jobDone = nodeTerminated.apply(uri);
-            boolean storageAcctDeleteStatus = false;
-            boolean deploymentDeleteStatus = false;
-
-            if (jobDone) {
-               Deployment deployment = api.getDeploymentApi(group).get(id);
-               if (deployment != null) {
-                  uri = api.getDeploymentApi(group).delete(id);
-                  jobDone = resourceDeleted.apply(uri);
-                  if (jobDone) {
-                     deploymentDeleteStatus = true;
+      
+/*      
+      for (ResourceGroup resourceGroup : api.getResourceGroupApi().list()) {
+         String group = resourceGroup.name();
+         VirtualMachine virtualMachine = api.getVirtualMachineApi(group).get(id);
+         if (virtualMachine != null) {
+            vmDeleted = resourceDeleted.apply(api.getVirtualMachineApi(group).delete(id));
+            for (IdReference idReference : virtualMachine.properties().networkProfile().networkInterfaces()) {
+               String nicName = Iterables.getLast(Splitter.on("/").split(idReference.id()));
+               NetworkInterfaceCard networkInterfaceCard = api.getNetworkInterfaceCardApi(group).get(nicName);
+               URI nicDeletionURI = api.getNetworkInterfaceCardApi(group).delete(nicName);
+               nicDeleted = resourceDeleted.apply(nicDeletionURI);
+               for (IpConfiguration ipConfiguration : networkInterfaceCard.properties().ipConfigurations()) {
+                  if (ipConfiguration.properties().publicIPAddress() != null) {
+                     String publicIpId = ipConfiguration.properties().publicIPAddress().id();
+                     String publicIpAddressName = Iterables.getLast(Splitter.on("/").split(publicIpId));
+                     publicIpAddressDeleted = api.getPublicIPAddressApi(group).delete(publicIpAddressName);
                   }
-               } else {
-                  deploymentDeleteStatus = true;
                }
-               NetworkInterfaceCard nic = api.getNetworkInterfaceCardApi(group).get(id + "nic");
-               if (nic != null) {
-                  uri = api.getNetworkInterfaceCardApi(group).delete(id + "nic");
-                  if (uri != null) {
-                     jobDone = resourceDeleted.apply(uri);
-                     if (jobDone) {
-                        boolean ipDeleteStatus = false;
-                        PublicIPAddress ip = api.getPublicIPAddressApi(group).get(id + "publicip");
-                        if (ip != null) {
-                           ipDeleteStatus = api.getPublicIPAddressApi(group).delete(id + "publicip");
-                        } else {
-                           ipDeleteStatus = true;
-                        }
-
-                        // Get NSG
-                        boolean nsgDeleteStatus = false;
-                        NetworkSecurityGroup nsg = api.getNetworkSecurityGroupApi(group).get(id + "nsg");
-                        if (nsg != null) {
-                           uri = api.getNetworkSecurityGroupApi(group).delete(id + "nsg");
-                           jobDone = resourceDeleted.apply(uri);
-                           if (jobDone) {
-                              nsgDeleteStatus = true;
-
-                           }
-                        }
-                        else {
-                           nsgDeleteStatus = true;
-                        }
-
-                        return deploymentDeleteStatus && storageAcctDeleteStatus && ipDeleteStatus && nsgDeleteStatus;
-                     } else {
-                        return false;
-                     }
-                  } else {
-                     return false;
-                  }
-               } else {
-                  return false;
+            }
+            for (VirtualNetwork virtualNetwork : api.getVirtualNetworkApi(group).list()) {
+               for (Subnet subnet : virtualNetwork.properties().subnets()) {
+                  api.getSubnetApi(group, virtualNetwork.name()).delete(subnet.name());
                }
-               */
+               virtualNetworkDeleted = api.getVirtualNetworkApi(group).delete(virtualNetwork.name());
+            }
+            String storageAccountNameURI = virtualMachine.properties().storageProfile().osDisk().vhd().uri();
+            storageAccountDeleted = api.getStorageAccountApi(group).delete(Iterables.get(Splitter.on(".").split(URI.create(storageAccountNameURI).getHost()), 0));
+         }
+         if (api.getVirtualMachineApi(group).list().isEmpty() &&
+                 api.getVirtualNetworkApi(group).list().isEmpty() &&
+                 api.getStorageAccountApi(group).list().isEmpty() &&
+                 api.getNetworkInterfaceCardApi(group).list().isEmpty()) {
+            resourceGroupDeleted = resourceDeleted.apply(api.getResourceGroupApi().delete(group));
+         }
+      }
+      return vmDeleted && nicDeleted && publicIpAddressDeleted && virtualNetworkDeleted && storageAccountDeleted && resourceGroupDeleted;
+   }
+
+   private List<String> getNetworkCardInterfaceNames(VirtualMachine virtualMachine) {
+      List<String> nics = Lists.newArrayList();
+      for (IdReference idReference : virtualMachine.properties().networkProfile().networkInterfaces()) {
+         nics.add(Iterables.getLast(Splitter.on("/").split(idReference.id())));
+      }
+      return nics;
+   }
+
+   private boolean deleteVirtualMachine(String group, VirtualMachine virtualMachine) {
+      return resourceDeleted.apply(api.getVirtualMachineApi(group).delete(virtualMachine.name()));
+   }
+
+   private Map<String, VirtualMachine> getResourceGroupNamesAndVirtualMachines(String id) {
+      for (ResourceGroup resourceGroup : api.getResourceGroupApi().list()) {
+         String group = resourceGroup.name();
+         VirtualMachine virtualMachine = api.getVirtualMachineApi(group).get(id);
+         if (virtualMachine != null) {
+            return ImmutableMap.of(group, virtualMachine);
+         }
+      }
+      return Maps.newHashMap();
+   }
+}
+*/