JCLOUDS-1273/JCLOUDS-1226: Support multiple resource groups in ARM
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/83c0a3c7 Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/83c0a3c7 Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/83c0a3c7 Branch: refs/heads/master Commit: 83c0a3c7b255ec744c6150ce76c40e8301280c79 Parents: cc13cfe Author: Ignasi Barrera <[email protected]> Authored: Mon Apr 24 14:49:57 2017 +0200 Committer: Ignasi Barrera <[email protected]> Committed: Wed Apr 26 00:12:53 2017 +0200 ---------------------------------------------------------------------- .../azurecompute/arm/AzureComputeApi.java | 8 +- .../arm/compute/AzureComputeService.java | 15 +- .../arm/compute/AzureComputeServiceAdapter.java | 88 ++++---- .../AzureComputeServiceContextModule.java | 18 +- .../arm/compute/domain/LocationAndName.java | 50 +++++ .../domain/RegionAndIdAndIngressRules.java | 66 ------ .../compute/domain/ResourceGroupAndName.java | 50 +++++ .../ResourceGroupAndNameAndIngressRules.java | 71 +++++++ .../extensions/AzureComputeImageExtension.java | 39 ++-- .../AzureComputeSecurityGroupExtension.java | 100 +++++----- .../compute/functions/CustomImageToVMImage.java | 4 +- .../NetworkSecurityGroupToSecurityGroup.java | 7 +- .../functions/TemplateToAvailabilitySet.java | 8 +- .../compute/functions/VMHardwareToHardware.java | 20 +- .../arm/compute/functions/VMImageToImage.java | 25 ++- .../functions/VirtualMachineToNodeMetadata.java | 50 ++--- .../functions/VirtualMachineToStatus.java | 11 +- .../loaders/CreateSecurityGroupIfNeeded.java | 15 +- .../compute/loaders/DefaultResourceGroup.java | 62 ++++++ .../loaders/ResourceGroupForLocation.java | 62 ------ .../compute/options/AzureTemplateOptions.java | 78 ++++---- .../arm/compute/strategy/CleanupResources.java | 79 +++----- .../CreateResourceGroupThenCreateNodes.java | 193 ------------------ .../CreateResourcesThenCreateNodes.java | 199 +++++++++++++++++++ .../azurecompute/arm/domain/IdReference.java | 39 +++- .../azurecompute/arm/domain/RegionAndId.java | 50 ----- .../azurecompute/arm/domain/VMHardware.java | 11 +- .../azurecompute/arm/domain/VMImage.java | 8 + .../azurecompute/arm/features/JobApi.java | 2 +- .../jclouds/azurecompute/arm/util/VMImages.java | 2 +- .../compute/AzureComputeServiceLiveTest.java | 29 +-- .../compute/AzureTemplateBuilderLiveTest.java | 2 +- .../AzureComputeImageExtensionLiveTest.java | 24 +-- ...reComputeSecurityGroupExtensionLiveTest.java | 40 ++-- .../arm/domain/IdReferenceTest.java | 62 ++++++ .../arm/features/ImageApiLiveTest.java | 30 +-- .../arm/features/LoadBalancerApiLiveTest.java | 50 ++--- .../arm/internal/AzureLiveTestUtils.java | 10 +- .../internal/BaseAzureComputeApiLiveTest.java | 2 +- 39 files changed, 884 insertions(+), 795 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java index 70814868..a25690f 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java @@ -17,15 +17,16 @@ package org.jclouds.azurecompute.arm; import java.io.Closeable; + import javax.ws.rs.PathParam; import org.jclouds.azurecompute.arm.features.AvailabilitySetApi; import org.jclouds.azurecompute.arm.features.DeploymentApi; +import org.jclouds.azurecompute.arm.features.DiskApi; import org.jclouds.azurecompute.arm.features.ImageApi; import org.jclouds.azurecompute.arm.features.JobApi; import org.jclouds.azurecompute.arm.features.LoadBalancerApi; import org.jclouds.azurecompute.arm.features.LocationApi; -import org.jclouds.azurecompute.arm.features.DiskApi; import org.jclouds.azurecompute.arm.features.NetworkInterfaceCardApi; import org.jclouds.azurecompute.arm.features.NetworkSecurityGroupApi; import org.jclouds.azurecompute.arm.features.NetworkSecurityRuleApi; @@ -47,7 +48,7 @@ import org.jclouds.rest.annotations.Delegate; * @see <a href="https://msdn.microsoft.com/en-us/library/azure/dn790568.aspx" >doc</a> */ public interface AzureComputeApi extends Closeable { - + /** * The Azure Resource Manager API includes operations for managing resource groups in your subscription. * @@ -56,6 +57,9 @@ public interface AzureComputeApi extends Closeable { @Delegate ResourceGroupApi getResourceGroupApi(); + /** + * Provides access to the Job tracking API. + */ @Delegate JobApi getJobApi(); http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeService.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeService.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeService.java index f566a69..dcb9c44 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeService.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeService.java @@ -31,8 +31,8 @@ import javax.inject.Provider; import javax.inject.Singleton; import org.jclouds.Constants; +import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName; import org.jclouds.azurecompute.arm.compute.strategy.CleanupResources; -import org.jclouds.azurecompute.arm.domain.ResourceGroup; import org.jclouds.collect.Memoized; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.callables.RunScriptOnNode; @@ -62,7 +62,6 @@ import org.jclouds.scriptbuilder.functions.InitAdminAccess; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.base.Supplier; -import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.ListeningExecutorService; @@ -70,7 +69,6 @@ import com.google.common.util.concurrent.ListeningExecutorService; @Singleton public class AzureComputeService extends BaseComputeService { private final CleanupResources cleanupResources; - private final LoadingCache<String, ResourceGroup> resourceGroupMap; @Inject protected AzureComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore, @@ -89,14 +87,13 @@ public class AzureComputeService extends BaseComputeService { PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, CleanupResources cleanupResources, Optional<ImageExtension> imageExtension, - Optional<SecurityGroupExtension> securityGroupExtension, LoadingCache<String, ResourceGroup> resourceGroupMap) { + Optional<SecurityGroupExtension> securityGroupExtension) { super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy, getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, persistNodeCredentials, timeouts, userExecutor, imageExtension, securityGroupExtension); this.cleanupResources = cleanupResources; - this.resourceGroupMap = resourceGroupMap; } @Override @@ -105,11 +102,11 @@ public class AzureComputeService extends BaseComputeService { ImmutableSet.Builder<String> resourceGroups = ImmutableSet.builder(); for (NodeMetadata deadNode : deadNodes) { - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(deadNode.getLocation().getId()); - - resourceGroups.add(resourceGroup.name()); + String resourceGroupName = ResourceGroupAndName.fromSlashEncoded(deadNode.getId()).resourceGroup(); + resourceGroups.add(resourceGroupName); + if (deadNode.getGroup() != null) { - regionGroups.put(resourceGroup.name(), deadNode.getGroup()); + regionGroups.put(resourceGroupName, deadNode.getGroup()); } try { http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java index 8f9b67c..2e9e0f6 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java @@ -19,10 +19,12 @@ package org.jclouds.azurecompute.arm.compute; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.ImmutableList.builder; import static com.google.common.collect.ImmutableList.of; -import static com.google.common.collect.Iterables.contains; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.common.collect.Iterables.transform; +import static com.google.common.collect.Lists.newArrayList; +import static org.jclouds.azurecompute.arm.compute.domain.LocationAndName.fromSlashEncoded; +import static org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName.fromResourceGroupAndName; import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.decodeFieldsFromUniqueId; import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.getMarketplacePlanFromImageMetadata; import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS; @@ -40,6 +42,7 @@ import javax.inject.Singleton; import org.jclouds.azurecompute.arm.AzureComputeApi; import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.PublicIpAvailablePredicateFactory; +import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName; import org.jclouds.azurecompute.arm.compute.functions.CustomImageToVMImage; import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions; import org.jclouds.azurecompute.arm.compute.strategy.CleanupResources; @@ -62,7 +65,6 @@ import org.jclouds.azurecompute.arm.domain.Offer; import org.jclouds.azurecompute.arm.domain.Plan; import org.jclouds.azurecompute.arm.domain.PublicIPAddress; import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties; -import org.jclouds.azurecompute.arm.domain.RegionAndId; import org.jclouds.azurecompute.arm.domain.ResourceGroup; import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData; import org.jclouds.azurecompute.arm.domain.SKU; @@ -90,7 +92,6 @@ import com.google.common.base.Objects; import com.google.common.base.Predicate; import com.google.common.base.Splitter; import com.google.common.base.Supplier; -import com.google.common.cache.LoadingCache; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -115,20 +116,18 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual private final List<String> imagePublishers; private final Supplier<Set<String>> regionIds; private final PublicIpAvailablePredicateFactory publicIpAvailable; - private final LoadingCache<String, ResourceGroup> resourceGroupMap; private final CustomImageToVMImage customImagetoVmImage; @Inject AzureComputeServiceAdapter(final AzureComputeApi api, @Named(IMAGE_PUBLISHERS) String imagePublishers, CleanupResources cleanupResources, @Region Supplier<Set<String>> regionIds, - PublicIpAvailablePredicateFactory publicIpAvailable, LoadingCache<String, ResourceGroup> resourceGroupMap, + PublicIpAvailablePredicateFactory publicIpAvailable, CustomImageToVMImage customImagetoVmImage) { this.api = api; this.imagePublishers = Splitter.on(',').trimResults().omitEmptyStrings().splitToList(imagePublishers); this.cleanupResources = cleanupResources; this.regionIds = regionIds; this.publicIpAvailable = publicIpAvailable; - this.resourceGroupMap = resourceGroupMap; this.customImagetoVmImage = customImagetoVmImage; } @@ -138,15 +137,15 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual String locationName = template.getLocation().getId(); Image image = template.getImage(); - String hardwareId = template.getHardware().getId(); - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(locationName); + String hardwareId = fromSlashEncoded(template.getHardware().getId()).name(); // TODO ARM specific options AzureTemplateOptions templateOptions = template.getOptions().as(AzureTemplateOptions.class); String subnetId = templateOptions.getSubnetId(); + String resourceGroupName = templateOptions.getResourceGroup(); IdReference availabilitySet = getAvailabilitySetIdReference(templateOptions.getAvailabilitySet()); StorageProfile storageProfile = createStorageProfile(image, templateOptions.getDataDisks()); - NetworkInterfaceCard nic = createNetworkInterfaceCard(subnetId, name, locationName, resourceGroup.name(), template.getOptions()); + NetworkInterfaceCard nic = createNetworkInterfaceCard(subnetId, name, locationName, resourceGroupName, template.getOptions()); HardwareProfile hardwareProfile = HardwareProfile.builder().vmSize(hardwareId).build(); OSProfile osProfile = createOsProfile(name, template); NetworkProfile networkProfile = NetworkProfile.builder().networkInterfaces(of(IdReference.create(nic.id()))).build(); @@ -165,14 +164,14 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual Map<String, String> metadataAndTags = metadataAndTagsAsCommaDelimitedValue(template.getOptions()); Plan plan = getMarketplacePlanFromImageMetadata(template.getImage()); - VirtualMachine virtualMachine = api.getVirtualMachineApi(resourceGroup.name()).createOrUpdate(name, template.getLocation().getId(), + VirtualMachine virtualMachine = api.getVirtualMachineApi(resourceGroupName).createOrUpdate(name, template.getLocation().getId(), virtualMachineProperties, metadataAndTags, plan); // 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. - RegionAndId regionAndId = RegionAndId.fromRegionAndId(locationName, name); - return new NodeAndInitialCredentials<VirtualMachine>(virtualMachine, regionAndId.slashEncode(), null); + ResourceGroupAndName resourceGroupAndName = fromResourceGroupAndName(resourceGroupName, name); + return new NodeAndInitialCredentials<VirtualMachine>(virtualMachine, resourceGroupAndName.slashEncode(), null); } @Override @@ -183,8 +182,7 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual for (VMSize vmSize : vmSizes) { VMHardware hwProfile = VMHardware .create(vmSize.name(), vmSize.numberOfCores(), vmSize.osDiskSizeInMB(), - vmSize.resourceDiskSizeInMB(), vmSize.memoryInMB(), vmSize.maxDataDiskCount(), location.name(), - false); + vmSize.resourceDiskSizeInMB(), vmSize.memoryInMB(), vmSize.maxDataDiskCount(), location.name()); hwProfiles.add(hwProfile); } } @@ -221,9 +219,8 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual return osImages; } - private List<VMImage> listCustomImagesByLocation(String location) { - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(location); - List<org.jclouds.azurecompute.arm.domain.Image> customImages = api.getVirtualMachineImageApi(resourceGroup.name()).list(); + private List<VMImage> listCustomImagesByResourceGroup(String resourceGroup) { + List<org.jclouds.azurecompute.arm.domain.Image> customImages = api.getVirtualMachineImageApi(resourceGroup).list(); return Lists.transform(customImages, customImagetoVmImage); } @@ -231,16 +228,29 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual public Iterable<VMImage> listImages() { final ImmutableList.Builder<VMImage> osImages = ImmutableList.builder(); - Iterable<String> availableLocationNames = transform(listLocations(), new Function<Location, String>() { - @Override - public String apply(Location location) { - return location.name(); - } - }); + final List<String> availableLocationNames = newArrayList(transform(listLocations(), + new Function<Location, String>() { + @Override + public String apply(Location location) { + return location.name(); + } + })); for (String locationName : availableLocationNames) { osImages.addAll(listImagesByLocation(locationName)); - osImages.addAll(listCustomImagesByLocation(locationName)); + } + + // We need to look for custom images in all resource groups + Iterable<ResourceGroup> resourceGroupsInLocation = filter(api.getResourceGroupApi().list(), + new Predicate<ResourceGroup>() { + @Override + public boolean apply(ResourceGroup input) { + return availableLocationNames.contains(input.location()); + } + }); + + for (ResourceGroup resourceGroup : resourceGroupsInLocation) { + osImages.addAll(listCustomImagesByResourceGroup(resourceGroup.name())); } return osImages.build(); @@ -249,10 +259,10 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual @Override public VMImage getImage(final String id) { VMImage image = decodeFieldsFromUniqueId(id); - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(image.location()); if (image.custom()) { - org.jclouds.azurecompute.arm.domain.Image vmImage = api.getVirtualMachineImageApi(resourceGroup.name()).get(image.name()); + org.jclouds.azurecompute.arm.domain.Image vmImage = api.getVirtualMachineImageApi(image.resourceGroup()).get( + image.name()); return vmImage == null ? null : customImagetoVmImage.apply(vmImage); } @@ -304,9 +314,8 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual @Override public VirtualMachine getNode(final String id) { - RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id); - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(regionAndId.region()); - return api.getVirtualMachineApi(resourceGroup.name()).get(regionAndId.id()); + ResourceGroupAndName resourceGroupAndName = ResourceGroupAndName.fromSlashEncoded(id); + return api.getVirtualMachineApi(resourceGroupAndName.resourceGroup()).get(resourceGroupAndName.name()); } @Override @@ -316,23 +325,20 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual @Override public void rebootNode(final String id) { - RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id); - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(regionAndId.region()); - api.getVirtualMachineApi(resourceGroup.name()).restart(regionAndId.id()); + ResourceGroupAndName resourceGroupAndName = ResourceGroupAndName.fromSlashEncoded(id); + api.getVirtualMachineApi(resourceGroupAndName.resourceGroup()).restart(resourceGroupAndName.name()); } @Override public void resumeNode(final String id) { - RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id); - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(regionAndId.region()); - api.getVirtualMachineApi(resourceGroup.name()).start(regionAndId.id()); + ResourceGroupAndName resourceGroupAndName = ResourceGroupAndName.fromSlashEncoded(id); + api.getVirtualMachineApi(resourceGroupAndName.resourceGroup()).start(resourceGroupAndName.name()); } @Override public void suspendNode(final String id) { - RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id); - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(regionAndId.region()); - api.getVirtualMachineApi(resourceGroup.name()).stop(regionAndId.id()); + ResourceGroupAndName resourceGroupAndName = ResourceGroupAndName.fromSlashEncoded(id); + api.getVirtualMachineApi(resourceGroupAndName.resourceGroup()).stop(resourceGroupAndName.name()); } @Override @@ -346,10 +352,10 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual @Override public Iterable<VirtualMachine> listNodesByIds(final Iterable<String> ids) { - return filter(listNodes(), new Predicate<VirtualMachine>() { + return transform(ids, new Function<String, VirtualMachine>() { @Override - public boolean apply(VirtualMachine virtualMachine) { - return contains(ids, virtualMachine.id()); + public VirtualMachine apply(String input) { + return getNode(input); } }); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java index cf3c90c..11d3ab1 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java @@ -34,7 +34,7 @@ import javax.inject.Singleton; import org.jclouds.azurecompute.arm.AzureComputeApi; import org.jclouds.azurecompute.arm.compute.AzureComputeService; import org.jclouds.azurecompute.arm.compute.AzureComputeServiceAdapter; -import org.jclouds.azurecompute.arm.compute.domain.RegionAndIdAndIngressRules; +import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndNameAndIngressRules; import org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension; import org.jclouds.azurecompute.arm.compute.extensions.AzureComputeSecurityGroupExtension; import org.jclouds.azurecompute.arm.compute.functions.LocationToLocation; @@ -44,9 +44,9 @@ import org.jclouds.azurecompute.arm.compute.functions.VMHardwareToHardware; import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage; import org.jclouds.azurecompute.arm.compute.functions.VirtualMachineToNodeMetadata; import org.jclouds.azurecompute.arm.compute.loaders.CreateSecurityGroupIfNeeded; -import org.jclouds.azurecompute.arm.compute.loaders.ResourceGroupForLocation; +import org.jclouds.azurecompute.arm.compute.loaders.DefaultResourceGroup; import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions; -import org.jclouds.azurecompute.arm.compute.strategy.CreateResourceGroupThenCreateNodes; +import org.jclouds.azurecompute.arm.compute.strategy.CreateResourcesThenCreateNodes; import org.jclouds.azurecompute.arm.domain.Image; import org.jclouds.azurecompute.arm.domain.Location; import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup; @@ -116,12 +116,12 @@ public class AzureComputeServiceContextModule extends bind(TemplateOptions.class).to(AzureTemplateOptions.class); bind(NodeAndTemplateOptionsToStatement.class).to(NodeAndTemplateOptionsToStatementWithoutPublicKey.class); - bind(CreateNodesInGroupThenAddToSet.class).to(CreateResourceGroupThenCreateNodes.class); + bind(CreateNodesInGroupThenAddToSet.class).to(CreateResourcesThenCreateNodes.class); - bind(new TypeLiteral<CacheLoader<RegionAndIdAndIngressRules, String>>() { + bind(new TypeLiteral<CacheLoader<ResourceGroupAndNameAndIngressRules, String>>() { }).to(CreateSecurityGroupIfNeeded.class); bind(new TypeLiteral<CacheLoader<String, ResourceGroup>>() { - }).to(ResourceGroupForLocation.class); + }).to(DefaultResourceGroup.class); bind(new TypeLiteral<ImageExtension>() { }).to(AzureComputeImageExtension.class); @@ -131,14 +131,14 @@ public class AzureComputeServiceContextModule extends @Provides @Singleton - protected final LoadingCache<RegionAndIdAndIngressRules, String> securityGroupMap( - CacheLoader<RegionAndIdAndIngressRules, String> in) { + protected final LoadingCache<ResourceGroupAndNameAndIngressRules, String> securityGroupMap( + CacheLoader<ResourceGroupAndNameAndIngressRules, String> in) { return CacheBuilder.newBuilder().build(in); } @Provides @Singleton - protected final LoadingCache<String, ResourceGroup> resourceGroupMap(CacheLoader<String, ResourceGroup> in) { + protected final LoadingCache<String, ResourceGroup> defaultResourceGroup(CacheLoader<String, ResourceGroup> in) { return CacheBuilder.newBuilder().build(in); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/LocationAndName.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/LocationAndName.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/LocationAndName.java new file mode 100644 index 0000000..0142448 --- /dev/null +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/LocationAndName.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.compute.domain; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.auto.value.AutoValue; +import com.google.common.base.Splitter; +import com.google.common.collect.Iterables; + +@AutoValue +public abstract class LocationAndName { + + public abstract String location(); + public abstract String name(); + + protected LocationAndName() { + + } + + public static LocationAndName fromSlashEncoded(String id) { + Iterable<String> parts = Splitter.on('/').split(checkNotNull(id, "id")); + checkArgument(Iterables.size(parts) == 2, "id must be in format location/name"); + return new AutoValue_LocationAndName(Iterables.get(parts, 0), Iterables.get(parts, 1)); + } + + public static LocationAndName fromLocationAndName(String location, String name) { + return new AutoValue_LocationAndName(location, name); + } + + public String slashEncode() { + return location() + "/" + name(); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/RegionAndIdAndIngressRules.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/RegionAndIdAndIngressRules.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/RegionAndIdAndIngressRules.java deleted file mode 100644 index fa9730d..0000000 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/RegionAndIdAndIngressRules.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jclouds.azurecompute.arm.compute.domain; - -import org.jclouds.azurecompute.arm.domain.RegionAndId; - -import com.google.auto.value.AutoValue; -import com.google.common.base.Objects; - -@AutoValue -public abstract class RegionAndIdAndIngressRules { - - abstract RegionAndId regionAndId(); // Intentionally hidden - public abstract int[] inboundPorts(); - - RegionAndIdAndIngressRules() { - - } - - public static RegionAndIdAndIngressRules create(String region, String id, int[] inboundPorts) { - return new AutoValue_RegionAndIdAndIngressRules(RegionAndId.fromRegionAndId(region, id), inboundPorts); - } - - public String id() { - return regionAndId().id(); - } - - public String region() { - return regionAndId().region(); - } - - // Intentionally delegate equals and hashcode to the fields in the parent - // class so that we can search only by region/id in a map - - @Override - public int hashCode() { - return Objects.hashCode(region(), id()); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof RegionAndId)) { - return false; - } - RegionAndId that = (RegionAndId) obj; - return Objects.equal(region(), that.region()) && Objects.equal(id(), that.id()); - } - -} http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndName.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndName.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndName.java new file mode 100644 index 0000000..c06056e --- /dev/null +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndName.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.compute.domain; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.auto.value.AutoValue; +import com.google.common.base.Splitter; +import com.google.common.collect.Iterables; + +@AutoValue +public abstract class ResourceGroupAndName { + + public abstract String resourceGroup(); + public abstract String name(); + + protected ResourceGroupAndName() { + + } + + public static ResourceGroupAndName fromSlashEncoded(String id) { + Iterable<String> parts = Splitter.on('/').split(checkNotNull(id, "id")); + checkArgument(Iterables.size(parts) == 2, "id must be in format resourcegroup/name"); + return new AutoValue_ResourceGroupAndName(Iterables.get(parts, 0), Iterables.get(parts, 1)); + } + + public static ResourceGroupAndName fromResourceGroupAndName(String resourceGroup, String name) { + return new AutoValue_ResourceGroupAndName(resourceGroup, name); + } + + public String slashEncode() { + return resourceGroup() + "/" + name(); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndNameAndIngressRules.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndNameAndIngressRules.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndNameAndIngressRules.java new file mode 100644 index 0000000..2b07406 --- /dev/null +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndNameAndIngressRules.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.compute.domain; + +import static org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName.fromResourceGroupAndName; + +import com.google.auto.value.AutoValue; +import com.google.common.base.Objects; + +@AutoValue +public abstract class ResourceGroupAndNameAndIngressRules { + + abstract ResourceGroupAndName resourceGroupAndName(); // Intentionally hidden + + public abstract String location(); + + public abstract int[] inboundPorts(); + + ResourceGroupAndNameAndIngressRules() { + + } + + public static ResourceGroupAndNameAndIngressRules create(String resourceGroup, String location, String name, + int[] inboundPorts) { + return new AutoValue_ResourceGroupAndNameAndIngressRules(fromResourceGroupAndName(resourceGroup, name), location, + inboundPorts); + } + + public String name() { + return resourceGroupAndName().name(); + } + + public String resourceGroup() { + return resourceGroupAndName().resourceGroup(); + } + + // Intentionally delegate equals and hashcode to the fields in the parent + // class so that we can search only by region/id in a map + + @Override + public int hashCode() { + return Objects.hashCode(resourceGroup(), name()); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ResourceGroupAndName)) { + return false; + } + ResourceGroupAndName that = (ResourceGroupAndName) obj; + return Objects.equal(resourceGroup(), that.resourceGroup()) && Objects.equal(name(), that.name()); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java index 4bfa449..7d654d5 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java @@ -19,6 +19,7 @@ package org.jclouds.azurecompute.arm.compute.extensions; import static com.google.common.base.Functions.compose; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; +import static org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName.fromSlashEncoded; import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.decodeFieldsFromUniqueId; import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; @@ -32,11 +33,10 @@ import org.jclouds.Constants; import org.jclouds.azurecompute.arm.AzureComputeApi; import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.ImageAvailablePredicateFactory; import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.VirtualMachineInStatePredicateFactory; +import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName; import org.jclouds.azurecompute.arm.compute.functions.CustomImageToVMImage; import org.jclouds.azurecompute.arm.domain.IdReference; import org.jclouds.azurecompute.arm.domain.ImageProperties; -import org.jclouds.azurecompute.arm.domain.RegionAndId; -import org.jclouds.azurecompute.arm.domain.ResourceGroup; import org.jclouds.azurecompute.arm.domain.VMImage; import org.jclouds.azurecompute.arm.domain.VirtualMachine; import org.jclouds.compute.domain.CloneImageTemplate; @@ -49,7 +49,6 @@ import org.jclouds.logging.Logger; import com.google.common.base.Function; import com.google.common.base.Predicate; -import com.google.common.cache.LoadingCache; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Inject; @@ -66,25 +65,21 @@ public class AzureComputeImageExtension implements ImageExtension { private final ListeningExecutorService userExecutor; private final ImageAvailablePredicateFactory imageAvailablePredicate; private final VirtualMachineInStatePredicateFactory nodeSuspendedPredicate; - private final LoadingCache<String, ResourceGroup> resourceGroupMap; private final Function<VMImage, Image> vmImageToImage; private final Predicate<URI> resourceDeleted; private final CustomImageToVMImage customImagetoVmImage; @Inject - AzureComputeImageExtension(AzureComputeApi api, - ImageAvailablePredicateFactory imageAvailablePredicate, + AzureComputeImageExtension(AzureComputeApi api, ImageAvailablePredicateFactory imageAvailablePredicate, @Named(TIMEOUT_NODE_SUSPENDED) VirtualMachineInStatePredicateFactory nodeSuspendedPredicate, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, - Function<VMImage, Image> vmImageToImage, LoadingCache<String, ResourceGroup> resourceGroupMap, - @Named(TIMEOUT_RESOURCE_DELETED) Predicate<URI> resourceDeleted, + Function<VMImage, Image> vmImageToImage, @Named(TIMEOUT_RESOURCE_DELETED) Predicate<URI> resourceDeleted, CustomImageToVMImage customImagetoVmImage) { this.api = api; this.imageAvailablePredicate = imageAvailablePredicate; this.nodeSuspendedPredicate = nodeSuspendedPredicate; this.userExecutor = userExecutor; this.vmImageToImage = vmImageToImage; - this.resourceGroupMap = resourceGroupMap; this.resourceDeleted = resourceDeleted; this.customImagetoVmImage = customImagetoVmImage; } @@ -97,27 +92,27 @@ public class AzureComputeImageExtension implements ImageExtension { @Override public ListenableFuture<Image> createImage(ImageTemplate template) { final CloneImageTemplate cloneTemplate = (CloneImageTemplate) template; - final RegionAndId regionAndId = RegionAndId.fromSlashEncoded(cloneTemplate.getSourceNodeId()); - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(regionAndId.region()); - final String resourceGroupName = resourceGroup.name(); + final ResourceGroupAndName resourceGroupAndName = fromSlashEncoded(cloneTemplate.getSourceNodeId()); + final String resourceGroupName = resourceGroupAndName.resourceGroup(); + final String vmName = resourceGroupAndName.name(); - final VirtualMachine vm = api.getVirtualMachineApi(resourceGroupName).get(regionAndId.id()); + final VirtualMachine vm = api.getVirtualMachineApi(resourceGroupName).get(vmName); final IdReference vmIdRef = IdReference.create(vm.id()); - logger.debug(">> stopping node %s...", regionAndId.slashEncode()); - api.getVirtualMachineApi(resourceGroupName).stop(regionAndId.id()); - checkState(nodeSuspendedPredicate.create(resourceGroupName).apply(regionAndId.id()), - "Node %s was not suspended within the configured time limit", regionAndId.slashEncode()); + logger.debug(">> stopping node %s...", cloneTemplate.getSourceNodeId()); + api.getVirtualMachineApi(resourceGroupName).stop(vmName); + checkState(nodeSuspendedPredicate.create(resourceGroupName).apply(vmName), + "Node %s was not suspended within the configured time limit", cloneTemplate.getSourceNodeId()); return userExecutor.submit(new Callable<Image>() { @Override public Image call() throws Exception { - logger.debug(">> generalizing virtal machine %s...", regionAndId.id()); + logger.debug(">> generalizing virtal machine %s...", vmName); - api.getVirtualMachineApi(resourceGroupName).generalize(regionAndId.id()); + api.getVirtualMachineApi(resourceGroupName).generalize(vmName); org.jclouds.azurecompute.arm.domain.Image imageFromVM = api.getVirtualMachineImageApi(resourceGroupName) - .createOrUpdate(cloneTemplate.getName(), regionAndId.region(), + .createOrUpdate(cloneTemplate.getName(), vm.location(), ImageProperties.builder().sourceVirtualMachine(vmIdRef).build()); checkState(imageAvailablePredicate.create(resourceGroupName).apply(imageFromVM.name()), @@ -134,9 +129,7 @@ public class AzureComputeImageExtension implements ImageExtension { checkArgument(image.custom(), "Only custom images can be deleted"); logger.debug(">> deleting image %s", id); - - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(image.location()); - URI uri = api.getVirtualMachineImageApi(resourceGroup.name()).delete(image.name()); + URI uri = api.getVirtualMachineImageApi(image.resourceGroup()).delete(image.name()); return resourceDeleted.apply(uri); } } http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeSecurityGroupExtension.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeSecurityGroupExtension.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeSecurityGroupExtension.java index f23cfd8..eafb4f1 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeSecurityGroupExtension.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeSecurityGroupExtension.java @@ -20,10 +20,10 @@ import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Predicates.equalTo; import static com.google.common.base.Predicates.notNull; import static com.google.common.collect.Iterables.any; -import static com.google.common.collect.Iterables.concat; 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.compute.predicates.NodePredicates.locationId; import java.net.URI; import java.util.ArrayList; @@ -36,6 +36,7 @@ import javax.inject.Named; import org.jclouds.azurecompute.arm.AzureComputeApi; import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.SecurityGroupAvailablePredicateFactory; +import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName; import org.jclouds.azurecompute.arm.domain.IdReference; import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard; import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup; @@ -45,12 +46,10 @@ import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties; import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties.Access; import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties.Direction; import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties.Protocol; -import org.jclouds.azurecompute.arm.domain.RegionAndId; import org.jclouds.azurecompute.arm.domain.ResourceGroup; import org.jclouds.azurecompute.arm.domain.VirtualMachine; import org.jclouds.azurecompute.arm.features.NetworkSecurityGroupApi; import org.jclouds.azurecompute.arm.features.NetworkSecurityRuleApi; -import org.jclouds.collect.Memoized; import org.jclouds.compute.domain.SecurityGroup; import org.jclouds.compute.domain.SecurityGroupBuilder; import org.jclouds.compute.extensions.SecurityGroupExtension; @@ -63,11 +62,8 @@ import org.jclouds.net.domain.IpProtocol; import com.google.common.base.Function; import com.google.common.base.Objects; import com.google.common.base.Predicate; -import com.google.common.base.Splitter; -import com.google.common.base.Supplier; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; import com.google.common.collect.Ordering; @@ -78,64 +74,67 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio private final AzureComputeApi api; private final Function<NetworkSecurityGroup, SecurityGroup> securityGroupConverter; - private final Supplier<Set<? extends Location>> locations; private final SecurityGroupAvailablePredicateFactory securityGroupAvailable; private final Predicate<URI> resourceDeleted; - private final LoadingCache<String, ResourceGroup> resourceGroupMap; + private final LoadingCache<String, ResourceGroup> defaultResourceGroup; @Inject - AzureComputeSecurityGroupExtension(AzureComputeApi api, @Memoized Supplier<Set<? extends Location>> locations, + AzureComputeSecurityGroupExtension(AzureComputeApi api, Function<NetworkSecurityGroup, SecurityGroup> groupConverter, SecurityGroupAvailablePredicateFactory securityRuleAvailable, @Named(TIMEOUT_RESOURCE_DELETED) Predicate<URI> resourceDeleted, - LoadingCache<String, ResourceGroup> resourceGroupMap) { + LoadingCache<String, ResourceGroup> defaultResourceGroup) { this.api = api; - this.locations = locations; this.securityGroupConverter = groupConverter; this.securityGroupAvailable = securityRuleAvailable; this.resourceDeleted = resourceDeleted; - this.resourceGroupMap = resourceGroupMap; + this.defaultResourceGroup = defaultResourceGroup; } @Override public Set<SecurityGroup> listSecurityGroups() { - return ImmutableSet.copyOf(concat(transform(locations.get(), new Function<Location, Set<SecurityGroup>>() { - @Override - public Set<SecurityGroup> apply(Location input) { - return listSecurityGroupsInLocation(input); - } - }))); + ImmutableSet.Builder<SecurityGroup> securityGroups = ImmutableSet.builder(); + for (ResourceGroup rg : api.getResourceGroupApi().list()) { + securityGroups.addAll(securityGroupsInResourceGroup(rg.name())); + } + return securityGroups.build(); + } + + private Set<SecurityGroup> securityGroupsInResourceGroup(String resourceGroup) { + List<NetworkSecurityGroup> networkGroups = api.getNetworkSecurityGroupApi(resourceGroup).list(); + return ImmutableSet.copyOf(transform(filter(networkGroups, notNull()), securityGroupConverter)); } @Override public Set<SecurityGroup> listSecurityGroupsInLocation(Location location) { - logger.debug(">> getting security groups for %s...", location); - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(location.getId()); - List<NetworkSecurityGroup> networkGroups = api.getNetworkSecurityGroupApi(resourceGroup.name()).list(); - return ImmutableSet.copyOf(transform(filter(networkGroups, notNull()), securityGroupConverter)); + // Even though the resource groups are in a location, each security group + // can be in a different resource group, so we need to inspect all teh + // existing resource groups, and filter afterwards + return ImmutableSet.copyOf(filter(listSecurityGroups(), locationId(location.getId()))); } @Override public Set<SecurityGroup> listSecurityGroupsForNode(String nodeId) { logger.debug(">> getting security groups for node %s...", nodeId); - final RegionAndId regionAndId = RegionAndId.fromSlashEncoded(nodeId); - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(regionAndId.region()); + final ResourceGroupAndName resourceGroupAndName = ResourceGroupAndName.fromSlashEncoded(nodeId); - VirtualMachine vm = api.getVirtualMachineApi(resourceGroup.name()).get(regionAndId.id()); + VirtualMachine vm = api.getVirtualMachineApi(resourceGroupAndName.resourceGroup()).get( + resourceGroupAndName.name()); if (vm == null) { - throw new IllegalArgumentException("Node " + regionAndId.id() + " was not found"); + throw new IllegalArgumentException("Node " + nodeId + " was not found"); } List<IdReference> networkInterfacesIdReferences = vm.properties().networkProfile().networkInterfaces(); List<NetworkSecurityGroup> networkGroups = new ArrayList<NetworkSecurityGroup>(); for (IdReference networkInterfaceCardIdReference : networkInterfacesIdReferences) { - String nicName = Iterables.getLast(Splitter.on("/").split(networkInterfaceCardIdReference.id())); - NetworkInterfaceCard card = api.getNetworkInterfaceCardApi(resourceGroup.name()).get(nicName); + String nicName = networkInterfaceCardIdReference.name(); + String nicResourceGroup = networkInterfaceCardIdReference.resourceGroup(); + NetworkInterfaceCard card = api.getNetworkInterfaceCardApi(nicResourceGroup).get(nicName); if (card != null && card.properties().networkSecurityGroup() != null) { - String secGroupName = Iterables.getLast(Splitter.on("/").split( - card.properties().networkSecurityGroup().id())); - NetworkSecurityGroup group = api.getNetworkSecurityGroupApi(resourceGroup.name()).get(secGroupName); + String secGroupName = card.properties().networkSecurityGroup().name(); + String sgResourceGroup = card.properties().networkSecurityGroup().resourceGroup(); + NetworkSecurityGroup group = api.getNetworkSecurityGroupApi(sgResourceGroup).get(secGroupName); networkGroups.add(group); } } @@ -146,15 +145,15 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio @Override public SecurityGroup getSecurityGroupById(String id) { logger.debug(">> getting security group %s...", id); - final RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id); - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(regionAndId.region()); - NetworkSecurityGroup securityGroup = api.getNetworkSecurityGroupApi(resourceGroup.name()).get(regionAndId.id()); + final ResourceGroupAndName resourceGroupAndName = ResourceGroupAndName.fromSlashEncoded(id); + NetworkSecurityGroup securityGroup = api.getNetworkSecurityGroupApi(resourceGroupAndName.resourceGroup()).get( + resourceGroupAndName.name()); return securityGroup == null ? null : securityGroupConverter.apply(securityGroup); } @Override public SecurityGroup createSecurityGroup(String name, Location location) { - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(location.getId()); + ResourceGroup resourceGroup = defaultResourceGroup.getUnchecked(location.getId()); logger.debug(">> creating security group %s in %s...", name, location); @@ -170,9 +169,9 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio public boolean removeSecurityGroup(String id) { logger.debug(">> deleting security group %s...", id); - final RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id); - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(regionAndId.region()); - URI uri = api.getNetworkSecurityGroupApi(resourceGroup.name()).delete(regionAndId.id()); + final ResourceGroupAndName resourceGroupAndName = ResourceGroupAndName.fromSlashEncoded(id); + URI uri = api.getNetworkSecurityGroupApi(resourceGroupAndName.resourceGroup()) + .delete(resourceGroupAndName.name()); return resourceDeleted.apply(uri); } @@ -199,17 +198,16 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio // TODO: Support Azure network tags somehow? - final RegionAndId regionAndId = RegionAndId.fromSlashEncoded(group.getId()); - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(regionAndId.region()); + final ResourceGroupAndName resourceGroupAndName = ResourceGroupAndName.fromSlashEncoded(group.getId()); - NetworkSecurityGroupApi groupApi = api.getNetworkSecurityGroupApi(resourceGroup.name()); - NetworkSecurityGroup networkSecurityGroup = groupApi.get(regionAndId.id()); + NetworkSecurityGroupApi groupApi = api.getNetworkSecurityGroupApi(resourceGroupAndName.resourceGroup()); + NetworkSecurityGroup networkSecurityGroup = groupApi.get(resourceGroupAndName.name()); if (networkSecurityGroup == null) { throw new IllegalArgumentException("Security group " + group.getName() + " was not found"); } - NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourceGroup.name(), networkSecurityGroup.name()); + NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourceGroupAndName.resourceGroup(), networkSecurityGroup.name()); int nextPriority = getRuleStartingPriority(networkSecurityGroup); for (String ipRange : ipRanges) { @@ -228,7 +226,8 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio ruleApi.createOrUpdate(ruleName, properties); - checkState(securityGroupAvailable.create(resourceGroup.name()).apply(networkSecurityGroup.name()), + checkState( + securityGroupAvailable.create(resourceGroupAndName.resourceGroup()).apply(networkSecurityGroup.name()), "Security group was not updated in the configured timeout"); } @@ -244,17 +243,17 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio logger.debug(">> deleting ip permissions matching [%s] from %s...", ruleName, group.getName()); - final RegionAndId regionAndId = RegionAndId.fromSlashEncoded(group.getId()); - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(regionAndId.region()); + final ResourceGroupAndName resourceGroupAndName = ResourceGroupAndName.fromSlashEncoded(group.getId()); - NetworkSecurityGroupApi groupApi = api.getNetworkSecurityGroupApi(resourceGroup.name()); - NetworkSecurityGroup networkSecurityGroup = groupApi.get(regionAndId.id()); + NetworkSecurityGroupApi groupApi = api.getNetworkSecurityGroupApi(resourceGroupAndName.resourceGroup()); + NetworkSecurityGroup networkSecurityGroup = groupApi.get(resourceGroupAndName.name()); if (networkSecurityGroup == null) { throw new IllegalArgumentException("Security group " + group.getName() + " was not found"); } - NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourceGroup.name(), networkSecurityGroup.name()); + NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourceGroupAndName.resourceGroup(), + networkSecurityGroup.name()); Iterable<NetworkSecurityRule> rules = filter(ruleApi.list(), new Predicate<NetworkSecurityRule>() { @Override public boolean apply(NetworkSecurityRule input) { @@ -270,7 +269,8 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio for (NetworkSecurityRule matchingRule : rules) { logger.debug(">> deleting network security rule %s from %s...", matchingRule.name(), group.getName()); ruleApi.delete(matchingRule.name()); - checkState(securityGroupAvailable.create(resourceGroup.name()).apply(networkSecurityGroup.name()), + checkState( + securityGroupAvailable.create(resourceGroupAndName.resourceGroup()).apply(networkSecurityGroup.name()), "Security group was not updated in the configured timeout"); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/CustomImageToVMImage.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/CustomImageToVMImage.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/CustomImageToVMImage.java index 9cb2188..2220535 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/CustomImageToVMImage.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/CustomImageToVMImage.java @@ -16,6 +16,8 @@ */ package org.jclouds.azurecompute.arm.compute.functions; +import static org.jclouds.azurecompute.arm.domain.IdReference.extractResourceGroup; + import org.jclouds.azurecompute.arm.domain.Image; import org.jclouds.azurecompute.arm.domain.VMImage; @@ -25,7 +27,7 @@ public class CustomImageToVMImage implements Function<Image, VMImage> { @Override public VMImage apply(Image input) { - return VMImage.customImage().customImageId(input.id()).location(input.location()).name(input.name()) + return VMImage.customImage().resourceGroup(extractResourceGroup(input.id())).customImageId(input.id()).location(input.location()).name(input.name()) .offer(input.properties().storageProfile().osDisk().osType()).build(); } } http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/NetworkSecurityGroupToSecurityGroup.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/NetworkSecurityGroupToSecurityGroup.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/NetworkSecurityGroupToSecurityGroup.java index 65f5b0d..71d51aa 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/NetworkSecurityGroupToSecurityGroup.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/NetworkSecurityGroupToSecurityGroup.java @@ -18,8 +18,10 @@ package org.jclouds.azurecompute.arm.compute.functions; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.transform; +import static org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName.fromResourceGroupAndName; import static org.jclouds.azurecompute.arm.compute.functions.NetworkSecurityRuleToIpPermission.InboundRule; import static org.jclouds.azurecompute.arm.compute.functions.VirtualMachineToNodeMetadata.getLocation; +import static org.jclouds.azurecompute.arm.domain.IdReference.extractResourceGroup; import java.util.Set; @@ -27,7 +29,6 @@ import javax.inject.Singleton; import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup; import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule; -import org.jclouds.azurecompute.arm.domain.RegionAndId; import org.jclouds.collect.Memoized; import org.jclouds.compute.domain.SecurityGroup; import org.jclouds.compute.domain.SecurityGroupBuilder; @@ -54,8 +55,8 @@ public class NetworkSecurityGroupToSecurityGroup implements Function<NetworkSecu public SecurityGroup apply(NetworkSecurityGroup input) { SecurityGroupBuilder builder = new SecurityGroupBuilder(); - builder.id(RegionAndId.fromRegionAndId(input.location(), input.name()).slashEncode()); - builder.providerId(input.properties().resourceGuid()); + builder.id(fromResourceGroupAndName(extractResourceGroup(input.id()), input.name()).slashEncode()); + builder.providerId(input.id()); builder.name(input.name()); builder.location(getLocation(locations, input.location())); http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/TemplateToAvailabilitySet.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/TemplateToAvailabilitySet.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/TemplateToAvailabilitySet.java index 2732b6e..7359ace 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/TemplateToAvailabilitySet.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/TemplateToAvailabilitySet.java @@ -29,14 +29,12 @@ import javax.inject.Singleton; import org.jclouds.azurecompute.arm.AzureComputeApi; import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions; import org.jclouds.azurecompute.arm.domain.AvailabilitySet; -import org.jclouds.azurecompute.arm.domain.ResourceGroup; import org.jclouds.compute.domain.Template; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.javax.annotation.Nullable; import org.jclouds.logging.Logger; import com.google.common.base.Function; -import com.google.common.cache.LoadingCache; @Singleton public class TemplateToAvailabilitySet implements Function<Template, AvailabilitySet> { @@ -46,12 +44,10 @@ public class TemplateToAvailabilitySet implements Function<Template, Availabilit protected Logger logger = Logger.NULL; private final AzureComputeApi api; - private final LoadingCache<String, ResourceGroup> resourceGroupMap; @Inject - TemplateToAvailabilitySet(AzureComputeApi api, LoadingCache<String, ResourceGroup> resourceGroupMap) { + TemplateToAvailabilitySet(AzureComputeApi api) { this.api = api; - this.resourceGroupMap = resourceGroupMap; } @Nullable @@ -62,7 +58,7 @@ public class TemplateToAvailabilitySet implements Function<Template, Availabilit AvailabilitySet availabilitySet = null; String location = input.getLocation().getId(); - String resourceGroup = resourceGroupMap.getUnchecked(location).name(); + String resourceGroup = options.getResourceGroup(); if (options.getAvailabilitySetName() != null) { availabilitySet = api.getAvailabilitySetApi(resourceGroup).get(options.getAvailabilitySetName()); http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMHardwareToHardware.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMHardwareToHardware.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMHardwareToHardware.java index 5303e25..d877aba 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMHardwareToHardware.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMHardwareToHardware.java @@ -16,9 +16,10 @@ */ package org.jclouds.azurecompute.arm.compute.functions; -import com.google.common.base.Supplier; -import com.google.common.collect.FluentIterable; -import com.google.inject.Inject; +import static org.jclouds.azurecompute.arm.compute.domain.LocationAndName.fromLocationAndName; + +import java.util.Set; + import org.jclouds.azurecompute.arm.domain.VMHardware; import org.jclouds.collect.Memoized; import org.jclouds.compute.domain.Hardware; @@ -26,14 +27,15 @@ import org.jclouds.compute.domain.HardwareBuilder; import org.jclouds.compute.domain.Processor; import org.jclouds.compute.domain.Volume; import org.jclouds.compute.domain.VolumeBuilder; +import org.jclouds.domain.Location; +import org.jclouds.location.predicates.LocationPredicates; import com.google.common.base.Function; +import com.google.common.base.Supplier; +import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import org.jclouds.domain.Location; -import org.jclouds.location.predicates.LocationPredicates; - -import java.util.Set; +import com.google.inject.Inject; public class VMHardwareToHardware implements Function<VMHardware, Hardware> { @@ -49,10 +51,10 @@ public class VMHardwareToHardware implements Function<VMHardware, Hardware> { final HardwareBuilder builder = new HardwareBuilder() .name(from.name()) .providerId(from.name()) - .id(from.name()) + .id(fromLocationAndName(from.location(), from.name()).slashEncode()) .processors(ImmutableList.of(new Processor(from.numberOfCores(), 2))) .ram(from.memoryInMB()) - .location(from.globallyAvailable() ? null : FluentIterable.from(locations.get()) + .location(FluentIterable.from(locations.get()) .firstMatch(LocationPredicates.idEquals(from.location())) .get()); http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java index 4f02100..2a5075c 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java @@ -16,6 +16,12 @@ */ package org.jclouds.azurecompute.arm.compute.functions; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.tryFind; +import static java.util.Arrays.asList; +import static org.jclouds.azurecompute.arm.domain.IdReference.extractResourceGroup; +import static org.jclouds.azurecompute.arm.util.VMImages.isCustom; + import java.util.Map; import java.util.Set; @@ -40,11 +46,6 @@ import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableMap; import com.google.inject.Inject; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.Iterables.tryFind; -import static java.util.Arrays.asList; -import static org.jclouds.azurecompute.arm.util.VMImages.isCustom; - public class VMImageToImage implements Function<VMImage, Image> { private static final Map<String, OsFamily> OTHER_OS_MAP = ImmutableMap.<String, OsFamily> builder() @@ -64,8 +65,8 @@ public class VMImageToImage implements Function<VMImage, Image> { public static String encodeFieldsToUniqueIdCustom(boolean globallyAvailable, String locationName, ImageReference imageReference) { - return (globallyAvailable ? "global" : locationName) + "/" + imageReference.customImageId() - .substring(imageReference.customImageId().lastIndexOf("/") + 1); + return extractResourceGroup(imageReference.customImageId()) + "/" + (globallyAvailable ? "global" : locationName) + + "/" + imageReference.customImageId().substring(imageReference.customImageId().lastIndexOf("/") + 1); } public static String encodeFieldsToUniqueId(VMImage imageReference) { @@ -74,7 +75,8 @@ public class VMImageToImage implements Function<VMImage, Image> { } public static String encodeFieldsToUniqueIdCustom(VMImage imageReference) { - return (imageReference.globallyAvailable() ? "global" : imageReference.location()) + "/" + imageReference.name(); + return imageReference.resourceGroup() + "/" + + (imageReference.globallyAvailable() ? "global" : imageReference.location()) + "/" + imageReference.name(); } public static VMImage decodeFieldsFromUniqueId(final String id) { @@ -82,10 +84,11 @@ public class VMImageToImage implements Function<VMImage, Image> { String[] fields = checkNotNull(id, "id").split("/"); if (isCustom(id)) { /* id fields indexes - 0: imageReference.location + "/" + - 1: imageReference.name + 0: imageReference.resourceGroup + 1: imageReference.location + "/" + + 2: imageReference.name */ - vmImage = VMImage.customImage().location(fields[0]).name(fields[1]).build(); + vmImage = VMImage.customImage().resourceGroup(fields[0]).location(fields[1]).name(fields[2]).build(); } else { /* id fields indexes 0: imageReference.location + "/" + http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java index 9bad6e5..bcfd4fe 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java @@ -20,8 +20,11 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Strings.nullToEmpty; import static com.google.common.collect.Iterables.find; import static org.jclouds.azurecompute.arm.compute.AzureComputeServiceAdapter.GROUP_KEY; +import static org.jclouds.azurecompute.arm.compute.domain.LocationAndName.fromLocationAndName; +import static org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName.fromResourceGroupAndName; import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.encodeFieldsToUniqueId; import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.encodeFieldsToUniqueIdCustom; +import static org.jclouds.azurecompute.arm.domain.IdReference.extractResourceGroup; import static org.jclouds.compute.util.ComputeServiceUtils.addMetadataAndParseTagsFromCommaDelimitedValue; import static org.jclouds.location.predicates.LocationPredicates.idEquals; @@ -34,13 +37,12 @@ import javax.inject.Inject; import javax.inject.Named; import org.jclouds.azurecompute.arm.AzureComputeApi; +import org.jclouds.azurecompute.arm.compute.domain.LocationAndName; import org.jclouds.azurecompute.arm.compute.functions.VirtualMachineToStatus.StatusAndBackendStatus; 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.PublicIPAddress; -import org.jclouds.azurecompute.arm.domain.RegionAndId; -import org.jclouds.azurecompute.arm.domain.ResourceGroup; import org.jclouds.azurecompute.arm.domain.StorageProfile; import org.jclouds.azurecompute.arm.domain.VirtualMachine; import org.jclouds.collect.Memoized; @@ -58,10 +60,7 @@ import org.jclouds.logging.Logger; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Predicate; -import com.google.common.base.Splitter; import com.google.common.base.Supplier; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.Iterables; import com.google.common.collect.Lists; public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, NodeMetadata> { @@ -74,20 +73,18 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No private final GroupNamingConvention nodeNamingConvention; private final Supplier<Set<? extends Location>> locations; private final Supplier<Map<String, ? extends Hardware>> hardwares; - private final LoadingCache<String, ResourceGroup> resourceGroupMap; private final ImageCacheSupplier imageCache; private final VirtualMachineToStatus virtualMachineToStatus; @Inject VirtualMachineToNodeMetadata(AzureComputeApi api, GroupNamingConvention.Factory namingConvention, Supplier<Map<String, ? extends Hardware>> hardwares, @Memoized Supplier<Set<? extends Location>> locations, - Map<String, Credentials> credentialStore, LoadingCache<String, ResourceGroup> resourceGroupMap, - @Memoized Supplier<Set<? extends Image>> imageCache, VirtualMachineToStatus virtualMachineToStatus) { + Map<String, Credentials> credentialStore, @Memoized Supplier<Set<? extends Image>> imageCache, + VirtualMachineToStatus virtualMachineToStatus) { this.api = api; this.nodeNamingConvention = namingConvention.createWithoutPrefix(); this.locations = locations; this.hardwares = hardwares; - this.resourceGroupMap = resourceGroupMap; this.virtualMachineToStatus = virtualMachineToStatus; checkArgument(imageCache instanceof ImageCacheSupplier, "This provider needs an instance of the ImageCacheSupplier"); @@ -96,10 +93,9 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No @Override public NodeMetadata apply(VirtualMachine virtualMachine) { - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(virtualMachine.location()); - NodeMetadataBuilder builder = new NodeMetadataBuilder(); - builder.id(RegionAndId.fromRegionAndId(virtualMachine.location(), virtualMachine.name()).slashEncode()); + builder.id(fromResourceGroupAndName(extractResourceGroup(virtualMachine.id()), virtualMachine.name()) + .slashEncode()); builder.providerId(virtualMachine.id()); builder.name(virtualMachine.name()); builder.hostname(virtualMachine.name()); @@ -125,8 +121,7 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No String locationName = virtualMachine.location(); builder.location(getLocation(locations, locationName)); - Optional<? extends Image> image = findImage(virtualMachine.properties().storageProfile(), locationName, - resourceGroup.name()); + Optional<? extends Image> image = findImage(virtualMachine.properties().storageProfile(), locationName); if (image.isPresent()) { builder.imageId(image.get().getId()); @@ -137,7 +132,8 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No virtualMachine.id(), virtualMachine.id()); } - builder.hardware(getHardware(virtualMachine.properties().hardwareProfile().vmSize())); + builder.hardware(getHardware(fromLocationAndName(virtualMachine.location(), virtualMachine.properties() + .hardwareProfile().vmSize()))); return builder.build(); } @@ -158,12 +154,8 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No return privateIpAddresses; } - private NetworkInterfaceCard getNetworkInterfaceCard(IdReference networkInterfaceCardIdReference) { - Iterables.get(Splitter.on("/").split(networkInterfaceCardIdReference.id()), 2); - 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 NetworkInterfaceCard getNetworkInterfaceCard(IdReference nic) { + return api.getNetworkInterfaceCardApi(nic.resourceGroup()).get(nic.name()); } private Iterable<String> getPublicIpAddresses(List<IdReference> idReferences) { @@ -172,11 +164,11 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No NetworkInterfaceCard networkInterfaceCard = getNetworkInterfaceCard(networkInterfaceCardIdReference); if (networkInterfaceCard != null && networkInterfaceCard.properties() != null && networkInterfaceCard.properties().ipConfigurations() != null) { - String resourceGroup = Iterables.get(Splitter.on("/").split(networkInterfaceCardIdReference.id()), 4); + String resourceGroup = networkInterfaceCardIdReference.resourceGroup(); for (IpConfiguration ipConfiguration : networkInterfaceCard.properties().ipConfigurations()) { if (ipConfiguration.properties().publicIPAddress() != null) { - String publicIpId = ipConfiguration.properties().publicIPAddress().id(); - PublicIPAddress publicIp = api.getPublicIPAddressApi(resourceGroup).get(Iterables.getLast(Splitter.on("/").split(publicIpId))); + IdReference publicIpId = ipConfiguration.properties().publicIPAddress(); + PublicIPAddress publicIp = api.getPublicIPAddressApi(resourceGroup).get(publicIpId.name()); if (publicIp != null && publicIp.properties().ipAddress() != null) { publicIpAddresses.add(publicIp.properties().ipAddress()); } @@ -191,8 +183,7 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No return find(locations.get(), idEquals(nullToEmpty(locationName)), null); } - protected Optional<? extends Image> findImage(final StorageProfile storageProfile, String locatioName, - String azureGroup) { + protected Optional<? extends Image> findImage(final StorageProfile storageProfile, String locatioName) { if (storageProfile.imageReference() != null) { // FIXME check this condition String imageId = storageProfile.imageReference().customImageId() != null ? @@ -205,11 +196,12 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No } } - protected Hardware getHardware(final String vmSize) { - return Iterables.find(hardwares.get().values(), new Predicate<Hardware>() { + protected Hardware getHardware(final LocationAndName hardwareId) { + final String slashEncoded = hardwareId.slashEncode(); + return find(hardwares.get().values(), new Predicate<Hardware>() { @Override public boolean apply(Hardware input) { - return input.getId().equals(vmSize); + return input.getId().equals(slashEncoded); } }); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/83c0a3c7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToStatus.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToStatus.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToStatus.java index c0e333e..9669f50 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToStatus.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToStatus.java @@ -17,13 +17,13 @@ package org.jclouds.azurecompute.arm.compute.functions; import static com.google.common.collect.Iterables.transform; +import static org.jclouds.azurecompute.arm.domain.IdReference.extractResourceGroup; import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.azurecompute.arm.AzureComputeApi; import org.jclouds.azurecompute.arm.compute.functions.VirtualMachineToStatus.StatusAndBackendStatus; -import org.jclouds.azurecompute.arm.domain.ResourceGroup; import org.jclouds.azurecompute.arm.domain.Status; import org.jclouds.azurecompute.arm.domain.VirtualMachine; import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance; @@ -36,7 +36,6 @@ import com.google.auto.value.AutoValue; import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.base.Joiner; -import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMap; @Singleton @@ -80,17 +79,15 @@ public class VirtualMachineToStatus implements Function<VirtualMachine, StatusAn NodeMetadata.Status.UNRECOGNIZED); private final AzureComputeApi api; - private final LoadingCache<String, ResourceGroup> resourceGroupMap; @Inject - VirtualMachineToStatus(AzureComputeApi api, LoadingCache<String, ResourceGroup> resourceGroupMap) { + VirtualMachineToStatus(AzureComputeApi api) { this.api = api; - this.resourceGroupMap = resourceGroupMap; } @Override public StatusAndBackendStatus apply(VirtualMachine virtualMachine) { - ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(virtualMachine.location()); + String resourceGroup = extractResourceGroup(virtualMachine.id()); ProvisioningState provisioningState = virtualMachine.properties().provisioningState(); NodeMetadata.Status status = PROVISIONINGSTATE_TO_NODESTATUS.apply(provisioningState); @@ -99,7 +96,7 @@ public class VirtualMachineToStatus implements Function<VirtualMachine, StatusAn if (ProvisioningState.SUCCEEDED.equals(provisioningState)) { // If the provisioning succeeded, we need to query the *real* status of // the VM - VirtualMachineInstance instanceDetails = api.getVirtualMachineApi(resourceGroup.name()).getInstanceDetails( + VirtualMachineInstance instanceDetails = api.getVirtualMachineApi(resourceGroup).getInstanceDetails( virtualMachine.name()); if (instanceDetails != null && instanceDetails.powerState() != null) { status = POWERSTATE_TO_NODESTATUS.apply(instanceDetails.powerState());
