diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/EC2AsyncClient.java b/apis/ec2/src/main/java/org/jclouds/ec2/EC2AsyncClient.java index b35b176d6a..4d775e5319 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/EC2AsyncClient.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/EC2AsyncClient.java @@ -25,8 +25,6 @@ import org.jclouds.ec2.services.ElasticBlockStoreAsyncClient; import org.jclouds.ec2.services.ElasticIPAddressAsyncClient; import org.jclouds.ec2.services.InstanceAsyncClient; import org.jclouds.ec2.services.KeyPairAsyncClient; -import org.jclouds.ec2.services.MonitoringAsyncClient; -import org.jclouds.ec2.services.PlacementGroupAsyncClient; import org.jclouds.ec2.services.SecurityGroupAsyncClient; import org.jclouds.ec2.services.WindowsAsyncClient; import org.jclouds.rest.annotations.Delegate; @@ -69,18 +67,6 @@ public interface EC2AsyncClient { @Delegate SecurityGroupAsyncClient getSecurityGroupServices(); - /** - * Provides asynchronous access to PlacementGroup services. - */ - @Delegate - PlacementGroupAsyncClient getPlacementGroupServices(); - - /** - * Provides asynchronous access to Monitoring services. - */ - @Delegate - MonitoringAsyncClient getMonitoringServices(); - /** * Provides asynchronous access to Windows services. */ diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/EC2Client.java b/apis/ec2/src/main/java/org/jclouds/ec2/EC2Client.java index f02e5cf528..d7f7e175e2 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/EC2Client.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/EC2Client.java @@ -21,17 +21,15 @@ package org.jclouds.ec2; import java.util.concurrent.TimeUnit; +import org.jclouds.concurrent.Timeout; import org.jclouds.ec2.services.AMIClient; import org.jclouds.ec2.services.AvailabilityZoneAndRegionClient; import org.jclouds.ec2.services.ElasticBlockStoreClient; import org.jclouds.ec2.services.ElasticIPAddressClient; import org.jclouds.ec2.services.InstanceClient; import org.jclouds.ec2.services.KeyPairClient; -import org.jclouds.ec2.services.MonitoringClient; -import org.jclouds.ec2.services.PlacementGroupClient; import org.jclouds.ec2.services.SecurityGroupClient; import org.jclouds.ec2.services.WindowsClient; -import org.jclouds.concurrent.Timeout; import org.jclouds.rest.annotations.Delegate; /** @@ -71,18 +69,6 @@ public interface EC2Client { @Delegate SecurityGroupClient getSecurityGroupServices(); - /** - * Provides synchronous access to PlacementGroup services. - */ - @Delegate - PlacementGroupClient getPlacementGroupServices(); - - /** - * Provides synchronous access to Monitoring services. - */ - @Delegate - MonitoringClient getMonitoringServices(); - /** * Provides asynchronous access to Windows services. */ diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/EC2ContextBuilder.java b/apis/ec2/src/main/java/org/jclouds/ec2/EC2ContextBuilder.java index 1237e31c11..8a4c5f32e9 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/EC2ContextBuilder.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/EC2ContextBuilder.java @@ -63,7 +63,7 @@ public class EC2ContextBuilder extends ComputeServiceContextBuilder modules) { - modules.add(new EC2RestClientModule()); + modules.add(EC2RestClientModule.create()); } @Override diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/EC2PropertiesBuilder.java b/apis/ec2/src/main/java/org/jclouds/ec2/EC2PropertiesBuilder.java index 21433ebd5f..03d60f595d 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/EC2PropertiesBuilder.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/EC2PropertiesBuilder.java @@ -24,7 +24,6 @@ import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG; import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; -import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs; import java.util.Properties; @@ -44,7 +43,6 @@ public class EC2PropertiesBuilder extends PropertiesBuilder { properties.setProperty(PROPERTY_ENDPOINT, "https://ec2.us-east-1.amazonaws.com"); properties.setProperty(PROPERTY_API_VERSION, EC2AsyncClient.VERSION); properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "*"); - properties.setProperty(PROPERTY_EC2_CC_AMIs, ""); return properties; } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindBlockDeviceMappingToIndexedFormParams.java b/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindBlockDeviceMappingToIndexedFormParams.java index 044cf0bdbe..8d558c79ca 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindBlockDeviceMappingToIndexedFormParams.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindBlockDeviceMappingToIndexedFormParams.java @@ -45,10 +45,10 @@ public class BindBlockDeviceMappingToIndexedFormParams implements Binder { private static final String volumeIdPattern = "BlockDeviceMapping.%d.Ebs.VolumeId"; private static final String deleteOnTerminationPattern = "BlockDeviceMapping.%d.Ebs.DeleteOnTermination"; + @SuppressWarnings("unchecked") @Override public R bindToRequest(R request, Object input) { checkArgument(checkNotNull(input, "input") instanceof Map, "this binder is only valid for Map"); - @SuppressWarnings("unchecked") Map blockDeviceMapping = (Map) input; com.google.common.collect.ImmutableMap.Builder builder = ImmutableMap. builder(); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java index 3481944a91..2e5af2b371 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java @@ -19,8 +19,6 @@ package org.jclouds.ec2.compute; -import static com.google.common.base.Preconditions.checkState; - import java.util.Map; import java.util.Set; import java.util.Map.Entry; @@ -32,7 +30,6 @@ import javax.inject.Provider; import javax.inject.Singleton; import org.jclouds.Constants; -import org.jclouds.aws.AWSResponseException; import org.jclouds.aws.util.AWSUtils; import org.jclouds.collect.Memoized; import org.jclouds.compute.ComputeServiceContext; @@ -58,9 +55,6 @@ import org.jclouds.ec2.compute.domain.RegionAndName; import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules; import org.jclouds.ec2.compute.options.EC2TemplateOptions; import org.jclouds.ec2.domain.KeyPair; -import org.jclouds.ec2.domain.PlacementGroup; -import org.jclouds.ec2.domain.PlacementGroup.State; -import org.jclouds.http.HttpResponseException; import org.jclouds.util.Preconditions2; import com.google.common.annotations.VisibleForTesting; @@ -76,8 +70,6 @@ public class EC2ComputeService extends BaseComputeService { private final EC2Client ec2Client; private final Map credentialsMap; private final Map securityGroupMap; - private final Map placementGroupMap; - private final Predicate placementGroupDeleted; @Inject protected EC2ComputeService(ComputeServiceContext context, Map credentialStore, @@ -92,9 +84,7 @@ public class EC2ComputeService extends BaseComputeService { @Named("NODE_SUSPENDED") Predicate nodeSuspended, InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client, - Map credentialsMap, @Named("SECURITY") Map securityGroupMap, - @Named("PLACEMENT") Map placementGroupMap, - @Named("DELETED") Predicate placementGroupDeleted) { + Map credentialsMap, @Named("SECURITY") Map securityGroupMap) { super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, @@ -102,38 +92,7 @@ public class EC2ComputeService extends BaseComputeService { this.ec2Client = ec2Client; this.credentialsMap = credentialsMap; this.securityGroupMap = securityGroupMap; - this.placementGroupMap = placementGroupMap; - this.placementGroupDeleted = placementGroupDeleted; - } - @VisibleForTesting - void deletePlacementGroup(String region, String tag) { - Preconditions2.checkNotEmpty(tag, "tag"); - String group = String.format("jclouds#%s#%s", tag, region); - try { - if (ec2Client.getPlacementGroupServices().describePlacementGroupsInRegion(region, group).size() > 0) { - logger.debug(">> deleting placementGroup(%s)", group); - try { - ec2Client.getPlacementGroupServices().deletePlacementGroupInRegion(region, group); - checkState(placementGroupDeleted.apply(new PlacementGroup(region, group, "cluster", State.PENDING)), - String.format("placementGroup region(%s) name(%s) failed to delete", region, group)); - placementGroupMap.remove(new RegionAndName(region, group)); - logger.debug("<< deleted placementGroup(%s)", group); - } catch (AWSResponseException e) { - if (e.getError().getCode().equals("InvalidPlacementGroup.InUse")) { - logger.debug("<< inUse placementGroup(%s)", group); - } else { - throw e; - } - } - } - } catch (UnsupportedOperationException e) { - } catch (HttpResponseException e) { - // Eucalyptus does not support placement groups yet. - if (!(e.getResponse().getStatusCode() == 400 && context.getProviderSpecificContext().getProvider().equals( - "eucalyptus"))) - throw e; - } } @VisibleForTesting @@ -142,10 +101,14 @@ public class EC2ComputeService extends BaseComputeService { String group = String.format("jclouds#%s#%s", tag, region); if (ec2Client.getSecurityGroupServices().describeSecurityGroupsInRegion(region, group).size() > 0) { logger.debug(">> deleting securityGroup(%s)", group); - ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(region, group); - // TODO: test this clear happens - securityGroupMap.remove(new RegionNameAndIngressRules(region, group, null, false)); - logger.debug("<< deleted securityGroup(%s)", group); + try { + ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(region, group); + // TODO: test this clear happens + securityGroupMap.remove(new RegionNameAndIngressRules(region, group, null, false)); + logger.debug("<< deleted securityGroup(%s)", group); + } catch (IllegalStateException e) { + logger.debug("<< inUse securityGroup(%s)", group); + } } } @@ -175,13 +138,16 @@ public class EC2ComputeService extends BaseComputeService { regionTags.put(AWSUtils.parseHandle(nodeMetadata.getId())[0], nodeMetadata.getTag()); } for (Entry regionTag : regionTags.entrySet()) { - deleteKeyPair(regionTag.getKey(), regionTag.getValue()); - deleteSecurityGroup(regionTag.getKey(), regionTag.getValue()); - deletePlacementGroup(regionTag.getKey(), regionTag.getValue()); + cleanUpIncidentalResources(regionTag); } return deadOnes; } + protected void cleanUpIncidentalResources(Entry regionTag) { + deleteKeyPair(regionTag.getKey(), regionTag.getValue()); + deleteSecurityGroup(regionTag.getKey(), regionTag.getValue()); + } + /** * returns template options, except of type {@link EC2TemplateOptions}. */ diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java index 5f6d312820..dc545e3a52 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java @@ -45,11 +45,15 @@ import com.google.inject.Provides; public class EC2ComputeServiceContextModule extends BaseComputeServiceContextModule { @Override protected void configure() { - install(new EC2ComputeServiceDependenciesModule()); + installDependencies(); install(new EC2BindComputeStrategiesByClass()); install(new EC2BindComputeSuppliersByClass()); super.configure(); } + + protected void installDependencies(){ + install(new EC2ComputeServiceDependenciesModule()); + } @Provides @Singleton diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java index 175270982a..6d17a4dddc 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java @@ -22,7 +22,6 @@ package org.jclouds.ec2.compute.config; import static com.google.common.collect.Iterables.toArray; import static com.google.common.collect.Maps.newLinkedHashMap; import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; -import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs; import java.security.SecureRandom; import java.util.Map; @@ -31,25 +30,6 @@ import java.util.concurrent.TimeUnit; import javax.inject.Named; import javax.inject.Singleton; -import org.jclouds.ec2.EC2AsyncClient; -import org.jclouds.ec2.EC2Client; -import org.jclouds.ec2.compute.EC2ComputeService; -import org.jclouds.ec2.compute.domain.RegionAndName; -import org.jclouds.ec2.compute.functions.CreatePlacementGroupIfNeeded; -import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; -import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; -import org.jclouds.ec2.compute.functions.CredentialsForInstance; -import org.jclouds.ec2.compute.functions.RegionAndIdToImage; -import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata; -import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl; -import org.jclouds.ec2.compute.options.EC2TemplateOptions; -import org.jclouds.ec2.domain.InstanceState; -import org.jclouds.ec2.domain.KeyPair; -import org.jclouds.ec2.domain.PlacementGroup; -import org.jclouds.ec2.domain.RunningInstance; -import org.jclouds.ec2.predicates.InstancePresent; -import org.jclouds.ec2.predicates.PlacementGroupAvailable; -import org.jclouds.ec2.predicates.PlacementGroupDeleted; import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.domain.Image; @@ -59,6 +39,21 @@ import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.options.TemplateOptions; import org.jclouds.domain.Credentials; +import org.jclouds.ec2.EC2AsyncClient; +import org.jclouds.ec2.EC2Client; +import org.jclouds.ec2.compute.EC2ComputeService; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; +import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; +import org.jclouds.ec2.compute.functions.CredentialsForInstance; +import org.jclouds.ec2.compute.functions.RegionAndIdToImage; +import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata; +import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.domain.InstanceState; +import org.jclouds.ec2.domain.KeyPair; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.predicates.InstancePresent; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.rest.RestContext; import org.jclouds.rest.internal.RestContextImpl; @@ -100,20 +95,6 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule { return new RetryablePredicate(present, 5000, 200, TimeUnit.MILLISECONDS); } - @Provides - @Singleton - @Named("AVAILABLE") - protected Predicate placementGroupAvailable(PlacementGroupAvailable available) { - return new RetryablePredicate(available, 60, 1, TimeUnit.SECONDS); - } - - @Provides - @Singleton - @Named("DELETED") - protected Predicate placementGroupDeleted(PlacementGroupDeleted deleted) { - return new RetryablePredicate(deleted, 60, 1, TimeUnit.SECONDS); - } - @Override protected void configure() { bind(TemplateBuilder.class).to(EC2TemplateBuilderImpl.class); @@ -162,14 +143,6 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule { return newLinkedHashMap(); } - @Provides - @Singleton - @Named("PLACEMENT") - protected final Map placementGroupMap(CreatePlacementGroupIfNeeded in) { - // doesn't seem to clear when someone issues remove(key) - // return new MapMaker().makeComputingMap(in); - return newLinkedHashMap(); - } @Provides @Singleton @@ -180,14 +153,6 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule { return toArray(Splitter.on(',').split(amiOwners), String.class); } - @Provides - @Singleton - @Named(PROPERTY_EC2_CC_AMIs) - String[] ccAmis(@Named(PROPERTY_EC2_CC_AMIs) String ccAmis) { - if (ccAmis.trim().equals("")) - return new String[] {}; - return toArray(Splitter.on(',').split(ccAmis), String.class); - } @Provides @Singleton diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/internal/EC2TemplateBuilderImpl.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/internal/EC2TemplateBuilderImpl.java index 05da0cff62..ae2e275150 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/internal/EC2TemplateBuilderImpl.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/internal/EC2TemplateBuilderImpl.java @@ -71,11 +71,6 @@ public class EC2TemplateBuilderImpl extends TemplateBuilderImpl { eTo.keyPair(eFrom.getKeyPair()); if (!eFrom.shouldAutomaticallyCreateKeyPair()) eTo.noKeyPair(); - if (eFrom.getSubnetId() != null) - eTo.subnetId(eFrom.getSubnetId()); - eTo.blockDeviceMappings(eFrom.getBlockDeviceMappings()); - if (eFrom.isMonitoringEnabled()) - eTo.enableMonitoring(); if (eFrom.getUserData() != null) eTo.userData(eFrom.getUserData()); } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/options/EC2TemplateOptions.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/options/EC2TemplateOptions.java index be4932c2d4..f776c2c14d 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/options/EC2TemplateOptions.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/options/EC2TemplateOptions.java @@ -65,10 +65,6 @@ public class EC2TemplateOptions extends TemplateOptions { private Set groupIds = ImmutableSet.of(); private String keyPair = null; private boolean noKeyPair; - private boolean monitoringEnabled; - private String placementGroup = null; - private boolean noPlacementGroup; - private String subnetId; private byte[] userData; private Set blockDeviceMappings = ImmutableSet.of(); @@ -93,22 +89,12 @@ public class EC2TemplateOptions extends TemplateOptions { return this; } - /** - * Enable Cloudwatch monitoring - * - * @see CloudWatchClient - */ - public EC2TemplateOptions enableMonitoring() { - this.monitoringEnabled = true; - return this; - } - /** * Unencoded data */ public EC2TemplateOptions userData(byte[] unencodedData) { checkArgument(checkNotNull(unencodedData, "unencodedData").length <= 16 * 1024, - "userData cannot be larger than 16kb"); + "userData cannot be larger than 16kb"); this.userData = unencodedData; return this; } @@ -133,41 +119,11 @@ public class EC2TemplateOptions extends TemplateOptions { return this; } - /** - * Specifies the keypair used to run instances with - */ - public EC2TemplateOptions placementGroup(String placementGroup) { - checkNotNull(placementGroup, "use noPlacementGroup option to request boot without a keypair"); - checkState(!noPlacementGroup, "you cannot specify both options placementGroup and noPlacementGroup"); - Preconditions2.checkNotEmpty(placementGroup, "placementGroup must be non-empty"); - this.placementGroup = placementGroup; - return this; - } - - /** - * Do not use a keypair on instances - */ - public EC2TemplateOptions noPlacementGroup() { - checkState(placementGroup == null, "you cannot specify both options placementGroup and noPlacementGroup"); - this.noPlacementGroup = true; - return this; - } - - /** - * Specifies the subnetId used to run instances in - */ - public EC2TemplateOptions subnetId(String subnetId) { - checkNotNull(subnetId, "subnetId cannot be null"); - Preconditions2.checkNotEmpty(subnetId, "subnetId must be non-empty"); - this.subnetId = subnetId; - return this; - } - /** * Specifies the block device mappings to be used to run the instance */ public EC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId, - @Nullable Integer sizeInGib, @Nullable Boolean deleteOnTermination) { + @Nullable Integer sizeInGib, @Nullable Boolean deleteOnTermination) { checkNotNull(deviceName, "deviceName cannot be null"); Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty"); checkNotNull(snapshotId, "snapshotId cannot be null"); @@ -175,7 +131,7 @@ public class EC2TemplateOptions extends TemplateOptions { Set mappings = new HashSet(); mappings.addAll(blockDeviceMappings); MapEBSSnapshotToDevice mapping = new MapEBSSnapshotToDevice(deviceName, snapshotId, sizeInGib, - deleteOnTermination); + deleteOnTermination); mappings.add(mapping); blockDeviceMappings = ImmutableSet.copyOf(mappings); return this; @@ -185,7 +141,7 @@ public class EC2TemplateOptions extends TemplateOptions { * Specifies the block device mappings to be used to run the instance */ public EC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, Integer sizeInGib, - @Nullable Boolean deleteOnTermination) { + @Nullable Boolean deleteOnTermination) { checkNotNull(deviceName, "deviceName cannot be null"); Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty"); checkNotNull(sizeInGib, "sizeInGib cannot be null"); @@ -280,30 +236,6 @@ public class EC2TemplateOptions extends TemplateOptions { return EC2TemplateOptions.class.cast(options.noKeyPair()); } - /** - * @see EC2TemplateOptions#placementGroup - */ - public static EC2TemplateOptions placementGroup(String placementGroup) { - EC2TemplateOptions options = new EC2TemplateOptions(); - return EC2TemplateOptions.class.cast(options.placementGroup(placementGroup)); - } - - /** - * @see EC2TemplateOptions#noPlacementGroup - */ - public static EC2TemplateOptions noPlacementGroup() { - EC2TemplateOptions options = new EC2TemplateOptions(); - return EC2TemplateOptions.class.cast(options.noPlacementGroup()); - } - - /** - * @see EC2TemplateOptions#enableMonitoring - */ - public static EC2TemplateOptions enableMonitoring() { - EC2TemplateOptions options = new EC2TemplateOptions(); - return EC2TemplateOptions.class.cast(options.enableMonitoring()); - } - // methods that only facilitate returning the correct object type /** * @see TemplateOptions#inboundPorts @@ -353,13 +285,6 @@ public class EC2TemplateOptions extends TemplateOptions { return EC2TemplateOptions.class.cast(options.withMetadata()); } - /** - * @see TemplateOptions#withSubnetId - */ - public static EC2TemplateOptions subnetId(String subnetId) { - EC2TemplateOptions options = new EC2TemplateOptions(); - return EC2TemplateOptions.class.cast(options.subnetId(subnetId)); - } } // methods that only facilitate returning the correct object type @@ -509,34 +434,6 @@ public class EC2TemplateOptions extends TemplateOptions { return !noKeyPair; } - /** - * @return placementGroup to use when running the instance or null, to generate a placementGroup. - */ - public String getPlacementGroup() { - return placementGroup; - } - - /** - * @return true (default) if we are supposed to use a placementGroup - */ - public boolean shouldAutomaticallyCreatePlacementGroup() { - return !noPlacementGroup; - } - - /** - * @return true (default) if we are supposed to enable cloudwatch - */ - public boolean isMonitoringEnabled() { - return monitoringEnabled; - } - - /** - * @return subnetId to use when running the instance or null. - */ - public String getSubnetId() { - return subnetId; - } - /** * @return unencoded user data. */ @@ -559,11 +456,7 @@ public class EC2TemplateOptions extends TemplateOptions { result = prime * result + ((blockDeviceMappings == null) ? 0 : blockDeviceMappings.hashCode()); result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode()); result = prime * result + ((keyPair == null) ? 0 : keyPair.hashCode()); - result = prime * result + (monitoringEnabled ? 1231 : 1237); result = prime * result + (noKeyPair ? 1231 : 1237); - result = prime * result + (noPlacementGroup ? 1231 : 1237); - result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode()); - result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode()); result = prime * result + Arrays.hashCode(userData); return result; } @@ -592,22 +485,7 @@ public class EC2TemplateOptions extends TemplateOptions { return false; } else if (!keyPair.equals(other.keyPair)) return false; - if (monitoringEnabled != other.monitoringEnabled) - return false; - if (noKeyPair != other.noKeyPair) - return false; - if (noPlacementGroup != other.noPlacementGroup) - return false; - if (placementGroup == null) { - if (other.placementGroup != null) - return false; - } else if (!placementGroup.equals(other.placementGroup)) - return false; - if (subnetId == null) { - if (other.subnetId != null) - return false; - } else if (!subnetId.equals(other.subnetId)) - return false; + if (!Arrays.equals(userData, other.userData)) return false; @@ -618,9 +496,6 @@ public class EC2TemplateOptions extends TemplateOptions { public String toString() { return "EC2TemplateOptions [groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair - + ", monitoringEnabled=" + monitoringEnabled + ", placementGroup=" + placementGroup + ", noPlacementGroup=" - + noPlacementGroup + ", subnetId=" + subnetId + ", userData=" + Arrays.toString(userData) - + ", blockDeviceMappings=" + blockDeviceMappings + "]"; + + ", userData=" + Arrays.toString(userData) + ", blockDeviceMappings=" + blockDeviceMappings + "]"; } - } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java similarity index 56% rename from apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java rename to apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java index 6da51f0e16..835dbd4973 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java @@ -20,7 +20,6 @@ package org.jclouds.ec2.compute.strategy; import static com.google.common.base.Preconditions.checkState; -import static org.jclouds.ec2.options.RunInstancesOptions.Builder.asType; import java.util.Map; import java.util.Set; @@ -34,14 +33,12 @@ import org.jclouds.compute.domain.Template; import org.jclouds.compute.options.TemplateOptions; import org.jclouds.ec2.compute.domain.RegionAndName; import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules; -import org.jclouds.ec2.compute.functions.CreatePlacementGroupIfNeeded; import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; import org.jclouds.ec2.compute.options.EC2TemplateOptions; import org.jclouds.ec2.domain.BlockDeviceMapping; import org.jclouds.ec2.domain.KeyPair; import org.jclouds.ec2.options.RunInstancesOptions; -import org.jclouds.location.Provider; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Sets; @@ -51,90 +48,70 @@ import com.google.common.collect.Sets; * @author Adrian Cole */ @Singleton -public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions { +public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions { + @VisibleForTesting - final String provider; + public final Map credentialsMap; @VisibleForTesting - final Map credentialsMap; + public final Map securityGroupMap; @VisibleForTesting - final Map securityGroupMap; + public final CreateUniqueKeyPair createUniqueKeyPair; @VisibleForTesting - final Map placementGroupMap; - @VisibleForTesting - final CreateUniqueKeyPair createUniqueKeyPair; - @VisibleForTesting - final CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded; - @VisibleForTesting - final CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded; + public final CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded; + private final javax.inject.Provider optionsProvider; @Inject - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions(@Provider String provider, - Map credentialsMap, @Named("SECURITY") Map securityGroupMap, - @Named("PLACEMENT") Map placementGroupMap, CreateUniqueKeyPair createUniqueKeyPair, - CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded, - CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded) { - this.provider = provider; + public CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(Map credentialsMap, + @Named("SECURITY") Map securityGroupMap, CreateUniqueKeyPair createUniqueKeyPair, + CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded, + javax.inject.Provider optionsProvider) { this.credentialsMap = credentialsMap; this.securityGroupMap = securityGroupMap; - this.placementGroupMap = placementGroupMap; this.createUniqueKeyPair = createUniqueKeyPair; this.createSecurityGroupIfNeeded = createSecurityGroupIfNeeded; - this.createPlacementGroupIfNeeded = createPlacementGroupIfNeeded; - } - - // this method only exists so that we can mock - String getProvider() { - return provider; + this.optionsProvider = optionsProvider; } public RunInstancesOptions execute(String region, String tag, Template template) { - RunInstancesOptions instanceOptions = asType(template.getHardware().getId()); + RunInstancesOptions instanceOptions = getOptionsProvider().get().asType(template.getHardware().getId()); String keyPairName = createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, template.getOptions()); - String placementGroupName = template.getHardware().getId().startsWith("cc") ? createNewPlacementGroupUnlessUserSpecifiedOtherwise( - region, tag, template.getOptions()) : null; - - String subnetId = EC2TemplateOptions.class.cast(template.getOptions()).getSubnetId(); - - if (subnetId != null) { - instanceOptions.withSubnetId(subnetId); - } else { - Set groups = getSecurityGroupsForTagAndOptions(region, tag, template.getOptions()); - instanceOptions.withSecurityGroups(groups); - } + addSecurityGroups(region, tag, template, instanceOptions); if (keyPairName != null) instanceOptions.withKeyName(keyPairName); - if (placementGroupName != null) - instanceOptions.inPlacementGroup(placementGroupName); - byte[] userData = EC2TemplateOptions.class.cast(template.getOptions()).getUserData(); if (userData != null) instanceOptions.withUserData(userData); Set blockDeviceMappings = EC2TemplateOptions.class.cast(template.getOptions()) - .getBlockDeviceMappings(); + .getBlockDeviceMappings(); if (blockDeviceMappings != null && blockDeviceMappings.size() > 0) { checkState("ebs".equals(template.getImage().getUserMetadata().get("rootDeviceType")), - "BlockDeviceMapping only available on ebs boot"); + "BlockDeviceMapping only available on ebs boot"); instanceOptions.withBlockDeviceMappings(blockDeviceMappings); } return instanceOptions; } + protected void addSecurityGroups(String region, String tag, Template template, RunInstancesOptions instanceOptions) { + Set groups = getSecurityGroupsForTagAndOptions(region, tag, template.getOptions()); + instanceOptions.withSecurityGroups(groups); + } + @VisibleForTesting - String createNewKeyPairUnlessUserSpecifiedOtherwise(String region, String tag, TemplateOptions options) { + public String createNewKeyPairUnlessUserSpecifiedOtherwise(String region, String tag, TemplateOptions options) { String keyPairName = null; boolean shouldAutomaticallyCreateKeyPair = true; if (options instanceof EC2TemplateOptions) { keyPairName = EC2TemplateOptions.class.cast(options).getKeyPair(); if (keyPairName == null) shouldAutomaticallyCreateKeyPair = EC2TemplateOptions.class.cast(options) - .shouldAutomaticallyCreateKeyPair(); + .shouldAutomaticallyCreateKeyPair(); } if (keyPairName == null && shouldAutomaticallyCreateKeyPair) { RegionAndName regionAndName = new RegionAndName(region, tag); @@ -152,27 +129,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions } @VisibleForTesting - String createNewPlacementGroupUnlessUserSpecifiedOtherwise(String region, String tag, TemplateOptions options) { - String placementGroupName = null; - boolean shouldAutomaticallyCreatePlacementGroup = true; - if (options instanceof EC2TemplateOptions) { - placementGroupName = EC2TemplateOptions.class.cast(options).getPlacementGroup(); - if (placementGroupName == null) - shouldAutomaticallyCreatePlacementGroup = EC2TemplateOptions.class.cast(options) - .shouldAutomaticallyCreatePlacementGroup(); - } - if (placementGroupName == null && shouldAutomaticallyCreatePlacementGroup) { - placementGroupName = String.format("jclouds#%s#%s", tag, region); - RegionAndName regionAndName = new RegionAndName(region, placementGroupName); - if (!placementGroupMap.containsKey(regionAndName)) { - placementGroupMap.put(regionAndName, createPlacementGroupIfNeeded.apply(regionAndName)); - } - } - return placementGroupName; - } - - @VisibleForTesting - Set getSecurityGroupsForTagAndOptions(String region, @Nullable String tag, TemplateOptions options) { + public Set getSecurityGroupsForTagAndOptions(String region, @Nullable String tag, TemplateOptions options) { Set groups = Sets.newLinkedHashSet(); if (tag != null) { @@ -183,19 +140,25 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions if (options instanceof EC2TemplateOptions && EC2TemplateOptions.class.cast(options).getGroupIds().size() > 0) { regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, new int[] {}, - false); + false); groups.addAll(EC2TemplateOptions.class.cast(options).getGroupIds()); } else { - regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, - options.getInboundPorts(), true); + regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, options + .getInboundPorts(), true); } if (!securityGroupMap.containsKey(regionNameAndIngessRulesForMarkerGroup)) { - securityGroupMap.put(regionNameAndIngessRulesForMarkerGroup, - createSecurityGroupIfNeeded.apply(regionNameAndIngessRulesForMarkerGroup)); + securityGroupMap.put(regionNameAndIngessRulesForMarkerGroup, createSecurityGroupIfNeeded + .apply(regionNameAndIngessRulesForMarkerGroup)); } } return groups; } + + // allows us to mock this method + @VisibleForTesting + public javax.inject.Provider getOptionsProvider() { + return optionsProvider; + } } \ No newline at end of file diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java index 6c2efe2617..73d6585cee 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java @@ -81,12 +81,13 @@ public class EC2ListNodesStrategy implements ListNodesStrategy { @Override public Set listDetailsOnNodesMatching(Predicate filter) { - Iterable>> reservations = transformParallel( + Iterable>> reservations = transformParallel( regions, new Function>>>() { + @SuppressWarnings("unchecked") @Override public Future>> apply(String from) { - return client.getInstanceServices().describeInstancesInRegion(from); + return (Future>>) client.getInstanceServices().describeInstancesInRegion(from); } }, executor, null, logger, "reservations"); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategy.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategy.java index 6d44e28fe2..edde764f99 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategy.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategy.java @@ -42,8 +42,6 @@ import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; import org.jclouds.compute.util.ComputeUtils; import org.jclouds.domain.Credentials; import org.jclouds.ec2.EC2Client; -import org.jclouds.ec2.compute.options.EC2TemplateOptions; -import org.jclouds.ec2.domain.Reservation; import org.jclouds.ec2.domain.RunningInstance; import org.jclouds.ec2.options.RunInstancesOptions; import org.jclouds.logging.Logger; @@ -52,6 +50,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; @@ -70,7 +69,7 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate @VisibleForTesting final EC2Client client; @VisibleForTesting - final CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize; + final CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize; @VisibleForTesting final Function runningInstanceToNodeMetadata; @VisibleForTesting @@ -82,7 +81,7 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate @Inject EC2RunNodesAndAddToSetStrategy( EC2Client client, - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize, + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize, @Named("PRESENT") Predicate instancePresent, Function runningInstanceToNodeMetadata, Function instanceToCredentials, Map credentialStore, @@ -100,33 +99,38 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate public Map> execute(String tag, int count, Template template, Set goodNodes, Map badNodes, Multimap customizationResponses) { - Reservation reservation = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(tag, - count, template); - - Iterable ids = transform(reservation, instanceToId); + Iterable started = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(tag, count, + template); + Iterable ids = transform(started, instanceToId); String idsString = Joiner.on(',').join(ids); if (Iterables.size(ids) > 0) { logger.debug("<< started instances(%s)", idsString); - all(reservation, instancePresent); + all(started, instancePresent); logger.debug("<< present instances(%s)", idsString); - populateCredentials(reservation); + populateCredentials(started); } - return utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(template.getOptions(), transform(reservation, + return utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(template.getOptions(), transform(started, runningInstanceToNodeMetadata), goodNodes, badNodes, customizationResponses); } - protected void populateCredentials(Reservation reservation) { - RunningInstance instance1 = Iterables.get(reservation, 0); - Credentials credentials = instanceToCredentials.apply(instance1); + protected void populateCredentials(Iterable started) { + Credentials credentials = null; + for (RunningInstance instance : started) { + credentials = instanceToCredentials.apply(instance); + if (credentials != null) + break; + } if (credentials != null) - for (RunningInstance instance : reservation) + for (RunningInstance instance : started) credentialStore.put("node#" + instance.getRegion() + "/" + instance.getId(), credentials); + } + // TODO write test for this @VisibleForTesting - Reservation createKeyPairAndSecurityGroupsAsNeededThenRunInstances(String tag, int count, + Iterable createKeyPairAndSecurityGroupsAsNeededThenRunInstances(String tag, int count, Template template) { String region = AWSUtils.getRegionFromLocationOrNull(template.getLocation()); String zone = getZoneFromLocationOrNull(template.getLocation()); @@ -134,15 +138,23 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate RunInstancesOptions instanceOptions = createKeyPairAndSecurityGroupsAsNeededAndReturncustomize.execute(region, tag, template); - if (EC2TemplateOptions.class.cast(template.getOptions()).isMonitoringEnabled()) - instanceOptions.enableMonitoring(); + int countStarted = 0; + int tries = 0; + Iterable started = ImmutableSet. of(); - if (logger.isDebugEnabled()) - logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count, region, zone, template - .getImage().getProviderId(), instanceOptions.buildFormParameters()); + while (countStarted < count && tries++ < count) { + if (logger.isDebugEnabled()) + logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count - countStarted, region, + zone, template.getImage().getProviderId(), instanceOptions.buildFormParameters()); - return client.getInstanceServices().runInstancesInRegion(region, zone, template.getImage().getProviderId(), 1, - count, instanceOptions); + started = Iterables.concat(started, client.getInstanceServices().runInstancesInRegion(region, zone, + template.getImage().getProviderId(), 1, count - countStarted, instanceOptions)); + + countStarted = Iterables.size(started); + if (countStarted < count) + logger.debug(">> not enough instances (%d/%d) started, attempting again", countStarted, count); + } + return started; } } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/EC2HardwareSupplier.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/EC2HardwareSupplier.java index 8f9608149c..8e79dca5eb 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/EC2HardwareSupplier.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/EC2HardwareSupplier.java @@ -19,37 +19,19 @@ package org.jclouds.ec2.compute.suppliers; -import static com.google.common.collect.Iterables.find; -import static com.google.common.collect.Sets.newLinkedHashSet; +import static org.jclouds.compute.predicates.ImagePredicates.any; import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_medium; import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_xlarge; -import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.cc1_4xlarge; import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_large; import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_small; import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_xlarge; -import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_2xlarge; -import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_4xlarge; -import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_xlarge; -import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.t1_micro; -import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs; -import static org.jclouds.compute.predicates.ImagePredicates.any; import java.util.Set; -import javax.annotation.Resource; -import javax.inject.Inject; -import javax.inject.Named; import javax.inject.Singleton; -import org.jclouds.collect.Memoized; import org.jclouds.compute.domain.Hardware; -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; -import org.jclouds.location.Provider; -import org.jclouds.logging.Logger; -import com.google.common.base.Predicate; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableSet; @@ -59,41 +41,10 @@ import com.google.common.collect.ImmutableSet; */ @Singleton public class EC2HardwareSupplier implements Supplier> { - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - private final Supplier> locations; - private final String[] ccAmis; - private final String providerName; - - @Inject - EC2HardwareSupplier(@Memoized Supplier> locations, @Provider String providerName, - @Named(PROPERTY_EC2_CC_AMIs) String[] ccAmis) { - this.locations = locations; - this.ccAmis = ccAmis; - this.providerName = providerName; - } @Override public Set get() { - Set sizes = newLinkedHashSet(); - for (String ccAmi : ccAmis) { - final String region = ccAmi.split("/")[0]; - Location location = find(locations.get(), new Predicate() { - - @Override - public boolean apply(Location input) { - return input.getScope() == LocationScope.REGION && input.getId().equals(region); - } - - }); - sizes.add(cc1_4xlarge().location(location).supportsImageIds(ccAmi).build()); - } - // TODO move logic to dependent module - sizes.addAll(ImmutableSet. of(t1_micro().build(), c1_medium().build(), c1_xlarge().build(), m1_large() - .build(), - !"aws-ec2".equals(providerName) ? m1_small().supportsImage(any()).build() : m1_small().build(), - m1_xlarge().build(), m2_xlarge().build(), m2_2xlarge().build(), m2_4xlarge().build())); - return sizes; + return ImmutableSet. of(m1_small().supportsImage(any()).build(), c1_medium().build(), c1_xlarge() + .build(), m1_large().build(), m1_xlarge().build()); } } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/RegionAndNameToImageSupplier.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/RegionAndNameToImageSupplier.java index c1df66b9ff..423894b6a6 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/RegionAndNameToImageSupplier.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/RegionAndNameToImageSupplier.java @@ -38,31 +38,27 @@ package org.jclouds.ec2.compute.suppliers; * ==================================================================== */ -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 com.google.common.collect.Maps.newLinkedHashMap; import static com.google.common.collect.Maps.uniqueIndex; -import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.imageIds; import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.ownedBy; import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; -import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; +import java.util.Map.Entry; import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.ec2.compute.domain.RegionAndName; import org.jclouds.ec2.compute.functions.EC2ImageParser; import org.jclouds.ec2.compute.strategy.DescribeImagesParallel; import org.jclouds.ec2.options.DescribeImagesOptions; -import org.jclouds.compute.domain.Image; -import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.location.Region; import org.jclouds.logging.Logger; @@ -84,18 +80,15 @@ public class RegionAndNameToImageSupplier implements Supplier regions; private final DescribeImagesParallel describer; - private final String[] ccAmis; private final String[] amiOwners; private final EC2ImageParser parser; private final Map images; @Inject - RegionAndNameToImageSupplier(@Region Set regions, DescribeImagesParallel describer, - @Named(PROPERTY_EC2_CC_AMIs) String[] ccAmis, @Named(PROPERTY_EC2_AMI_OWNERS) final String[] amiOwners, - final EC2ImageParser parser, final Map images) { + protected RegionAndNameToImageSupplier(@Region Set regions, DescribeImagesParallel describer, + @Named(PROPERTY_EC2_AMI_OWNERS) String[] amiOwners, EC2ImageParser parser, Map images) { this.regions = regions; this.describer = describer; - this.ccAmis = ccAmis; this.amiOwners = amiOwners; this.parser = parser; this.images = images; @@ -108,12 +101,11 @@ public class RegionAndNameToImageSupplier implements Supplier> providing images"); - Iterable> queries = concat( - getDescribeQueriesForOwnersInRegions(regions, amiOwners).entrySet(), ccAmisToDescribeQueries(ccAmis) - .entrySet()); + Iterable> queries = getDescribeQueriesForOwnersInRegions(regions, + amiOwners); - Iterable parsedImages = filter(transform(describer.apply(queries), parser), - Predicates.notNull()); + Iterable parsedImages = filter(transform(describer.apply(queries), parser), Predicates + .notNull()); images.putAll(uniqueIndex(parsedImages, new Function() { @@ -129,24 +121,16 @@ public class RegionAndNameToImageSupplier implements Supplier ccAmisToDescribeQueries(String[] ccAmis) { - Map queries = newLinkedHashMap(); - for (String from : ccAmis) { - queries.put(from.split("/")[0], imageIds(from.split("/")[1])); - } - return queries; - } - - private static Map getDescribeQueriesForOwnersInRegions(Set regions, - final String[] amiOwners) { - final DescribeImagesOptions options = getOptionsForOwners(amiOwners); + public Iterable> getDescribeQueriesForOwnersInRegions(Set regions, + String[] amiOwners) { + DescribeImagesOptions options = getOptionsForOwners(amiOwners); Builder builder = ImmutableMap. builder(); for (String region : regions) builder.put(region, options); - return builder.build(); + return builder.build().entrySet(); } - private static DescribeImagesOptions getOptionsForOwners(final String[] amiOwners) { + public static DescribeImagesOptions getOptionsForOwners(String[] amiOwners) { final DescribeImagesOptions options; if (amiOwners.length == 1 && amiOwners[0].equals("*")) options = new DescribeImagesOptions(); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/config/EC2RestClientModule.java b/apis/ec2/src/main/java/org/jclouds/ec2/config/EC2RestClientModule.java index 5ab839e40f..2bc635a9db 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/config/EC2RestClientModule.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/config/EC2RestClientModule.java @@ -42,10 +42,6 @@ import org.jclouds.ec2.services.InstanceAsyncClient; import org.jclouds.ec2.services.InstanceClient; import org.jclouds.ec2.services.KeyPairAsyncClient; import org.jclouds.ec2.services.KeyPairClient; -import org.jclouds.ec2.services.MonitoringAsyncClient; -import org.jclouds.ec2.services.MonitoringClient; -import org.jclouds.ec2.services.PlacementGroupAsyncClient; -import org.jclouds.ec2.services.PlacementGroupClient; import org.jclouds.ec2.services.SecurityGroupAsyncClient; import org.jclouds.ec2.services.SecurityGroupClient; import org.jclouds.ec2.services.WindowsAsyncClient; @@ -65,23 +61,26 @@ import com.google.common.collect.ImmutableMap.Builder; */ @RequiresHttp @ConfiguresRestClient -public class EC2RestClientModule extends WithZonesFormSigningRestClientModule { +public class EC2RestClientModule extends + WithZonesFormSigningRestClientModule { public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class> builder()// - .put(AMIClient.class, AMIAsyncClient.class)// - .put(ElasticIPAddressClient.class, ElasticIPAddressAsyncClient.class)// - .put(InstanceClient.class, InstanceAsyncClient.class)// - .put(KeyPairClient.class, KeyPairAsyncClient.class)// - .put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)// - .put(PlacementGroupClient.class, PlacementGroupAsyncClient.class)// - .put(MonitoringClient.class, MonitoringAsyncClient.class)// - .put(WindowsClient.class, WindowsAsyncClient.class)// - .put(AvailabilityZoneAndRegionClient.class, AvailabilityZoneAndRegionAsyncClient.class)// - .put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)// - .build(); + .put(AMIClient.class, AMIAsyncClient.class)// + .put(ElasticIPAddressClient.class, ElasticIPAddressAsyncClient.class)// + .put(InstanceClient.class, InstanceAsyncClient.class)// + .put(KeyPairClient.class, KeyPairAsyncClient.class)// + .put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)// + .put(WindowsClient.class, WindowsAsyncClient.class)// + .put(AvailabilityZoneAndRegionClient.class, AvailabilityZoneAndRegionAsyncClient.class)// + .put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)// + .build(); - public EC2RestClientModule() { - super(EC2Client.class, EC2AsyncClient.class, DELEGATE_MAP); + public static EC2RestClientModule create() { + return new EC2RestClientModule(EC2Client.class, EC2AsyncClient.class, DELEGATE_MAP); + } + + public EC2RestClientModule(Class sync, Class async, Map, Class> delegateMap) { + super(sync, async, delegateMap); } @Override @@ -111,6 +110,7 @@ public class EC2RestClientModule extends WithZonesFormSigningRestClientModule> { private final AvailabilityZoneAndRegionClient client; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/Reservation.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/Reservation.java index fa41f67da9..03f982704b 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/Reservation.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/domain/Reservation.java @@ -42,15 +42,15 @@ public class Reservation extends LinkedHashSet imp private static final long serialVersionUID = -9051777593518861395L; private final String region; private final Set groupIds = Sets.newLinkedHashSet(); - private final @Nullable - String ownerId; - private final @Nullable - String requesterId; - private final @Nullable - String reservationId; + @Nullable + private final String ownerId; + @Nullable + private final String requesterId; + @Nullable + private final String reservationId; - public Reservation(String region, Iterable groupIds, Iterable instances, - @Nullable String ownerId, @Nullable String requesterId, @Nullable String reservationId) { + public Reservation(String region, Iterable groupIds, Iterable instances, @Nullable String ownerId, + @Nullable String requesterId, @Nullable String reservationId) { this.region = checkNotNull(region, "region"); Iterables.addAll(this.groupIds, checkNotNull(groupIds, "groupIds")); Iterables.addAll(this, checkNotNull(instances, "instances")); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/RunningInstance.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/RunningInstance.java index 645de2b7b9..020c2e975f 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/RunningInstance.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/domain/RunningInstance.java @@ -27,8 +27,8 @@ import java.util.Set; import javax.annotation.Nullable; - -import com.google.common.collect.Iterables; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -40,64 +40,221 @@ import com.google.common.collect.Sets; */ public class RunningInstance implements Comparable { - private final String region; - private final Set groupIds = Sets.newLinkedHashSet(); + public static class Builder { + protected String region; + protected Set groupIds = Sets.newLinkedHashSet(); + protected String amiLaunchIndex; + protected String dnsName; + protected String imageId; + protected String instanceId; + protected InstanceState instanceState; + protected String instanceType; + protected String ipAddress; + protected String kernelId; + protected String keyName; + protected Date launchTime; + protected String availabilityZone; + protected String virtualizationType = "paravirtual"; + protected String platform; + protected String privateDnsName; + protected String privateIpAddress; + protected String ramdiskId; + protected String reason; + protected RootDeviceType rootDeviceType = RootDeviceType.INSTANCE_STORE; + protected String rootDeviceName; + protected Map ebsBlockDevices = Maps.newLinkedHashMap(); - private final String amiLaunchIndex; + public Builder region(String region) { + this.region = region; + return this; + } + + public Builder groupIds(Iterable groupIds) { + this.groupIds = ImmutableSet.copyOf(checkNotNull(groupIds, "groupIds")); + return this; + } + + public Builder groupId(String groupId) { + if (groupId != null) + this.groupIds.add(groupId); + return this; + } + + public Builder amiLaunchIndex(String amiLaunchIndex) { + this.amiLaunchIndex = amiLaunchIndex; + return this; + } + + public Builder dnsName(String dnsName) { + this.dnsName = dnsName; + return this; + } + + public Builder imageId(String imageId) { + this.imageId = imageId; + return this; + } + + public Builder instanceId(String instanceId) { + this.instanceId = instanceId; + return this; + } + + public Builder instanceState(InstanceState instanceState) { + this.instanceState = instanceState; + return this; + } + + public Builder instanceType(String instanceType) { + this.instanceType = instanceType; + return this; + } + + public Builder ipAddress(String ipAddress) { + this.ipAddress = ipAddress; + return this; + } + + public Builder kernelId(String kernelId) { + this.kernelId = kernelId; + return this; + } + + public Builder keyName(String keyName) { + this.keyName = keyName; + return this; + } + + public Builder launchTime(Date launchTime) { + this.launchTime = launchTime; + return this; + } + + public Builder availabilityZone(String availabilityZone) { + this.availabilityZone = availabilityZone; + return this; + } + + public Builder virtualizationType(String virtualizationType) { + this.virtualizationType = virtualizationType; + return this; + } + + public Builder platform(String platform) { + this.platform = platform; + return this; + } + + public Builder privateDnsName(String privateDnsName) { + this.privateDnsName = privateDnsName; + return this; + } + + public Builder privateIpAddress(String privateIpAddress) { + this.privateIpAddress = privateIpAddress; + return this; + } + + public Builder ramdiskId(String ramdiskId) { + this.ramdiskId = ramdiskId; + return this; + } + + public Builder reason(String reason) { + this.reason = reason; + return this; + } + + public Builder rootDeviceType(RootDeviceType rootDeviceType) { + this.rootDeviceType = rootDeviceType; + return this; + } + + public Builder rootDeviceName(String rootDeviceName) { + this.rootDeviceName = rootDeviceName; + return this; + } + + public Builder devices(Map ebsBlockDevices) { + this.ebsBlockDevices = ImmutableMap.copyOf(checkNotNull(ebsBlockDevices, "ebsBlockDevices")); + return this; + } + + public Builder device(String key, BlockDevice value) { + if (key != null && value != null) + this.ebsBlockDevices.put(key, value); + return this; + } + + public RunningInstance build() { + return new RunningInstance(region, groupIds, amiLaunchIndex, dnsName, imageId, instanceId, instanceState, + instanceType, ipAddress, kernelId, keyName, launchTime, availabilityZone, virtualizationType, + platform, privateDnsName, privateIpAddress, ramdiskId, reason, rootDeviceType, rootDeviceName, + ebsBlockDevices); + } + + public String getDnsName() { + return dnsName; + } + + public String getIpAddress() { + return ipAddress; + } + + public String getPrivateDnsName() { + return privateDnsName; + } + + public String getPrivateIpAddress() { + return privateIpAddress; + } + + } + + protected final String region; + protected final Set groupIds; + protected final String amiLaunchIndex; @Nullable - private final String dnsName; - private final String imageId; - private final String instanceId; - private final InstanceState instanceState; - private final String instanceType; + protected final String dnsName; + protected final String imageId; + protected final String instanceId; + protected final InstanceState instanceState; + protected final String instanceType; @Nullable - private final String ipAddress; + protected final String ipAddress; @Nullable - private final String kernelId; + protected final String kernelId; @Nullable - private final String keyName; - private final Date launchTime; - private final MonitoringState monitoringState; - private final String availabilityZone; + protected final String keyName; + protected final Date launchTime; + protected final String availabilityZone; + protected final String virtualizationType; @Nullable - private final String placementGroup; - private final String virtualizationType; + protected final String platform; @Nullable - private final String platform; + protected final String privateDnsName; @Nullable - private final String privateDnsName; + protected final String privateIpAddress; @Nullable - private final String privateIpAddress; - private final Set productCodes = Sets.newLinkedHashSet(); + protected final String ramdiskId; @Nullable - private final String ramdiskId; + protected final String reason; + protected final RootDeviceType rootDeviceType; @Nullable - private final String reason; - @Nullable - private final String subnetId; - @Nullable - private final String spotInstanceRequestId; - @Nullable - private final String vpcId; - private final RootDeviceType rootDeviceType; - @Nullable - private final String rootDeviceName; - private final Map ebsBlockDevices = Maps.newHashMap(); + protected final String rootDeviceName; + protected final Map ebsBlockDevices; public int compareTo(RunningInstance o) { return (this == o) ? 0 : getId().compareTo(o.getId()); } - public RunningInstance(String region, Iterable groupIds, @Nullable String amiLaunchIndex, + protected RunningInstance(String region, Iterable groupIds, @Nullable String amiLaunchIndex, @Nullable String dnsName, String imageId, String instanceId, InstanceState instanceState, String instanceType, @Nullable String ipAddress, @Nullable String kernelId, @Nullable String keyName, - Date launchTime, MonitoringState monitoringState, String availabilityZone, @Nullable String placementGroup, - String virtualizationType, @Nullable String platform, @Nullable String privateDnsName, - @Nullable String privateIpAddress, Set productCodes, @Nullable String ramdiskId, - @Nullable String reason, @Nullable String subnetId, @Nullable String spotInstanceRequestId, - @Nullable String vpcId, RootDeviceType rootDeviceType, @Nullable String rootDeviceName, + Date launchTime, String availabilityZone, String virtualizationType, @Nullable String platform, + @Nullable String privateDnsName, @Nullable String privateIpAddress, @Nullable String ramdiskId, + @Nullable String reason, RootDeviceType rootDeviceType, @Nullable String rootDeviceName, Map ebsBlockDevices) { - Iterables.addAll(this.groupIds, checkNotNull(groupIds, "groupIds")); this.region = checkNotNull(region, "region"); this.amiLaunchIndex = amiLaunchIndex; // nullable on runinstances. this.dnsName = dnsName; // nullable on runinstances. @@ -109,22 +266,17 @@ public class RunningInstance implements Comparable { this.kernelId = kernelId; this.keyName = keyName; this.launchTime = checkNotNull(launchTime, "launchTime"); - this.monitoringState = monitoringState; - this.availabilityZone = availabilityZone; // nullable on Nova. - this.placementGroup = placementGroup; + this.availabilityZone = checkNotNull(availabilityZone, "availabilityZone"); this.virtualizationType = virtualizationType; this.platform = platform; - this.privateDnsName = privateDnsName; // nullable on Nova. - this.privateIpAddress = privateIpAddress; - Iterables.addAll(this.productCodes, checkNotNull(productCodes, "productCodes")); + this.privateDnsName = privateDnsName;// nullable on runinstances. + this.privateIpAddress = privateIpAddress;// nullable on runinstances. this.ramdiskId = ramdiskId; this.reason = reason; - this.subnetId = subnetId; - this.spotInstanceRequestId = spotInstanceRequestId; - this.vpcId = vpcId; this.rootDeviceType = checkNotNull(rootDeviceType, "rootDeviceType"); this.rootDeviceName = rootDeviceName; - this.getEbsBlockDevices().putAll(checkNotNull(ebsBlockDevices, "ebsBlockDevices")); + this.ebsBlockDevices = ImmutableMap.copyOf(checkNotNull(ebsBlockDevices, "ebsBlockDevices")); + this.groupIds = ImmutableSet.copyOf(checkNotNull(groupIds, "groupIds")); } /** @@ -209,13 +361,6 @@ public class RunningInstance implements Comparable { return launchTime; } - /** - * State of monitoring for the instance. - */ - public MonitoringState getMonitoringState() { - return monitoringState; - } - /** * The location where the instance launched. */ @@ -223,13 +368,6 @@ public class RunningInstance implements Comparable { return availabilityZone; } - /** - * The name of the placement group the instance is in (for cluster compute instances). - */ - public String getPlacementGroup() { - return placementGroup; - } - /** * Specifies the instance's virtualization type. Valid values are paravirtual or hvm. */ @@ -259,13 +397,6 @@ public class RunningInstance implements Comparable { return privateIpAddress; } - /** - * Product codes attached to this instance. - */ - public Set getProductCodes() { - return productCodes; - } - /** * Optional. RAM disk associated with this instance. */ @@ -280,27 +411,6 @@ public class RunningInstance implements Comparable { return reason; } - /** - * The ID of the Spot Instance request - */ - public String getSpotInstanceRequestId() { - return spotInstanceRequestId; - } - - /** - * Specifies the subnet ID in which the instance is running (Amazon Virtual Private Cloud). - */ - public String getSubnetId() { - return subnetId; - } - - /** - * Specifies the VPC in which the instance is running (Amazon Virtual Private Cloud). - */ - public String getVpcId() { - return vpcId; - } - public RootDeviceType getRootDeviceType() { return rootDeviceType; } @@ -339,21 +449,14 @@ public class RunningInstance implements Comparable { result = prime * result + ((kernelId == null) ? 0 : kernelId.hashCode()); result = prime * result + ((keyName == null) ? 0 : keyName.hashCode()); result = prime * result + ((launchTime == null) ? 0 : launchTime.hashCode()); - result = prime * result + ((monitoringState == null) ? 0 : monitoringState.hashCode()); - result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode()); result = prime * result + ((platform == null) ? 0 : platform.hashCode()); result = prime * result + ((privateDnsName == null) ? 0 : privateDnsName.hashCode()); result = prime * result + ((privateIpAddress == null) ? 0 : privateIpAddress.hashCode()); - result = prime * result + ((productCodes == null) ? 0 : productCodes.hashCode()); result = prime * result + ((ramdiskId == null) ? 0 : ramdiskId.hashCode()); - result = prime * result + ((reason == null) ? 0 : reason.hashCode()); result = prime * result + ((region == null) ? 0 : region.hashCode()); result = prime * result + ((rootDeviceName == null) ? 0 : rootDeviceName.hashCode()); result = prime * result + ((rootDeviceType == null) ? 0 : rootDeviceType.hashCode()); - result = prime * result + ((spotInstanceRequestId == null) ? 0 : spotInstanceRequestId.hashCode()); - result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode()); result = prime * result + ((virtualizationType == null) ? 0 : virtualizationType.hashCode()); - result = prime * result + ((vpcId == null) ? 0 : vpcId.hashCode()); return result; } @@ -426,16 +529,6 @@ public class RunningInstance implements Comparable { return false; } else if (!launchTime.equals(other.launchTime)) return false; - if (monitoringState == null) { - if (other.monitoringState != null) - return false; - } else if (!monitoringState.equals(other.monitoringState)) - return false; - if (placementGroup == null) { - if (other.placementGroup != null) - return false; - } else if (!placementGroup.equals(other.placementGroup)) - return false; if (platform == null) { if (other.platform != null) return false; @@ -451,21 +544,11 @@ public class RunningInstance implements Comparable { return false; } else if (!privateIpAddress.equals(other.privateIpAddress)) return false; - if (productCodes == null) { - if (other.productCodes != null) - return false; - } else if (!productCodes.equals(other.productCodes)) - return false; if (ramdiskId == null) { if (other.ramdiskId != null) return false; } else if (!ramdiskId.equals(other.ramdiskId)) return false; - if (reason == null) { - if (other.reason != null) - return false; - } else if (!reason.equals(other.reason)) - return false; if (region == null) { if (other.region != null) return false; @@ -481,41 +564,22 @@ public class RunningInstance implements Comparable { return false; } else if (!rootDeviceType.equals(other.rootDeviceType)) return false; - if (spotInstanceRequestId == null) { - if (other.spotInstanceRequestId != null) - return false; - } else if (!spotInstanceRequestId.equals(other.spotInstanceRequestId)) - return false; - if (subnetId == null) { - if (other.subnetId != null) - return false; - } else if (!subnetId.equals(other.subnetId)) - return false; if (virtualizationType == null) { if (other.virtualizationType != null) return false; } else if (!virtualizationType.equals(other.virtualizationType)) return false; - if (vpcId == null) { - if (other.vpcId != null) - return false; - } else if (!vpcId.equals(other.vpcId)) - return false; return true; } @Override public String toString() { - return "RunningInstance [amiLaunchIndex=" + amiLaunchIndex + ", availabilityZone=" + availabilityZone - + ", placementGroup=" + placementGroup + ", virtualizationType=" + virtualizationType + ", dnsName=" - + dnsName + ", ebsBlockDevices=" + ebsBlockDevices + ", groupIds=" + groupIds + ", imageId=" + imageId - + ", instanceId=" + instanceId + ", instanceState=" + instanceState + ", instanceType=" + instanceType - + ", ipAddress=" + ipAddress + ", kernelId=" + kernelId + ", keyName=" + keyName + ", launchTime=" - + launchTime + ", monitoringState=" + monitoringState + ", platform=" + platform + ", privateDnsName=" - + privateDnsName + ", privateIpAddress=" + privateIpAddress + ", productCodes=" + productCodes - + ", ramdiskId=" + ramdiskId + ", reason=" + reason + ", region=" + region + ", rootDeviceName=" - + rootDeviceName + ", rootDeviceType=" + rootDeviceType + ", spotInstanceRequestId=" - + spotInstanceRequestId + ", subnetId=" + subnetId + ", vpcId=" + vpcId + "]"; + return "[region=" + region + ", availabilityZone=" + availabilityZone + ", instanceId=" + instanceId + + ", instanceState=" + instanceState + ", instanceType=" + instanceType + ", virtualizationType=" + + virtualizationType + ", imageId=" + imageId + ", ipAddress=" + ipAddress + ", dnsName=" + dnsName + + ", privateIpAddress=" + privateIpAddress + ", privateDnsName=" + privateDnsName + ", keyName=" + + keyName + ", platform=" + platform + ", launchTime=" + launchTime + ", rootDeviceName=" + + rootDeviceName + ", rootDeviceType=" + rootDeviceType + ", ebsBlockDevices=" + ebsBlockDevices + "]"; } } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/options/RunInstancesOptions.java b/apis/ec2/src/main/java/org/jclouds/ec2/options/RunInstancesOptions.java index b3e743653d..0e35548e78 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/options/RunInstancesOptions.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/options/RunInstancesOptions.java @@ -43,8 +43,7 @@ import org.jclouds.encryption.internal.Base64; * * * @author Adrian Cole - * @see */ @@ -93,22 +92,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions { return getFirstFormOrNull("SecurityGroup.1"); } - /** - * Specifies the name of an existing placement group you want to launch the instance into (for - * cluster compute instances). - * - * @param placementGroup - * name of an existing placement group - */ - public RunInstancesOptions inPlacementGroup(String placementGroup) { - formParameters.put("Placement.GroupName", checkNotNull(placementGroup, "placementGroup")); - return this; - } - - String getPlacementGroup() { - return getFirstFormOrNull("Placement.GroupName"); - } - /** * Unencoded data */ @@ -163,58 +146,34 @@ public class RunInstancesOptions extends BaseEC2RequestOptions { return getFirstFormOrNull("RamdiskId"); } - /** - * Enables monitoring for the instance. - */ - public RunInstancesOptions enableMonitoring() { - formParameters.put("Monitoring.Enabled", "true"); - return this; - } - - String getMonitoringEnabled() { - return getFirstFormOrNull("Monitoring.Enabled"); - } - - /** - * Specifies the subnet ID within which to launch the instance(s) for Amazon Virtual Private - * Cloud. - */ - public RunInstancesOptions withSubnetId(String subnetId) { - formParameters.put("SubnetId", checkNotNull(subnetId, "subnetId")); - return this; - } - - String getSubnetId() { - return getFirstFormOrNull("SubnetId"); - } - /** * Specifies the Block Device Mapping for the instance - * + * */ - - public RunInstancesOptions withBlockDeviceMappings(Set mappings) { - int i = 1; - for(BlockDeviceMapping mapping: mappings) - { - checkNotNull(mapping.getDeviceName(), "deviceName"); - formParameters.put(String.format("BlockDeviceMapping.%d.DeviceName", i), mapping.getDeviceName()); - if(mapping.getVirtualName() != null) - formParameters.put(String.format("BlockDeviceMapping.%d.VirtualName", i), mapping.getVirtualName()); - if(mapping.getEbsSnapshotId() != null) - formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.SnapshotId", i), mapping.getEbsSnapshotId()); - if(mapping.getEbsVolumeSize() != null) - formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.VolumeSize", i), String.valueOf(mapping.getEbsVolumeSize())); - if(mapping.getEbsNoDevice() != null) - formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.NoDevice", i), String.valueOf(mapping.getEbsNoDevice())); - if(mapping.getEbsDeleteOnTermination() != null) - formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.DeleteOnTermination", i), String.valueOf(mapping.getEbsDeleteOnTermination())); - - i++; - } - return this; - } + public RunInstancesOptions withBlockDeviceMappings(Set mappings) { + int i = 1; + for (BlockDeviceMapping mapping : mappings) { + checkNotNull(mapping.getDeviceName(), "deviceName"); + formParameters.put(String.format("BlockDeviceMapping.%d.DeviceName", i), mapping.getDeviceName()); + if (mapping.getVirtualName() != null) + formParameters.put(String.format("BlockDeviceMapping.%d.VirtualName", i), mapping.getVirtualName()); + if (mapping.getEbsSnapshotId() != null) + formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.SnapshotId", i), mapping.getEbsSnapshotId()); + if (mapping.getEbsVolumeSize() != null) + formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.VolumeSize", i), String.valueOf(mapping + .getEbsVolumeSize())); + if (mapping.getEbsNoDevice() != null) + formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.NoDevice", i), String.valueOf(mapping + .getEbsNoDevice())); + if (mapping.getEbsDeleteOnTermination() != null) + formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.DeleteOnTermination", i), String + .valueOf(mapping.getEbsDeleteOnTermination())); + + i++; + } + return this; + } public static class Builder { /** @@ -233,14 +192,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions { return options.withSecurityGroup(securityGroup); } - /** - * @see RunInstancesOptions#inPlacementGroup(String) - */ - public static RunInstancesOptions inPlacementGroup(String placementGroup) { - RunInstancesOptions options = new RunInstancesOptions(); - return options.inPlacementGroup(placementGroup); - } - /** * @see RunInstancesOptions#withUserData(byte []) */ @@ -265,22 +216,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions { return options.withKernelId(kernelId); } - /** - * @see RunInstancesOptions#enableMonitoring() - */ - public static RunInstancesOptions enableMonitoring() { - RunInstancesOptions options = new RunInstancesOptions(); - return options.enableMonitoring(); - } - - /** - * @see RunInstancesOptions#withSubnetId(String) - */ - public static RunInstancesOptions withSubnetId(String subnetId) { - RunInstancesOptions options = new RunInstancesOptions(); - return options.withSubnetId(subnetId); - } - /** * @see RunInstancesOptions#withRamdisk(String) */ @@ -288,7 +223,7 @@ public class RunInstancesOptions extends BaseEC2RequestOptions { RunInstancesOptions options = new RunInstancesOptions(); return options.withRamdisk(ramdiskId); } - + /** * @see RunInstancesOptions#withBlockDeviceMappings(Set mappings) */ diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/reference/EC2Constants.java b/apis/ec2/src/main/java/org/jclouds/ec2/reference/EC2Constants.java index f54a5d63f1..f51281f681 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/reference/EC2Constants.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/reference/EC2Constants.java @@ -26,19 +26,11 @@ import org.jclouds.compute.ComputeService; * * @author Adrian Cole */ -public interface EC2Constants{ +public interface EC2Constants { /** * Listing the universe of amis is extremely expensive. set this to a comma separated value of * the ami owners you wish to use in {@link ComputeService} */ public static final String PROPERTY_EC2_AMI_OWNERS = "jclouds.ec2.ami-owners"; - public static final String PROPERTY_ELB_ENDPOINT = "jclouds.elb.endpoint"; - - /** - * amis that work on the cluster instance type - * - * @see InstanceType.CC1_4XLARGE - */ - public static final String PROPERTY_EC2_CC_AMIs = "jclouds.ec2.cc-amis"; } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIAsyncClient.java b/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIAsyncClient.java index 39253ff9ee..d86528fbbe 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIAsyncClient.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIAsyncClient.java @@ -32,12 +32,11 @@ import javax.ws.rs.Path; import org.jclouds.aws.filters.FormSigner; import org.jclouds.ec2.EC2AsyncClient; -import org.jclouds.ec2.binders.BindProductCodesToIndexedFormParams; import org.jclouds.ec2.binders.BindUserGroupsToIndexedFormParams; import org.jclouds.ec2.binders.BindUserIdsToIndexedFormParams; import org.jclouds.ec2.domain.Image; -import org.jclouds.ec2.domain.Image.EbsBlockDevice; import org.jclouds.ec2.domain.Permission; +import org.jclouds.ec2.domain.Image.EbsBlockDevice; import org.jclouds.ec2.options.CreateImageOptions; import org.jclouds.ec2.options.DescribeImagesOptions; import org.jclouds.ec2.options.RegisterImageBackedByEbsOptions; @@ -46,7 +45,6 @@ import org.jclouds.ec2.xml.BlockDeviceMappingHandler; import org.jclouds.ec2.xml.DescribeImagesResponseHandler; import org.jclouds.ec2.xml.ImageIdHandler; import org.jclouds.ec2.xml.PermissionHandler; -import org.jclouds.ec2.xml.ProductCodesHandler; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.EndpointParam; @@ -79,7 +77,8 @@ public interface AMIAsyncClient { @XMLResponseParser(DescribeImagesResponseHandler.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) ListenableFuture> describeImagesInRegion( - @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, DescribeImagesOptions... options); + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + DescribeImagesOptions... options); /** * @see AMIClient#createImageInRegion @@ -88,7 +87,8 @@ public interface AMIAsyncClient { @Path("/") @FormParams(keys = ACTION, values = "CreateImage") @XMLResponseParser(ImageIdHandler.class) - ListenableFuture createImageInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + ListenableFuture createImageInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("Name") String name, @FormParam("InstanceId") String instanceId, CreateImageOptions... options); /** @@ -97,7 +97,8 @@ public interface AMIAsyncClient { @POST @Path("/") @FormParams(keys = ACTION, values = "DeregisterImage") - ListenableFuture deregisterImageInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + ListenableFuture deregisterImageInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("ImageId") String imageId); /** @@ -173,17 +174,6 @@ public interface AMIAsyncClient { @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("ImageId") String imageId); - /** - * @see AMIClient#getProductCodesForImageInRegion - */ - @POST - @Path("/") - @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeImageAttribute", "productCodes" }) - @XMLResponseParser(ProductCodesHandler.class) - ListenableFuture> getProductCodesForImageInRegion( - @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, - @FormParam("ImageId") String imageId); - /** * @see AMIClient#getBlockDeviceMappingsForImageInRegion */ @@ -194,27 +184,4 @@ public interface AMIAsyncClient { ListenableFuture> getBlockDeviceMappingsForImageInRegion( @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("ImageId") String imageId); - - /** - * @see AMIClient#addProductCodesToImageInRegion - */ - @POST - @Path("/") - @FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = { "ModifyImageAttribute", "add", - "productCodes" }) - ListenableFuture addProductCodesToImageInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, - @BinderParam(BindProductCodesToIndexedFormParams.class) Iterable productCodes, - @FormParam("ImageId") String imageId); - - /** - * @see AMIClient#removeProductCodesToImageInRegion - */ - @POST - @Path("/") - @FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = { "ModifyImageAttribute", "remove", - "productCodes" }) - ListenableFuture removeProductCodesFromImageInRegion( - @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, - @BinderParam(BindProductCodesToIndexedFormParams.class) Iterable productCodes, - @FormParam("ImageId") String imageId); } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIClient.java b/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIClient.java index 9e621fcbc2..29d1b5aadb 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIClient.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIClient.java @@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; +import org.jclouds.concurrent.Timeout; import org.jclouds.ec2.domain.Image; import org.jclouds.ec2.domain.Permission; import org.jclouds.ec2.domain.Image.EbsBlockDevice; @@ -32,7 +33,6 @@ import org.jclouds.ec2.options.CreateImageOptions; import org.jclouds.ec2.options.DescribeImagesOptions; import org.jclouds.ec2.options.RegisterImageBackedByEbsOptions; import org.jclouds.ec2.options.RegisterImageOptions; -import org.jclouds.concurrent.Timeout; /** * Provides access to EC2 via their REST API. @@ -60,22 +60,6 @@ public interface AMIClient { @Timeout(duration = 300, timeUnit = TimeUnit.SECONDS) Set describeImagesInRegion(@Nullable String region, DescribeImagesOptions... options); - /** - * Returns the Product Codes of an image. - * - * @param region - * AMIs are tied to the Region where its files are located within Amazon S3. - * @param imageId - * The ID of the AMI for which an attribute will be described - * @see #describeImages - * @see #modifyImageAttribute - * @see #resetImageAttribute - * @see - * @see DescribeImagesOptions - */ - Set getProductCodesForImageInRegion(@Nullable String region, String imageId); - /** * Returns a map of device name to block device for the image. * @@ -114,8 +98,7 @@ public interface AMIClient { * "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateImage.html" * /> */ - String createImageInRegion(@Nullable String region, String name, String instanceId, - CreateImageOptions... options); + String createImageInRegion(@Nullable String region, String name, String instanceId, CreateImageOptions... options); /** * @@ -201,7 +184,7 @@ public interface AMIClient { */ String registerUnixImageBackedByEbsInRegion(@Nullable String region, String name, String ebsSnapshotId, RegisterImageBackedByEbsOptions... options); - + /** * Returns the {@link Permission}s of an image. * @@ -276,40 +259,4 @@ public interface AMIClient { void removeLaunchPermissionsFromImageInRegion(@Nullable String region, Iterable userIds, Iterable userGroups, String imageId); - /** - * Adds {@code productCode}s to an AMI. - * - * @param region - * AMIs are tied to the Region where its files are located within Amazon S3. - * @param productCodes - * Product Codes - * @param imageId - * The AMI ID. - * - * @see #removeProductCodesFromImage - * @see #describeImageAttribute - * @see #resetImageAttribute - * @see - */ - void addProductCodesToImageInRegion(@Nullable String region, Iterable productCodes, String imageId); - - /** - * Removes {@code productCode}s from an AMI. - * - * @param region - * AMIs are tied to the Region where its files are located within Amazon S3. - * @param productCodes - * Product Codes - * @param imageId - * The AMI ID. - * - * @see #addProductCodesToImage - * @see #describeImageAttribute - * @see #resetImageAttribute - * @see - */ - void removeProductCodesFromImageInRegion(@Nullable String region, Iterable productCodes, - String imageId); } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/InstanceAsyncClient.java b/apis/ec2/src/main/java/org/jclouds/ec2/services/InstanceAsyncClient.java index cecacd6ecc..b30afddbf7 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/InstanceAsyncClient.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/services/InstanceAsyncClient.java @@ -83,7 +83,7 @@ public interface InstanceAsyncClient { @FormParams(keys = ACTION, values = "DescribeInstances") @XMLResponseParser(DescribeInstancesResponseHandler.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) - ListenableFuture>> describeInstancesInRegion( + ListenableFuture>> describeInstancesInRegion( @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds); @@ -94,7 +94,7 @@ public interface InstanceAsyncClient { @Path("/") @FormParams(keys = ACTION, values = "RunInstances") @XMLResponseParser(RunInstancesResponseHandler.class) - ListenableFuture> runInstancesInRegion( + ListenableFuture> runInstancesInRegion( @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @Nullable @BinderParam(IfNotNullBindAvailabilityZoneToFormParam.class) String nullableAvailabilityZone, @FormParam("ImageId") String imageId, @FormParam("MinCount") int minCount, diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/BaseReservationHandler.java b/apis/ec2/src/main/java/org/jclouds/ec2/xml/BaseReservationHandler.java index 6a60ae61b2..04c4af953d 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/BaseReservationHandler.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/xml/BaseReservationHandler.java @@ -20,28 +20,27 @@ package org.jclouds.ec2.xml; import java.util.Date; -import java.util.Map; import java.util.Set; import javax.annotation.Resource; import javax.inject.Inject; +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.date.DateService; import org.jclouds.ec2.domain.Attachment; import org.jclouds.ec2.domain.BlockDevice; import org.jclouds.ec2.domain.InstanceState; -import org.jclouds.ec2.domain.MonitoringState; import org.jclouds.ec2.domain.Reservation; import org.jclouds.ec2.domain.RootDeviceType; import org.jclouds.ec2.domain.RunningInstance; -import org.jclouds.aws.util.AWSUtils; -import org.jclouds.date.DateService; +import org.jclouds.ec2.domain.RunningInstance.Builder; import org.jclouds.http.functions.ParseSax.HandlerForGeneratedRequestWithResult; import org.jclouds.location.Region; import org.jclouds.logging.Logger; import org.xml.sax.Attributes; -import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.google.inject.Provider; /** * @@ -49,75 +48,49 @@ import com.google.common.collect.Sets; */ public abstract class BaseReservationHandler extends HandlerForGeneratedRequestWithResult { - protected final DateService dateService; - - protected final String defaultRegion; - - @Inject - public BaseReservationHandler(DateService dateService, @Region String defaultRegion) { - this.dateService = dateService; - this.defaultRegion = defaultRegion; - } - @Resource protected Logger logger = Logger.NULL; - private StringBuilder currentText = new StringBuilder(); - private Set groupIds = Sets.newLinkedHashSet(); - private Set instances = Sets.newLinkedHashSet(); - private String ownerId; - private String requesterId; - private String reservationId; - private String amiLaunchIndex; - private String dnsName; - private String imageId; - private String instanceId; - private InstanceState instanceState; - private String instanceType; - private String ipAddress; - private String kernelId; - private String keyName; - private Date launchTime; - private MonitoringState monitoringState; - private String availabilityZone; - private String placementGroup; - private String virtualizationType = "paravirtual"; - private String platform; - private String privateDnsName; - private String privateIpAddress; - private Set productCodes = Sets.newHashSet(); - private String ramdiskId; - private String reason; - private String spotInstanceRequestId; - private String subnetId; - private String vpcId; - protected boolean inInstances; - protected boolean inProductCodes; - protected boolean inGroups; - protected boolean inMonitoring; - private boolean inBlockDeviceMapping; - private Map ebsBlockDevices = Maps.newHashMap(); + protected final DateService dateService; + protected final String defaultRegion; + protected final Provider builderProvider; + @Inject + public BaseReservationHandler(DateService dateService, @Region String defaultRegion, + Provider builderProvider) { + this.dateService = dateService; + this.defaultRegion = defaultRegion; + this.builderProvider = builderProvider; + this.builder = builderProvider.get(); + } + + protected StringBuilder currentText = new StringBuilder(); + + protected Builder builder; + + protected int itemDepth; + boolean inInstancesSet; + // attachments private String volumeId; private Attachment.Status attachmentStatus; private Date attachTime; private boolean deleteOnTermination; - private RootDeviceType rootDeviceType = RootDeviceType.INSTANCE_STORE; private String deviceName; - private String rootDeviceName; + + // reservation stuff + private Set groupIds = Sets.newLinkedHashSet(); + private String ownerId; + private String requesterId; + private String reservationId; + + private Set instances = Sets.newLinkedHashSet(); public void startElement(String uri, String name, String qName, Attributes attrs) { - if (qName.equals("instancesSet")) { - inInstances = true; - } else if (qName.equals("productCodesSet")) { - inProductCodes = true; - } else if (qName.equals("groupSet")) { - inGroups = true; - } else if (qName.equals("blockDeviceMapping")) { - inBlockDeviceMapping = true; + if (qName.equals("item")) { + itemDepth++; + } else if (qName.equals("instancesSet")) { + inInstancesSet = true; } - if (qName.equals("monitoring")) - inMonitoring = true; } protected String currentOrNull() { @@ -126,7 +99,12 @@ public abstract class BaseReservationHandler extends HandlerForGeneratedReque } public void endElement(String uri, String name, String qName) { - if (qName.equals("groupId")) { + if (qName.equals("item")) { + inItem(); + itemDepth--; + } else if (qName.equals("instancesSet")) { + inInstancesSet = false; + } else if (qName.equals("groupId")) { groupIds.add(currentOrNull()); } else if (qName.equals("ownerId")) { ownerId = currentOrNull(); @@ -135,83 +113,51 @@ public abstract class BaseReservationHandler extends HandlerForGeneratedReque } else if (qName.equals("reservationId")) { reservationId = currentOrNull(); } else if (qName.equals("amiLaunchIndex")) { - amiLaunchIndex = currentOrNull(); + builder.amiLaunchIndex(currentOrNull()); } else if (qName.equals("dnsName")) { - dnsName = currentOrNull(); + String dnsName = currentOrNull(); // Eucalyptus - if ("0.0.0.0".equals(dnsName)) - dnsName = null; + if (!"0.0.0.0".equals(dnsName)) + builder.dnsName(dnsName); } else if (qName.equals("imageId")) { - imageId = currentOrNull(); + builder.imageId(currentOrNull()); } else if (qName.equals("instanceId")) { - instanceId = currentOrNull(); + builder.instanceId(currentOrNull()); } else if (qName.equals("name")) { - String state = currentOrNull(); - if (state != null) { - // Nova - if ("shutdown".equalsIgnoreCase(state)) - instanceState = InstanceState.TERMINATED; - else - instanceState = InstanceState.fromValue(state); - } + builder.instanceState(InstanceState.fromValue(currentOrNull())); } else if (qName.equals("instanceType")) { - instanceType = currentOrNull(); + builder.instanceType(currentOrNull()); } else if (qName.equals("ipAddress")) { - ipAddress = currentOrNull(); + builder.ipAddress(currentOrNull()); } else if (qName.equals("kernelId")) { - kernelId = currentOrNull(); + builder.kernelId(currentOrNull()); } else if (qName.equals("keyName")) { - keyName = currentOrNull(); + builder.keyName(currentOrNull()); } else if (qName.equals("launchTime")) { - try { - launchTime = dateService.iso8601DateParse(currentOrNull()); - } catch (RuntimeException e) { - // Eucalyptus - launchTime = dateService.iso8601SecondsDateParse(currentOrNull()); - } - } else if (qName.equals("state") && inMonitoring) { - monitoringState = MonitoringState.fromValue(currentOrNull()); + builder.launchTime(parseDate()); } else if (qName.equals("availabilityZone")) { - availabilityZone = currentOrNull(); - } else if (qName.equals("groupName")) { - placementGroup = currentOrNull(); + builder.availabilityZone(currentOrNull()); } else if (qName.equals("virtualizationType")) { - virtualizationType = currentOrNull(); + builder.virtualizationType(currentOrNull()); } else if (qName.equals("platform")) { - platform = currentOrNull(); + builder.platform(currentOrNull()); } else if (qName.equals("privateDnsName")) { - privateDnsName = currentOrNull(); + String privateDnsName = currentOrNull(); // Eucalyptus - if ("0.0.0.0".equals(privateDnsName)) - privateDnsName = null; + if (!"0.0.0.0".equals(privateDnsName)) + builder.privateDnsName(privateDnsName); } else if (qName.equals("privateIpAddress")) { - privateIpAddress = currentOrNull(); + builder.privateIpAddress(currentOrNull()); } else if (qName.equals("ramdiskId")) { - ramdiskId = currentOrNull(); + builder.ramdiskId(currentOrNull()); } else if (qName.equals("reason")) { - reason = currentOrNull(); - } else if (qName.equals("subnetId")) { - subnetId = currentOrNull(); - } else if (qName.equals("spotInstanceRequestId")) { - spotInstanceRequestId = currentOrNull(); - } else if (qName.equals("vpcId")) { - vpcId = currentOrNull(); - } else if (qName.equals("productCode")) { - productCodes.add(currentOrNull()); - } else if (qName.equals("productCodesSet")) { - inProductCodes = false; - } else if (qName.equals("instancesSet")) { - inInstances = false; - } else if (qName.equals("groupSet")) { - inGroups = false; - } else if (qName.equals("monitoring")) { - inMonitoring = false; - } else if (qName.equals("blockDeviceMapping")) { - inBlockDeviceMapping = false; + builder.reason(currentOrNull()); + } else if (qName.equals("rootDeviceType")) { + builder.rootDeviceType(RootDeviceType.fromValue(currentOrNull())); + } else if (qName.equals("rootDeviceName")) { + builder.rootDeviceName(currentOrNull()); } else if (qName.equals("deviceName")) { deviceName = currentOrNull(); - } else if (qName.equals("rootDeviceType")) { - rootDeviceType = RootDeviceType.fromValue(currentOrNull()); } else if (qName.equals("volumeId")) { volumeId = currentOrNull(); } else if (qName.equals("status")) { @@ -220,72 +166,60 @@ public abstract class BaseReservationHandler extends HandlerForGeneratedReque attachTime = dateService.iso8601DateParse(currentText.toString().trim()); } else if (qName.equals("deleteOnTermination")) { deleteOnTermination = Boolean.parseBoolean(currentText.toString().trim()); - } else if (qName.equals("rootDeviceName")) { - rootDeviceName = currentOrNull(); - } else if (qName.equals("item")) { - inItem(); - } - currentText = new StringBuilder(); - } - - protected void inItem() { - if (inBlockDeviceMapping) { - ebsBlockDevices.put(deviceName, new BlockDevice(volumeId, attachmentStatus, attachTime, - deleteOnTermination)); + } else if (qName.equals("ebs")) { + builder.device(deviceName, new BlockDevice(volumeId, attachmentStatus, attachTime, deleteOnTermination)); this.deviceName = null; this.volumeId = null; this.attachmentStatus = null; this.attachTime = null; this.deleteOnTermination = true; - } else if (inInstances && !inProductCodes && !inBlockDeviceMapping) { - String region = getRequest() != null ? AWSUtils.findRegionInArgsOrNull(getRequest()) : null; + } + currentText = new StringBuilder(); + } + protected Date parseDate() { + try { + return dateService.iso8601DateParse(currentOrNull()); + } catch (RuntimeException e) { // Eucalyptus - if (ipAddress == null && dnsName != null && dnsName.matches(".*[0-9]$")) { - ipAddress = dnsName; - dnsName = null; - } - - if (privateIpAddress == null && privateDnsName != null && privateDnsName.matches(".*[0-9]$")) { - privateIpAddress = privateDnsName; - privateDnsName = null; - } - if (region == null) - region = defaultRegion; - instances.add(new RunningInstance(region, groupIds, amiLaunchIndex, dnsName, imageId, instanceId, - instanceState, instanceType, ipAddress, kernelId, keyName, launchTime, monitoringState, - availabilityZone, placementGroup, virtualizationType, platform, privateDnsName, privateIpAddress, - productCodes, ramdiskId, reason, subnetId, spotInstanceRequestId, vpcId, rootDeviceType, rootDeviceName, - ebsBlockDevices)); - this.amiLaunchIndex = null; - this.dnsName = null; - this.imageId = null; - this.instanceId = null; - this.instanceState = null; - this.instanceType = null; - this.ipAddress = null; - this.kernelId = null; - this.keyName = null; - this.launchTime = null; - this.monitoringState = null; - this.availabilityZone = null; - this.placementGroup = null; - this.virtualizationType = "paravirtual"; - this.platform = null; - this.privateDnsName = null; - this.privateIpAddress = null; - this.productCodes = Sets.newHashSet(); - this.ramdiskId = null; - this.reason = null; - this.subnetId = null; - this.spotInstanceRequestId = null; - this.vpcId = null; - this.rootDeviceType = RootDeviceType.INSTANCE_STORE; - this.rootDeviceName = null; - this.ebsBlockDevices = Maps.newHashMap(); + return dateService.iso8601SecondsDateParse(currentOrNull()); } } + protected void inItem() { + if (endOfInstanceItem()) { + refineBuilderBeforeAddingInstance(); + instances.add(builder.build()); + builder = builderProvider.get(); + } + } + + protected void refineBuilderBeforeAddingInstance() { + String region = getRequest() != null ? AWSUtils.findRegionInArgsOrNull(getRequest()) : null; + + // Eucalyptus + if (builder.getIpAddress() == null && builder.getDnsName() != null && builder.getDnsName().matches(".*[0-9]$")) { + builder.ipAddress(builder.getDnsName()); + builder.dnsName(null); + } + if (builder.getPrivateIpAddress() == null && builder.getPrivateDnsName() != null + && builder.getPrivateDnsName().matches(".*[0-9]$")) { + builder.privateIpAddress(builder.getPrivateDnsName()); + builder.privateDnsName(null); + } + + builder.region((region == null) ? defaultRegion : region); + builder.groupIds(groupIds); + } + + protected Builder builder() { + return builder; + } + + protected boolean endOfInstanceItem() { + return itemDepth <= 2 && inInstancesSet; + } + public void characters(char ch[], int start, int length) { currentText.append(ch, start, length); } @@ -295,7 +229,7 @@ public abstract class BaseReservationHandler extends HandlerForGeneratedReque if (region == null) region = defaultRegion; Reservation info = new Reservation(region, groupIds, instances, - ownerId, requesterId, reservationId); + ownerId, requesterId, reservationId); this.groupIds = Sets.newLinkedHashSet(); this.instances = Sets.newLinkedHashSet(); this.ownerId = null; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeInstancesResponseHandler.java b/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeInstancesResponseHandler.java index 57fc65e789..a63eb307e4 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeInstancesResponseHandler.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeInstancesResponseHandler.java @@ -23,12 +23,13 @@ import java.util.Set; import javax.inject.Inject; +import org.jclouds.date.DateService; import org.jclouds.ec2.domain.Reservation; import org.jclouds.ec2.domain.RunningInstance; -import org.jclouds.date.DateService; import org.jclouds.location.Region; import com.google.common.collect.Sets; +import com.google.inject.Provider; /** * Parses the following XML document: @@ -43,8 +44,9 @@ public class DescribeInstancesResponseHandler extends private Set> reservations = Sets.newLinkedHashSet(); @Inject - DescribeInstancesResponseHandler(DateService dateService, @Region String defaultRegion) { - super(dateService, defaultRegion); + DescribeInstancesResponseHandler(DateService dateService, @Region String defaultRegion, + Provider builderProvider) { + super(dateService, defaultRegion, builderProvider); } @Override @@ -52,9 +54,13 @@ public class DescribeInstancesResponseHandler extends return reservations; } + protected boolean endOfReservationItem() { + return itemDepth == 1; + } + @Override protected void inItem() { - if (!inInstances && !inProductCodes && !inGroups) { + if (endOfReservationItem()) { reservations.add(super.newReservation()); } else { super.inItem(); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/RunInstancesResponseHandler.java b/apis/ec2/src/main/java/org/jclouds/ec2/xml/RunInstancesResponseHandler.java index 5188ae029c..ab776e81f7 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/RunInstancesResponseHandler.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/xml/RunInstancesResponseHandler.java @@ -21,11 +21,13 @@ package org.jclouds.ec2.xml; import javax.inject.Inject; +import org.jclouds.date.DateService; import org.jclouds.ec2.domain.Reservation; import org.jclouds.ec2.domain.RunningInstance; -import org.jclouds.date.DateService; import org.jclouds.location.Region; +import com.google.inject.Provider; + /** * Parses the following XML document: *

@@ -37,8 +39,9 @@ import org.jclouds.location.Region; public class RunInstancesResponseHandler extends BaseReservationHandler> { @Inject - RunInstancesResponseHandler(DateService dateService, @Region String defaultRegion) { - super(dateService, defaultRegion); + RunInstancesResponseHandler(DateService dateService, @Region String defaultRegion, + Provider builderProvider) { + super(dateService, defaultRegion, builderProvider); } @Override diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/EC2AsyncClientTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/EC2AsyncClientTest.java index 52bf7daaa8..ae90573c74 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/EC2AsyncClientTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/EC2AsyncClientTest.java @@ -49,9 +49,7 @@ public class EC2AsyncClientTest extends BaseEC2AsyncClientTest { assert syncClient.getElasticIPAddressServices() != null; assert syncClient.getInstanceServices() != null; assert syncClient.getKeyPairServices() != null; - assert syncClient.getMonitoringServices() != null; assert syncClient.getSecurityGroupServices() != null; - assert syncClient.getPlacementGroupServices() != null; assert syncClient.getWindowsServices() != null; } @@ -63,9 +61,7 @@ public class EC2AsyncClientTest extends BaseEC2AsyncClientTest { assert asyncClient.getElasticIPAddressServices() != null; assert asyncClient.getInstanceServices() != null; assert asyncClient.getKeyPairServices() != null; - assert asyncClient.getMonitoringServices() != null; assert asyncClient.getSecurityGroupServices() != null; - assert asyncClient.getPlacementGroupServices() != null; assert asyncClient.getWindowsServices() != null; } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java index 61d4ed91c5..94959534b5 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java @@ -101,11 +101,8 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest { TemplateOptions options = client.templateOptions(); -// Date before = new Date(); - options.as(EC2TemplateOptions.class).securityGroups(tag); options.as(EC2TemplateOptions.class).keyPair(tag); - options.as(EC2TemplateOptions.class).enableMonitoring(); String startedId = null; try { @@ -129,7 +126,6 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest { RunningInstance instance = getInstance(instanceClient, startedId); assertEquals(instance.getKeyName(), tag); -// checkMonitoringEnabled(before, instance); // make sure we made our dummy group and also let in the user's group assertEquals(Sets.newTreeSet(instance.getGroupIds()), @@ -155,21 +151,6 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest { } } -// private void checkMonitoringEnabled(Date before, RunningInstance instance) { -// assertEquals(instance.getMonitoringState(), MonitoringState.ENABLED); -// -// RestContext monitoringContext = new RestContextFactory().createContext( -// "cloudwatch", identity, credential, ImmutableSet. of(new Log4JLoggingModule())); -// -// try { -// Set datapoints = monitoringContext.getApi().getMetricStatisticsInRegion(instance.getRegion(), -// "CPUUtilization", before, new Date(), 60, "Average"); -// assert datapoints != null; -// } finally { -// monitoringContext.close(); -// } -// } - @Test(enabled = true, dependsOnMethods = "testCompareSizes") public void testExtendedOptionsNoKeyPair() throws Exception { SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) @@ -224,73 +205,13 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest { } } - @Test(enabled = true, dependsOnMethods = "testCompareSizes") - public void testExtendedOptionsWithSubnetId() throws Exception { - - String subnetId = System.getProperty("test.subnetId"); - if (subnetId == null) { - // Skip test and return - return; - } - SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) - .getSecurityGroupServices(); - - KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) - .getKeyPairServices(); - - InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) - .getInstanceServices(); - - String tag = this.tag + "g"; - - TemplateOptions options = client.templateOptions(); - - // options.as(EC2TemplateOptions.class).securityGroups(tag); - options.as(EC2TemplateOptions.class).keyPair(tag); - options.as(EC2TemplateOptions.class).subnetId(subnetId); - - String startedId = null; - String nodeId = null; - try { - cleanupExtendedStuff(securityGroupClient, keyPairClient, tag); - - // create the security group - // securityGroupClient.createSecurityGroupInRegion(null, tag, tag); - - // create a keypair to pass in as well - keyPairClient.createKeyPairInRegion(null, tag); - - Set nodes = client.runNodesWithTag(tag, 1, options); - - NodeMetadata first = Iterables.get(nodes, 0); - assert first.getCredentials() != null : first; - assert first.getCredentials().identity != null : first; - - startedId = Iterables.getOnlyElement(nodes).getProviderId(); - nodeId = Iterables.getOnlyElement(nodes).getId(); - - RunningInstance instance = getInstance(instanceClient, startedId); - - assertEquals(instance.getSubnetId(), subnetId); - - } finally { - if (nodeId != null) - client.destroyNode(nodeId); - if (startedId != null) { - // ensure we didn't delete these resources! - assertEquals(keyPairClient.describeKeyPairsInRegion(null, tag).size(), 1); - } - cleanupExtendedStuff(securityGroupClient, keyPairClient, tag); - } - } - - private RunningInstance getInstance(InstanceClient instanceClient, String id) { + protected RunningInstance getInstance(InstanceClient instanceClient, String id) { RunningInstance instance = Iterables.getOnlyElement(Iterables.getOnlyElement(instanceClient .describeInstancesInRegion(null, id))); return instance; } - private void cleanupExtendedStuff(SecurityGroupClient securityGroupClient, KeyPairClient keyPairClient, String tag) + protected void cleanupExtendedStuff(SecurityGroupClient securityGroupClient, KeyPairClient keyPairClient, String tag) throws InterruptedException { try { for (SecurityGroup group : securityGroupClient.describeSecurityGroupsInRegion(null)) diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceTest.java deleted file mode 100644 index 5e61476aea..0000000000 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * Licensed 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.ec2.compute; - -import static org.easymock.EasyMock.expect; -import static org.easymock.classextension.EasyMock.createMock; -import static org.easymock.classextension.EasyMock.replay; -import static org.easymock.classextension.EasyMock.verify; - -import java.util.Map; -import java.util.concurrent.ExecutorService; - -import javax.inject.Provider; - -import org.jclouds.compute.ComputeServiceContext; -import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; -import org.jclouds.compute.strategy.DestroyNodeStrategy; -import org.jclouds.compute.strategy.GetNodeMetadataStrategy; -import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap; -import org.jclouds.compute.strategy.ListNodesStrategy; -import org.jclouds.compute.strategy.RebootNodeStrategy; -import org.jclouds.compute.strategy.ResumeNodeStrategy; -import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; -import org.jclouds.compute.strategy.SuspendNodeStrategy; -import org.jclouds.ec2.EC2Client; -import org.jclouds.ec2.services.PlacementGroupClient; -import org.testng.annotations.Test; - -import com.google.common.base.Predicate; -import com.google.common.base.Supplier; - -/** - * @author Adrian Cole - */ -@Test(groups = "unit") -public class EC2ComputeServiceTest { - - @SuppressWarnings( { "unchecked" }) - public void testUnsupportedOperationOkForPlacementGroups() { - EC2Client client = createMock(EC2Client.class); - EC2ComputeService service = new EC2ComputeService(createMock(ComputeServiceContext.class), createMock(Map.class), - createMock(Supplier.class), createMock(Supplier.class), createMock(Supplier.class), - createMock(ListNodesStrategy.class), createMock(GetNodeMetadataStrategy.class), - createMock(RunNodesAndAddToSetStrategy.class), createMock(RebootNodeStrategy.class), - createMock(DestroyNodeStrategy.class), createMock(ResumeNodeStrategy.class), - createMock(SuspendNodeStrategy.class), createMock(Provider.class), createMock(Provider.class), - createMock(Predicate.class), createMock(Predicate.class), createMock(Predicate.class), - createMock(InitializeRunScriptOnNodeOrPlaceInBadMap.Factory.class), - createMock(Timeouts.class), createMock(ExecutorService.class), client, createMock(Map.class), - createMock(Map.class), createMock(Map.class), createMock(Predicate.class)); - - PlacementGroupClient placementClient = createMock(PlacementGroupClient.class); - - // setup expectations - expect(client.getPlacementGroupServices()).andReturn(placementClient).atLeastOnce(); - expect(placementClient.describePlacementGroupsInRegion("us-west-1", "jclouds#tag#us-west-1")).andThrow( - new UnsupportedOperationException()); - - // replay mocks - replay(client); - replay(placementClient); - // run - service.deletePlacementGroup("us-west-1", "tag"); - - // verify mocks - verify(client); - verify(placementClient); - - } -} diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java index b8246cc91c..5d17292245 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java @@ -76,14 +76,14 @@ public class RunningInstanceToNodeMetadataTest { RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet. of(), ImmutableSet . of(), ImmutableSet. of(), ImmutableMap. of( - "node#us-east-1/i-9slweygo", creds)); + "node#us-east-1/i-0799056f", creds)); - RunningInstance server = firstInstanceFromResource("/describe_instances_nova.xml"); + RunningInstance server = firstInstanceFromResource("/describe_instances_running.xml"); - assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.TERMINATED).publicAddresses( - ImmutableSet. of()).privateAddresses(ImmutableSet.of("10.128.207.5")).tag("NOTAG#i-9slweygo") - .credentials(creds).imageId("us-east-1/ami-82e4b5c7").id("us-east-1/i-9slweygo") - .providerId("i-9slweygo").build()); + assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.RUNNING).publicAddresses( + ImmutableSet. of()).privateAddresses(ImmutableSet.of("10.243.42.70")).publicAddresses(ImmutableSet.of("174.129.81.68")).tag("NOTAG#i-0799056f") + .credentials(creds).imageId("us-east-1/ami-82e4b5c7").id("us-east-1/i-0799056f") + .providerId("i-0799056f").build()); } @Test @@ -91,11 +91,11 @@ public class RunningInstanceToNodeMetadataTest { RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet. of(), ImmutableSet . of(), ImmutableSet. of(), ImmutableMap. of()); - RunningInstance server = firstInstanceFromResource("/describe_instances_nova.xml"); + RunningInstance server = firstInstanceFromResource("/describe_instances_running.xml"); - assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.TERMINATED).publicAddresses( - ImmutableSet. of()).privateAddresses(ImmutableSet.of("10.128.207.5")).tag("NOTAG#i-9slweygo") - .imageId("us-east-1/ami-82e4b5c7").id("us-east-1/i-9slweygo").providerId("i-9slweygo").build()); + assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.RUNNING).publicAddresses( + ImmutableSet. of()).privateAddresses(ImmutableSet.of("10.243.42.70")).publicAddresses(ImmutableSet.of("174.129.81.68")).tag("NOTAG#i-0799056f") + .imageId("us-east-1/ami-82e4b5c7").id("us-east-1/i-0799056f").providerId("i-0799056f").build()); } @Test @@ -103,11 +103,11 @@ public class RunningInstanceToNodeMetadataTest { RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet. of(), ImmutableSet.of(provider), ImmutableSet. of(), ImmutableMap. of()); - RunningInstance server = firstInstanceFromResource("/describe_instances_nova.xml"); + RunningInstance server = firstInstanceFromResource("/describe_instances_running.xml"); - assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.TERMINATED).privateAddresses( - ImmutableSet.of("10.128.207.5")).tag("NOTAG#i-9slweygo").imageId("us-east-1/ami-82e4b5c7").id( - "us-east-1/i-9slweygo").providerId("i-9slweygo").location(provider).build()); + assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.RUNNING).privateAddresses( + ImmutableSet.of("10.243.42.70")).publicAddresses(ImmutableSet.of("174.129.81.68")).tag("NOTAG#i-0799056f").imageId("us-east-1/ami-82e4b5c7").id( + "us-east-1/i-0799056f").providerId("i-0799056f").location(provider).build()); } @Test @@ -115,14 +115,14 @@ public class RunningInstanceToNodeMetadataTest { RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet. of(), ImmutableSet.of(provider), EC2ImageParserTest.convertImages("/amzn_images.xml"), ImmutableMap. of()); - RunningInstance server = firstInstanceFromResource("/describe_instances_nova.xml"); + RunningInstance server = firstInstanceFromResource("/describe_instances_running.xml"); - assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.TERMINATED).privateAddresses( - ImmutableSet.of("10.128.207.5")).tag("NOTAG#i-9slweygo").imageId("us-east-1/ami-82e4b5c7") + assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.RUNNING).privateAddresses( + ImmutableSet.of("10.243.42.70")).publicAddresses(ImmutableSet.of("174.129.81.68")).tag("NOTAG#i-0799056f").imageId("us-east-1/ami-82e4b5c7") .operatingSystem( new OperatingSystemBuilder().family(OsFamily.UNRECOGNIZED).version("").arch("paravirtual") .description("137112412989/amzn-ami-0.9.7-beta.i386-ebs").is64Bit(false).build()).id( - "us-east-1/i-9slweygo").providerId("i-9slweygo").location(provider).build()); + "us-east-1/i-0799056f").providerId("i-0799056f").location(provider).build()); } @Test @@ -131,14 +131,14 @@ public class RunningInstanceToNodeMetadataTest { .of(provider), EC2ImageParserTest.convertImages("/amzn_images.xml"), ImmutableMap . of()); - RunningInstance server = firstInstanceFromResource("/describe_instances_nova.xml"); + RunningInstance server = firstInstanceFromResource("/describe_instances_running.xml"); - assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.TERMINATED).privateAddresses( - ImmutableSet.of("10.128.207.5")).tag("NOTAG#i-9slweygo").imageId("us-east-1/ami-82e4b5c7").hardware( + assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.RUNNING).privateAddresses( + ImmutableSet.of("10.243.42.70")).publicAddresses(ImmutableSet.of("174.129.81.68")).tag("NOTAG#i-0799056f").imageId("us-east-1/ami-82e4b5c7").hardware( m1_small().build()).operatingSystem( new OperatingSystemBuilder().family(OsFamily.UNRECOGNIZED).version("").arch("paravirtual").description( - "137112412989/amzn-ami-0.9.7-beta.i386-ebs").is64Bit(false).build()).id("us-east-1/i-9slweygo") - .providerId("i-9slweygo").location(provider).build()); + "137112412989/amzn-ami-0.9.7-beta.i386-ebs").is64Bit(false).build()).id("us-east-1/i-0799056f") + .providerId("i-0799056f").location(provider).build()); } @Test @@ -160,11 +160,12 @@ public class RunningInstanceToNodeMetadataTest { .of(provider), ImmutableMap. of(), EC2ComputeServiceDependenciesModule.instanceToNodeState, instanceToImage); - RunningInstance server = firstInstanceFromResource("/describe_instances_nova.xml"); + RunningInstance server = firstInstanceFromResource("/describe_instances_running.xml"); - assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.TERMINATED).privateAddresses( - ImmutableSet.of("10.128.207.5")).tag("NOTAG#i-9slweygo").imageId("us-east-1/ami-82e4b5c7").id( - "us-east-1/i-9slweygo").providerId("i-9slweygo").hardware(m1_small().build()).location(provider).build()); + assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.RUNNING).privateAddresses( + ImmutableSet.of("10.243.42.70")).publicAddresses(ImmutableSet.of("174.129.81.68")).tag( + "NOTAG#i-0799056f").imageId("us-east-1/ami-82e4b5c7").id("us-east-1/i-0799056f") + .providerId("i-0799056f").hardware(m1_small().build()).location(provider).build()); } protected RunningInstance firstInstanceFromResource(String resource) { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/options/EC2TemplateOptionsTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/options/EC2TemplateOptionsTest.java index 070cf275ec..1de6ded869 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/options/EC2TemplateOptionsTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/options/EC2TemplateOptionsTest.java @@ -21,7 +21,6 @@ package org.jclouds.ec2.compute.options; import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.authorizePublicKey; import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.blockOnPort; -import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.enableMonitoring; import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.inboundPorts; import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.installPrivateKey; import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.keyPair; @@ -172,26 +171,6 @@ public class EC2TemplateOptionsTest { assert !options.shouldAutomaticallyCreateKeyPair(); } - @Test - public void testMonitoringEnabledDefault() { - EC2TemplateOptions options = new EC2TemplateOptions(); - assert !options.isMonitoringEnabled(); - } - - @Test - public void testMonitoringEnabled() { - EC2TemplateOptions options = new EC2TemplateOptions(); - options.enableMonitoring(); - assert options.isMonitoringEnabled(); - } - - @Test - public void testEnableMonitoringStatic() { - EC2TemplateOptions options = enableMonitoring(); - assertEquals(options.getKeyPair(), null); - assert options.isMonitoringEnabled(); - } - // superclass tests @Test(expectedExceptions = IllegalArgumentException.class) public void testinstallPrivateKeyBadFormat() { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java new file mode 100644 index 0000000000..5b20782e9a --- /dev/null +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java @@ -0,0 +1,442 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.ec2.compute.strategy; + +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; +import static org.testng.Assert.assertEquals; + +import java.lang.reflect.Method; +import java.util.Map; +import java.util.Set; + +import javax.inject.Provider; + +import org.jclouds.aws.domain.Region; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.ec2.compute.domain.EC2HardwareBuilder; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules; +import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; +import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.domain.BlockDeviceMapping; +import org.jclouds.ec2.domain.KeyPair; +import org.jclouds.ec2.options.RunInstancesOptions; +import org.jclouds.encryption.internal.Base64; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit") +public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { + + private static final Provider OPTIONS_PROVIDER = new javax.inject.Provider() { + + @Override + public RunInstancesOptions get() { + return new RunInstancesOptions(); + } + + }; + + public void testExecuteWithDefaultOptionsEC2() throws SecurityException, NoSuchMethodException { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + Hardware size = EC2HardwareBuilder.m1_small().build(); + String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; + String generatedGroup = "group"; + Set generatedGroups = ImmutableSet.of(generatedGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, + TemplateOptions.class) }); + + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + Template template = createMock(Template.class); + + // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); + expect(template.getHardware()).andReturn(size).atLeastOnce(); + expect(template.getOptions()).andReturn(options).atLeastOnce(); + expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); + expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( + systemGeneratedKeyPairName); + expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); + expect(options.getUserData()).andReturn(null); + + // replay mocks + replay(options); + replay(template); + replay(strategy); + + // run + RunInstancesOptions customize = strategy.execute(region, tag, template); + assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); + assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", + size.getProviderId(), "SecurityGroup.1", generatedGroup, "KeyName", systemGeneratedKeyPairName) + .entries()); + assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); + assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); + assertEquals(customize.buildStringPayload(), null); + + // verify mocks + verify(options); + verify(template); + verify(strategy); + } + + public void testExecuteWithUserData() throws SecurityException, NoSuchMethodException { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + Hardware size = EC2HardwareBuilder.m1_small().build(); + String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; + String generatedGroup = "group"; + Set generatedGroups = ImmutableSet.of(generatedGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, + TemplateOptions.class) }); + + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + Template template = createMock(Template.class); + + // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); + expect(template.getHardware()).andReturn(size).atLeastOnce(); + expect(template.getOptions()).andReturn(options).atLeastOnce(); + expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); + expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( + systemGeneratedKeyPairName); + expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); + expect(options.getUserData()).andReturn("hello".getBytes()); + + // replay mocks + replay(options); + replay(template); + replay(strategy); + + // run + RunInstancesOptions customize = strategy.execute(region, tag, template); + assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); + assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", + size.getProviderId(), "SecurityGroup.1", "group", "KeyName", systemGeneratedKeyPairName, "UserData", + Base64.encodeBytes("hello".getBytes())).entries()); + assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); + assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); + assertEquals(customize.buildStringPayload(), null); + + // verify mocks + verify(options); + verify(template); + verify(strategy); + } + + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldTo() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String userSuppliedKeyPair = "myKeyPair"; + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), userSuppliedKeyPair); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_createsNewKeyPairAndReturnsItsNameByDefault() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String userSuppliedKeyPair = null; + boolean shouldAutomaticallyCreateKeyPair = true; + String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair); + expect(strategy.createUniqueKeyPair.apply(new RegionAndName(region, tag))).andReturn(keyPair); + expect(keyPair.getKeyName()).andReturn(systemGeneratedKeyPairName).atLeastOnce(); + expect(strategy.credentialsMap.put(new RegionAndName(region, systemGeneratedKeyPairName), keyPair)).andReturn( + null); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), + systemGeneratedKeyPairName); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_doesntCreateAKeyPairAndReturnsNullWhenToldNotTo() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String userSuppliedKeyPair = null; + boolean shouldAutomaticallyCreateKeyPair = false; // here's the important + // part! + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), null); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + public void testGetSecurityGroupsForTagAndOptions_createsNewGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesntExist() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String generatedMarkerGroup = "jclouds#tag#" + Region.AP_SOUTHEAST_1; + Set groupIds = ImmutableSet. of(); + int[] ports = new int[] {}; + boolean shouldAuthorizeSelf = true; + boolean groupExisted = false; + Set returnVal = ImmutableSet. of(generatedMarkerGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + + // setup expectations + expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); + expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); + RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, + ports, shouldAuthorizeSelf); + expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted); + expect(strategy.createSecurityGroupIfNeeded.apply(regionNameAndIngressRules)).andReturn(generatedMarkerGroup); + expect(strategy.securityGroupMap.put(regionNameAndIngressRules, generatedMarkerGroup)).andReturn(null); + + // replay mocks + replay(options); + replayStrategy(strategy); + + // run + assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, tag, options), returnVal); + + // verify mocks + verify(options); + verifyStrategy(strategy); + } + + public void testGetSecurityGroupsForTagAndOptions_createsNewGroupByDefaultWhenPortsAreSpecifiedWhenDoesntExist() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String generatedMarkerGroup = "jclouds#tag#" + Region.AP_SOUTHEAST_1; + Set groupIds = ImmutableSet. of(); + int[] ports = new int[] { 22, 80 }; + boolean shouldAuthorizeSelf = true; + boolean groupExisted = false; + Set returnVal = ImmutableSet. of(generatedMarkerGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + + // setup expectations + expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); + expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); + RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, + ports, shouldAuthorizeSelf); + expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted); + expect(strategy.createSecurityGroupIfNeeded.apply(regionNameAndIngressRules)).andReturn(generatedMarkerGroup); + expect(strategy.securityGroupMap.put(regionNameAndIngressRules, generatedMarkerGroup)).andReturn(null); + + // replay mocks + replay(options); + replayStrategy(strategy); + + // run + assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, tag, options), returnVal); + + // verify mocks + verify(options); + verifyStrategy(strategy); + } + + public void testGetSecurityGroupsForTagAndOptions_reusesGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesExist() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String generatedMarkerGroup = "jclouds#tag#" + Region.AP_SOUTHEAST_1; + Set groupIds = ImmutableSet. of(); + int[] ports = new int[] {}; + boolean shouldAuthorizeSelf = true; + boolean groupExisted = true; + Set returnVal = ImmutableSet. of(generatedMarkerGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + + // setup expectations + expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); + expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); + RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, + ports, shouldAuthorizeSelf); + expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted); + + // replay mocks + replay(options); + replayStrategy(strategy); + + // run + assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, tag, options), returnVal); + + // verify mocks + verify(options); + verifyStrategy(strategy); + } + + public void testGetSecurityGroupsForTagAndOptions_reusesGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesExistAndAcceptsUserSuppliedGroups() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String generatedMarkerGroup = "jclouds#tag#" + Region.AP_SOUTHEAST_1; + Set groupIds = ImmutableSet. of("group1", "group2"); + int[] ports = new int[] {}; + boolean shouldAuthorizeSelf = true; + boolean groupExisted = true; + Set returnVal = ImmutableSet. of(generatedMarkerGroup, "group1", "group2"); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + + // setup expectations + expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); + RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, + ports, shouldAuthorizeSelf); // note + // this + // works + // since + // there's + // no equals on portsq + expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted); + + // replay mocks + replay(options); + replayStrategy(strategy); + + // run + assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, tag, options), returnVal); + + // verify mocks + verify(options); + verifyStrategy(strategy); + } + + private void verifyStrategy(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy) { + verify(strategy.credentialsMap); + verify(strategy.securityGroupMap); + verify(strategy.createUniqueKeyPair); + verify(strategy.createSecurityGroupIfNeeded); + } + + @SuppressWarnings("unchecked") + private CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions setupStrategy() { + Map credentialsMap = createMock(Map.class); + Map securityGroupMap = createMock(Map.class); + CreateUniqueKeyPair createUniqueKeyPair = createMock(CreateUniqueKeyPair.class); + CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded = createMock(CreateSecurityGroupIfNeeded.class); + + return new CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(credentialsMap, securityGroupMap, + createUniqueKeyPair, createSecurityGroupIfNeeded, OPTIONS_PROVIDER); + } + + private void replayStrategy(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy) { + replay(strategy.credentialsMap); + replay(strategy.securityGroupMap); + replay(strategy.createUniqueKeyPair); + replay(strategy.createSecurityGroupIfNeeded); + } + +} diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategyTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategyTest.java index f584ed933d..60e98f350f 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategyTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategyTest.java @@ -127,7 +127,6 @@ public class EC2RunNodesAndAddToSetStrategyTest { expect(strategy.instancePresent.apply(instance)).andReturn(true); expect(input.template.getOptions()).andReturn(input.options).atLeastOnce(); - expect(input.options.isMonitoringEnabled()).andReturn(false); expect(strategy.runningInstanceToNodeMetadata.apply(instance)).andReturn(nodeMetadata); expect( @@ -212,7 +211,7 @@ public class EC2RunNodesAndAddToSetStrategyTest { @SuppressWarnings("unchecked") private EC2RunNodesAndAddToSetStrategy setupStrategy() { EC2Client client = createMock(EC2Client.class); - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize = createMock(CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class); + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize = createMock(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class); Predicate instanceStateRunning = createMock(Predicate.class); RunningInstanceToNodeMetadata runningInstanceToNodeMetadata = createMock(RunningInstanceToNodeMetadata.class); Function instanceToCredentials = createMock(Function.class); diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/options/RunInstancesOptionsTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/options/RunInstancesOptionsTest.java index e94200e161..86671e087d 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/options/RunInstancesOptionsTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/options/RunInstancesOptionsTest.java @@ -20,14 +20,12 @@ package org.jclouds.ec2.options; import static org.jclouds.ec2.options.RunInstancesOptions.Builder.asType; -import static org.jclouds.ec2.options.RunInstancesOptions.Builder.enableMonitoring; +import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withBlockDeviceMappings; import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withKernelId; import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withKeyName; import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withRamdisk; import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withSecurityGroup; -import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withSubnetId; import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withUserData; -import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withBlockDeviceMappings; import static org.testng.Assert.assertEquals; import java.util.Collections; @@ -183,49 +181,6 @@ public class RunInstancesOptionsTest { withKernelId(null); } - @Test - public void testWithMonitoringEnabled() { - RunInstancesOptions options = new RunInstancesOptions(); - options.enableMonitoring(); - assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections.singletonList("true")); - } - - @Test - public void testNullWithMonitoringEnabled() { - RunInstancesOptions options = new RunInstancesOptions(); - assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections.EMPTY_LIST); - } - - @Test - public void testWithMonitoringEnabledStatic() { - RunInstancesOptions options = enableMonitoring(); - assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections.singletonList("true")); - } - - @Test - public void testWithSubnetId() { - RunInstancesOptions options = new RunInstancesOptions(); - options.withSubnetId("test"); - assertEquals(options.buildFormParameters().get("SubnetId"), Collections.singletonList("test")); - } - - @Test - public void testNullWithSubnetId() { - RunInstancesOptions options = new RunInstancesOptions(); - assertEquals(options.buildFormParameters().get("SubnetId"), Collections.EMPTY_LIST); - } - - @Test - public void testWithSubnetIdStatic() { - RunInstancesOptions options = withSubnetId("test"); - assertEquals(options.buildFormParameters().get("SubnetId"), Collections.singletonList("test")); - } - - @Test(expectedExceptions = NullPointerException.class) - public void testWithSubnetIdNPE() { - withSubnetId(null); - } - @Test public void testWithRamdisk() { RunInstancesOptions options = new RunInstancesOptions(); @@ -255,17 +210,20 @@ public class RunInstancesOptionsTest { RunInstancesOptions options = new RunInstancesOptions(); assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"), Collections.EMPTY_LIST); } - + @Test public void testWithBlockDeviceMapping() { RunInstancesOptions options = new RunInstancesOptions(); BlockDeviceMapping mapping = new BlockDeviceMapping("/dev/sda1", null, null, 120, null, true); - Set mappings = new HashSet(); + Set mappings = new HashSet(); mappings.add(mapping); options.withBlockDeviceMappings(mappings); - assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections.singletonList("/dev/sda1")); - assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections.singletonList("120")); - assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections.singletonList("true")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections + .singletonList("/dev/sda1")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections + .singletonList("120")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections + .singletonList("true")); } @Test @@ -277,17 +235,20 @@ public class RunInstancesOptionsTest { @Test public void testWithBlockDeviceMappingStatic() { BlockDeviceMapping mapping = new BlockDeviceMapping("/dev/sda1", null, null, 120, null, true); - Set mappings = new HashSet(); + Set mappings = new HashSet(); mappings.add(mapping); RunInstancesOptions options = withBlockDeviceMappings(mappings); - assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections.singletonList("/dev/sda1")); - assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections.singletonList("120")); - assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections.singletonList("true")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections + .singletonList("/dev/sda1")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections + .singletonList("120")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections + .singletonList("true")); } @Test(expectedExceptions = NullPointerException.class) public void testWithBlockDeviceMappingNPE() { - withBlockDeviceMappings(null); + withBlockDeviceMappings(null); } } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIAsyncClientTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIAsyncClientTest.java index 5d5afa3766..d63ca92ec9 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIAsyncClientTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIAsyncClientTest.java @@ -33,7 +33,6 @@ import org.jclouds.ec2.xml.BlockDeviceMappingHandler; import org.jclouds.ec2.xml.DescribeImagesResponseHandler; import org.jclouds.ec2.xml.ImageIdHandler; import org.jclouds.ec2.xml.PermissionHandler; -import org.jclouds.ec2.xml.ProductCodesHandler; import org.jclouds.http.HttpRequest; import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ReleasePayloadAndReturn; @@ -222,23 +221,6 @@ public class AMIAsyncClientTest extends BaseEC2AsyncClientTest { checkFilters(request); } - public void testGetProductCodesForImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("getProductCodesForImageInRegion", String.class, String.class); - HttpRequest request = processor.createRequest(method, null, "imageId"); - - assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); - assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); - assertPayloadEquals(request, - "Version=2010-06-15&Action=DescribeImageAttribute&Attribute=productCodes&ImageId=imageId", - "application/x-www-form-urlencoded", false); - - assertResponseParserClassEquals(method, request, ParseSax.class); - assertSaxResponseParserClassEquals(method, ProductCodesHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(request); - } - public void testGetBlockDeviceMappingsForImage() throws SecurityException, NoSuchMethodException, IOException { Method method = AMIAsyncClient.class.getMethod("getBlockDeviceMappingsForImageInRegion", String.class, String.class); @@ -335,44 +317,6 @@ public class AMIAsyncClientTest extends BaseEC2AsyncClientTest { checkFilters(request); } - public void testAddProductCodesToImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("addProductCodesToImageInRegion", String.class, Iterable.class, - String.class); - HttpRequest request = processor.createRequest(method, null, ImmutableList.of("code1", "code2"), "imageId"); - - assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); - assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); - assertPayloadEquals( - request, - "Version=2010-06-15&Action=ModifyImageAttribute&OperationType=add&Attribute=productCodes&ImageId=imageId&ProductCode.1=code1&ProductCode.2=code2", - "application/x-www-form-urlencoded", false); - - assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, null); - - checkFilters(request); - } - - public void testRemoveProductCodesFromImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("removeProductCodesFromImageInRegion", String.class, - Iterable.class, String.class); - HttpRequest request = processor.createRequest(method, null, ImmutableList.of("code1", "code2"), "imageId"); - - assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); - assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); - assertPayloadEquals( - request, - "Version=2010-06-15&Action=ModifyImageAttribute&OperationType=remove&Attribute=productCodes&ImageId=imageId&ProductCode.1=code1&ProductCode.2=code2", - "application/x-www-form-urlencoded", false); - - assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, null); - - checkFilters(request); - } - @Override protected TypeLiteral> createTypeLiteral() { return new TypeLiteral>() { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIClientLiveTest.java index 4703aadc0c..7e6a7208a8 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIClientLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIClientLiveTest.java @@ -37,8 +37,8 @@ import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.ec2.EC2AsyncClient; import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.domain.Image; -import org.jclouds.ec2.domain.Image.ImageType; import org.jclouds.ec2.domain.RootDeviceType; +import org.jclouds.ec2.domain.Image.ImageType; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.rest.RestContext; import org.testng.annotations.AfterTest; @@ -101,8 +101,8 @@ public class AMIClientLiveTest { public void setupClient() { setupCredentials(); Properties overrides = setupProperties(); - context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet. of(new Log4JLoggingModule()), - overrides).getProviderSpecificContext(); + context = new ComputeServiceContextFactory().createContext(provider, + ImmutableSet. of(new Log4JLoggingModule()), overrides).getProviderSpecificContext(); client = context.getApi().getAMIServices(); } @@ -223,10 +223,6 @@ public class AMIClientLiveTest { System.out.println(client.getLaunchPermissionForImageInRegion(null, imageId)); } - public void testGetProductCodesForImage() { - System.out.println(client.getProductCodesForImageInRegion(null, imageId)); - } - @Test(enabled = false) // awaiting ebs support public void testGetBlockDeviceMappingsForImage() { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/BaseEC2AsyncClientTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/BaseEC2AsyncClientTest.java index f9eff08931..9aec3ddb74 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/BaseEC2AsyncClientTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/BaseEC2AsyncClientTest.java @@ -29,6 +29,8 @@ import java.util.Properties; import org.jclouds.aws.domain.Region; import org.jclouds.aws.filters.FormSigner; import org.jclouds.date.DateService; +import org.jclouds.ec2.EC2AsyncClient; +import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.config.EC2RestClientModule; import org.jclouds.ec2.domain.AvailabilityZone; import org.jclouds.http.HttpRequest; @@ -50,7 +52,11 @@ import com.google.inject.Module; public abstract class BaseEC2AsyncClientTest extends RestClientTest { @RequiresHttp @ConfiguresRestClient - protected static class StubEC2RestClientModule extends EC2RestClientModule { + protected static class StubEC2RestClientModule extends EC2RestClientModule { + + public StubEC2RestClientModule() { + super(EC2Client.class, EC2AsyncClient.class, DELEGATE_MAP); + } @Override protected String provideTimeStamp(DateService dateService, int expiration) { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceAsyncClientTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceAsyncClientTest.java index 6fdbbf9a5f..3088a7ffd7 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceAsyncClientTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceAsyncClientTest.java @@ -64,7 +64,7 @@ public class InstanceAsyncClientTest extends BaseEC2AsyncClientTest mapping = Maps.newLinkedHashMap(); mapping.put("/dev/sda1", new BlockDevice("vol-test1", true)); @@ -478,14 +476,14 @@ public class InstanceAsyncClientTest extends BaseEC2AsyncClientTest> contents = Sets.newLinkedHashSet(); - - contents.add(new Reservation(defaultRegion, ImmutableSet.of("adriancole.ec2ingress"), - ImmutableSet.of(new RunningInstance(defaultRegion, ImmutableSet.of("adriancole.ec2ingress"), "0", - "ec2-174-129-81-68.compute-1.amazonaws.com", "ami-1fd73376", "i-0799056f", InstanceState.RUNNING, - InstanceType.M1_SMALL, "174.129.81.68", "aki-a71cf9ce", "adriancole.ec21", dateService - .iso8601DateParse("2009-11-09T03:00:34.000Z"), MonitoringState.DISABLED, - AvailabilityZone.US_EAST_1C, null, "paravirtual", null, "ip-10-243-42-70.ec2.internal", - "10.243.42.70", ImmutableSet. of(), "ari-a51cf9cc", null, null, null, null, - RootDeviceType.INSTANCE_STORE, null, ImmutableMap. of())), "993194456877", - null, "r-a3c508cb")); + Set> contents = ImmutableSet.of(new Reservation(defaultRegion, + ImmutableSet.of("adriancole.ec2ingress"), ImmutableSet.of(new RunningInstance.Builder().region( + defaultRegion).groupId("adriancole.ec2ingress").amiLaunchIndex("0").dnsName( + "ec2-174-129-81-68.compute-1.amazonaws.com").imageId("ami-82e4b5c7").instanceId("i-0799056f") + .instanceState(InstanceState.RUNNING).instanceType(InstanceType.M1_SMALL).ipAddress( + "174.129.81.68").kernelId("aki-a71cf9ce").keyName("adriancole.ec21").launchTime( + dateService.iso8601DateParse("2009-11-09T03:00:34.000Z")) + // MonitoringState.DISABLED, + .availabilityZone(AvailabilityZone.US_EAST_1C).virtualizationType("paravirtual") + .privateDnsName("ip-10-243-42-70.ec2.internal").privateIpAddress("10.243.42.70").ramdiskId( + "ari-a51cf9cc").rootDeviceType(RootDeviceType.INSTANCE_STORE).build()), + "993194456877", null, "r-a3c508cb")); Set> result = parseRunningInstances("/describe_instances_running.xml"); @@ -86,82 +85,54 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest { } public void testApplyInputStream() { - - Set> contents = Sets.newLinkedHashSet(); - - contents.add(new Reservation(defaultRegion, ImmutableSet.of("default"), ImmutableSet.of( - new RunningInstance(defaultRegion, ImmutableSet.of("default"), "23", - "ec2-72-44-33-4.compute-1.amazonaws.com", "ami-6ea54007", "i-28a64341", InstanceState.RUNNING, - InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3", "example-key-name", dateService - .iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED, - AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-132.ec2.internal", null, - ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null, null, RootDeviceType.INSTANCE_STORE, - null, ImmutableMap. of()), - new RunningInstance(defaultRegion, ImmutableSet.of("default"), "23", - "ec2-72-44-33-6.compute-1.amazonaws.com", "ami-6ea54007", "i-28a64435", InstanceState.RUNNING, - InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3", "example-key-name", dateService - .iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED, - AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-134.ec2.internal", null, - ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null, null, RootDeviceType.INSTANCE_STORE, - null, ImmutableMap. of())), "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null, - "r-44a5402d")); + Set> contents = ImmutableSet.of(new Reservation(defaultRegion, + ImmutableSet.of("default"), ImmutableSet.of(new RunningInstance.Builder().region(defaultRegion).groupId( + "default").amiLaunchIndex("23").dnsName("ec2-72-44-33-4.compute-1.amazonaws.com").imageId( + "ami-6ea54007").instanceId("i-28a64341").instanceState(InstanceState.RUNNING).instanceType( + InstanceType.M1_LARGE).kernelId("aki-ba3adfd3").keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:54:42.000Z")) + // MonitoringState.DISABLED, + .availabilityZone(AvailabilityZone.US_EAST_1B).virtualizationType("paravirtual") + .privateDnsName("10-251-50-132.ec2.internal")// product codes + // ImmutableSet.of("774F4FF8") + .ramdiskId("ari-badbad00").rootDeviceType(RootDeviceType.INSTANCE_STORE).build(), + new RunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("23") + .dnsName("ec2-72-44-33-6.compute-1.amazonaws.com").imageId("ami-6ea54007").instanceId( + "i-28a64435").instanceState(InstanceState.RUNNING).instanceType( + InstanceType.M1_LARGE).kernelId("aki-ba3adfd3").keyName("example-key-name") + .launchTime(dateService.iso8601DateParse("2007-08-07T11:54:42.000Z")) + // MonitoringState.DISABLED, + .availabilityZone(AvailabilityZone.US_EAST_1B).virtualizationType("paravirtual") + .privateDnsName("10-251-50-134.ec2.internal")// product codes + // ImmutableSet.of("774F4FF8") + .ramdiskId("ari-badbad00").rootDeviceType(RootDeviceType.INSTANCE_STORE).build()), + "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null, "r-44a5402d")); Set> result = parseRunningInstances("/describe_instances.xml"); assertEquals(result, contents); } - @Test(enabled = false) - // TODO not sure why equals fails - public void testApplyInputStreamEuc() { - - Set> contents = Sets.newLinkedHashSet(); - - contents.add(new Reservation(defaultRegion, ImmutableSet.of("default"), ImmutableSet - .of(new RunningInstance(defaultRegion, ImmutableSet.of("jclouds#euc"), "1", null, "emi-9ACB1363", - "i-3FFA0762", InstanceState.SHUTTING_DOWN, InstanceType.M1_LARGE, null, "eki-6CBD12F2", - "jclouds#euc-17", dateService.iso8601DateParse("2010-06-16T03:06:19.000Z"), MonitoringState.DISABLED, - "open", null, "paravirtual", null, "10.7.0.179", null, ImmutableSet. of(), "eri-A97113E4", - null, null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap - . of())), "jclouds", null, "r-4D2A08AD")); - - Set> result = parseRunningInstances("/describe_instances_euc.xml"); - - assertEquals(result, contents); - } - - public void testApplyInputStreamNovaNoAvailabilityZone() { - Set> contents = Sets.newLinkedHashSet(); - - contents.add(new Reservation(defaultRegion, ImmutableSet.of("default"), ImmutableSet - .of(new RunningInstance(defaultRegion, ImmutableSet. of(), "0", null, "ami-82e4b5c7", "i-9slweygo", - InstanceState.TERMINATED, InstanceType.M1_SMALL, null, null, "nebulatanimislam", dateService - .iso8601SecondsDateParse("2010-09-09T18:09:42Z"), null, null, null, "paravirtual", null, null, - "10.128.207.5", ImmutableSet. of("None"), null, null, null, null, null, - RootDeviceType.INSTANCE_STORE, null, ImmutableMap. of())), "tislam1", null, - "r-opqeylmj")); - - Set> result = parseRunningInstances("/describe_instances_nova.xml"); - - assertEquals(result, contents); - } - public void testEBS() throws UnknownHostException { - Set> contents = Sets.newLinkedHashSet(); - - contents.add(new Reservation(defaultRegion, ImmutableSet.of("adriancole.ec2ebsingress"), - ImmutableSet.of(new RunningInstance(defaultRegion, ImmutableSet.of("adriancole.ec2ebsingress"), "0", - "ec2-75-101-203-146.compute-1.amazonaws.com", "ami-849875ed", "i-e564438d", InstanceState.RUNNING, - InstanceType.M1_SMALL, "75.101.203.146", "aki-a71cf9ce", "adriancole.ec2ebs1", dateService - .iso8601DateParse("2009-12-30T04:06:23.000Z"), MonitoringState.DISABLED, - AvailabilityZone.US_EAST_1B, "placement", "hvm", null, "domU-12-31-39-09-CE-53.compute-1.internal", - "10.210.209.157", ImmutableSet. of(), "ari-a51cf9cc", null, null, null, null, - RootDeviceType.EBS, "/dev/sda1", ImmutableMap. of( - "/dev/sda1", - new BlockDevice("vol-dc6ca8b5", Attachment.Status.ATTACHED, dateService - .iso8601DateParse("2009-12-30T04:06:29.000Z"), true)))), "993194456877", null, - "r-596dd731")); + Set> contents = ImmutableSet.of(new Reservation(defaultRegion, + ImmutableSet.of("adriancole.ec2ebsingress"), ImmutableSet.of(new RunningInstance.Builder().region( + defaultRegion).groupId("adriancole.ec2ebsingress").amiLaunchIndex("0").dnsName( + "ec2-75-101-203-146.compute-1.amazonaws.com").imageId("ami-849875ed").instanceId("i-e564438d") + .instanceState(InstanceState.RUNNING).instanceType(InstanceType.M1_SMALL).ipAddress( + "75.101.203.146").kernelId("aki-a71cf9ce") + .keyName("adriancole.ec2ebs1") + .launchTime(dateService.iso8601DateParse("2009-12-30T04:06:23.000Z")) + // MonitoringState.DISABLED + .availabilityZone(AvailabilityZone.US_EAST_1B) + // "placement" + .virtualizationType("hvm").privateDnsName("domU-12-31-39-09-CE-53.compute-1.internal") + .privateIpAddress("10.210.209.157").ramdiskId("ari-a51cf9cc") + .rootDeviceType(RootDeviceType.EBS).rootDeviceName("/dev/sda1").device( + "/dev/sda1", + new BlockDevice("vol-dc6ca8b5", Attachment.Status.ATTACHED, dateService + .iso8601DateParse("2009-12-30T04:06:29.000Z"), true)).build()), + "993194456877", null, "r-596dd731")); Set> result = parseRunningInstances("/describe_instances_ebs.xml"); @@ -178,7 +149,8 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest { }); ParseSax>> parser = (ParseSax>>) injector - .getInstance(ParseSax.Factory.class).create(injector.getInstance(DescribeInstancesResponseHandler.class)); + .getInstance(ParseSax.Factory.class) + .create(injector.getInstance(DescribeInstancesResponseHandler.class)); return parser; } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/xml/RunInstancesResponseHandlerTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/xml/RunInstancesResponseHandlerTest.java index 9988a14e38..a35063aaf5 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/xml/RunInstancesResponseHandlerTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/xml/RunInstancesResponseHandlerTest.java @@ -26,31 +26,26 @@ import static org.testng.Assert.assertEquals; import java.io.InputStream; +import org.jclouds.date.DateService; import org.jclouds.ec2.domain.AvailabilityZone; -import org.jclouds.ec2.domain.BlockDevice; import org.jclouds.ec2.domain.InstanceState; import org.jclouds.ec2.domain.InstanceType; -import org.jclouds.ec2.domain.MonitoringState; import org.jclouds.ec2.domain.Reservation; -import org.jclouds.ec2.domain.RootDeviceType; import org.jclouds.ec2.domain.RunningInstance; -import org.jclouds.date.DateService; import org.jclouds.http.functions.ParseSax; import org.jclouds.rest.internal.GeneratedHttpRequest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; /** * Tests behavior of {@code RunInstancesResponseHandler} * * @author Adrian Cole */ -//NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire @Test(groups = "unit", testName = "RunInstancesResponseHandlerTest") public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest { @@ -69,24 +64,27 @@ public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest { InputStream is = getClass().getResourceAsStream("/run_instances.xml"); Reservation expected = new Reservation(defaultRegion, ImmutableSet - .of("default"), ImmutableSet.of(new RunningInstance(defaultRegion, ImmutableSet.of("default"), "0", - null, "ami-60a54009", "i-2ba64342", InstanceState.PENDING, InstanceType.M1_SMALL, (String) null, null, - "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), MonitoringState.ENABLED, - AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, Sets - . newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, - null, ImmutableMap. of()), new RunningInstance(defaultRegion, ImmutableSet - .of("default"), "1", null, "ami-60a54009", "i-2bc64242", InstanceState.PENDING, InstanceType.M1_SMALL, - (String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), - MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, - Sets. newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, null, - ImmutableMap. of()), new RunningInstance(defaultRegion, ImmutableSet - .of("default"), "2", null, "ami-60a54009", "i-2be64332", InstanceState.PENDING, InstanceType.M1_SMALL, - (String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), - MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, - Sets. newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, null, - ImmutableMap. of()) + .of("default"), ImmutableSet.of( - ), "AIDADH4IGTRXXKCD", null, "r-47a5402e"); + new RunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("0") + .imageId("ami-60a54009").instanceId("i-2ba64342").instanceState(InstanceState.PENDING).instanceType( + InstanceType.M1_SMALL).keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"))// MonitoringState.ENABLED, + .availabilityZone(AvailabilityZone.US_EAST_1B).build(), + + new RunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("1") + .imageId("ami-60a54009").instanceId("i-2bc64242").instanceState(InstanceState.PENDING).instanceType( + InstanceType.M1_SMALL).keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"))// MonitoringState.ENABLED, + .availabilityZone(AvailabilityZone.US_EAST_1B).build(), + + new RunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("2") + .imageId("ami-60a54009").instanceId("i-2be64332").instanceState(InstanceState.PENDING).instanceType( + InstanceType.M1_SMALL).keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"))// MonitoringState.ENABLED, + .availabilityZone(AvailabilityZone.US_EAST_1B).build()) + + , "AIDADH4IGTRXXKCD", null, "r-47a5402e"); RunInstancesResponseHandler handler = injector.getInstance(RunInstancesResponseHandler.class); addDefaultRegionToHandler(handler); @@ -96,7 +94,7 @@ public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest { private void addDefaultRegionToHandler(ParseSax.HandlerWithResult handler) { GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); - expect(request.getArgs()).andReturn(ImmutableList.of()).atLeastOnce(); + expect(request.getArgs()).andReturn(ImmutableList. of()).atLeastOnce(); replay(request); handler.setContext(request); } diff --git a/apis/ec2/src/test/resources/describe_instances_euc.xml b/apis/ec2/src/test/resources/describe_instances_euc.xml deleted file mode 100644 index 7ee16645a2..0000000000 --- a/apis/ec2/src/test/resources/describe_instances_euc.xml +++ /dev/null @@ -1,39 +0,0 @@ - - e323d0bd-48a2-401b-aeee-1cbf653bc6db - - - r-4D2A08AD - jclouds - - - jclouds#euc - - - - - i-3FFA0762 - emi-9ACB1363 - - 32 - shutting-down - - 10.7.0.179 - 0.0.0.0 - jclouds#euc-17 - 1 - - m1.large - 2010-06-16T03:06:19Z - - open - - eki-6CBD12F2 - eri-A97113E4 - - false - - - - - - \ No newline at end of file diff --git a/apis/ec2/src/test/resources/describe_instances_nova.xml b/apis/ec2/src/test/resources/describe_instances_nova.xml deleted file mode 100644 index f38353fc12..0000000000 --- a/apis/ec2/src/test/resources/describe_instances_nova.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - G7PDD1DNVLO7DZS6AFZH - - - - - 10.128.207.5 - 0 - m1.small - - 2010-09-09T18:09:42Z - i-9slweygo - ami-82e4b5c7 - - 1 - shutdown - - nebulatanimislam - 10.128.207.5 - - - None - - - - - r-opqeylmj - - - default - - - tislam1 - - - \ No newline at end of file diff --git a/apis/ec2/src/test/resources/describe_instances_running.xml b/apis/ec2/src/test/resources/describe_instances_running.xml index 41332fd38a..d3813d4356 100644 --- a/apis/ec2/src/test/resources/describe_instances_running.xml +++ b/apis/ec2/src/test/resources/describe_instances_running.xml @@ -12,7 +12,7 @@ i-0799056f - ami-1fd73376 + ami-82e4b5c7 16 running diff --git a/apis/eucalyptus/src/main/java/org/jclouds/eucalyptus/EucalyptusPropertiesBuilder.java b/apis/eucalyptus/src/main/java/org/jclouds/eucalyptus/EucalyptusPropertiesBuilder.java index d8048aa959..d9de27819c 100644 --- a/apis/eucalyptus/src/main/java/org/jclouds/eucalyptus/EucalyptusPropertiesBuilder.java +++ b/apis/eucalyptus/src/main/java/org/jclouds/eucalyptus/EucalyptusPropertiesBuilder.java @@ -22,7 +22,6 @@ package org.jclouds.eucalyptus; import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_TIMEOUT_PORT_OPEN; import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; -import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; import java.util.Properties; @@ -38,12 +37,9 @@ public class EucalyptusPropertiesBuilder extends EC2PropertiesBuilder { @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); - properties.setProperty(PROPERTY_ENDPOINT, - "http://173.205.188.130:8773/services/Eucalyptus"); + properties.setProperty(PROPERTY_ENDPOINT, "http://173.205.188.130:8773/services/Eucalyptus"); properties.setProperty(PROPERTY_REGIONS, "Eucalyptus"); properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "admin"); - // amis that work with the cluster instances - properties.setProperty(PROPERTY_EC2_CC_AMIs, ""); properties.setProperty(PROPERTY_TIMEOUT_PORT_OPEN, 5 * 60 * 1000 + ""); return properties; diff --git a/apis/eucalyptus/src/test/java/org/jclouds/eucalyptus/compute/EucalyptusComputeServiceLiveTest.java b/apis/eucalyptus/src/test/java/org/jclouds/eucalyptus/compute/EucalyptusComputeServiceLiveTest.java index 91ea635f07..48d600754d 100644 --- a/apis/eucalyptus/src/test/java/org/jclouds/eucalyptus/compute/EucalyptusComputeServiceLiveTest.java +++ b/apis/eucalyptus/src/test/java/org/jclouds/eucalyptus/compute/EucalyptusComputeServiceLiveTest.java @@ -25,6 +25,7 @@ import static org.testng.Assert.assertEquals; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Template; import org.jclouds.ec2.compute.EC2ComputeServiceLiveTest; +import org.jclouds.http.HttpResponseException; import org.testng.annotations.Test; /** @@ -60,4 +61,33 @@ public class EucalyptusComputeServiceLiveTest extends EC2ComputeServiceLiveTest assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } + @Override + @Test(enabled = true, dependsOnMethods = "testReboot") + public void testSuspendResume() throws Exception { + try { + super.testSuspendResume(); + assert false; + } catch (HttpResponseException e) { + // ebs backed not yet available + } + } + + @Override + @Test(enabled = true, dependsOnMethods = "testSuspendResume") + public void testListNodes() throws Exception { + super.testListNodes(); + } + + @Override + @Test(enabled = true, dependsOnMethods = "testSuspendResume") + public void testGetNodesWithDetails() throws Exception { + super.testGetNodesWithDetails(); + } + + @Override + @Test(enabled = true, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails" }) + public void testDestroyNodes() { + super.testDestroyNodes(); + } + } diff --git a/common/aws/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java b/common/aws/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java index 3e1613b4fc..76c06390d7 100755 --- a/common/aws/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java +++ b/common/aws/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java @@ -82,7 +82,7 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler { } } message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(), - response.getStatusLine()); + response.getStatusLine()); exception = refineException(command, response, exception, error, message); } finally { releasePayload(response); @@ -91,33 +91,36 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler { } protected Exception refineException(HttpCommand command, HttpResponse response, Exception exception, AWSError error, - String message) { + String message) { switch (response.getStatusCode()) { - case 400: - if (error != null && error.getCode() != null && (error.getCode().equals("UnsupportedOperation"))) - exception = new UnsupportedOperationException(message, exception); - if (error != null && error.getCode() != null - && (error.getCode().endsWith("NotFound") || error.getCode().endsWith(".Unknown"))) - exception = new ResourceNotFoundException(message, exception); - else if ((error != null && error.getCode() != null && (error.getCode().equals("IncorrectState") || error - .getCode().endsWith(".Duplicate"))) || (message != null && (message.indexOf("already exists") != -1))) - exception = new IllegalStateException(message, exception); - else if (error != null && error.getCode() != null && error.getCode().equals("AuthFailure")) + case 400: + if (error != null && error.getCode() != null && (error.getCode().equals("UnsupportedOperation"))) + exception = new UnsupportedOperationException(message, exception); + if (error != null && error.getCode() != null + && (error.getCode().endsWith("NotFound") || error.getCode().endsWith(".Unknown"))) + exception = new ResourceNotFoundException(message, exception); + else if ((error != null && error.getCode() != null && (error.getCode().equals("IncorrectState") || error + .getCode().endsWith(".Duplicate") + | error.getCode().endsWith(".InUse"))) + || (message != null && (message.indexOf("already exists") != -1 || message.indexOf("is in use") != -1))) + exception = new IllegalStateException(message, exception); + else if (error != null && error.getCode() != null && error.getCode().equals("AuthFailure")) + exception = new AuthorizationException(message, exception); + else if (message != null + && (message.indexOf("Invalid id") != -1 || message.indexOf("Failed to bind") != -1)) + exception = new IllegalArgumentException(message, exception); + break; + case 401: + case 403: exception = new AuthorizationException(message, exception); - else if (message != null && message.indexOf("Failed to bind the following fields") != -1)// Nova - exception = new IllegalArgumentException(message, exception); - break; - case 401: - case 403: - exception = new AuthorizationException(message, exception); - break; - case 404: - if (!command.getCurrentRequest().getMethod().equals("DELETE")) { - exception = new ResourceNotFoundException(message, exception); - } - break; - case 409: - exception = new IllegalStateException(message, exception); + break; + case 404: + if (!command.getCurrentRequest().getMethod().equals("DELETE")) { + exception = new ResourceNotFoundException(message, exception); + } + break; + case 409: + exception = new IllegalStateException(message, exception); } return exception; } diff --git a/common/aws/src/test/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContentTest.java b/common/aws/src/test/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContentTest.java index 00fd23b35c..fee547ece9 100644 --- a/common/aws/src/test/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContentTest.java +++ b/common/aws/src/test/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContentTest.java @@ -54,87 +54,106 @@ public class ParseAWSErrorFromXmlContentTest { @Test public void test400WithNotFoundSetsResourceNotFoundException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", - "Monster.NotFound", ResourceNotFoundException.class); + "Monster.NotFound", ResourceNotFoundException.class); + } + + @Test + public void test400WithInvalidIdIllegalArgumentException() { + assertCodeMakes("POST", URI.create("https://ec2.us-east-1.amazonaws.com"), 400, "HTTP/1.1 400", "", + "Invalid id: \"asdaasdsa\" (expecting \"ami-...\")", IllegalArgumentException.class); } @Test public void test400WithLoadBalancerNotFoundSetsResourceNotFoundException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", - "LoadBalancerNotFound", ResourceNotFoundException.class); + "LoadBalancerNotFound", ResourceNotFoundException.class); } @Test public void test400WithUnsupportedCodeMakesUnsupportedOperationException() { assertCodeMakes("POST", URI.create("https://ec2.us-west-1.amazonaws.com/"), 400, "", - "UnsupportedOperation", UnsupportedOperationException.class); + "UnsupportedOperation", UnsupportedOperationException.class); + } + + @Test + public void test400WithInUseCodeSetsIllegalStateException() { + assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", + "InvalidPlacementGroup.InUse", IllegalStateException.class); } @Test public void test400WithUnknownSetsResourceNotFoundException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", - "InvalidPlacementGroup.Unknown", ResourceNotFoundException.class); + "InvalidPlacementGroup.Unknown", ResourceNotFoundException.class); } @Test public void test400WithIncorrectStateSetsIllegalStateException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", - "IncorrectState", IllegalStateException.class); + "IncorrectState", IllegalStateException.class); + } + + @Test + public void test400WithInUseSetsIllegalStateException() { + assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", "text/plain", + "The placement group 'jclouds#adriancoleec2cccluster#us-east-1' is in use and may not be deleted.", + IllegalStateException.class); } @Test public void test409SetsIllegalStateException() { assertCodeMakes( - "PUT", - URI.create("https://adriancole-blobstore011.s3.amazonaws.com/"), - 409, - "", - "OperationAbortedA conflicting conditional operation is currently in progress against this resource. Please try again.F716E81C3D814E59SDprHxWzG/YXzanVnV7VTz/wP+6fRt1dS+q00kH1rz248YOOSddkFiTXF04XtqNO", - IllegalStateException.class); + "PUT", + URI.create("https://adriancole-blobstore011.s3.amazonaws.com/"), + 409, + "", + "OperationAbortedA conflicting conditional operation is currently in progress against this resource. Please try again.F716E81C3D814E59SDprHxWzG/YXzanVnV7VTz/wP+6fRt1dS+q00kH1rz248YOOSddkFiTXF04XtqNO", + IllegalStateException.class); } @Test public void test400WithInvalidGroupDuplicateIllegalStateException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "Bad Request", "application/unknown", - "InvalidGroup.Duplicate", IllegalStateException.class); + "InvalidGroup.Duplicate", IllegalStateException.class); } @Test public void test400WithInvalidKeyPairGroupDuplicateIllegalStateException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "Bad Request", "application/unknown", - "InvalidKeyPair.Duplicate", IllegalStateException.class); + "InvalidKeyPair.Duplicate", IllegalStateException.class); } @Test public void test400WithTextPlainIllegalArgumentException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "Bad Request", "text/plain", - "Failure: 400 Bad Request\nFailed to bind the following fields\nMonitoring.Enabled = true\n\n\n", - IllegalArgumentException.class); + "Failure: 400 Bad Request\nFailed to bind the following fields\nMonitoring.Enabled = true\n\n\n", + IllegalArgumentException.class); } @Test public void test400WithGroupAlreadyExistsEucalyptusIllegalStateException() { assertCodeMakes( - "GET", - URI.create("https://amazonaws.com/foo"), - 400, - "", - "Groups\nError adding network group: group named jclouds#eucrun#Eucalyptus already exists\nError adding network group: group named jclouds#eucrun#Eucalyptus already existse0133975-3bc5-456d-9753-1d61b27e07e9", - IllegalStateException.class); + "GET", + URI.create("https://amazonaws.com/foo"), + 400, + "", + "Groups\nError adding network group: group named jclouds#eucrun#Eucalyptus already exists\nError adding network group: group named jclouds#eucrun#Eucalyptus already existse0133975-3bc5-456d-9753-1d61b27e07e9", + IllegalStateException.class); } @Test public void test400WithAuthFailureSetsAuthorizationException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", - "AuthFailure", AuthorizationException.class); + "AuthFailure", AuthorizationException.class); } private void assertCodeMakes(String method, URI uri, int statusCode, String message, String content, - Class expected) { + Class expected) { assertCodeMakes(method, uri, statusCode, message, "text/xml", content, expected); } private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType, - String content, Class expected) { + String content, Class expected) { ParseAWSErrorFromXmlContent function = Guice.createInjector(new SaxParserModule(), new AbstractModule() { @@ -149,7 +168,7 @@ public class ParseAWSErrorFromXmlContentTest { HttpCommand command = createMock(HttpCommand.class); HttpRequest request = new HttpRequest(method, uri); HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Strings2 - .toInputStream(content))); + .toInputStream(content))); response.getPayload().getContentMetadata().setContentType(contentType); expect(command.getCurrentRequest()).andReturn(request).atLeastOnce(); diff --git a/common/azure/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java b/common/azure/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java index 052fab388e..d9ed86b50c 100644 --- a/common/azure/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java +++ b/common/azure/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java @@ -63,6 +63,7 @@ public class ParseAzureErrorFromXmlContentTest { "", IllegalArgumentException.class); } + @Test public void test412WithTextHtmlHttpResponseException() { assertCodeMakes( diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2AsyncClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2AsyncClient.java new file mode 100644 index 0000000000..c556e487f7 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2AsyncClient.java @@ -0,0 +1,63 @@ +package org.jclouds.aws.ec2; + +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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. + * ==================================================================== + */ + +import org.jclouds.aws.ec2.services.AWSAMIAsyncClient; +import org.jclouds.aws.ec2.services.AWSInstanceAsyncClient; +import org.jclouds.aws.ec2.services.MonitoringAsyncClient; +import org.jclouds.aws.ec2.services.PlacementGroupAsyncClient; +import org.jclouds.ec2.EC2AsyncClient; +import org.jclouds.rest.annotations.Delegate; + +/** + * Provides asynchronous access to EC2 services. + * + * @author Adrian Cole + */ +public interface AWSEC2AsyncClient extends EC2AsyncClient { + public final static String VERSION = "2010-06-15"; + + /** + * {@inheritDoc} + */ + @Delegate + @Override + AWSInstanceAsyncClient getInstanceServices(); + + /** + * {@inheritDoc} + */ + @Delegate + @Override + AWSAMIAsyncClient getAMIServices(); + + /** + * Provides asynchronous access to PlacementGroup services. + */ + @Delegate + PlacementGroupAsyncClient getPlacementGroupServices(); + + /** + * Provides asynchronous access to Monitoring services. + */ + @Delegate + MonitoringAsyncClient getMonitoringServices(); + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Client.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Client.java new file mode 100644 index 0000000000..8bd8ea53f7 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Client.java @@ -0,0 +1,66 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2; + +import java.util.concurrent.TimeUnit; + +import org.jclouds.aws.ec2.services.AWSAMIClient; +import org.jclouds.aws.ec2.services.AWSInstanceClient; +import org.jclouds.aws.ec2.services.MonitoringClient; +import org.jclouds.aws.ec2.services.PlacementGroupClient; +import org.jclouds.concurrent.Timeout; +import org.jclouds.ec2.EC2Client; +import org.jclouds.rest.annotations.Delegate; + +/** + * Provides synchronous access to EC2 services. + * + * @author Adrian Cole + */ +@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) +public interface AWSEC2Client extends EC2Client { + + /** + * {@inheritDoc} + */ + @Delegate + @Override + AWSInstanceClient getInstanceServices(); + + /** + * {@inheritDoc} + */ + @Delegate + @Override + AWSAMIClient getAMIServices(); + + /** + * Provides synchronous access to PlacementGroup services. + */ + @Delegate + PlacementGroupClient getPlacementGroupServices(); + + /** + * Provides synchronous access to Monitoring services. + */ + @Delegate + MonitoringClient getMonitoringServices(); + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ContextBuilder.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ContextBuilder.java index d92b6632fd..94430969a4 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ContextBuilder.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ContextBuilder.java @@ -22,7 +22,8 @@ package org.jclouds.aws.ec2; import java.util.List; import java.util.Properties; -import org.jclouds.aws.ec2.config.AWSEC2ComputeServiceContextModule; +import org.jclouds.aws.ec2.compute.config.AWSEC2ComputeServiceContextModule; +import org.jclouds.aws.ec2.config.AWSEC2RestClientModule; import org.jclouds.ec2.EC2ContextBuilder; import com.google.inject.Module; @@ -37,6 +38,11 @@ public class AWSEC2ContextBuilder extends EC2ContextBuilder { super(props); } + @Override + protected void addClientModule(List modules) { + modules.add(new AWSEC2RestClientModule()); + } + @Override protected void addContextModule(List modules) { modules.add(new AWSEC2ComputeServiceContextModule()); diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilder.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilder.java index 5a76413779..f204f096b2 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilder.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilder.java @@ -25,7 +25,7 @@ import static org.jclouds.aws.domain.Region.US_EAST_1; import static org.jclouds.aws.domain.Region.US_WEST_1; import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_TIMEOUT_NODE_SUSPENDED; import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; -import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs; +import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_CC_AMIs; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; import java.util.Properties; diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java new file mode 100644 index 0000000000..2acde48a95 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java @@ -0,0 +1,132 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.compute; + +import static com.google.common.base.Preconditions.checkState; + +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; +import java.util.concurrent.ExecutorService; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; +import javax.inject.Singleton; + +import org.jclouds.Constants; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.domain.PlacementGroup.State; +import org.jclouds.collect.Memoized; +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; +import org.jclouds.compute.strategy.DestroyNodeStrategy; +import org.jclouds.compute.strategy.GetNodeMetadataStrategy; +import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap; +import org.jclouds.compute.strategy.ListNodesStrategy; +import org.jclouds.compute.strategy.RebootNodeStrategy; +import org.jclouds.compute.strategy.ResumeNodeStrategy; +import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; +import org.jclouds.compute.strategy.SuspendNodeStrategy; +import org.jclouds.domain.Credentials; +import org.jclouds.domain.Location; +import org.jclouds.ec2.compute.EC2ComputeService; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.domain.KeyPair; +import org.jclouds.util.Preconditions2; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; + +/** + * @author Adrian Cole + */ +@Singleton +public class AWSEC2ComputeService extends EC2ComputeService { + + private final Map placementGroupMap; + private final Predicate placementGroupDeleted; + private final AWSEC2Client ec2Client; + + @Inject + protected AWSEC2ComputeService(ComputeServiceContext context, Map credentialStore, + @Memoized Supplier> images, @Memoized Supplier> sizes, + @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, + GetNodeMetadataStrategy getNodeMetadataStrategy, RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy, + RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, + ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy, + Provider templateBuilderProvider, Provider templateOptionsProvider, + @Named("NODE_RUNNING") Predicate nodeRunning, + @Named("NODE_TERMINATED") Predicate nodeTerminated, + @Named("NODE_SUSPENDED") Predicate nodeSuspended, + InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, Timeouts timeouts, + @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, AWSEC2Client ec2Client, + Map credentialsMap, @Named("SECURITY") Map securityGroupMap, + @Named("PLACEMENT") Map placementGroupMap, + @Named("DELETED") Predicate placementGroupDeleted) { + super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy, + runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, + stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, + nodeSuspended, initScriptRunnerFactory, timeouts, executor, ec2Client, credentialsMap, securityGroupMap); + this.ec2Client = ec2Client; + this.placementGroupMap = placementGroupMap; + this.placementGroupDeleted = placementGroupDeleted; + } + + @VisibleForTesting + void deletePlacementGroup(String region, String tag) { + Preconditions2.checkNotEmpty(tag, "tag"); + String group = String.format("jclouds#%s#%s", tag, region); + if (ec2Client.getPlacementGroupServices().describePlacementGroupsInRegion(region, group).size() > 0) { + logger.debug(">> deleting placementGroup(%s)", group); + try { + ec2Client.getPlacementGroupServices().deletePlacementGroupInRegion(region, group); + checkState(placementGroupDeleted.apply(new PlacementGroup(region, group, "cluster", State.PENDING)), String + .format("placementGroup region(%s) name(%s) failed to delete", region, group)); + placementGroupMap.remove(new RegionAndName(region, group)); + logger.debug("<< deleted placementGroup(%s)", group); + } catch (IllegalStateException e) { + logger.debug("<< inUse placementGroup(%s)", group); + } + } + } + + protected void cleanUpIncidentalResources(Entry regionTag) { + super.cleanUpIncidentalResources(regionTag); + deletePlacementGroup(regionTag.getKey(), regionTag.getValue()); + } + + /** + * returns template options, except of type {@link EC2TemplateOptions}. + */ + @Override + public EC2TemplateOptions templateOptions() { + return EC2TemplateOptions.class.cast(super.templateOptions()); + } + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateBuilderImpl.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateBuilderImpl.java new file mode 100644 index 0000000000..fd41fc3a84 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateBuilderImpl.java @@ -0,0 +1,72 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.compute; + +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; + +import org.jclouds.collect.Memoized; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Location; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl; + +import com.google.common.base.Supplier; + +/** + * + * @author Adrian Cole + */ +public class AWSEC2TemplateBuilderImpl extends EC2TemplateBuilderImpl { + + @Inject + protected AWSEC2TemplateBuilderImpl(@Memoized Supplier> locations, + @Memoized Supplier> images, @Memoized Supplier> sizes, + Supplier defaultLocation, Provider optionsProvider, + @Named("DEFAULT") Provider defaultTemplateProvider, Map imageMap) { + super(locations, images, sizes, defaultLocation, optionsProvider, defaultTemplateProvider, imageMap); + } + + @Override + protected void copyTemplateOptions(TemplateOptions from, TemplateOptions to) { + super.copyTemplateOptions(from, to); + if (from instanceof AWSEC2TemplateOptions) { + AWSEC2TemplateOptions eFrom = AWSEC2TemplateOptions.class.cast(from); + AWSEC2TemplateOptions eTo = AWSEC2TemplateOptions.class.cast(to); + + if (eFrom.getSubnetId() != null) + eTo.subnetId(eFrom.getSubnetId()); + if (eFrom.isMonitoringEnabled()) + eTo.enableMonitoring(); + if (!eFrom.shouldAutomaticallyCreatePlacementGroup()) + eTo.noPlacementGroup(); + if (eFrom.getPlacementGroup() != null) + eTo.placementGroup(eFrom.getPlacementGroup()); + } + } + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateOptions.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateOptions.java new file mode 100644 index 0000000000..a3688d7f2d --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateOptions.java @@ -0,0 +1,423 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.compute; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import java.util.Arrays; + +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Credentials; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.io.Payload; +import org.jclouds.scriptbuilder.domain.Statement; +import org.jclouds.util.Preconditions2; + +/** + * Contains options supported in the {@code ComputeService#runNode} operation on the "ec2" provider. + *

+ * Usage

The recommended way to instantiate a AWSEC2TemplateOptions object is to statically + * import AWSEC2TemplateOptions.* and invoke a static creation method followed by an instance + * mutator (if needed): + *

+ * + * import static org.jclouds.aws.ec2.compute.options.AWSEC2TemplateOptions.Builder.*; + *

+ * ComputeService client = // get connection + * templateBuilder.options(inboundPorts(22, 80, 8080, 443)); + * Set set = client.runNodesWithTag(tag, 2, templateBuilder.build()); + * + * + * @author Adrian Cole + */ +public class AWSEC2TemplateOptions extends EC2TemplateOptions { + + private boolean monitoringEnabled; + private String placementGroup = null; + private boolean noPlacementGroup; + private String subnetId; + + public static final AWSEC2TemplateOptions NONE = new AWSEC2TemplateOptions(); + + /** + * Enable Cloudwatch monitoring + * + * @see CloudWatchClient + */ + public AWSEC2TemplateOptions enableMonitoring() { + this.monitoringEnabled = true; + return this; + } + + /** + * Specifies the keypair used to run instances with + */ + public AWSEC2TemplateOptions placementGroup(String placementGroup) { + checkNotNull(placementGroup, "use noPlacementGroup option to request boot without a keypair"); + checkState(!noPlacementGroup, "you cannot specify both options placementGroup and noPlacementGroup"); + Preconditions2.checkNotEmpty(placementGroup, "placementGroup must be non-empty"); + this.placementGroup = placementGroup; + return this; + } + + /** + * Do not use a keypair on instances + */ + public AWSEC2TemplateOptions noPlacementGroup() { + checkState(placementGroup == null, "you cannot specify both options placementGroup and noPlacementGroup"); + this.noPlacementGroup = true; + return this; + } + + /** + * Specifies the subnetId used to run instances in + */ + public AWSEC2TemplateOptions subnetId(String subnetId) { + checkNotNull(subnetId, "subnetId cannot be null"); + Preconditions2.checkNotEmpty(subnetId, "subnetId must be non-empty"); + this.subnetId = subnetId; + return this; + } + + public static class Builder { + + /** + * @see AWSEC2TemplateOptions#securityGroups(Iterable) + */ + public static AWSEC2TemplateOptions securityGroups(String... groupIds) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.securityGroups(groupIds)); + } + + /** + * @see AWSEC2TemplateOptions#securityGroups(Iterable) + */ + public static AWSEC2TemplateOptions securityGroups(Iterable groupIds) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.securityGroups(groupIds)); + } + + /** + * @see AWSEC2TemplateOptions#keyPair + */ + public static AWSEC2TemplateOptions keyPair(String keyPair) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.keyPair(keyPair)); + } + + /** + * @see AWSEC2TemplateOptions#userData + */ + public static AWSEC2TemplateOptions userData(byte[] unencodedData) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.userData(unencodedData)); + } + + /** + * @see AWSEC2TemplateOptions#noKeyPair + */ + public static AWSEC2TemplateOptions noKeyPair() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.noKeyPair()); + } + + /** + * @see AWSEC2TemplateOptions#placementGroup + */ + public static AWSEC2TemplateOptions placementGroup(String placementGroup) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.placementGroup(placementGroup)); + } + + /** + * @see AWSEC2TemplateOptions#noPlacementGroup + */ + public static AWSEC2TemplateOptions noPlacementGroup() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.noPlacementGroup()); + } + + /** + * @see AWSEC2TemplateOptions#enableMonitoring + */ + public static AWSEC2TemplateOptions enableMonitoring() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.enableMonitoring()); + } + + // methods that only facilitate returning the correct object type + /** + * @see TemplateOptions#inboundPorts + */ + public static AWSEC2TemplateOptions inboundPorts(int... ports) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.inboundPorts(ports)); + } + + /** + * @see TemplateOptions#port + */ + public static AWSEC2TemplateOptions blockOnPort(int port, int seconds) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.blockOnPort(port, seconds)); + } + + /** + * @see TemplateOptions#runScript + */ + public static AWSEC2TemplateOptions runScript(byte[] script) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.runScript(script)); + } + + /** + * @see TemplateOptions#installPrivateKey + */ + public static AWSEC2TemplateOptions installPrivateKey(String rsaKey) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.installPrivateKey(rsaKey)); + } + + /** + * @see TemplateOptions#authorizePublicKey + */ + public static AWSEC2TemplateOptions authorizePublicKey(String rsaKey) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.authorizePublicKey(rsaKey)); + } + + /** + * @see TemplateOptions#withDetails + */ + public static AWSEC2TemplateOptions withDetails() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.withMetadata()); + } + + /** + * @see TemplateOptions#withSubnetId + */ + public static AWSEC2TemplateOptions subnetId(String subnetId) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return AWSEC2TemplateOptions.class.cast(options.subnetId(subnetId)); + } + } + + // methods that only facilitate returning the correct object type + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions blockOnPort(int port, int seconds) { + return AWSEC2TemplateOptions.class.cast(super.blockOnPort(port, seconds)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions inboundPorts(int... ports) { + return AWSEC2TemplateOptions.class.cast(super.inboundPorts(ports)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions authorizePublicKey(String publicKey) { + return AWSEC2TemplateOptions.class.cast(super.authorizePublicKey(publicKey)); + } + + /** + * {@inheritDoc} + */ + @Override + @Deprecated + public AWSEC2TemplateOptions authorizePublicKey(Payload publicKey) { + return AWSEC2TemplateOptions.class.cast(super.authorizePublicKey(publicKey)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions installPrivateKey(String privateKey) { + return AWSEC2TemplateOptions.class.cast(super.installPrivateKey(privateKey)); + } + + /** + * {@inheritDoc} + */ + @Override + @Deprecated + public AWSEC2TemplateOptions installPrivateKey(Payload privateKey) { + return AWSEC2TemplateOptions.class.cast(super.installPrivateKey(privateKey)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions runScript(Payload script) { + return AWSEC2TemplateOptions.class.cast(super.runScript(script)); + } + + /** + * {@inheritDoc} + */ + @Override + @Deprecated + public AWSEC2TemplateOptions runScript(byte[] script) { + return AWSEC2TemplateOptions.class.cast(super.runScript(script)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions withMetadata() { + return AWSEC2TemplateOptions.class.cast(super.withMetadata()); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions blockUntilRunning(boolean blockUntilRunning) { + return AWSEC2TemplateOptions.class.cast(super.blockUntilRunning(blockUntilRunning)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions dontAuthorizePublicKey() { + return AWSEC2TemplateOptions.class.cast(super.dontAuthorizePublicKey()); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions nameTask(String name) { + return AWSEC2TemplateOptions.class.cast(super.nameTask(name)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions runAsRoot(boolean runAsRoot) { + return AWSEC2TemplateOptions.class.cast(super.runAsRoot(runAsRoot)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions runScript(Statement script) { + return AWSEC2TemplateOptions.class.cast(super.runScript(script)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions withOverridingCredentials(Credentials overridingCredentials) { + return AWSEC2TemplateOptions.class.cast(super.withOverridingCredentials(overridingCredentials)); + } + + /** + * @return placementGroup to use when running the instance or null, to generate a placementGroup. + */ + public String getPlacementGroup() { + return placementGroup; + } + + /** + * @return true (default) if we are supposed to use a placementGroup + */ + public boolean shouldAutomaticallyCreatePlacementGroup() { + return !noPlacementGroup; + } + + /** + * @return true (default) if we are supposed to enable cloudwatch + */ + public boolean isMonitoringEnabled() { + return monitoringEnabled; + } + + /** + * @return subnetId to use when running the instance or null. + */ + public String getSubnetId() { + return subnetId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + (monitoringEnabled ? 1231 : 1237); + result = prime * result + (noPlacementGroup ? 1231 : 1237); + result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode()); + result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + AWSEC2TemplateOptions other = (AWSEC2TemplateOptions) obj; + if (monitoringEnabled != other.monitoringEnabled) + return false; + if (noPlacementGroup != other.noPlacementGroup) + return false; + if (placementGroup == null) { + if (other.placementGroup != null) + return false; + } else if (!placementGroup.equals(other.placementGroup)) + return false; + if (subnetId == null) { + if (other.subnetId != null) + return false; + } else if (!subnetId.equals(other.subnetId)) + return false; + return true; + } + + @Override + public String toString() { + + return "AWSEC2TemplateOptions [groupIds=" + getGroupIds() + ", keyPair=" + getKeyPair() + ", noKeyPair=" + + !shouldAutomaticallyCreateKeyPair() + ", monitoringEnabled=" + monitoringEnabled + ", placementGroup=" + + placementGroup + ", noPlacementGroup=" + noPlacementGroup + ", subnetId=" + subnetId + ", userData=" + + Arrays.toString(getUserData()) + ", blockDeviceMappings=" + getBlockDeviceMappings() + "]"; + } + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/config/AWSEC2ComputeServiceContextModule.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceContextModule.java similarity index 50% rename from providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/config/AWSEC2ComputeServiceContextModule.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceContextModule.java index 4d93da2c86..6d189a42c5 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/config/AWSEC2ComputeServiceContextModule.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceContextModule.java @@ -17,14 +17,24 @@ * ==================================================================== */ -package org.jclouds.aws.ec2.config; +package org.jclouds.aws.ec2.compute.config; import static org.jclouds.compute.domain.OsFamily.AMZN_LINUX; -import org.jclouds.aws.ec2.strategy.AWSEC2ReviseParsedImage; +import org.jclouds.aws.ec2.compute.AWSEC2TemplateBuilderImpl; +import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions; +import org.jclouds.aws.ec2.compute.strategy.AWSEC2ReviseParsedImage; +import org.jclouds.aws.ec2.compute.strategy.CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions; +import org.jclouds.aws.ec2.compute.suppliers.AWSEC2HardwareSupplier; +import org.jclouds.aws.ec2.compute.suppliers.AWSRegionAndNameToImageSupplier; import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.ec2.compute.config.EC2ComputeServiceContextModule; +import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.compute.strategy.CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions; import org.jclouds.ec2.compute.strategy.ReviseParsedImage; +import org.jclouds.ec2.compute.suppliers.EC2HardwareSupplier; +import org.jclouds.ec2.compute.suppliers.RegionAndNameToImageSupplier; import com.google.inject.Injector; @@ -43,6 +53,17 @@ public class AWSEC2ComputeServiceContextModule extends EC2ComputeServiceContextM protected void configure() { super.configure(); bind(ReviseParsedImage.class).to(AWSEC2ReviseParsedImage.class); + bind(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class).to( + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class); + bind(EC2HardwareSupplier.class).to(AWSEC2HardwareSupplier.class); + bind(RegionAndNameToImageSupplier.class).to(AWSRegionAndNameToImageSupplier.class); + bind(EC2TemplateBuilderImpl.class).to(AWSEC2TemplateBuilderImpl.class); + bind(EC2TemplateOptions.class).to(AWSEC2TemplateOptions.class); + } + + @Override + protected void installDependencies() { + install(new AWSEC2ComputeServiceDependenciesModule()); } } diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java new file mode 100644 index 0000000000..b8f0b723c3 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java @@ -0,0 +1,117 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.compute.config; + +import static com.google.common.collect.Iterables.toArray; +import static com.google.common.collect.Maps.newLinkedHashMap; +import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_CC_AMIs; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.aws.ec2.AWSEC2AsyncClient; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.compute.AWSEC2ComputeService; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.predicates.PlacementGroupAvailable; +import org.jclouds.aws.ec2.predicates.PlacementGroupDeleted; +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.compute.internal.ComputeServiceContextImpl; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Credentials; +import org.jclouds.ec2.compute.config.EC2ComputeServiceDependenciesModule; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; +import org.jclouds.ec2.compute.functions.CredentialsForInstance; +import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata; +import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.predicates.RetryablePredicate; +import org.jclouds.rest.RestContext; +import org.jclouds.rest.internal.RestContextImpl; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.base.Splitter; +import com.google.inject.Provides; +import com.google.inject.Scopes; +import com.google.inject.TypeLiteral; + +/** + * + * @author Adrian Cole + */ +public class AWSEC2ComputeServiceDependenciesModule extends EC2ComputeServiceDependenciesModule { + @Override + protected void configure() { + bind(TemplateBuilder.class).to(EC2TemplateBuilderImpl.class); + bind(TemplateOptions.class).to(EC2TemplateOptions.class); + bind(ComputeService.class).to(AWSEC2ComputeService.class); + bind(new TypeLiteral>() { + }).to(RunningInstanceToNodeMetadata.class); + bind(new TypeLiteral>() { + }).to(CredentialsForInstance.class); + bind(new TypeLiteral() { + }).to(new TypeLiteral>() { + }).in(Scopes.SINGLETON); + bind(new TypeLiteral>() { + }).to(new TypeLiteral>() { + }).in(Scopes.SINGLETON); + } + + @Provides + @Singleton + @Named("AVAILABLE") + protected Predicate placementGroupAvailable(PlacementGroupAvailable available) { + return new RetryablePredicate(available, 60, 1, TimeUnit.SECONDS); + } + + @Provides + @Singleton + @Named("DELETED") + protected Predicate placementGroupDeleted(PlacementGroupDeleted deleted) { + return new RetryablePredicate(deleted, 60, 1, TimeUnit.SECONDS); + } + + @Provides + @Singleton + @Named("PLACEMENT") + protected Map placementGroupMap(CreateSecurityGroupIfNeeded in) { + // doesn't seem to clear when someone issues remove(key) + // return new MapMaker().makeComputingMap(in); + return newLinkedHashMap(); + } + + @Provides + @Singleton + @Named(PROPERTY_EC2_CC_AMIs) + protected String[] ccAmis(@Named(PROPERTY_EC2_CC_AMIs) String ccAmis) { + if (ccAmis.trim().equals("")) + return new String[] {}; + return toArray(Splitter.on(',').split(ccAmis), String.class); + } +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/strategy/AWSEC2ReviseParsedImage.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ReviseParsedImage.java similarity index 99% rename from providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/strategy/AWSEC2ReviseParsedImage.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ReviseParsedImage.java index 88824475a6..83a894594b 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/strategy/AWSEC2ReviseParsedImage.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ReviseParsedImage.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.aws.ec2.strategy; +package org.jclouds.aws.ec2.compute.strategy; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java new file mode 100644 index 0000000000..35913beb32 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java @@ -0,0 +1,113 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.compute.strategy; + +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions; +import org.jclouds.aws.ec2.functions.CreatePlacementGroupIfNeeded; +import org.jclouds.aws.ec2.options.AWSRunInstancesOptions; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; +import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.compute.strategy.CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions; +import org.jclouds.ec2.domain.KeyPair; +import org.jclouds.ec2.options.RunInstancesOptions; + +import com.google.common.annotations.VisibleForTesting; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions extends + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions { + + @VisibleForTesting + final Map placementGroupMap; + @VisibleForTesting + final CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded; + + @Inject + public CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions( + Map credentialsMap, @Named("SECURITY") Map securityGroupMap, + @Named("PLACEMENT") Map placementGroupMap, CreateUniqueKeyPair createUniqueKeyPair, + CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded, + javax.inject.Provider optionsProvider, + CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded) { + super(credentialsMap, securityGroupMap, createUniqueKeyPair, createSecurityGroupIfNeeded, optionsProvider); + this.placementGroupMap = placementGroupMap; + this.createPlacementGroupIfNeeded = createPlacementGroupIfNeeded; + } + + public AWSRunInstancesOptions execute(String region, String tag, Template template) { + AWSRunInstancesOptions instanceOptions = AWSRunInstancesOptions.class.cast(super.execute(region, tag, template)); + + String placementGroupName = template.getHardware().getId().startsWith("cc") ? createNewPlacementGroupUnlessUserSpecifiedOtherwise( + region, tag, template.getOptions()) + : null; + + if (placementGroupName != null) + instanceOptions.inPlacementGroup(placementGroupName); + + if (AWSEC2TemplateOptions.class.cast(template.getOptions()).isMonitoringEnabled()) + instanceOptions.enableMonitoring(); + + return instanceOptions; + } + + @VisibleForTesting + String createNewPlacementGroupUnlessUserSpecifiedOtherwise(String region, String tag, TemplateOptions options) { + String placementGroupName = null; + boolean shouldAutomaticallyCreatePlacementGroup = true; + if (options instanceof EC2TemplateOptions) { + placementGroupName = AWSEC2TemplateOptions.class.cast(options).getPlacementGroup(); + if (placementGroupName == null) + shouldAutomaticallyCreatePlacementGroup = AWSEC2TemplateOptions.class.cast(options) + .shouldAutomaticallyCreatePlacementGroup(); + } + if (placementGroupName == null && shouldAutomaticallyCreatePlacementGroup) { + placementGroupName = String.format("jclouds#%s#%s", tag, region); + RegionAndName regionAndName = new RegionAndName(region, placementGroupName); + if (!placementGroupMap.containsKey(regionAndName)) { + placementGroupMap.put(regionAndName, createPlacementGroupIfNeeded.apply(regionAndName)); + } + } + return placementGroupName; + } + + @Override + protected void addSecurityGroups(String region, String tag, Template template, RunInstancesOptions instanceOptions) { + String subnetId = AWSEC2TemplateOptions.class.cast(template.getOptions()).getSubnetId(); + if (subnetId != null) { + AWSRunInstancesOptions.class.cast(instanceOptions).withSubnetId(subnetId); + } else { + super.addSecurityGroups(region, tag, template, instanceOptions); + } + } +} \ No newline at end of file diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSEC2HardwareSupplier.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSEC2HardwareSupplier.java new file mode 100644 index 0000000000..c1c6316a56 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSEC2HardwareSupplier.java @@ -0,0 +1,90 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.compute.suppliers; + +import static com.google.common.collect.Iterables.find; +import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_CC_AMIs; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_medium; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_xlarge; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.cc1_4xlarge; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_large; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_small; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_xlarge; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_2xlarge; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_4xlarge; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_xlarge; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.t1_micro; + +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.collect.Memoized; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationScope; +import org.jclouds.ec2.compute.suppliers.EC2HardwareSupplier; +import org.jclouds.location.Provider; + +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSet.Builder; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class AWSEC2HardwareSupplier extends EC2HardwareSupplier { + + private final Supplier> locations; + private final String[] ccAmis; + + @Inject + public AWSEC2HardwareSupplier(@Memoized Supplier> locations, @Provider String providerName, + @Named(PROPERTY_EC2_CC_AMIs) String[] ccAmis) { + this.locations = locations; + this.ccAmis = ccAmis; + } + + @Override + public Set get() { + Builder sizes = ImmutableSet.builder(); + for (String ccAmi : ccAmis) { + final String region = ccAmi.split("/")[0]; + Location location = find(locations.get(), new Predicate() { + + @Override + public boolean apply(Location input) { + return input.getScope() == LocationScope.REGION && input.getId().equals(region); + } + + }); + sizes.add(cc1_4xlarge().location(location).supportsImageIds(ccAmi).build()); + } + sizes.addAll(ImmutableSet. of(t1_micro().build(), c1_medium().build(), c1_xlarge().build(), m1_large() + .build(), m1_small().build(), m1_xlarge().build(), m2_xlarge().build(), m2_2xlarge().build(), + m2_4xlarge().build())); + return sizes.build(); + } +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSRegionAndNameToImageSupplier.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSRegionAndNameToImageSupplier.java new file mode 100644 index 0000000000..be88ce886e --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSRegionAndNameToImageSupplier.java @@ -0,0 +1,93 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.compute.suppliers; + +/** + * + * + * ==================================================================== + * Licensed 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. + * ==================================================================== + */ + +import static com.google.common.collect.Iterables.concat; +import static com.google.common.collect.Maps.newLinkedHashMap; +import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_CC_AMIs; +import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.imageIds; +import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; + +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.compute.domain.Image; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.functions.EC2ImageParser; +import org.jclouds.ec2.compute.strategy.DescribeImagesParallel; +import org.jclouds.ec2.compute.suppliers.RegionAndNameToImageSupplier; +import org.jclouds.ec2.options.DescribeImagesOptions; +import org.jclouds.location.Region; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class AWSRegionAndNameToImageSupplier extends RegionAndNameToImageSupplier { + + private final String[] ccAmis; + + @Inject + AWSRegionAndNameToImageSupplier(@Region Set regions, DescribeImagesParallel describer, + @Named(PROPERTY_EC2_CC_AMIs) String[] ccAmis, @Named(PROPERTY_EC2_AMI_OWNERS) String[] amiOwners, + EC2ImageParser parser, Map images) { + super(regions, describer, amiOwners, parser, images); + this.ccAmis = ccAmis; + } + + public Iterable> getDescribeQueriesForOwnersInRegions(Set regions, + String[] amiOwners) { + return concat(super.getDescribeQueriesForOwnersInRegions(regions, amiOwners), ccAmisToDescribeQueries(ccAmis) + .entrySet()); + } + + static Map ccAmisToDescribeQueries(String[] ccAmis) { + Map queries = newLinkedHashMap(); + for (String from : ccAmis) { + queries.put(from.split("/")[0], imageIds(from.split("/")[1])); + } + return queries; + } + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/config/AWSEC2RestClientModule.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/config/AWSEC2RestClientModule.java new file mode 100644 index 0000000000..ad0866e6d2 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/config/AWSEC2RestClientModule.java @@ -0,0 +1,133 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.config; + +import java.util.Map; + +import javax.inject.Singleton; + +import org.jclouds.aws.ec2.AWSEC2AsyncClient; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.domain.AWSRunningInstance; +import org.jclouds.aws.ec2.options.AWSRunInstancesOptions; +import org.jclouds.aws.ec2.services.AWSAMIAsyncClient; +import org.jclouds.aws.ec2.services.AWSAMIClient; +import org.jclouds.aws.ec2.services.AWSInstanceAsyncClient; +import org.jclouds.aws.ec2.services.AWSInstanceClient; +import org.jclouds.aws.ec2.services.MonitoringAsyncClient; +import org.jclouds.aws.ec2.services.MonitoringClient; +import org.jclouds.aws.ec2.services.PlacementGroupAsyncClient; +import org.jclouds.aws.ec2.services.PlacementGroupClient; +import org.jclouds.ec2.EC2AsyncClient; +import org.jclouds.ec2.EC2Client; +import org.jclouds.ec2.config.EC2RestClientModule; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.options.RunInstancesOptions; +import org.jclouds.ec2.services.AMIAsyncClient; +import org.jclouds.ec2.services.AMIClient; +import org.jclouds.ec2.services.AvailabilityZoneAndRegionAsyncClient; +import org.jclouds.ec2.services.AvailabilityZoneAndRegionClient; +import org.jclouds.ec2.services.ElasticBlockStoreAsyncClient; +import org.jclouds.ec2.services.ElasticBlockStoreClient; +import org.jclouds.ec2.services.ElasticIPAddressAsyncClient; +import org.jclouds.ec2.services.ElasticIPAddressClient; +import org.jclouds.ec2.services.InstanceAsyncClient; +import org.jclouds.ec2.services.InstanceClient; +import org.jclouds.ec2.services.KeyPairAsyncClient; +import org.jclouds.ec2.services.KeyPairClient; +import org.jclouds.ec2.services.SecurityGroupAsyncClient; +import org.jclouds.ec2.services.SecurityGroupClient; +import org.jclouds.ec2.services.WindowsAsyncClient; +import org.jclouds.ec2.services.WindowsClient; +import org.jclouds.http.RequiresHttp; +import org.jclouds.rest.ConfiguresRestClient; + +import com.google.common.collect.ImmutableMap; +import com.google.inject.Provides; + +/** + * Configures the EC2 connection. + * + * @author Adrian Cole + */ +@RequiresHttp +@ConfiguresRestClient +public class AWSEC2RestClientModule extends EC2RestClientModule { + + public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class> builder()// + .put(AWSAMIClient.class, AWSAMIAsyncClient.class)// + .put(ElasticIPAddressClient.class, ElasticIPAddressAsyncClient.class)// + .put(AWSInstanceClient.class, AWSInstanceAsyncClient.class)// + .put(KeyPairClient.class, KeyPairAsyncClient.class)// + .put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)// + .put(PlacementGroupClient.class, PlacementGroupAsyncClient.class)// + .put(MonitoringClient.class, MonitoringAsyncClient.class)// + .put(WindowsClient.class, WindowsAsyncClient.class)// + .put(AvailabilityZoneAndRegionClient.class, AvailabilityZoneAndRegionAsyncClient.class)// + .put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)// + .build(); + + public AWSEC2RestClientModule() { + super(AWSEC2Client.class, AWSEC2AsyncClient.class, DELEGATE_MAP); + } + + @Singleton + @Provides + EC2Client provide(AWSEC2Client in) { + return in; + } + + @Singleton + @Provides + EC2AsyncClient provide(AWSEC2AsyncClient in) { + return in; + } + + @Singleton + @Provides + InstanceClient getInstanceServices(AWSEC2Client in) { + return in.getInstanceServices(); + } + + @Singleton + @Provides + InstanceAsyncClient getInstanceServices(AWSEC2AsyncClient in) { + return in.getInstanceServices(); + } + + @Singleton + @Provides + AMIClient getAMIServices(AWSEC2Client in) { + return in.getAMIServices(); + } + + @Singleton + @Provides + AMIAsyncClient getAMIServices(AWSEC2AsyncClient in) { + return in.getAMIServices(); + } + + @Override + protected void configure() { + bind(RunningInstance.Builder.class).to(AWSRunningInstance.Builder.class); + bind(RunInstancesOptions.class).to(AWSRunInstancesOptions.class); + super.configure(); + } +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/AWSRunningInstance.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/AWSRunningInstance.java new file mode 100644 index 0000000000..03f4ad0e75 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/AWSRunningInstance.java @@ -0,0 +1,354 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Date; +import java.util.Map; +import java.util.Set; + +import javax.annotation.Nullable; + +import org.jclouds.ec2.domain.BlockDevice; +import org.jclouds.ec2.domain.InstanceState; +import org.jclouds.ec2.domain.RootDeviceType; +import org.jclouds.ec2.domain.RunningInstance; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; + +/** + * + * @see + * @author Adrian Cole + */ +public class AWSRunningInstance extends RunningInstance { + + public static class Builder extends org.jclouds.ec2.domain.RunningInstance.Builder { + private MonitoringState monitoringState; + private String placementGroup; + private Set productCodes = Sets.newLinkedHashSet(); + private String subnetId; + private String spotInstanceRequestId; + private String vpcId; + + public Builder monitoringState(MonitoringState monitoringState) { + this.monitoringState = monitoringState; + return this; + } + + public Builder placementGroup(String placementGroup) { + this.placementGroup = placementGroup; + return this; + } + + public Builder productCodes(Iterable productCodes) { + this.productCodes = ImmutableSet.copyOf(checkNotNull(productCodes, "productCodes")); + return this; + } + + public Builder productCode(String productCode) { + if (productCode != null) + this.productCodes.add(productCode); + return this; + } + + public Builder subnetId(String subnetId) { + this.subnetId = subnetId; + return this; + } + + public Builder spotInstanceRequestId(String spotInstanceRequestId) { + this.spotInstanceRequestId = spotInstanceRequestId; + return this; + } + + public Builder vpcId(String vpcId) { + this.vpcId = vpcId; + return this; + } + + @Override + public Builder amiLaunchIndex(String amiLaunchIndex) { + return Builder.class.cast(super.amiLaunchIndex(amiLaunchIndex)); + } + + @Override + public Builder availabilityZone(String availabilityZone) { + return Builder.class.cast(super.availabilityZone(availabilityZone)); + } + + @Override + public Builder devices(Map ebsBlockDevices) { + return Builder.class.cast(super.devices(ebsBlockDevices)); + } + + @Override + public Builder dnsName(String dnsName) { + return Builder.class.cast(super.dnsName(dnsName)); + } + + @Override + public Builder imageId(String imageId) { + return Builder.class.cast(super.imageId(imageId)); + } + + @Override + public Builder instanceId(String instanceId) { + return Builder.class.cast(super.instanceId(instanceId)); + } + + @Override + public Builder instanceState(InstanceState instanceState) { + return Builder.class.cast(super.instanceState(instanceState)); + } + + @Override + public Builder instanceType(String instanceType) { + return Builder.class.cast(super.instanceType(instanceType)); + } + + @Override + public Builder ipAddress(String ipAddress) { + return Builder.class.cast(super.ipAddress(ipAddress)); + } + + @Override + public Builder kernelId(String kernelId) { + return Builder.class.cast(super.kernelId(kernelId)); + } + + @Override + public Builder keyName(String keyName) { + return Builder.class.cast(super.keyName(keyName)); + } + + @Override + public Builder launchTime(Date launchTime) { + return Builder.class.cast(super.launchTime(launchTime)); + } + + @Override + public Builder platform(String platform) { + return Builder.class.cast(super.platform(platform)); + } + + @Override + public Builder privateDnsName(String privateDnsName) { + return Builder.class.cast(super.privateDnsName(privateDnsName)); + } + + @Override + public Builder privateIpAddress(String privateIpAddress) { + return Builder.class.cast(super.privateIpAddress(privateIpAddress)); + } + + @Override + public Builder ramdiskId(String ramdiskId) { + return Builder.class.cast(super.ramdiskId(ramdiskId)); + } + + @Override + public Builder reason(String reason) { + return Builder.class.cast(super.reason(reason)); + } + + @Override + public Builder region(String region) { + return Builder.class.cast(super.region(region)); + } + + @Override + public Builder rootDeviceName(String rootDeviceName) { + return Builder.class.cast(super.rootDeviceName(rootDeviceName)); + } + + @Override + public Builder rootDeviceType(RootDeviceType rootDeviceType) { + return Builder.class.cast(super.rootDeviceType(rootDeviceType)); + } + + @Override + public Builder virtualizationType(String virtualizationType) { + return Builder.class.cast(super.virtualizationType(virtualizationType)); + } + + @Override + public Builder device(String key, BlockDevice value) { + return Builder.class.cast(super.device(key, value)); + } + + @Override + public Builder groupId(String groupId) { + return Builder.class.cast(super.groupId(groupId)); + } + + @Override + public Builder groupIds(Iterable groupIds) { + return Builder.class.cast(super.groupIds(groupIds)); + } + + @Override + public AWSRunningInstance build() { + return new AWSRunningInstance(region, groupIds, amiLaunchIndex, dnsName, imageId, instanceId, instanceState, + instanceType, ipAddress, kernelId, keyName, launchTime, availabilityZone, virtualizationType, + platform, privateDnsName, privateIpAddress, ramdiskId, reason, rootDeviceType, rootDeviceName, + ebsBlockDevices, monitoringState, placementGroup, productCodes, subnetId, spotInstanceRequestId, + vpcId); + } + + } + + private final MonitoringState monitoringState; + @Nullable + private final String placementGroup; + private final Set productCodes; + @Nullable + private final String subnetId; + @Nullable + private final String spotInstanceRequestId; + @Nullable + private final String vpcId; + + protected AWSRunningInstance(String region, Iterable groupIds, String amiLaunchIndex, String dnsName, + String imageId, String instanceId, InstanceState instanceState, String instanceType, String ipAddress, + String kernelId, String keyName, Date launchTime, String availabilityZone, String virtualizationType, + String platform, String privateDnsName, String privateIpAddress, String ramdiskId, String reason, + RootDeviceType rootDeviceType, String rootDeviceName, Map ebsBlockDevices, + MonitoringState monitoringState, String placementGroup, Iterable productCodes, String subnetId, + String spotInstanceRequestId, String vpcId) { + super(region, groupIds, amiLaunchIndex, dnsName, imageId, instanceId, instanceState, instanceType, ipAddress, + kernelId, keyName, launchTime, availabilityZone, virtualizationType, platform, privateDnsName, + privateIpAddress, ramdiskId, reason, rootDeviceType, rootDeviceName, ebsBlockDevices); + this.monitoringState = checkNotNull(monitoringState, "monitoringState"); + this.placementGroup = placementGroup; + this.productCodes = ImmutableSet.copyOf(checkNotNull(groupIds, "groupIds")); + this.subnetId = subnetId; + this.spotInstanceRequestId = spotInstanceRequestId; + this.vpcId = vpcId; + } + + /** + * State of monitoring for the instance. + */ + public MonitoringState getMonitoringState() { + return monitoringState; + } + + /** + * The name of the placement group the instance is in (for cluster compute instances). + */ + public String getPlacementGroup() { + return placementGroup; + } + + /** + * Product codes attached to this instance. + */ + public Set getProductCodes() { + return productCodes; + } + + /** + * The ID of the Spot Instance request + */ + public String getSpotInstanceRequestId() { + return spotInstanceRequestId; + } + + /** + * Specifies the VPC in which the instance is running (Amazon Virtual Private Cloud). + */ + public String getVpcId() { + return vpcId; + } + + /** + * Specifies the subnet ID in which the instance is running (Amazon Virtual Private Cloud). + */ + public String getSubnetId() { + return subnetId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode()); + result = prime * result + ((productCodes == null) ? 0 : productCodes.hashCode()); + result = prime * result + ((spotInstanceRequestId == null) ? 0 : spotInstanceRequestId.hashCode()); + result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode()); + result = prime * result + ((vpcId == null) ? 0 : vpcId.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + AWSRunningInstance other = (AWSRunningInstance) obj; + if (placementGroup == null) { + if (other.placementGroup != null) + return false; + } else if (!placementGroup.equals(other.placementGroup)) + return false; + if (productCodes == null) { + if (other.productCodes != null) + return false; + } else if (!productCodes.equals(other.productCodes)) + return false; + if (spotInstanceRequestId == null) { + if (other.spotInstanceRequestId != null) + return false; + } else if (!spotInstanceRequestId.equals(other.spotInstanceRequestId)) + return false; + if (subnetId == null) { + if (other.subnetId != null) + return false; + } else if (!subnetId.equals(other.subnetId)) + return false; + if (vpcId == null) { + if (other.vpcId != null) + return false; + } else if (!vpcId.equals(other.vpcId)) + return false; + return true; + } + + @Override + public String toString() { + return "[region=" + region + ", availabilityZone=" + availabilityZone + ", instanceId=" + instanceId + + ", instanceState=" + instanceState + ", instanceType=" + instanceType + ", virtualizationType=" + + virtualizationType + ", imageId=" + imageId + ", ipAddress=" + ipAddress + ", dnsName=" + dnsName + + ", privateIpAddress=" + privateIpAddress + ", privateDnsName=" + privateDnsName + ", keyName=" + + keyName + ", platform=" + platform + ", launchTime=" + launchTime + ", rootDeviceName=" + + rootDeviceName + ", rootDeviceType=" + rootDeviceType + ", ebsBlockDevices=" + ebsBlockDevices + + ", monitoringState=" + monitoringState + ", placementGroup=" + placementGroup + ", productCodes=" + + productCodes + ", spotInstanceRequestId=" + spotInstanceRequestId + ", subnetId=" + subnetId + + ", vpcId=" + vpcId + "]"; + } + +} diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/MonitoringState.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/MonitoringState.java similarity index 86% rename from apis/ec2/src/main/java/org/jclouds/ec2/domain/MonitoringState.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/MonitoringState.java index cdf7a2a669..0facfdd784 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/MonitoringState.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/MonitoringState.java @@ -17,12 +17,12 @@ * ==================================================================== */ -package org.jclouds.ec2.domain; +package org.jclouds.aws.ec2.domain; import static com.google.common.base.Preconditions.checkNotNull; +import org.jclouds.aws.ec2.services.MonitoringClient; import org.jclouds.ec2.services.InstanceClient; -import org.jclouds.ec2.services.MonitoringClient; /** * @@ -47,13 +47,6 @@ public enum MonitoringState { } public static MonitoringState fromValue(String state) { - /** - * Eucalyptus - */ - if ("false".endsWith(state)) - return DISABLED; - if ("true".endsWith(state)) - return ENABLED; try { return valueOf(checkNotNull(state, "state").toUpperCase()); } catch (IllegalArgumentException e) { diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/PlacementGroup.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/PlacementGroup.java similarity index 99% rename from apis/ec2/src/main/java/org/jclouds/ec2/domain/PlacementGroup.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/PlacementGroup.java index 2d2f5cd6cd..467b8a6498 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/PlacementGroup.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/PlacementGroup.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.domain; +package org.jclouds.aws.ec2.domain; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/CreatePlacementGroupIfNeeded.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/functions/CreatePlacementGroupIfNeeded.java similarity index 90% rename from apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/CreatePlacementGroupIfNeeded.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/functions/CreatePlacementGroupIfNeeded.java index 549582a5c1..584a04bb38 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/CreatePlacementGroupIfNeeded.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/functions/CreatePlacementGroupIfNeeded.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.compute.functions; +package org.jclouds.aws.ec2.functions; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; @@ -28,11 +28,11 @@ import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.aws.AWSResponseException; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.domain.PlacementGroup.State; import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.compute.domain.RegionAndName; -import org.jclouds.ec2.domain.PlacementGroup; -import org.jclouds.ec2.domain.PlacementGroup.State; import org.jclouds.logging.Logger; import com.google.common.base.Function; @@ -47,11 +47,11 @@ public class CreatePlacementGroupIfNeeded implements Function placementGroupAvailable; @Inject - public CreatePlacementGroupIfNeeded(EC2Client ec2Client, + public CreatePlacementGroupIfNeeded(AWSEC2Client ec2Client, @Named("AVAILABLE") Predicate placementGroupAvailable) { this.ec2Client = ec2Client; this.placementGroupAvailable = placementGroupAvailable; diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/AWSRunInstancesOptions.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/AWSRunInstancesOptions.java new file mode 100644 index 0000000000..a4cf04183c --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/AWSRunInstancesOptions.java @@ -0,0 +1,220 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.options; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Set; + +import org.jclouds.ec2.domain.BlockDeviceMapping; +import org.jclouds.ec2.domain.InstanceType; +import org.jclouds.ec2.options.RunInstancesOptions; + +/** + * Contains options supported in the Form API for the RunInstances operation.

+ * Usage

The recommended way to instantiate a RunInstancesOptions object is to statically + * import RunInstancesOptions.Builder.* and invoke a static creation method followed by an instance + * mutator (if needed): + *

+ * + * import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.* + *

+ * EC2Client connection = // get connection + * Future instances = connection.runInstances(executableBy("123125").imageIds(1000, 1004)); + * + * + * @author Adrian Cole + * @see + */ +public class AWSRunInstancesOptions extends RunInstancesOptions { + public static final AWSRunInstancesOptions NONE = new AWSRunInstancesOptions(); + + /** + * Specifies the name of an existing placement group you want to launch the instance into (for + * cluster compute instances). + * + * @param placementGroup + * name of an existing placement group + */ + public AWSRunInstancesOptions inPlacementGroup(String placementGroup) { + formParameters.put("Placement.GroupName", checkNotNull(placementGroup, "placementGroup")); + return this; + } + + String getPlacementGroup() { + return getFirstFormOrNull("Placement.GroupName"); + } + + /** + * Enables monitoring for the instance. + */ + public AWSRunInstancesOptions enableMonitoring() { + formParameters.put("Monitoring.Enabled", "true"); + return this; + } + + String getMonitoringEnabled() { + return getFirstFormOrNull("Monitoring.Enabled"); + } + + /** + * Specifies the subnet ID within which to launch the instance(s) for Amazon Virtual Private + * Cloud. + */ + public AWSRunInstancesOptions withSubnetId(String subnetId) { + formParameters.put("SubnetId", checkNotNull(subnetId, "subnetId")); + return this; + } + + String getSubnetId() { + return getFirstFormOrNull("SubnetId"); + } + + public static class Builder extends RunInstancesOptions.Builder { + + /** + * @see AWSRunInstancesOptions#inPlacementGroup(String) + */ + public static AWSRunInstancesOptions inPlacementGroup(String placementGroup) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.inPlacementGroup(placementGroup); + } + + /** + * @see AWSRunInstancesOptions#enableMonitoring() + */ + public static AWSRunInstancesOptions enableMonitoring() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.enableMonitoring(); + } + + /** + * @see AWSRunInstancesOptions#withSubnetId(String) + */ + public static AWSRunInstancesOptions withSubnetId(String subnetId) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.withSubnetId(subnetId); + } + + /** + * @see AWSRunInstancesOptions#withKeyName(String) + */ + public static AWSRunInstancesOptions withKeyName(String keyName) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.withKeyName(keyName); + } + + /** + * @see AWSRunInstancesOptions#withSecurityGroup(String) + */ + public static AWSRunInstancesOptions withSecurityGroup(String securityGroup) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.withSecurityGroup(securityGroup); + } + + /** + * @see AWSRunInstancesOptions#withUserData(byte []) + */ + public static AWSRunInstancesOptions withUserData(byte[] unencodedData) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.withUserData(unencodedData); + } + + /** + * @see AWSRunInstancesOptions#asType(InstanceType) + */ + public static AWSRunInstancesOptions asType(String instanceType) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.asType(instanceType); + } + + /** + * @see AWSRunInstancesOptions#withKernelId(String) + */ + public static AWSRunInstancesOptions withKernelId(String kernelId) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.withKernelId(kernelId); + } + + /** + * @see AWSRunInstancesOptions#withRamdisk(String) + */ + public static AWSRunInstancesOptions withRamdisk(String ramdiskId) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.withRamdisk(ramdiskId); + } + + /** + * @see AWSRunInstancesOptions#withBlockDeviceMappings(Set mappings) + */ + public static AWSRunInstancesOptions withBlockDeviceMappings(Set mappings) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.withBlockDeviceMappings(mappings); + } + + } + + @Override + public AWSRunInstancesOptions withBlockDeviceMappings(Set mappings) { + return AWSRunInstancesOptions.class.cast(super.withBlockDeviceMappings(mappings)); + } + + @Override + public AWSRunInstancesOptions withKernelId(String kernelId) { + return AWSRunInstancesOptions.class.cast(super.withKernelId(kernelId)); + } + + @Override + public AWSRunInstancesOptions withKeyName(String keyName) { + return AWSRunInstancesOptions.class.cast(super.withKeyName(keyName)); + } + + @Override + public AWSRunInstancesOptions withRamdisk(String ramDiskId) { + return AWSRunInstancesOptions.class.cast(super.withRamdisk(ramDiskId)); + } + + @Override + public AWSRunInstancesOptions withSecurityGroup(String securityGroup) { + return AWSRunInstancesOptions.class.cast(super.withSecurityGroup(securityGroup)); + } + + @Override + public AWSRunInstancesOptions withSecurityGroups(Iterable securityGroups) { + return AWSRunInstancesOptions.class.cast(super.withSecurityGroups(securityGroups)); + } + + @Override + public AWSRunInstancesOptions withSecurityGroups(String... securityGroups) { + return AWSRunInstancesOptions.class.cast(super.withSecurityGroups(securityGroups)); + } + + @Override + public AWSRunInstancesOptions withUserData(byte[] unencodedData) { + return AWSRunInstancesOptions.class.cast(super.withUserData(unencodedData)); + } + + @Override + public AWSRunInstancesOptions asType(String type) { + return AWSRunInstancesOptions.class.cast(super.asType(type)); + } +} diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/predicates/PlacementGroupAvailable.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/predicates/PlacementGroupAvailable.java similarity index 90% rename from apis/ec2/src/main/java/org/jclouds/ec2/predicates/PlacementGroupAvailable.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/predicates/PlacementGroupAvailable.java index 21ebc2057c..9acdd978cd 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/predicates/PlacementGroupAvailable.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/predicates/PlacementGroupAvailable.java @@ -17,15 +17,15 @@ * ==================================================================== */ -package org.jclouds.ec2.predicates; +package org.jclouds.aws.ec2.predicates; import java.util.NoSuchElementException; import javax.annotation.Resource; import javax.inject.Singleton; -import org.jclouds.ec2.EC2Client; -import org.jclouds.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.domain.PlacementGroup; import org.jclouds.logging.Logger; import org.jclouds.rest.ResourceNotFoundException; @@ -41,13 +41,13 @@ import com.google.inject.Inject; @Singleton public class PlacementGroupAvailable implements Predicate { - private final EC2Client client; + private final AWSEC2Client client; @Resource protected Logger logger = Logger.NULL; @Inject - public PlacementGroupAvailable(EC2Client client) { + public PlacementGroupAvailable(AWSEC2Client client) { this.client = client; } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/predicates/PlacementGroupDeleted.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/predicates/PlacementGroupDeleted.java similarity index 89% rename from apis/ec2/src/main/java/org/jclouds/ec2/predicates/PlacementGroupDeleted.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/predicates/PlacementGroupDeleted.java index e3cfa0bfdd..b8e6c86564 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/predicates/PlacementGroupDeleted.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/predicates/PlacementGroupDeleted.java @@ -17,15 +17,15 @@ * ==================================================================== */ -package org.jclouds.ec2.predicates; +package org.jclouds.aws.ec2.predicates; import java.util.NoSuchElementException; import javax.annotation.Resource; import javax.inject.Singleton; -import org.jclouds.ec2.EC2Client; -import org.jclouds.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.domain.PlacementGroup; import org.jclouds.logging.Logger; import com.google.common.base.Predicate; @@ -40,13 +40,13 @@ import com.google.inject.Inject; @Singleton public class PlacementGroupDeleted implements Predicate { - private final EC2Client client; + private final AWSEC2Client client; @Resource protected Logger logger = Logger.NULL; @Inject - public PlacementGroupDeleted(EC2Client client) { + public PlacementGroupDeleted(AWSEC2Client client) { this.client = client; } diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/reference/AWSEC2Constants.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/reference/AWSEC2Constants.java new file mode 100644 index 0000000000..a410666c32 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/reference/AWSEC2Constants.java @@ -0,0 +1,58 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.reference; + +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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. + * ==================================================================== + */ + +import org.jclouds.ec2.domain.InstanceType; +import org.jclouds.ec2.reference.EC2Constants; + +/** + * Configuration properties and constants used in EC2 connections. + * + * @author Adrian Cole + */ +public interface AWSEC2Constants extends EC2Constants { + + /** + * amis that work on the cluster instance type + * + * @see InstanceType.CC1_4XLARGE + */ + public static final String PROPERTY_EC2_CC_AMIs = "jclouds.ec2.cc-amis"; + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSAMIAsyncClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSAMIAsyncClient.java new file mode 100644 index 0000000000..9962e31246 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSAMIAsyncClient.java @@ -0,0 +1,94 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.services; + +import static org.jclouds.aws.reference.FormParameters.ACTION; +import static org.jclouds.aws.reference.FormParameters.VERSION; + +import java.util.Set; + +import javax.annotation.Nullable; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +import org.jclouds.aws.ec2.AWSEC2AsyncClient; +import org.jclouds.aws.ec2.xml.ProductCodesHandler; +import org.jclouds.aws.filters.FormSigner; +import org.jclouds.ec2.binders.BindProductCodesToIndexedFormParams; +import org.jclouds.ec2.services.AMIAsyncClient; +import org.jclouds.ec2.services.AMIClient; +import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.EndpointParam; +import org.jclouds.rest.annotations.FormParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides access to AMI Services. + *

+ * + * @author Adrian Cole + */ +@RequestFilters(FormSigner.class) +@FormParams(keys = VERSION, values = AWSEC2AsyncClient.VERSION) +@VirtualHost +public interface AWSAMIAsyncClient extends AMIAsyncClient { + // TODO make AWSImage as it has product codes... + + /** + * @see AMIClient#getProductCodesForImageInRegion + */ + @POST + @Path("/") + @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeImageAttribute", "productCodes" }) + @XMLResponseParser(ProductCodesHandler.class) + ListenableFuture> getProductCodesForImageInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @FormParam("ImageId") String imageId); + + /** + * @see AMIClient#addProductCodesToImageInRegion + */ + @POST + @Path("/") + @FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = { "ModifyImageAttribute", "add", + "productCodes" }) + ListenableFuture addProductCodesToImageInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @BinderParam(BindProductCodesToIndexedFormParams.class) Iterable productCodes, + @FormParam("ImageId") String imageId); + + /** + * @see AMIClient#removeProductCodesToImageInRegion + */ + @POST + @Path("/") + @FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = { "ModifyImageAttribute", "remove", + "productCodes" }) + ListenableFuture removeProductCodesFromImageInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @BinderParam(BindProductCodesToIndexedFormParams.class) Iterable productCodes, + @FormParam("ImageId") String imageId); +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSAMIClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSAMIClient.java new file mode 100644 index 0000000000..aa66609d9a --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSAMIClient.java @@ -0,0 +1,94 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.services; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Nullable; + +import org.jclouds.concurrent.Timeout; +import org.jclouds.ec2.options.DescribeImagesOptions; +import org.jclouds.ec2.services.AMIClient; + +/** + * Provides access to EC2 via their REST API. + *

+ * + * @author Adrian Cole + */ +@Timeout(duration = 45, timeUnit = TimeUnit.SECONDS) +public interface AWSAMIClient extends AMIClient{ + + + /** + * Returns the Product Codes of an image. + * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. + * @param imageId + * The ID of the AMI for which an attribute will be described + * @see #describeImages + * @see #modifyImageAttribute + * @see #resetImageAttribute + * @see + * @see DescribeImagesOptions + */ + Set getProductCodesForImageInRegion(@Nullable String region, String imageId); + + + /** + * Adds {@code productCode}s to an AMI. + * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. + * @param productCodes + * Product Codes + * @param imageId + * The AMI ID. + * + * @see #removeProductCodesFromImage + * @see #describeImageAttribute + * @see #resetImageAttribute + * @see + */ + void addProductCodesToImageInRegion(@Nullable String region, Iterable productCodes, String imageId); + + /** + * Removes {@code productCode}s from an AMI. + * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. + * @param productCodes + * Product Codes + * @param imageId + * The AMI ID. + * + * @see #addProductCodesToImage + * @see #describeImageAttribute + * @see #resetImageAttribute + * @see + */ + void removeProductCodesFromImageInRegion(@Nullable String region, Iterable productCodes, + String imageId); +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSInstanceAsyncClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSInstanceAsyncClient.java new file mode 100644 index 0000000000..f01ecedbfd --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSInstanceAsyncClient.java @@ -0,0 +1,92 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.services; + +import static org.jclouds.aws.reference.FormParameters.ACTION; +import static org.jclouds.aws.reference.FormParameters.VERSION; + +import java.util.Set; + +import javax.annotation.Nullable; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +import org.jclouds.aws.ec2.AWSEC2AsyncClient; +import org.jclouds.aws.ec2.domain.AWSRunningInstance; +import org.jclouds.aws.ec2.xml.AWSDescribeInstancesResponseHandler; +import org.jclouds.aws.ec2.xml.AWSRunInstancesResponseHandler; +import org.jclouds.aws.filters.FormSigner; +import org.jclouds.ec2.binders.BindInstanceIdsToIndexedFormParams; +import org.jclouds.ec2.binders.IfNotNullBindAvailabilityZoneToFormParam; +import org.jclouds.ec2.domain.Reservation; +import org.jclouds.ec2.options.RunInstancesOptions; +import org.jclouds.ec2.services.InstanceAsyncClient; +import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.EndpointParam; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.FormParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides access to EC2 Instance Services via their REST API. + *

+ * + * @author Adrian Cole + */ +@RequestFilters(FormSigner.class) +@FormParams(keys = VERSION, values = AWSEC2AsyncClient.VERSION) +@VirtualHost +public interface AWSInstanceAsyncClient extends InstanceAsyncClient { + + /** + * @see AWSInstanceClient#describeInstancesInRegion + */ + @Override + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DescribeInstances") + @XMLResponseParser(AWSDescribeInstancesResponseHandler.class) + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture>> describeInstancesInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds); + + /** + * @see AWSInstanceClient#runInstancesInRegion + */ + @Override + @POST + @Path("/") + @FormParams(keys = ACTION, values = "RunInstances") + @XMLResponseParser(AWSRunInstancesResponseHandler.class) + ListenableFuture> runInstancesInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @Nullable @BinderParam(IfNotNullBindAvailabilityZoneToFormParam.class) String nullableAvailabilityZone, + @FormParam("ImageId") String imageId, @FormParam("MinCount") int minCount, + @FormParam("MaxCount") int maxCount, RunInstancesOptions... options); + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSInstanceClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSInstanceClient.java new file mode 100644 index 0000000000..185fb04567 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSInstanceClient.java @@ -0,0 +1,51 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.services; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Nullable; + +import org.jclouds.aws.ec2.domain.AWSRunningInstance; +import org.jclouds.concurrent.Timeout; +import org.jclouds.ec2.domain.Reservation; +import org.jclouds.ec2.options.RunInstancesOptions; +import org.jclouds.ec2.services.InstanceClient; + +/** + * Provides access to EC2 via their REST API. + *

+ * + * @author Adrian Cole + */ +@Timeout(duration = 90, timeUnit = TimeUnit.SECONDS) +public interface AWSInstanceClient extends InstanceClient { + + @Override + Set> describeInstancesInRegion(@Nullable String region, + String... instanceIds); + + @Override + Reservation runInstancesInRegion(@Nullable String region, + @Nullable String nullableAvailabilityZone, String imageId, int minCount, int maxCount, + RunInstancesOptions... options); + +} diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/MonitoringAsyncClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/MonitoringAsyncClient.java similarity index 95% rename from apis/ec2/src/main/java/org/jclouds/ec2/services/MonitoringAsyncClient.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/MonitoringAsyncClient.java index 6e3264d3c1..0c42604f61 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/MonitoringAsyncClient.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/MonitoringAsyncClient.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import static org.jclouds.aws.reference.FormParameters.ACTION; import static org.jclouds.aws.reference.FormParameters.VERSION; @@ -29,11 +29,11 @@ import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.Path; +import org.jclouds.aws.ec2.domain.MonitoringState; +import org.jclouds.aws.ec2.xml.MonitoringStateHandler; import org.jclouds.aws.filters.FormSigner; import org.jclouds.ec2.EC2AsyncClient; import org.jclouds.ec2.binders.BindInstanceIdsToIndexedFormParams; -import org.jclouds.ec2.domain.MonitoringState; -import org.jclouds.ec2.xml.MonitoringStateHandler; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.EndpointParam; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/MonitoringClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/MonitoringClient.java similarity index 94% rename from apis/ec2/src/main/java/org/jclouds/ec2/services/MonitoringClient.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/MonitoringClient.java index a9b11bfae5..2b272216fb 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/MonitoringClient.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/MonitoringClient.java @@ -17,14 +17,15 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import java.util.Map; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; -import org.jclouds.ec2.domain.MonitoringState; +import org.jclouds.ec2.services.InstanceClient; +import org.jclouds.aws.ec2.domain.MonitoringState; import org.jclouds.concurrent.Timeout; /** diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/PlacementGroupAsyncClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/PlacementGroupAsyncClient.java similarity index 96% rename from apis/ec2/src/main/java/org/jclouds/ec2/services/PlacementGroupAsyncClient.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/PlacementGroupAsyncClient.java index a5f431cf88..45adce9236 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/PlacementGroupAsyncClient.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/PlacementGroupAsyncClient.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import static org.jclouds.aws.reference.FormParameters.ACTION; import static org.jclouds.aws.reference.FormParameters.VERSION; @@ -29,11 +29,11 @@ import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.Path; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.xml.DescribePlacementGroupsResponseHandler; import org.jclouds.aws.filters.FormSigner; import org.jclouds.ec2.EC2AsyncClient; import org.jclouds.ec2.binders.BindGroupNamesToIndexedFormParams; -import org.jclouds.ec2.domain.PlacementGroup; -import org.jclouds.ec2.xml.DescribePlacementGroupsResponseHandler; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.EndpointParam; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/PlacementGroupClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/PlacementGroupClient.java similarity index 97% rename from apis/ec2/src/main/java/org/jclouds/ec2/services/PlacementGroupClient.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/PlacementGroupClient.java index 4e07ee137c..b02357839a 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/PlacementGroupClient.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/PlacementGroupClient.java @@ -17,14 +17,14 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import java.util.Set; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; -import org.jclouds.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.domain.PlacementGroup; import org.jclouds.concurrent.Timeout; /** diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/AWSDescribeInstancesResponseHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/AWSDescribeInstancesResponseHandler.java new file mode 100644 index 0000000000..40553a7302 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/AWSDescribeInstancesResponseHandler.java @@ -0,0 +1,71 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.xml; + +import java.util.Set; + +import javax.inject.Inject; + +import org.jclouds.date.DateService; +import org.jclouds.ec2.domain.Reservation; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.domain.RunningInstance.Builder; +import org.jclouds.location.Region; + +import com.google.common.collect.Sets; +import com.google.inject.Provider; + +/** + * Parses the following XML document: + *

+ * DescribeImagesResponse xmlns="http: + * + * @author Adrian Cole + * @see + * RunInstancesResponse xmlns="http: + * + * @author Adrian Cole + * @see extends BaseReservationHandler { + + public BaseAWSReservationHandler(DateService dateService, String defaultRegion, Provider builderProvider) { + super(dateService, defaultRegion, builderProvider); + } + + protected String currentOrNull() { + String returnVal = currentText.toString().trim(); + return returnVal.equals("") ? null : returnVal; + } + + public void endElement(String uri, String name, String qName) { + if (qName.equals("state")) { + builder().monitoringState(MonitoringState.fromValue(currentOrNull())); + } else if (qName.equals("groupName")) { + builder().placementGroup(currentOrNull()); + } else if (qName.equals("subnetId")) { + builder().subnetId(currentOrNull()); + } else if (qName.equals("spotInstanceRequestId")) { + builder().spotInstanceRequestId(currentOrNull()); + } else if (qName.equals("vpcId")) { + builder().vpcId(currentOrNull()); + } else if (qName.equals("productCode")) { + builder().productCode(currentOrNull()); + } + super.endElement(uri, name, qName); + } + + @Override + protected AWSRunningInstance.Builder builder() { + return AWSRunningInstance.Builder.class.cast(builder); + } + + public void characters(char ch[], int start, int length) { + super.characters(ch, start, length); + } + +} diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribePlacementGroupsResponseHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribePlacementGroupsResponseHandler.java similarity index 96% rename from apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribePlacementGroupsResponseHandler.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribePlacementGroupsResponseHandler.java index 38f6484a45..7596b05957 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribePlacementGroupsResponseHandler.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribePlacementGroupsResponseHandler.java @@ -17,13 +17,13 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import java.util.Set; import javax.inject.Inject; -import org.jclouds.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.domain.PlacementGroup; import org.jclouds.http.HttpRequest; import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax.HandlerWithResult; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeReservedInstancesOfferingResponseHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribeReservedInstancesOfferingResponseHandler.java similarity index 98% rename from apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeReservedInstancesOfferingResponseHandler.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribeReservedInstancesOfferingResponseHandler.java index 9b3f2b1590..c036d71c47 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeReservedInstancesOfferingResponseHandler.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribeReservedInstancesOfferingResponseHandler.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import java.util.Set; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/MonitoringStateHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/MonitoringStateHandler.java similarity index 95% rename from apis/ec2/src/main/java/org/jclouds/ec2/xml/MonitoringStateHandler.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/MonitoringStateHandler.java index cfa7e8ec60..9e6e6626b6 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/MonitoringStateHandler.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/MonitoringStateHandler.java @@ -17,11 +17,11 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import java.util.Map; -import org.jclouds.ec2.domain.MonitoringState; +import org.jclouds.aws.ec2.domain.MonitoringState; import org.jclouds.http.functions.ParseSax; import com.google.common.collect.Maps; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/PlacementGroupHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/PlacementGroupHandler.java similarity index 94% rename from apis/ec2/src/main/java/org/jclouds/ec2/xml/PlacementGroupHandler.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/PlacementGroupHandler.java index ce2cc6cf66..e466204b6c 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/PlacementGroupHandler.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/PlacementGroupHandler.java @@ -17,12 +17,12 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import javax.inject.Inject; -import org.jclouds.ec2.domain.PlacementGroup; -import org.jclouds.ec2.domain.PlacementGroup.State; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.domain.PlacementGroup.State; import org.jclouds.aws.util.AWSUtils; import org.jclouds.date.DateService; import org.jclouds.http.functions.ParseSax; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/ProductCodesHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/ProductCodesHandler.java similarity index 98% rename from apis/ec2/src/main/java/org/jclouds/ec2/xml/ProductCodesHandler.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/ProductCodesHandler.java index 820fe74ad1..6f9e76722d 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/ProductCodesHandler.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/ProductCodesHandler.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import java.util.Set; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/ReservedInstancesOfferingHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/ReservedInstancesOfferingHandler.java similarity index 99% rename from apis/ec2/src/main/java/org/jclouds/ec2/xml/ReservedInstancesOfferingHandler.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/ReservedInstancesOfferingHandler.java index f29c1fb567..c09d409b4b 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/ReservedInstancesOfferingHandler.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/ReservedInstancesOfferingHandler.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import javax.inject.Inject; diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2AsyncClientTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2AsyncClientTest.java new file mode 100644 index 0000000000..d17725be56 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2AsyncClientTest.java @@ -0,0 +1,91 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +import org.jclouds.aws.ec2.services.BaseAWSEC2AsyncClientTest; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.inject.TypeLiteral; + +/** + * Tests behavior of {@code AWSEC2AsyncClient} + * + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "AWSEC2AsyncClientTest") +public class AWSEC2AsyncClientTest extends BaseAWSEC2AsyncClientTest { + + private AWSEC2AsyncClient asyncClient; + private AWSEC2Client syncClient; + + public void testSync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException { + assert syncClient.getAMIServices() != null; + assert syncClient.getAvailabilityZoneAndRegionServices() != null; + assert syncClient.getElasticBlockStoreServices() != null; + assert syncClient.getElasticIPAddressServices() != null; + assert syncClient.getInstanceServices() != null; + assert syncClient.getKeyPairServices() != null; + assert syncClient.getMonitoringServices() != null; + assert syncClient.getSecurityGroupServices() != null; + assert syncClient.getPlacementGroupServices() != null; + assert syncClient.getWindowsServices() != null; + + } + + public void testAsync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException { + assert asyncClient.getAMIServices() != null; + assert asyncClient.getAvailabilityZoneAndRegionServices() != null; + assert asyncClient.getElasticBlockStoreServices() != null; + assert asyncClient.getElasticIPAddressServices() != null; + assert asyncClient.getInstanceServices() != null; + assert asyncClient.getKeyPairServices() != null; + assert asyncClient.getMonitoringServices() != null; + assert asyncClient.getSecurityGroupServices() != null; + assert asyncClient.getPlacementGroupServices() != null; + assert asyncClient.getWindowsServices() != null; + } + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } + + @BeforeClass + @Override + protected void setupFactory() throws IOException { + super.setupFactory(); + asyncClient = injector.getInstance(AWSEC2AsyncClient.class); + syncClient = injector.getInstance(AWSEC2Client.class); + } + + @Override + protected void checkFilters(HttpRequest request) { + + } + +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java index bf214e6507..aa4327621f 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java @@ -19,9 +19,30 @@ package org.jclouds.aws.ec2.compute; +import static org.testng.Assert.assertEquals; + +import java.util.Set; + +import org.jclouds.aws.ec2.domain.AWSRunningInstance; +import org.jclouds.aws.ec2.domain.MonitoringState; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.compute.predicates.NodePredicates; +import org.jclouds.domain.Credentials; +import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.compute.EC2ComputeServiceLiveTest; +import org.jclouds.ec2.domain.IpProtocol; +import org.jclouds.ec2.domain.KeyPair; +import org.jclouds.ec2.domain.SecurityGroup; +import org.jclouds.ec2.services.InstanceClient; +import org.jclouds.ec2.services.KeyPairClient; +import org.jclouds.ec2.services.SecurityGroupClient; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; + /** * * @author Adrian Cole @@ -34,4 +55,149 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest { tag = "ec2"; } + @Override + @Test(enabled = true, dependsOnMethods = "testCompareSizes") + public void testExtendedOptionsAndLogin() throws Exception { + SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) + .getSecurityGroupServices(); + + KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) + .getKeyPairServices(); + + InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) + .getInstanceServices(); + + String tag = this.tag + "o"; + + TemplateOptions options = client.templateOptions(); + + // Date before = new Date(); + + options.as(AWSEC2TemplateOptions.class).securityGroups(tag); + options.as(AWSEC2TemplateOptions.class).keyPair(tag); + options.as(AWSEC2TemplateOptions.class).enableMonitoring(); + + String startedId = null; + try { + cleanupExtendedStuff(securityGroupClient, keyPairClient, tag); + + // create a security group that allows ssh in so that our scripts later + // will work + securityGroupClient.createSecurityGroupInRegion(null, tag, tag); + securityGroupClient.authorizeSecurityGroupIngressInRegion(null, tag, IpProtocol.TCP, 22, 22, "0.0.0.0/0"); + + // create a keypair to pass in as well + KeyPair result = keyPairClient.createKeyPairInRegion(null, tag); + + Set nodes = client.runNodesWithTag(tag, 1, options); + NodeMetadata first = Iterables.get(nodes, 0); + assert first.getCredentials() != null : first; + assert first.getCredentials().identity != null : first; + + startedId = Iterables.getOnlyElement(nodes).getProviderId(); + + AWSRunningInstance instance = AWSRunningInstance.class.cast(getInstance(instanceClient, startedId)); + + assertEquals(instance.getKeyName(), tag); + assertEquals(instance.getMonitoringState(), MonitoringState.ENABLED); + + // TODO when the cloudwatchclient is finished + + // RestContext monitoringContext = new + // RestContextFactory().createContext( + // "cloudwatch", identity, credential, ImmutableSet. of(new Log4JLoggingModule())); + // + // try { + // Set datapoints = + // monitoringContext.getApi().getMetricStatisticsInRegion(instance.getRegion(), + // "CPUUtilization", before, new Date(), 60, "Average"); + // assert datapoints != null; + // } finally { + // monitoringContext.close(); + // } + + // make sure we made our dummy group and also let in the user's group + assertEquals(Sets.newTreeSet(instance.getGroupIds()), ImmutableSortedSet. of("jclouds#" + tag + "#" + + instance.getRegion(), tag)); + + // make sure our dummy group has no rules + SecurityGroup group = Iterables.getOnlyElement(securityGroupClient.describeSecurityGroupsInRegion(null, + "jclouds#" + tag + "#" + instance.getRegion())); + assert group.getIpPermissions().size() == 0 : group; + + // try to run a script with the original keyPair + runScriptWithCreds(tag, first.getOperatingSystem(), new Credentials(first.getCredentials().identity, result + .getKeyMaterial())); + + } finally { + client.destroyNodesMatching(NodePredicates.withTag(tag)); + if (startedId != null) { + // ensure we didn't delete these resources! + assertEquals(keyPairClient.describeKeyPairsInRegion(null, tag).size(), 1); + assertEquals(securityGroupClient.describeSecurityGroupsInRegion(null, tag).size(), 1); + } + cleanupExtendedStuff(securityGroupClient, keyPairClient, tag); + } + + } + @Test(enabled = true, dependsOnMethods = "testCompareSizes") + public void testExtendedOptionsWithSubnetId() throws Exception { + + String subnetId = System.getProperty("test.subnetId"); + if (subnetId == null) { + // Skip test and return + return; + } + SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) + .getSecurityGroupServices(); + + KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) + .getKeyPairServices(); + + InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) + .getInstanceServices(); + + String tag = this.tag + "g"; + + TemplateOptions options = client.templateOptions(); + + // options.as(AWSEC2TemplateOptions.class).securityGroups(tag); + options.as(AWSEC2TemplateOptions.class).keyPair(tag); + options.as(AWSEC2TemplateOptions.class).subnetId(subnetId); + + String startedId = null; + String nodeId = null; + try { + cleanupExtendedStuff(securityGroupClient, keyPairClient, tag); + + // create the security group + // securityGroupClient.createSecurityGroupInRegion(null, tag, tag); + + // create a keypair to pass in as well + keyPairClient.createKeyPairInRegion(null, tag); + + Set nodes = client.runNodesWithTag(tag, 1, options); + + NodeMetadata first = Iterables.get(nodes, 0); + assert first.getCredentials() != null : first; + assert first.getCredentials().identity != null : first; + + startedId = Iterables.getOnlyElement(nodes).getProviderId(); + nodeId = Iterables.getOnlyElement(nodes).getId(); + + AWSRunningInstance instance = AWSRunningInstance.class.cast(getInstance(instanceClient, startedId)); + + assertEquals(instance.getSubnetId(), subnetId); + + } finally { + if (nodeId != null) + client.destroyNode(nodeId); + if (startedId != null) { + // ensure we didn't delete these resources! + assertEquals(keyPairClient.describeKeyPairsInRegion(null, tag).size(), 1); + } + cleanupExtendedStuff(securityGroupClient, keyPairClient, tag); + } + } + } diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateBuilderLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateBuilderLiveTest.java index e0267fbf55..55617fb968 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateBuilderLiveTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateBuilderLiveTest.java @@ -58,8 +58,8 @@ public class AWSEC2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { @Override public boolean apply(OsFamilyVersion64Bit input) { return input.family == OsFamily.RHEL || // - (input.family == OsFamily.CENTOS && !input.version.matches("5.[42]")) || // - (input.family == OsFamily.WINDOWS && !input.version.matches("200[38]")); + (input.family == OsFamily.CENTOS && !input.version.matches("5.[42]")) || // + (input.family == OsFamily.WINDOWS && !input.version.matches("200[38]")); } }; @@ -69,13 +69,13 @@ public class AWSEC2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { public void testTemplateBuilderM1SMALLWithDescription() { Template template = context.getComputeService().templateBuilder().hardwareId(InstanceType.M1_SMALL) - .osVersionMatches("10.10").imageDescriptionMatches("ubuntu-images").osFamily(OsFamily.UBUNTU).build(); + .osVersionMatches("10.10").imageDescriptionMatches("ubuntu-images").osFamily(OsFamily.UBUNTU).build(); assert (template.getImage().getProviderId().startsWith("ami-")) : template; assertEquals(template.getImage().getOperatingSystem().getVersion(), "10.10"); assertEquals(template.getImage().getOperatingSystem().is64Bit(), false); assertEquals(template.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); - assertEquals(template.getImage().getVersion(), "20110122"); + assertEquals(template.getImage().getVersion(), "20110126"); assertEquals(template.getImage().getUserMetadata().get("rootDeviceType"), "instance-store"); assertEquals(template.getLocation().getId(), "us-east-1"); assertEquals(getCores(template.getHardware()), 1.0d); @@ -86,8 +86,8 @@ public class AWSEC2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { @Test public void testTemplateBuilderCanUseImageIdAndhardwareId() { - Template template = context.getComputeService().templateBuilder().imageId("us-east-1/ami-ccb35ea5") - .hardwareId(InstanceType.M2_2XLARGE).build(); + Template template = context.getComputeService().templateBuilder().imageId("us-east-1/ami-ccb35ea5").hardwareId( + InstanceType.M2_2XLARGE).build(); System.out.println(template.getHardware()); assert (template.getImage().getProviderId().startsWith("ami-")) : template; @@ -119,11 +119,12 @@ public class AWSEC2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { @Test public void testTemplateBuilderMicro() throws IOException { - Template microTemplate = context.getComputeService().templateBuilder().hardwareId(InstanceType.T1_MICRO).build(); + Template microTemplate = context.getComputeService().templateBuilder().hardwareId(InstanceType.T1_MICRO) + .osFamily(OsFamily.UBUNTU).build(); assert (microTemplate.getImage().getProviderId().startsWith("ami-")) : microTemplate; - assertEquals(microTemplate.getImage().getOperatingSystem().getVersion(), "9.10"); - assertEquals(microTemplate.getImage().getOperatingSystem().is64Bit(), false); + assertEquals(microTemplate.getImage().getOperatingSystem().getVersion(), "10.04"); + assertEquals(microTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(microTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); assertEquals(microTemplate.getImage().getUserMetadata().get("rootDeviceType"), "ebs"); assertEquals(microTemplate.getLocation().getId(), "us-east-1"); @@ -139,8 +140,8 @@ public class AWSEC2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { // set owners to nothing overrides.setProperty(EC2Constants.PROPERTY_EC2_AMI_OWNERS, ""); - context = new ComputeServiceContextFactory().createContext(provider, - ImmutableSet. of(new Log4JLoggingModule()), overrides); + context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet + . of(new Log4JLoggingModule()), overrides); assertEquals(context.getComputeService().listImages().size(), 0); diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/options/AWSEC2TemplateOptionsTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/options/AWSEC2TemplateOptionsTest.java new file mode 100644 index 0000000000..1445940736 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/options/AWSEC2TemplateOptionsTest.java @@ -0,0 +1,313 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.compute.options; + +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.authorizePublicKey; +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.blockOnPort; +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.enableMonitoring; +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.inboundPorts; +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.installPrivateKey; +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.keyPair; +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.noKeyPair; +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.securityGroups; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; + +import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions; +import org.jclouds.compute.options.TemplateOptions; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * Tests possible uses of AWSEC2TemplateOptions and AWSEC2TemplateOptions.Builder.* + * + * @author Adrian Cole + */ +public class AWSEC2TemplateOptionsTest { + + public void testAs() { + TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.as(AWSEC2TemplateOptions.class), options); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testsecurityGroupsIterableBadFormat() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.securityGroups(ImmutableSet.of("group1", "")); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testsecurityGroupsIterableEmptyNotOk() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.securityGroups(ImmutableSet. of()); + } + + @Test + public void testsecurityGroupsIterable() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.securityGroups(ImmutableSet.of("group1", "group2")); + assertEquals(options.getGroupIds(), ImmutableSet.of("group1", "group2")); + + } + + @Test + public void testsecurityGroupsIterableStatic() { + AWSEC2TemplateOptions options = securityGroups(ImmutableSet.of("group1", "group2")); + assertEquals(options.getGroupIds(), ImmutableSet.of("group1", "group2")); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testsecurityGroupsVarArgsBadFormat() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.securityGroups("mygroup", ""); + } + + @Test + public void testsecurityGroupsVarArgs() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.securityGroups("group1", "group2"); + assertEquals(options.getGroupIds(), ImmutableSet.of("group1", "group2")); + + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testsecurityGroupsVarArgsEmptyNotOk() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.securityGroups(); + } + + @Test + public void testDefaultGroupsVarArgsEmpty() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.getGroupIds(), ImmutableSet.of()); + } + + @Test + public void testsecurityGroupsVarArgsStatic() { + AWSEC2TemplateOptions options = securityGroups("group1", "group2"); + assertEquals(options.getGroupIds(), ImmutableSet.of("group1", "group2")); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testkeyPairBadFormat() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.keyPair(""); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void testkeyPairAndNoKeyPair() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.keyPair("mykeypair"); + options.noKeyPair(); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void testNoKeyPairAndKeyPair() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.noKeyPair(); + options.keyPair("mykeypair"); + } + + @Test + public void testkeyPair() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.keyPair("mykeypair"); + assertEquals(options.getKeyPair(), "mykeypair"); + } + + @Test + public void testNullkeyPair() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.getKeyPair(), null); + } + + @Test + public void testkeyPairStatic() { + AWSEC2TemplateOptions options = keyPair("mykeypair"); + assertEquals(options.getKeyPair(), "mykeypair"); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testkeyPairNPE() { + keyPair(null); + } + + @Test + public void testnoKeyPair() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.noKeyPair(); + assertEquals(options.getKeyPair(), null); + assert !options.shouldAutomaticallyCreateKeyPair(); + } + + @Test + public void testFalsenoKeyPair() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.getKeyPair(), null); + assert options.shouldAutomaticallyCreateKeyPair(); + } + + @Test + public void testnoKeyPairStatic() { + AWSEC2TemplateOptions options = noKeyPair(); + assertEquals(options.getKeyPair(), null); + assert !options.shouldAutomaticallyCreateKeyPair(); + } + + @Test + public void testMonitoringEnabledDefault() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assert !options.isMonitoringEnabled(); + } + + @Test + public void testMonitoringEnabled() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.enableMonitoring(); + assert options.isMonitoringEnabled(); + } + + @Test + public void testEnableMonitoringStatic() { + AWSEC2TemplateOptions options = enableMonitoring(); + assertEquals(options.getKeyPair(), null); + assert options.isMonitoringEnabled(); + } + + // superclass tests + @Test(expectedExceptions = IllegalArgumentException.class) + public void testinstallPrivateKeyBadFormat() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.installPrivateKey("whompy"); + } + + @Test + public void testinstallPrivateKey() throws IOException { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.installPrivateKey("-----BEGIN RSA PRIVATE KEY-----"); + assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----"); + } + + @Test + public void testNullinstallPrivateKey() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.getPrivateKey(), null); + } + + @Test + public void testinstallPrivateKeyStatic() throws IOException { + AWSEC2TemplateOptions options = installPrivateKey("-----BEGIN RSA PRIVATE KEY-----"); + assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----"); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testinstallPrivateKeyNPE() { + installPrivateKey(null); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testauthorizePublicKeyBadFormat() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.authorizePublicKey("whompy"); + } + + @Test + public void testauthorizePublicKey() throws IOException { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.authorizePublicKey("ssh-rsa"); + assertEquals(options.getPublicKey(), "ssh-rsa"); + } + + @Test + public void testNullauthorizePublicKey() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.getPublicKey(), null); + } + + @Test + public void testauthorizePublicKeyStatic() throws IOException { + AWSEC2TemplateOptions options = authorizePublicKey("ssh-rsa"); + assertEquals(options.getPublicKey(), "ssh-rsa"); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testauthorizePublicKeyNPE() { + authorizePublicKey(null); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testblockOnPortBadFormat() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.blockOnPort(-1, -1); + } + + @Test + public void testblockOnPort() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.blockOnPort(22, 30); + assertEquals(options.getPort(), 22); + assertEquals(options.getSeconds(), 30); + + } + + @Test + public void testNullblockOnPort() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.getPort(), -1); + assertEquals(options.getSeconds(), -1); + } + + @Test + public void testblockOnPortStatic() { + AWSEC2TemplateOptions options = blockOnPort(22, 30); + assertEquals(options.getPort(), 22); + assertEquals(options.getSeconds(), 30); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testinboundPortsBadFormat() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.inboundPorts(-1, -1); + } + + @Test + public void testinboundPorts() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.inboundPorts(22, 30); + assertEquals(options.getInboundPorts()[0], 22); + assertEquals(options.getInboundPorts()[1], 30); + + } + + @Test + public void testDefaultOpen22() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.getInboundPorts()[0], 22); + } + + @Test + public void testinboundPortsStatic() { + AWSEC2TemplateOptions options = inboundPorts(22, 30); + assertEquals(options.getInboundPorts()[0], 22); + assertEquals(options.getInboundPorts()[1], 30); + } +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/strategy/AWSEC2ImageParserTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ImageParserTest.java similarity index 98% rename from providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/strategy/AWSEC2ImageParserTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ImageParserTest.java index 2de043d677..bcff702c96 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/strategy/AWSEC2ImageParserTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ImageParserTest.java @@ -17,13 +17,14 @@ * ==================================================================== */ -package org.jclouds.aws.ec2.strategy; +package org.jclouds.aws.ec2.compute.strategy; import static org.testng.Assert.assertEquals; import java.util.Map; import java.util.Set; +import org.jclouds.aws.ec2.compute.strategy.AWSEC2ReviseParsedImage; import org.jclouds.compute.config.BaseComputeServiceContextModule; import org.jclouds.compute.domain.ImageBuilder; import org.jclouds.compute.domain.OperatingSystemBuilder; diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java similarity index 71% rename from apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java index b023e570d0..244f481b2a 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.compute.strategy; +package org.jclouds.aws.ec2.compute.strategy; import static org.easymock.EasyMock.expect; import static org.easymock.classextension.EasyMock.createMock; @@ -29,7 +29,13 @@ import java.lang.reflect.Method; import java.util.Map; import java.util.Set; +import javax.inject.Provider; + import org.jclouds.aws.domain.Region; +import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.functions.CreatePlacementGroupIfNeeded; +import org.jclouds.aws.ec2.options.AWSRunInstancesOptions; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Template; import org.jclouds.compute.options.TemplateOptions; @@ -37,13 +43,11 @@ import org.jclouds.ec2.compute.EC2TemplateBuilderTest; import org.jclouds.ec2.compute.domain.EC2HardwareBuilder; import org.jclouds.ec2.compute.domain.RegionAndName; import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules; -import org.jclouds.ec2.compute.functions.CreatePlacementGroupIfNeeded; import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; -import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.compute.strategy.CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions; import org.jclouds.ec2.domain.BlockDeviceMapping; import org.jclouds.ec2.domain.KeyPair; -import org.jclouds.ec2.domain.PlacementGroup; import org.jclouds.ec2.options.RunInstancesOptions; import org.jclouds.encryption.internal.Base64; import org.testng.annotations.Test; @@ -56,6 +60,14 @@ import com.google.common.collect.ImmutableSet; */ @Test(groups = "unit") public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest { + private static final Provider OPTIONS_PROVIDER = new javax.inject.Provider() { + + @Override + public RunInstancesOptions get() { + return new AWSRunInstancesOptions(); + } + + }; public void testExecuteWithDefaultOptionsEC2() throws SecurityException, NoSuchMethodException { // setup constants @@ -68,31 +80,33 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, - new Method[] { - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class - .getDeclaredMethod("getProvider"), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) }); + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, + TemplateOptions.class) }); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); Template template = createMock(Template.class); // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); expect(options.getSubnetId()).andReturn(null); expect(options.getUserData()).andReturn(null); + expect(options.isMonitoringEnabled()).andReturn(false); // replay mocks replay(options); @@ -102,10 +116,9 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run RunInstancesOptions customize = strategy.execute(region, tag, template); assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); - assertEquals( - customize.buildFormParameters().entries(), - ImmutableMultimap. of("InstanceType", size.getProviderId(), "SecurityGroup.1", - generatedGroup, "KeyName", systemGeneratedKeyPairName).entries()); + assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", + size.getProviderId(), "SecurityGroup.1", generatedGroup, "KeyName", systemGeneratedKeyPairName) + .entries()); assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); assertEquals(customize.buildStringPayload(), null); @@ -127,31 +140,35 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, - new Method[] { - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) }); + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, + TemplateOptions.class) }); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); Template template = createMock(Template.class); // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); expect(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - generatedGroup); + generatedGroup); expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); expect(options.getSubnetId()).andReturn(null); expect(options.getUserData()).andReturn(null); + expect(options.isMonitoringEnabled()).andReturn(false); // replay mocks replay(options); @@ -161,11 +178,9 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run RunInstancesOptions customize = strategy.execute(region, tag, template); assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); - assertEquals( - customize.buildFormParameters().entries(), - ImmutableMultimap. of("InstanceType", size.getProviderId(), "SecurityGroup.1", - generatedGroup, "KeyName", systemGeneratedKeyPairName, "Placement.GroupName", generatedGroup) - .entries()); + assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", + size.getProviderId(), "SecurityGroup.1", generatedGroup, "KeyName", systemGeneratedKeyPairName, + "Placement.GroupName", generatedGroup).entries()); assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); assertEquals(customize.buildStringPayload(), null); @@ -187,31 +202,35 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, - new Method[] { - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) }); + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, + TemplateOptions.class) }); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); Template template = createMock(Template.class); // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); expect(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - generatedGroup); + generatedGroup); expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); expect(options.getSubnetId()).andReturn(null); expect(options.getUserData()).andReturn(null); + expect(options.isMonitoringEnabled()).andReturn(false); // replay mocks replay(options); @@ -221,11 +240,9 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run RunInstancesOptions customize = strategy.execute(region, tag, template); assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); - assertEquals( - customize.buildFormParameters().entries(), - ImmutableMultimap. of("InstanceType", size.getProviderId(), "SecurityGroup.1", - generatedGroup, "KeyName", systemGeneratedKeyPairName, "Placement.GroupName", generatedGroup) - .entries()); + assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", + size.getProviderId(), "SecurityGroup.1", generatedGroup, "KeyName", systemGeneratedKeyPairName, + "Placement.GroupName", generatedGroup).entries()); assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); assertEquals(customize.buildStringPayload(), null); @@ -245,28 +262,32 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, - new Method[] { - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) }); + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, + TemplateOptions.class) }); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); Template template = createMock(Template.class); // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); expect(options.getSubnetId()).andReturn("1"); expect(options.getUserData()).andReturn(null); + expect(options.isMonitoringEnabled()).andReturn(false); // replay mocks replay(options); @@ -276,10 +297,8 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run RunInstancesOptions customize = strategy.execute(region, tag, template); assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); - assertEquals( - customize.buildFormParameters().entries(), - ImmutableMultimap. of("InstanceType", size.getProviderId(), "SubnetId", "1", "KeyName", - systemGeneratedKeyPairName).entries()); + assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", + size.getProviderId(), "SubnetId", "1", "KeyName", systemGeneratedKeyPairName).entries()); assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); assertEquals(customize.buildStringPayload(), null); @@ -301,29 +320,33 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, - new Method[] { - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) }); + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, + TemplateOptions.class) }); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); Template template = createMock(Template.class); // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); expect(options.getSubnetId()).andReturn(null); expect(options.getUserData()).andReturn("hello".getBytes()); + expect(options.isMonitoringEnabled()).andReturn(false); // replay mocks replay(options); @@ -333,10 +356,9 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run RunInstancesOptions customize = strategy.execute(region, tag, template); assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); - assertEquals( - customize.buildFormParameters().entries(), - ImmutableMultimap. of("InstanceType", size.getProviderId(), "SecurityGroup.1", "group", - "KeyName", systemGeneratedKeyPairName, "UserData", Base64.encodeBytes("hello".getBytes())).entries()); + assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", + size.getProviderId(), "SecurityGroup.1", "group", "KeyName", systemGeneratedKeyPairName, "UserData", + Base64.encodeBytes("hello".getBytes())).entries()); assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); assertEquals(customize.buildStringPayload(), null); @@ -355,7 +377,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); KeyPair keyPair = createMock(KeyPair.class); // setup expectations @@ -385,7 +407,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); KeyPair keyPair = createMock(KeyPair.class); // setup expectations @@ -394,7 +416,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT expect(strategy.createUniqueKeyPair.apply(new RegionAndName(region, tag))).andReturn(keyPair); expect(keyPair.getKeyName()).andReturn(systemGeneratedKeyPairName).atLeastOnce(); expect(strategy.credentialsMap.put(new RegionAndName(region, systemGeneratedKeyPairName), keyPair)).andReturn( - null); + null); // replay mocks replay(options); @@ -403,7 +425,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); // verify mocks verify(options); @@ -421,7 +443,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); KeyPair keyPair = createMock(KeyPair.class); // setup expectations @@ -455,13 +477,13 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); // setup expectations expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, - ports, shouldAuthorizeSelf); + ports, shouldAuthorizeSelf); expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted); expect(strategy.createSecurityGroupIfNeeded.apply(regionNameAndIngressRules)).andReturn(generatedMarkerGroup); expect(strategy.securityGroupMap.put(regionNameAndIngressRules, generatedMarkerGroup)).andReturn(null); @@ -491,13 +513,13 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); // setup expectations expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, - ports, shouldAuthorizeSelf); + ports, shouldAuthorizeSelf); expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted); expect(strategy.createSecurityGroupIfNeeded.apply(regionNameAndIngressRules)).andReturn(generatedMarkerGroup); expect(strategy.securityGroupMap.put(regionNameAndIngressRules, generatedMarkerGroup)).andReturn(null); @@ -527,13 +549,13 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); // setup expectations expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, - ports, shouldAuthorizeSelf); + ports, shouldAuthorizeSelf); expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted); // replay mocks @@ -561,12 +583,12 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); // setup expectations expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, - ports, shouldAuthorizeSelf); // note + ports, shouldAuthorizeSelf); // note // this // works // since @@ -594,7 +616,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); PlacementGroup placementGroup = createMock(PlacementGroup.class); // setup expectations @@ -607,7 +629,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run assertEquals(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options), - userSuppliedPlacementGroup); + userSuppliedPlacementGroup); // verify mocks verify(options); @@ -625,16 +647,16 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); // setup expectations expect(options.getPlacementGroup()).andReturn(userSuppliedPlacementGroup); expect(options.shouldAutomaticallyCreatePlacementGroup()).andReturn(shouldAutomaticallyCreatePlacementGroup); expect(strategy.placementGroupMap.containsKey(new RegionAndName(region, generatedMarkerGroup))).andReturn(false); expect(strategy.createPlacementGroupIfNeeded.apply(new RegionAndName(region, generatedMarkerGroup))).andReturn( - generatedMarkerGroup); + generatedMarkerGroup); expect(strategy.placementGroupMap.put(new RegionAndName(region, generatedMarkerGroup), generatedMarkerGroup)) - .andReturn(null); + .andReturn(null); // replay mocks replay(options); @@ -642,7 +664,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run assertEquals(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options), - generatedMarkerGroup); + generatedMarkerGroup); // verify mocks verify(options); @@ -659,7 +681,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); PlacementGroup placementGroup = createMock(PlacementGroup.class); // setup expectations @@ -689,12 +711,8 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT verify(strategy.createPlacementGroupIfNeeded); } - private CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions setupStrategy() { - return setupStrategy("ec2"); - } - @SuppressWarnings("unchecked") - private CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions setupStrategy(String provider) { + private CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions setupStrategy() { Map credentialsMap = createMock(Map.class); Map securityGroupMap = createMock(Map.class); Map placementGroupMap = createMock(Map.class); @@ -702,9 +720,9 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded = createMock(CreateSecurityGroupIfNeeded.class); CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded = createMock(CreatePlacementGroupIfNeeded.class); - return new CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions(provider, credentialsMap, - securityGroupMap, placementGroupMap, createUniqueKeyPair, createSecurityGroupIfNeeded, - createPlacementGroupIfNeeded); + return new CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions(credentialsMap, securityGroupMap, + placementGroupMap, createUniqueKeyPair, createSecurityGroupIfNeeded, OPTIONS_PROVIDER, + createPlacementGroupIfNeeded); } private void replayStrategy(CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy) { diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/options/AWSRunInstancesOptionsTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/options/AWSRunInstancesOptionsTest.java new file mode 100644 index 0000000000..daf8e3928d --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/options/AWSRunInstancesOptionsTest.java @@ -0,0 +1,293 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.options; + +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.asType; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.enableMonitoring; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withBlockDeviceMappings; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withKernelId; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withKeyName; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withRamdisk; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withSecurityGroup; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withSubnetId; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withUserData; +import static org.testng.Assert.assertEquals; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.jclouds.ec2.domain.BlockDeviceMapping; +import org.jclouds.ec2.domain.InstanceType; +import org.jclouds.http.options.HttpRequestOptions; +import org.testng.annotations.Test; + +/** + * Tests possible uses of AWSRunInstancesOptions and AWSRunInstancesOptions.Builder.* + * + * @author Adrian Cole + */ +public class AWSRunInstancesOptionsTest { + + @Test + public void testAssignability() { + assert HttpRequestOptions.class.isAssignableFrom(AWSRunInstancesOptions.class); + assert !String.class.isAssignableFrom(AWSRunInstancesOptions.class); + } + + @Test + public void testWithKeyName() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.withKeyName("test"); + assertEquals(options.buildFormParameters().get("KeyName"), Collections.singletonList("test")); + } + + @Test + public void testNullWithKeyName() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("KeyName"), Collections.EMPTY_LIST); + } + + @Test + public void testWithKeyNameStatic() { + AWSRunInstancesOptions options = withKeyName("test"); + assertEquals(options.buildFormParameters().get("KeyName"), Collections.singletonList("test")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithKeyNameNPE() { + withKeyName(null); + } + + @Test + public void testWithSecurityGroup() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.withSecurityGroup("test"); + assertEquals(options.buildFormParameters().get("SecurityGroup.1"), Collections.singletonList("test")); + } + + @Test + public void testNullWithSecurityGroup() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("SecurityGroup"), Collections.EMPTY_LIST); + } + + @Test + public void testWithSecurityGroupStatic() { + AWSRunInstancesOptions options = withSecurityGroup("test"); + assertEquals(options.buildFormParameters().get("SecurityGroup.1"), Collections.singletonList("test")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithSecurityGroupNPE() { + withSecurityGroup(null); + } + + @Test + public void testNullWithAdditionalInfo() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("AdditionalInfo"), Collections.EMPTY_LIST); + } + + @Test + public void testWithUserData() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.withUserData("test".getBytes()); + assertEquals(options.buildFormParameters().get("UserData"), Collections.singletonList("dGVzdA==")); + } + + @Test + public void testNullWithUserData() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("UserData"), Collections.EMPTY_LIST); + } + + @Test + public void testWithUserDataStatic() { + AWSRunInstancesOptions options = withUserData("test".getBytes()); + assertEquals(options.buildFormParameters().get("UserData"), Collections.singletonList("dGVzdA==")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithUserDataNPE() { + withUserData(null); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testWithUserDataEmpty() { + withUserData("".getBytes()); + } + + @Test + public void testWithInstanceType() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.asType(InstanceType.C1_XLARGE); + assertEquals(options.buildFormParameters().get("InstanceType"), Collections.singletonList("c1.xlarge")); + } + + @Test + public void testNullWithInstanceType() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("InstanceType"), Collections.EMPTY_LIST); + } + + @Test + public void testWithInstanceTypeStatic() { + AWSRunInstancesOptions options = asType(InstanceType.C1_XLARGE); + assertEquals(options.buildFormParameters().get("InstanceType"), Collections.singletonList("c1.xlarge")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithInstanceTypeNPE() { + asType(null); + } + + @Test + public void testWithKernelId() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.withKernelId("test"); + assertEquals(options.buildFormParameters().get("KernelId"), Collections.singletonList("test")); + } + + @Test + public void testNullWithKernelId() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("KernelId"), Collections.EMPTY_LIST); + } + + @Test + public void testWithKernelIdStatic() { + AWSRunInstancesOptions options = withKernelId("test"); + assertEquals(options.buildFormParameters().get("KernelId"), Collections.singletonList("test")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithKernelIdNPE() { + withKernelId(null); + } + + @Test + public void testWithMonitoringEnabled() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.enableMonitoring(); + assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections.singletonList("true")); + } + + @Test + public void testNullWithMonitoringEnabled() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections.EMPTY_LIST); + } + + @Test + public void testWithMonitoringEnabledStatic() { + AWSRunInstancesOptions options = enableMonitoring(); + assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections.singletonList("true")); + } + + @Test + public void testWithSubnetId() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.withSubnetId("test"); + assertEquals(options.buildFormParameters().get("SubnetId"), Collections.singletonList("test")); + } + + @Test + public void testNullWithSubnetId() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("SubnetId"), Collections.EMPTY_LIST); + } + + @Test + public void testWithSubnetIdStatic() { + AWSRunInstancesOptions options = withSubnetId("test"); + assertEquals(options.buildFormParameters().get("SubnetId"), Collections.singletonList("test")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithSubnetIdNPE() { + withSubnetId(null); + } + + @Test + public void testWithRamdisk() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.withRamdisk("test"); + assertEquals(options.buildFormParameters().get("RamdiskId"), Collections.singletonList("test")); + } + + @Test + public void testNullWithRamdisk() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("RamdiskId"), Collections.EMPTY_LIST); + } + + @Test + public void testWithRamdiskStatic() { + AWSRunInstancesOptions options = withRamdisk("test"); + assertEquals(options.buildFormParameters().get("RamdiskId"), Collections.singletonList("test")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithRamdiskNPE() { + withRamdisk(null); + } + + @Test + public void testNullWithVirtualName() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"), Collections.EMPTY_LIST); + } + + @Test + public void testWithBlockDeviceMapping() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + BlockDeviceMapping mapping = new BlockDeviceMapping("/dev/sda1", null, null, 120, null, true); + Set mappings = new HashSet(); + mappings.add(mapping); + options.withBlockDeviceMappings(mappings); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections.singletonList("/dev/sda1")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections.singletonList("120")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections.singletonList("true")); + } + + @Test + public void testNullWithBlockDeviceMapping() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping"), Collections.EMPTY_LIST); + } + + @Test + public void testWithBlockDeviceMappingStatic() { + BlockDeviceMapping mapping = new BlockDeviceMapping("/dev/sda1", null, null, 120, null, true); + Set mappings = new HashSet(); + mappings.add(mapping); + AWSRunInstancesOptions options = withBlockDeviceMappings(mappings); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections.singletonList("/dev/sda1")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections.singletonList("120")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections.singletonList("true")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithBlockDeviceMappingNPE() { + withBlockDeviceMappings(null); + } + +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIAsyncClientTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIAsyncClientTest.java new file mode 100644 index 0000000000..55e59271ab --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIAsyncClientTest.java @@ -0,0 +1,386 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.services; + +import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.executableBy; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Method; + +import org.jclouds.aws.ec2.xml.ProductCodesHandler; +import org.jclouds.ec2.options.CreateImageOptions; +import org.jclouds.ec2.options.DescribeImagesOptions; +import org.jclouds.ec2.options.RegisterImageBackedByEbsOptions; +import org.jclouds.ec2.options.RegisterImageOptions; +import org.jclouds.ec2.xml.BlockDeviceMappingHandler; +import org.jclouds.ec2.xml.DescribeImagesResponseHandler; +import org.jclouds.ec2.xml.ImageIdHandler; +import org.jclouds.ec2.xml.PermissionHandler; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ReleasePayloadAndReturn; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.inject.TypeLiteral; + +/** + * Tests behavior of {@code AWSAMIAsyncClient} + * + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "AWSAMIAsyncClientTest") +public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest { + public AWSAMIAsyncClientTest() { + provider = "aws-ec2"; + } + + public void testCreateImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("createImageInRegion", String.class, String.class, + String.class, Array.newInstance(CreateImageOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "name", "instanceId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=CreateImage&InstanceId=instanceId&Name=name", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, ImageIdHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testCreateImageOptions() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("createImageInRegion", String.class, String.class, + String.class, Array.newInstance(CreateImageOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "name", "instanceId", new CreateImageOptions() + .withDescription("description").noReboot()); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=CreateImage&InstanceId=instanceId&Name=name&Description=description&NoReboot=true", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, ImageIdHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testDescribeImages() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("describeImagesInRegion", String.class, Array.newInstance( + DescribeImagesOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, (String) null); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=DescribeImages", "application/x-www-form-urlencoded", + false); + filter.filter(request); + assertPayloadEquals( + request, + "Action=DescribeImages&Signature=qE4vexSFJqS0UWK%2BccV3s%2BP9woL3M5HI5bTBoM7s%2FLY%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2010-06-15&AWSAccessKeyId=identity", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeImagesResponseHandler.class); + assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class); + + checkFilters(request); + } + + public void testDescribeImagesOptions() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("describeImagesInRegion", String.class, Array.newInstance( + DescribeImagesOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, executableBy("me").ownedBy("fred", "nancy").imageIds( + "1", "2")); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=DescribeImages&ExecutableBy=me&Owner.1=fred&Owner.2=nancy&ImageId.1=1&ImageId.2=2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeImagesResponseHandler.class); + assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class); + + checkFilters(request); + } + + public void testDeregisterImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("deregisterImageInRegion", String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=DeregisterImage&ImageId=imageId", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRegisterImageFromManifest() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("registerImageFromManifestInRegion", String.class, + String.class, String.class, Array.newInstance(RegisterImageOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "name", "pathToManifest"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=RegisterImage&ImageLocation=pathToManifest&Name=name", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, ImageIdHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRegisterImageFromManifestOptions() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("registerImageFromManifestInRegion", String.class, + String.class, String.class, Array.newInstance(RegisterImageOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "name", "pathToManifest", new RegisterImageOptions() + .withDescription("description")); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=RegisterImage&ImageLocation=pathToManifest&Name=name&Description=description", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, ImageIdHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRegisterImageBackedByEBS() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("registerUnixImageBackedByEbsInRegion", String.class, + String.class, String.class, Array.newInstance(RegisterImageBackedByEbsOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "imageName", "snapshotId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=RegisterImage&RootDeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.Ebs.SnapshotId=snapshotId&Name=imageName", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, ImageIdHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRegisterImageBackedByEBSOptions() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("registerUnixImageBackedByEbsInRegion", String.class, + String.class, String.class, Array.newInstance(RegisterImageBackedByEbsOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "imageName", "snapshotId", + new RegisterImageBackedByEbsOptions().withDescription("description").addBlockDeviceFromSnapshot( + "/dev/device", null, "snapshot").addNewBlockDevice("/dev/newdevice", "newblock", 100)); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=RegisterImage&RootDeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.Ebs.SnapshotId=snapshotId&Name=imageName&Description=description&BlockDeviceMapping.1.Ebs.DeleteOnTermination=false&BlockDeviceMapping.1.DeviceName=%2Fdev%2Fdevice&BlockDeviceMapping.1.Ebs.SnapshotId=snapshot&BlockDeviceMapping.2.Ebs.DeleteOnTermination=false&BlockDeviceMapping.2.DeviceName=%2Fdev%2Fnewdevice&BlockDeviceMapping.2.VirtualName=newblock&BlockDeviceMapping.2.Ebs.VolumeSize=100", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, ImageIdHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetProductCodesForImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("getProductCodesForImageInRegion", String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeImageAttribute&Attribute=productCodes&ImageId=imageId", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, ProductCodesHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetBlockDeviceMappingsForImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("getBlockDeviceMappingsForImageInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeImageAttribute&Attribute=blockDeviceMapping&ImageId=imageId", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, BlockDeviceMappingHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetLaunchPermissionForImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("getLaunchPermissionForImageInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeImageAttribute&Attribute=launchPermission&ImageId=imageId", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, PermissionHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testAddLaunchPermissionsToImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("addLaunchPermissionsToImageInRegion", String.class, + Iterable.class, Iterable.class, String.class); + HttpRequest request = processor.createRequest(method, null, ImmutableList.of("bob", "sue"), ImmutableList + .of("all"), "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=ModifyImageAttribute&OperationType=add&Attribute=launchPermission&ImageId=imageId&UserGroup.1=all&UserId.1=bob&UserId.2=sue", + "application/x-www-form-urlencoded", false); + filter.filter(request); + assertPayloadEquals( + request, + "Action=ModifyImageAttribute&Attribute=launchPermission&ImageId=imageId&OperationType=add&Signature=WZzNWOC1KHbuySvXEuLTiBA%2BVUfKpSBN2Lud6MrhlCQ%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&UserGroup.1=all&UserId.1=bob&UserId.2=sue&Version=2010-06-15&AWSAccessKeyId=identity", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRemoveLaunchPermissionsFromImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("removeLaunchPermissionsFromImageInRegion", String.class, + Iterable.class, Iterable.class, String.class); + HttpRequest request = processor.createRequest(method, null, ImmutableList.of("bob", "sue"), ImmutableList + .of("all"), "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=ModifyImageAttribute&OperationType=remove&Attribute=launchPermission&ImageId=imageId&UserGroup.1=all&UserId.1=bob&UserId.2=sue", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testResetLaunchPermissionsOnImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("resetLaunchPermissionsOnImageInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=ResetImageAttribute&Attribute=launchPermission&ImageId=imageId", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testAddProductCodesToImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("addProductCodesToImageInRegion", String.class, Iterable.class, + String.class); + HttpRequest request = processor.createRequest(method, null, ImmutableList.of("code1", "code2"), "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=ModifyImageAttribute&OperationType=add&Attribute=productCodes&ImageId=imageId&ProductCode.1=code1&ProductCode.2=code2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRemoveProductCodesFromImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("removeProductCodesFromImageInRegion", String.class, + Iterable.class, String.class); + HttpRequest request = processor.createRequest(method, null, ImmutableList.of("code1", "code2"), "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=ModifyImageAttribute&OperationType=remove&Attribute=productCodes&ImageId=imageId&ProductCode.1=code1&ProductCode.2=code2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } + +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIClientLiveTest.java new file mode 100644 index 0000000000..93670a523a --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIClientLiveTest.java @@ -0,0 +1,243 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.services; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.imageIds; +import static org.jclouds.ec2.options.RegisterImageBackedByEbsOptions.Builder.addNewBlockDevice; +import static org.jclouds.ec2.options.RegisterImageOptions.Builder.withDescription; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +import java.util.Iterator; +import java.util.Properties; +import java.util.Set; + +import org.jclouds.Constants; +import org.jclouds.aws.domain.Region; +import org.jclouds.aws.ec2.AWSEC2AsyncClient; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.compute.ComputeServiceContextFactory; +import org.jclouds.ec2.domain.Image; +import org.jclouds.ec2.domain.RootDeviceType; +import org.jclouds.ec2.domain.Image.ImageType; +import org.jclouds.logging.log4j.config.Log4JLoggingModule; +import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.RestContext; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.inject.Module; + +/** + * Tests behavior of {@code AWSAMIClient} + * + * @author Adrian Cole + */ +@Test(groups = "live", sequential = true) +public class AWSAMIClientLiveTest { + + private AWSAMIClient client; + private String imageId = "ami-7ea24a17"; + private static final String DEFAULT_MANIFEST = "adrianimages/image.manifest.xml"; + private static final String DEFAULT_SNAPSHOT = "TODO"; + private RestContext context; + + private Set imagesToDeregister = Sets.newHashSet(); + + protected String provider = "aws-ec2"; + protected String identity; + protected String credential; + protected String endpoint; + protected String apiversion; + + @BeforeClass + protected void setupCredentials() { + identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity"); + credential = System.getProperty("test." + provider + ".credential"); + endpoint = System.getProperty("test." + provider + ".endpoint"); + apiversion = System.getProperty("test." + provider + ".apiversion"); + } + + protected Properties setupProperties() { + Properties overrides = new Properties(); + overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true"); + overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true"); + overrides.setProperty(provider + ".identity", identity); + if (credential != null) + overrides.setProperty(provider + ".credential", credential); + if (endpoint != null) + overrides.setProperty(provider + ".endpoint", endpoint); + if (apiversion != null) + overrides.setProperty(provider + ".apiversion", apiversion); + return overrides; + } + + @BeforeGroups(groups = { "live" }) + public void setupClient() { + setupCredentials(); + Properties overrides = setupProperties(); + context = new ComputeServiceContextFactory().createContext(provider, + ImmutableSet. of(new Log4JLoggingModule()), overrides).getProviderSpecificContext(); + client = context.getApi().getAMIServices(); + } + + public void testDescribeImageNotExists() { + assertEquals(client.describeImagesInRegion(null, imageIds("ami-cdf819a3")).size(), 0); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testDescribeImageBadId() { + client.describeImagesInRegion(null, imageIds("asdaasdsa")); + } + + public void testDescribeImages() { + for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1, + Region.AP_SOUTHEAST_1)) { + Set allResults = Sets.newLinkedHashSet(client.describeImagesInRegion(region)); + assertNotNull(allResults); + assert allResults.size() >= 2 : allResults.size(); + Iterator iterator = allResults.iterator(); + String id1 = iterator.next().getId(); + String id2 = iterator.next().getId(); + Set twoResults = Sets.newLinkedHashSet(client.describeImagesInRegion(region, imageIds(id1, id2))); + assertNotNull(twoResults); + assertEquals(twoResults.size(), 2); + iterator = twoResults.iterator(); + assertEquals(iterator.next().getId(), id1); + assertEquals(iterator.next().getId(), id2); + } + } + + @Test(enabled = false) + public void testRegisterImageFromManifest() { + String imageRegisteredId = client.registerImageFromManifestInRegion(null, "jcloudstest1", DEFAULT_MANIFEST); + imagesToDeregister.add(imageRegisteredId); + Image imageRegisteredFromManifest = Iterables.getOnlyElement(client.describeImagesInRegion(null, + imageIds(imageRegisteredId))); + assertEquals(imageRegisteredFromManifest.getName(), "jcloudstest1"); + assertEquals(imageRegisteredFromManifest.getImageLocation(), DEFAULT_MANIFEST); + assertEquals(imageRegisteredFromManifest.getImageType(), ImageType.MACHINE); + assertEquals(imageRegisteredFromManifest.getRootDeviceType(), RootDeviceType.INSTANCE_STORE); + assertEquals(imageRegisteredFromManifest.getRootDeviceName(), "/dev/sda1"); + } + + @Test(enabled = false) + public void testRegisterImageFromManifestOptions() { + String imageRegisteredWithOptionsId = client.registerImageFromManifestInRegion(null, "jcloudstest2", + DEFAULT_MANIFEST, withDescription("adrian")); + imagesToDeregister.add(imageRegisteredWithOptionsId); + Image imageRegisteredFromManifestWithOptions = Iterables.getOnlyElement(client.describeImagesInRegion(null, + imageIds(imageRegisteredWithOptionsId))); + assertEquals(imageRegisteredFromManifestWithOptions.getName(), "jcloudstest2"); + assertEquals(imageRegisteredFromManifestWithOptions.getImageLocation(), DEFAULT_MANIFEST); + assertEquals(imageRegisteredFromManifestWithOptions.getImageType(), ImageType.MACHINE); + assertEquals(imageRegisteredFromManifestWithOptions.getRootDeviceType(), RootDeviceType.INSTANCE_STORE); + assertEquals(imageRegisteredFromManifestWithOptions.getRootDeviceName(), "/dev/sda1"); + assertEquals(imageRegisteredFromManifestWithOptions.getDescription(), "adrian"); + } + + @Test(enabled = false) + // awaiting EBS functionality to be added to jclouds + public void testRegisterImageBackedByEBS() { + String imageRegisteredId = client.registerUnixImageBackedByEbsInRegion(null, "jcloudstest1", DEFAULT_MANIFEST); + imagesToDeregister.add(imageRegisteredId); + Image imageRegistered = Iterables + .getOnlyElement(client.describeImagesInRegion(null, imageIds(imageRegisteredId))); + assertEquals(imageRegistered.getName(), "jcloudstest1"); + assertEquals(imageRegistered.getImageType(), ImageType.MACHINE); + assertEquals(imageRegistered.getRootDeviceType(), RootDeviceType.EBS); + assertEquals(imageRegistered.getRootDeviceName(), "/dev/sda1"); + } + + @Test(enabled = false) + // awaiting EBS functionality to be added to jclouds + public void testRegisterImageBackedByEBSOptions() { + String imageRegisteredWithOptionsId = client.registerUnixImageBackedByEbsInRegion(null, "jcloudstest2", + DEFAULT_SNAPSHOT, addNewBlockDevice("/dev/sda2", "myvirtual", 1).withDescription("adrian")); + imagesToDeregister.add(imageRegisteredWithOptionsId); + Image imageRegisteredWithOptions = Iterables.getOnlyElement(client.describeImagesInRegion(null, + imageIds(imageRegisteredWithOptionsId))); + assertEquals(imageRegisteredWithOptions.getName(), "jcloudstest2"); + assertEquals(imageRegisteredWithOptions.getImageType(), ImageType.MACHINE); + assertEquals(imageRegisteredWithOptions.getRootDeviceType(), RootDeviceType.EBS); + assertEquals(imageRegisteredWithOptions.getRootDeviceName(), "/dev/sda1"); + assertEquals(imageRegisteredWithOptions.getDescription(), "adrian"); + assertEquals(imageRegisteredWithOptions.getEbsBlockDevices().entrySet(), ImmutableMap.of("/dev/sda1", + new Image.EbsBlockDevice("/dev/sda1", 30, true), "/dev/sda2", + new Image.EbsBlockDevice("/dev/sda2", 1, true)).entrySet()); + } + + @Test(enabled = false) + public void testCreateImage() { + // TODO client.createImageInRegion(null, name, instanceId, options); + } + + @Test(enabled = false) + public void testAddProductCodesToImage() { + // TODO client.addProductCodesToImageInRegion(null, productCodes, imageId); + } + + @Test(enabled = false) + public void testAddLaunchPermissionsToImage() { + // TODO client.addLaunchPermissionsToImageInRegion(null, userIds, userGroups, + // imageId); + } + + @Test(enabled = false) + public void testRemoveLaunchPermissionsFromImage() { + // TODO client.removeLaunchPermissionsFromImageInRegion(null, userIds, userGroups, + // imageId); + } + + @Test(enabled = false) + public void testResetLaunchPermissionsOnImage() { + // TODO client.resetLaunchPermissionsOnImageInRegion(null, imageId); + } + + @Test(expectedExceptions = AuthorizationException.class) + public void testGetLaunchPermissionForImage() { + System.out.println(client.getLaunchPermissionForImageInRegion(null, imageId)); + } + + @Test(expectedExceptions = AuthorizationException.class) + public void testGetProductCodesForImage() { + System.out.println(client.getProductCodesForImageInRegion(null, imageId)); + } + + @Test(enabled = false) + // awaiting ebs support + public void testGetBlockDeviceMappingsForImage() { + System.out.println(client.getBlockDeviceMappingsForImageInRegion(null, imageId)); + } + + @AfterTest + public void deregisterImages() { + for (String imageId : imagesToDeregister) + client.deregisterImageInRegion(null, imageId); + } +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceAsyncClientTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceAsyncClientTest.java new file mode 100644 index 0000000000..6ba5b680a7 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceAsyncClientTest.java @@ -0,0 +1,505 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.services; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.util.Map; + +import org.jclouds.aws.domain.Region; +import org.jclouds.aws.ec2.options.AWSRunInstancesOptions; +import org.jclouds.aws.ec2.xml.AWSDescribeInstancesResponseHandler; +import org.jclouds.aws.ec2.xml.AWSRunInstancesResponseHandler; +import org.jclouds.ec2.domain.AvailabilityZone; +import org.jclouds.ec2.domain.BlockDevice; +import org.jclouds.ec2.domain.InstanceType; +import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior; +import org.jclouds.ec2.options.RunInstancesOptions; +import org.jclouds.ec2.xml.BlockDeviceMappingHandler; +import org.jclouds.ec2.xml.BooleanValueHandler; +import org.jclouds.ec2.xml.InstanceInitiatedShutdownBehaviorHandler; +import org.jclouds.ec2.xml.InstanceStateChangeHandler; +import org.jclouds.ec2.xml.InstanceTypeHandler; +import org.jclouds.ec2.xml.StringValueHandler; +import org.jclouds.ec2.xml.UnencodeStringValueHandler; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ReleasePayloadAndReturn; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.testng.annotations.Test; + +import com.google.common.collect.Maps; +import com.google.inject.TypeLiteral; + +/** + * Tests behavior of {@code AWSInstanceAsyncClient} + * + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "AWSInstanceAsyncClientTest") +public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest { + public void testDescribeInstances() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("describeInstancesInRegion", String.class, String[].class); + HttpRequest request = processor.createRequest(method, (String) null); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=DescribeInstances", "application/x-www-form-urlencoded", + false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, AWSDescribeInstancesResponseHandler.class); + assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class); + + checkFilters(request); + } + + public void testDescribeInstancesArgs() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("describeInstancesInRegion", String.class, String[].class); + HttpRequest request = processor.createRequest(method, null, "1", "2"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=DescribeInstances&InstanceId.1=1&InstanceId.2=2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, AWSDescribeInstancesResponseHandler.class); + assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class); + + checkFilters(request); + } + + public void testTerminateInstances() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("terminateInstancesInRegion", String.class, Array + .newInstance(String.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "1", "2"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=TerminateInstances&InstanceId.1=1&InstanceId.2=2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, InstanceStateChangeHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRunInstances() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("runInstancesInRegion", String.class, String.class, + String.class, int.class, int.class, Array.newInstance(RunInstancesOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, null, "ami-voo", 1, 1); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + try { + assertPayloadEquals(request, "Version=2010-06-15&Action=RunInstances&ImageId=ami-voo&MinCount=1&MaxCount=1", + "application/x-www-form-urlencoded", false); + } catch (AssertionError e) { + // mvn 3.0 osx 10.6.5 somehow sorts differently + assertPayloadEquals(request, "Version=2010-06-15&Action=RunInstances&ImageId=ami-voo&MaxCount=1&MinCount=1", + "application/x-www-form-urlencoded", false); + } + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, AWSRunInstancesResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRunInstancesOptions() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("runInstancesInRegion", String.class, String.class, + String.class, int.class, int.class, Array.newInstance(RunInstancesOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, Region.EU_WEST_1, AvailabilityZone.EU_WEST_1A, "ami-voo", + 1, 5, new AWSRunInstancesOptions().withKernelId("kernelId").enableMonitoring().withSecurityGroups( + "group1", "group2")); + + assertRequestLineEquals(request, "POST https://ec2.eu-west-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.eu-west-1.amazonaws.com\n"); + try { + assertPayloadEquals( + request, + "Version=2010-06-15&Action=RunInstances&ImageId=ami-voo&MinCount=1&MaxCount=5&KernelId=kernelId&Monitoring.Enabled=true&SecurityGroup.1=group1&SecurityGroup.2=group2&Placement.AvailabilityZone=eu-west-1a", + "application/x-www-form-urlencoded", false); + } catch (AssertionError e) { + // mvn 3.0 osx 10.6.5 somehow sorts differently + assertPayloadEquals( + request, + "Version=2010-06-15&Action=RunInstances&ImageId=ami-voo&MaxCount=5&MinCount=1&KernelId=kernelId&Monitoring.Enabled=true&SecurityGroup.1=group1&SecurityGroup.2=group2&Placement.AvailabilityZone=eu-west-1a", + "application/x-www-form-urlencoded", false); + } + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, AWSRunInstancesResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testStopInstances() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("stopInstancesInRegion", String.class, boolean.class, + Array.newInstance(String.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, true, "1", "2"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=StopInstances&Force=true&InstanceId.1=1&InstanceId.2=2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, InstanceStateChangeHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRebootInstances() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("rebootInstancesInRegion", String.class, Array + .newInstance(String.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "1", "2"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=RebootInstances&InstanceId.1=1&InstanceId.2=2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testStartInstances() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("startInstancesInRegion", String.class, Array.newInstance( + String.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "1", "2"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=StartInstances&InstanceId.1=1&InstanceId.2=2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, InstanceStateChangeHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetUserDataForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("getUserDataForInstanceInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=userData&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, UnencodeStringValueHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetRootDeviceNameForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("getRootDeviceNameForInstanceInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=rootDeviceName&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, StringValueHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetRamdiskForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("getRamdiskForInstanceInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=ramdisk&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, StringValueHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetDisableApiTerminationForInstanceInRegion() throws SecurityException, NoSuchMethodException, + IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("isApiTerminationDisabledForInstanceInRegion", + String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=disableApiTermination&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, BooleanValueHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetKernelForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class + .getMethod("getKernelForInstanceInRegion", String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=kernel&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, StringValueHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetInstanceTypeForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("getInstanceTypeForInstanceInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=instanceType&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, InstanceTypeHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetInstanceInitiatedShutdownBehaviorForInstanceInRegion() throws SecurityException, + NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("getInstanceInitiatedShutdownBehaviorForInstanceInRegion", + String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=instanceInitiatedShutdownBehavior&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, InstanceInitiatedShutdownBehaviorHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetBlockDeviceMappingForInstanceInRegion() throws SecurityException, NoSuchMethodException, + IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("getBlockDeviceMappingForInstanceInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=blockDeviceMapping&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, BlockDeviceMappingHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testSetUserDataForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("setUserDataForInstanceInRegion", String.class, + String.class, Array.newInstance(byte.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "1", "test".getBytes()); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=userData&Value=dGVzdA%3D%3D&InstanceId=1", + "application/x-www-form-urlencoded", false); + filter.filter(request);// ensure encoding worked properly + assertPayloadEquals( + request, + "Action=ModifyInstanceAttribute&Attribute=userData&InstanceId=1&Signature=LfUmzLM5DsACR5nQcEfGF5FPdznOwwhJ7tjhBWfHtGs%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Value=dGVzdA%3D%3D&Version=2010-06-15&AWSAccessKeyId=identity", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testSetRamdiskForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("setRamdiskForInstanceInRegion", String.class, + String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "1", "test"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=ramdisk&Value=test&InstanceId=1", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testSetKernelForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("setKernelForInstanceInRegion", String.class, + String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "1", "test"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=kernel&Value=test&InstanceId=1", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testSetApiTerminationDisabledForInstanceInRegion() throws SecurityException, NoSuchMethodException, + IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("setApiTerminationDisabledForInstanceInRegion", + String.class, String.class, boolean.class); + HttpRequest request = processor.createRequest(method, null, "1", true); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=disableApiTermination&Value=true&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testSetInstanceTypeForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("setInstanceTypeForInstanceInRegion", String.class, + String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "1", InstanceType.C1_MEDIUM); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=instanceType&Value=c1.medium&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testSetInstanceInitiatedShutdownBehaviorForInstanceInRegion() throws SecurityException, + NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("setInstanceInitiatedShutdownBehaviorForInstanceInRegion", + String.class, String.class, InstanceInitiatedShutdownBehavior.class); + HttpRequest request = processor.createRequest(method, null, "1", InstanceInitiatedShutdownBehavior.TERMINATE); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=instanceInitiatedShutdownBehavior&Value=terminate&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testSetBlockDeviceMappingForInstanceInRegion() throws SecurityException, NoSuchMethodException, + IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("setBlockDeviceMappingForInstanceInRegion", String.class, + String.class, Map.class); + + Map mapping = Maps.newLinkedHashMap(); + mapping.put("/dev/sda1", new BlockDevice("vol-test1", true)); + HttpRequest request = processor.createRequest(method, null, "1", mapping); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=ModifyInstanceAttribute&InstanceId=1&BlockDeviceMapping.1.Ebs.VolumeId=vol-test1&BlockDeviceMapping.1.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.1.Ebs.DeleteOnTermination=true", + "application/x-www-form-urlencoded", false); + filter.filter(request);// ensure encoding worked properly + assertPayloadEquals( + request, + "Action=ModifyInstanceAttribute&BlockDeviceMapping.1.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.1.Ebs.DeleteOnTermination=true&BlockDeviceMapping.1.Ebs.VolumeId=vol-test1&InstanceId=1&Signature=RwY8lVPHSQxQkd5efUKccHdSTkN4OxMIMFiYAe3rrUE%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2010-06-15&AWSAccessKeyId=identity", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } + +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceClientLiveTest.java new file mode 100644 index 0000000000..a6e801a9aa --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceClientLiveTest.java @@ -0,0 +1,106 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.services; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.testng.Assert.assertNotNull; + +import java.util.Properties; +import java.util.Set; + +import org.jclouds.Constants; +import org.jclouds.aws.domain.Region; +import org.jclouds.aws.ec2.AWSEC2AsyncClient; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.compute.ComputeServiceContextFactory; +import org.jclouds.ec2.domain.Reservation; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.logging.log4j.config.Log4JLoggingModule; +import org.jclouds.rest.RestContext; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.inject.Module; + +/** + * Tests behavior of {@code EC2Client} + * + * @author Adrian Cole + */ +@Test(groups = "live", sequential = true) +public class AWSInstanceClientLiveTest { + public static final String PREFIX = System.getProperty("user.name") + "-ec2"; + + private AWSInstanceClient client; + private RestContext context; + protected String provider = "aws-ec2"; + protected String identity; + protected String credential; + protected String endpoint; + protected String apiversion; + + protected void setupCredentials() { + identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity"); + credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider + + ".credential"); + endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint"); + apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider + + ".apiversion"); + } + + protected Properties setupProperties() { + Properties overrides = new Properties(); + overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true"); + overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true"); + overrides.setProperty(provider + ".identity", identity); + overrides.setProperty(provider + ".credential", credential); + overrides.setProperty(provider + ".endpoint", endpoint); + overrides.setProperty(provider + ".apiversion", apiversion); + return overrides; + } + + @BeforeGroups(groups = { "live" }) + public void setupClient() { + setupCredentials(); + Properties overrides = setupProperties(); + context = new ComputeServiceContextFactory().createContext(provider, + ImmutableSet. of(new Log4JLoggingModule()), overrides).getProviderSpecificContext(); + client = context.getApi().getInstanceServices(); + + } + + @Test + void testDescribeInstances() { + for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1, + Region.AP_SOUTHEAST_1)) { + Set> allResults = client.describeInstancesInRegion(region); + assertNotNull(allResults); + assert allResults.size() >= 0 : allResults.size(); + } + } + + @AfterTest + public void shutdown() { + context.close(); + } +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/BaseAWSEC2AsyncClientTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/BaseAWSEC2AsyncClientTest.java new file mode 100644 index 0000000000..69f40e6e61 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/BaseAWSEC2AsyncClientTest.java @@ -0,0 +1,93 @@ +package org.jclouds.aws.ec2.services; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.net.URI; +import java.util.Map; +import java.util.Properties; + +import org.jclouds.aws.domain.Region; +import org.jclouds.aws.ec2.config.AWSEC2RestClientModule; +import org.jclouds.aws.filters.FormSigner; +import org.jclouds.date.DateService; +import org.jclouds.ec2.domain.AvailabilityZone; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.RequiresHttp; +import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.RestClientTest; +import org.jclouds.rest.RestContextFactory; +import org.jclouds.rest.RestContextSpec; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.inject.Module; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit") +public abstract class BaseAWSEC2AsyncClientTest extends RestClientTest { + @RequiresHttp + @ConfiguresRestClient + protected static class StubAWSEC2RestClientModule extends AWSEC2RestClientModule { + + @Override + protected String provideTimeStamp(DateService dateService, int expiration) { + return "2009-11-08T15:54:08.897Z"; + } + + protected void bindRegionsToProvider() { + bindRegionsToProvider(Regions.class); + } + + static class Regions implements javax.inject.Provider> { + @Override + public Map get() { + return ImmutableMap. of(Region.EU_WEST_1, URI.create("https://ec2.eu-west-1.amazonaws.com"), + Region.US_EAST_1, URI.create("https://ec2.us-east-1.amazonaws.com"), Region.US_WEST_1, URI + .create("https://ec2.us-west-1.amazonaws.com")); + } + } + + protected void bindZonesToProvider() { + bindZonesToProvider(Zones.class); + } + + static class Zones implements javax.inject.Provider> { + @Override + public Map get() { + return ImmutableMap. of(AvailabilityZone.US_EAST_1A, Region.US_EAST_1); + } + } + } + + protected FormSigner filter; + + @Override + protected void checkFilters(HttpRequest request) { + assertEquals(request.getFilters().size(), 1); + assertEquals(request.getFilters().get(0).getClass(), FormSigner.class); + } + + @Override + @BeforeTest + protected void setupFactory() throws IOException { + super.setupFactory(); + this.filter = injector.getInstance(FormSigner.class); + } + + @Override + protected Module createModule() { + return new StubAWSEC2RestClientModule(); + } + + protected String provider = "aws-ec2"; + + @Override + public RestContextSpec createContextSpec() { + return new RestContextFactory().createContextSpec(provider, "identity", "credential", new Properties()); + } + +} diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/MonitoringAsyncClientTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringAsyncClientTest.java similarity index 94% rename from apis/ec2/src/test/java/org/jclouds/ec2/services/MonitoringAsyncClientTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringAsyncClientTest.java index e3aa9399c6..1a576a4e1c 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/MonitoringAsyncClientTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringAsyncClientTest.java @@ -17,13 +17,13 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import java.io.IOException; import java.lang.reflect.Array; import java.lang.reflect.Method; -import org.jclouds.ec2.xml.MonitoringStateHandler; +import org.jclouds.aws.ec2.xml.MonitoringStateHandler; import org.jclouds.http.HttpRequest; import org.jclouds.http.functions.ParseSax; import org.jclouds.rest.internal.RestAnnotationProcessor; @@ -38,7 +38,7 @@ import com.google.inject.TypeLiteral; */ // NOTE:without testName, this will not call @Before* and fail w/NPE during surefire @Test(groups = "unit", testName = "MonitoringAsyncClientTest") -public class MonitoringAsyncClientTest extends BaseEC2AsyncClientTest { +public class MonitoringAsyncClientTest extends BaseAWSEC2AsyncClientTest { public void testUnmonitorInstances() throws SecurityException, NoSuchMethodException, IOException { Method method = MonitoringAsyncClient.class.getMethod("unmonitorInstancesInRegion", String.class, String.class, diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/MonitoringClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringClientLiveTest.java similarity index 92% rename from apis/ec2/src/test/java/org/jclouds/ec2/services/MonitoringClientLiveTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringClientLiveTest.java index b05a8b4152..f8f58f1fe6 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/MonitoringClientLiveTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringClientLiveTest.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import static com.google.common.base.Preconditions.checkNotNull; import static org.testng.Assert.assertEquals; @@ -26,9 +26,9 @@ import java.util.Map; import java.util.Properties; import org.jclouds.Constants; -import org.jclouds.ec2.EC2AsyncClient; -import org.jclouds.ec2.EC2Client; -import org.jclouds.ec2.domain.MonitoringState; +import org.jclouds.aws.ec2.AWSEC2AsyncClient; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.domain.MonitoringState; import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.rest.RestContext; @@ -48,8 +48,8 @@ public class MonitoringClientLiveTest { private MonitoringClient client; private static final String DEFAULT_INSTANCE = "i-TODO"; - private RestContext context; - protected String provider = "ec2"; + private RestContext context; + protected String provider = "aws-ec2"; protected String identity; protected String credential; protected String endpoint; diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/PlacementGroupAsyncClientTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupAsyncClientTest.java similarity index 96% rename from apis/ec2/src/test/java/org/jclouds/ec2/services/PlacementGroupAsyncClientTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupAsyncClientTest.java index 237135ffb5..421d885e23 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/PlacementGroupAsyncClientTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupAsyncClientTest.java @@ -17,12 +17,12 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import java.io.IOException; import java.lang.reflect.Method; -import org.jclouds.ec2.xml.DescribePlacementGroupsResponseHandler; +import org.jclouds.aws.ec2.xml.DescribePlacementGroupsResponseHandler; import org.jclouds.http.HttpRequest; import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ReleasePayloadAndReturn; @@ -40,7 +40,7 @@ import com.google.inject.TypeLiteral; */ // NOTE:without testName, this will not call @Before* and fail w/NPE during surefire @Test(groups = "unit", testName = "PlacementGroupAsyncClientTest") -public class PlacementGroupAsyncClientTest extends BaseEC2AsyncClientTest { +public class PlacementGroupAsyncClientTest extends BaseAWSEC2AsyncClientTest { public void testDeletePlacementGroup() throws SecurityException, NoSuchMethodException, IOException { Method method = PlacementGroupAsyncClient.class.getMethod("deletePlacementGroupInRegion", String.class, diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/PlacementGroupClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupClientLiveTest.java similarity index 89% rename from apis/ec2/src/test/java/org/jclouds/ec2/services/PlacementGroupClientLiveTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupClientLiveTest.java index cd7e5e64b4..de12ec2d0a 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/PlacementGroupClientLiveTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupClientLiveTest.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.any; @@ -38,8 +38,12 @@ import java.util.SortedSet; import java.util.concurrent.TimeUnit; import org.jclouds.Constants; -import org.jclouds.aws.AWSResponseException; import org.jclouds.aws.domain.Region; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.domain.PlacementGroup.State; +import org.jclouds.aws.ec2.predicates.PlacementGroupAvailable; +import org.jclouds.aws.ec2.predicates.PlacementGroupDeleted; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.RunNodesException; @@ -48,12 +52,7 @@ import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; import org.jclouds.compute.predicates.NodePredicates; -import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.domain.InstanceType; -import org.jclouds.ec2.domain.PlacementGroup; -import org.jclouds.ec2.domain.PlacementGroup.State; -import org.jclouds.ec2.predicates.PlacementGroupAvailable; -import org.jclouds.ec2.predicates.PlacementGroupDeleted; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.ssh.jsch.config.JschSshClientModule; @@ -75,13 +74,13 @@ import com.google.inject.Module; @Test(groups = "live", sequential = true) public class PlacementGroupClientLiveTest { - private EC2Client client; + private AWSEC2Client client; private ComputeServiceContext context; private RetryablePredicate availableTester; private RetryablePredicate deletedTester; private PlacementGroup group; private Map keyPair; - protected String provider = "ec2"; + protected String provider = "aws-ec2"; protected String identity; protected String credential; protected String endpoint; @@ -113,14 +112,14 @@ public class PlacementGroupClientLiveTest { public void setupClient() throws FileNotFoundException, IOException { setupCredentials(); Properties overrides = setupProperties(); - context = new ComputeServiceContextFactory().createContext(provider, - ImmutableSet. of(new Log4JLoggingModule(), new JschSshClientModule()), overrides); + context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet. of( + new Log4JLoggingModule(), new JschSshClientModule()), overrides); keyPair = setupKeyPair(); - client = EC2Client.class.cast(context.getProviderSpecificContext().getApi()); + client = AWSEC2Client.class.cast(context.getProviderSpecificContext().getApi()); availableTester = new RetryablePredicate(new PlacementGroupAvailable(client), 60, 1, - TimeUnit.SECONDS); + TimeUnit.SECONDS); deletedTester = new RetryablePredicate(new PlacementGroupDeleted(client), 60, 1, TimeUnit.SECONDS); } @@ -129,12 +128,12 @@ public class PlacementGroupClientLiveTest { void testDescribe() { for (String region : newArrayList(Region.US_EAST_1)) { SortedSet allResults = newTreeSet(client.getPlacementGroupServices() - .describePlacementGroupsInRegion(region)); + .describePlacementGroupsInRegion(region)); assertNotNull(allResults); if (allResults.size() >= 1) { PlacementGroup group = allResults.last(); SortedSet result = newTreeSet(client.getPlacementGroupServices() - .describePlacementGroupsInRegion(region, group.getName())); + .describePlacementGroupsInRegion(region, group.getName())); assertNotNull(result); PlacementGroup compare = result.last(); assertEquals(compare, group); @@ -145,8 +144,7 @@ public class PlacementGroupClientLiveTest { try { client.getPlacementGroupServices().describePlacementGroupsInRegion(region); assert false : "should be unsupported"; - } catch (AWSResponseException e) { - assertEquals(e.getError().getCode(), "UnsupportedOperation"); + } catch (UnsupportedOperationException e) { } } } @@ -163,7 +161,7 @@ public class PlacementGroupClientLiveTest { private void verifyPlacementGroup(String groupName) { assert availableTester.apply(new PlacementGroup(Region.US_EAST_1, groupName, "cluster", State.PENDING)) : group; Set oneResult = client.getPlacementGroupServices().describePlacementGroupsInRegion(null, - groupName); + groupName); assertNotNull(oneResult); assertEquals(oneResult.size(), 1); group = oneResult.iterator().next(); @@ -199,7 +197,7 @@ public class PlacementGroupClientLiveTest { assertEquals(template.getImage().getId(), "us-east-1/ami-7ea24a17"); template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(keyPair.get("public")) - .runScript(buildScript(template.getImage().getOperatingSystem())); + .runScript(buildScript(template.getImage().getOperatingSystem())); String tag = PREFIX + "cccluster"; context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag)); @@ -211,7 +209,7 @@ public class PlacementGroupClientLiveTest { NodeMetadata node = getOnlyElement(nodes); getOnlyElement(getOnlyElement(client.getInstanceServices().describeInstancesInRegion(null, - node.getProviderId()))); + node.getProviderId()))); } catch (RunNodesException e) { System.err.println(e.getNodeErrors().keySet()); diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/AWSDescribeInstancesResponseHandlerTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/AWSDescribeInstancesResponseHandlerTest.java new file mode 100644 index 0000000000..ff2099e669 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/AWSDescribeInstancesResponseHandlerTest.java @@ -0,0 +1,161 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.xml; + +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; +import java.net.UnknownHostException; +import java.util.Set; + +import org.jclouds.aws.ec2.domain.AWSRunningInstance; +import org.jclouds.aws.ec2.domain.MonitoringState; +import org.jclouds.date.DateService; +import org.jclouds.ec2.domain.Attachment; +import org.jclouds.ec2.domain.AvailabilityZone; +import org.jclouds.ec2.domain.BlockDevice; +import org.jclouds.ec2.domain.InstanceState; +import org.jclouds.ec2.domain.InstanceType; +import org.jclouds.ec2.domain.Reservation; +import org.jclouds.ec2.domain.RootDeviceType; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.xml.BaseEC2HandlerTest; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.config.SaxParserModule; +import org.jclouds.location.Region; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * Tests behavior of {@code AWSDescribeInstancesResponseHandler} + * + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "AWSDescribeInstancesResponseHandlerTest") +public class AWSDescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest { + + private DateService dateService; + + @BeforeTest + @Override + protected void setUpInjector() { + super.setUpInjector(); + dateService = injector.getInstance(DateService.class); + assert dateService != null; + } + + public void testWhenRunning() throws UnknownHostException { + + Set> contents = ImmutableSet.of(new Reservation( + defaultRegion, ImmutableSet.of("adriancole.ec2ingress"), ImmutableSet + .of(new AWSRunningInstance.Builder().region(defaultRegion).groupId("adriancole.ec2ingress") + .amiLaunchIndex("0").dnsName("ec2-174-129-81-68.compute-1.amazonaws.com").imageId( + "ami-82e4b5c7").instanceId("i-0799056f").instanceState(InstanceState.RUNNING) + .instanceType(InstanceType.M1_SMALL).ipAddress("174.129.81.68").kernelId( + "aki-a71cf9ce").keyName("adriancole.ec21").launchTime( + dateService.iso8601DateParse("2009-11-09T03:00:34.000Z")).monitoringState( + MonitoringState.DISABLED).availabilityZone(AvailabilityZone.US_EAST_1C) + .virtualizationType("paravirtual").privateDnsName("ip-10-243-42-70.ec2.internal") + .privateIpAddress("10.243.42.70").ramdiskId("ari-a51cf9cc").rootDeviceType( + RootDeviceType.INSTANCE_STORE).build()), "993194456877", null, "r-a3c508cb")); + + Set> result = parseAWSRunningInstances("/describe_instances_running.xml"); + + assertEquals(result, contents); + } + + public void testApplyInputStream() { + Set> contents = ImmutableSet.of(new Reservation( + defaultRegion, ImmutableSet.of("default"), ImmutableSet.of(new AWSRunningInstance.Builder().region( + defaultRegion).groupId("default").amiLaunchIndex("23").dnsName( + "ec2-72-44-33-4.compute-1.amazonaws.com").imageId("ami-6ea54007").instanceId("i-28a64341") + .instanceState(InstanceState.RUNNING).instanceType(InstanceType.M1_LARGE).kernelId( + "aki-ba3adfd3").keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:54:42.000Z")).monitoringState( + MonitoringState.DISABLED).availabilityZone(AvailabilityZone.US_EAST_1B) + .virtualizationType("paravirtual").privateDnsName("10-251-50-132.ec2.internal").productCode( + "774F4FF8").ramdiskId("ari-badbad00").rootDeviceType(RootDeviceType.INSTANCE_STORE) + .build(), new AWSRunningInstance.Builder().region(defaultRegion).groupId("default") + .amiLaunchIndex("23").dnsName("ec2-72-44-33-6.compute-1.amazonaws.com").imageId("ami-6ea54007") + .instanceId("i-28a64435").instanceState(InstanceState.RUNNING).instanceType( + InstanceType.M1_LARGE).kernelId("aki-ba3adfd3").keyName("example-key-name") + .launchTime(dateService.iso8601DateParse("2007-08-07T11:54:42.000Z")).monitoringState( + MonitoringState.DISABLED).availabilityZone(AvailabilityZone.US_EAST_1B) + .virtualizationType("paravirtual").privateDnsName("10-251-50-134.ec2.internal").productCode( + "774F4FF8").ramdiskId("ari-badbad00").rootDeviceType(RootDeviceType.INSTANCE_STORE) + .build()), "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null, "r-44a5402d")); + + Set> result = parseAWSRunningInstances("/describe_instances.xml"); + + assertEquals(result, contents); + } + + public void testEBS() throws UnknownHostException { + + Set> contents = ImmutableSet.of(new Reservation( + defaultRegion, ImmutableSet.of("adriancole.ec2ebsingress"), ImmutableSet + .of(new AWSRunningInstance.Builder().region(defaultRegion).groupId("adriancole.ec2ebsingress") + .amiLaunchIndex("0").dnsName("ec2-75-101-203-146.compute-1.amazonaws.com").imageId( + "ami-849875ed").instanceId("i-e564438d").instanceState(InstanceState.RUNNING) + .instanceType(InstanceType.M1_SMALL).ipAddress("75.101.203.146").kernelId( + "aki-a71cf9ce").keyName("adriancole.ec2ebs1").launchTime( + dateService.iso8601DateParse("2009-12-30T04:06:23.000Z")).monitoringState( + MonitoringState.DISABLED).availabilityZone(AvailabilityZone.US_EAST_1B) + .placementGroup("placement").virtualizationType("hvm").privateDnsName( + "domU-12-31-39-09-CE-53.compute-1.internal").privateIpAddress( + "10.210.209.157").ramdiskId("ari-a51cf9cc") + .rootDeviceType(RootDeviceType.EBS).rootDeviceName("/dev/sda1").device( + "/dev/sda1", + new BlockDevice("vol-dc6ca8b5", Attachment.Status.ATTACHED, dateService + .iso8601DateParse("2009-12-30T04:06:29.000Z"), true)).build()), + "993194456877", null, "r-596dd731")); + + Set> result = parseAWSRunningInstances("/describe_instances_ebs.xml"); + + assertEquals(result, contents); + } + + static ParseSax>> createParser() { + Injector injector = Guice.createInjector(new SaxParserModule(), new AbstractModule() { + + @Override + protected void configure() { + bind(String.class).annotatedWith(Region.class).toInstance("us-east-1"); + bind(RunningInstance.Builder.class).to(AWSRunningInstance.Builder.class); + } + + }); + ParseSax>> parser = (ParseSax>>) injector + .getInstance(ParseSax.Factory.class).create( + injector.getInstance(AWSDescribeInstancesResponseHandler.class)); + return parser; + } + + public static Set> parseAWSRunningInstances(String resource) { + InputStream is = AWSDescribeInstancesResponseHandlerTest.class.getResourceAsStream(resource); + return createParser().parse(is); + } +} diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribePlacementGroupsResponseHandlerTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/DescribePlacementGroupsResponseHandlerTest.java similarity index 92% rename from apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribePlacementGroupsResponseHandlerTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/DescribePlacementGroupsResponseHandlerTest.java index 22b2c6d28b..0b84c608a3 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribePlacementGroupsResponseHandlerTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/DescribePlacementGroupsResponseHandlerTest.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import static org.easymock.EasyMock.expect; import static org.easymock.classextension.EasyMock.createMock; @@ -26,7 +26,9 @@ import static org.testng.Assert.assertEquals; import java.io.InputStream; -import org.jclouds.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.xml.DescribePlacementGroupsResponseHandler; +import org.jclouds.ec2.xml.BaseEC2HandlerTest; import org.jclouds.http.functions.ParseSax; import org.jclouds.rest.internal.GeneratedHttpRequest; import org.testng.annotations.Test; diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeReservedInstancesOfferingResponseHandlerTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/DescribeReservedInstancesOfferingResponseHandlerTest.java similarity index 97% rename from apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeReservedInstancesOfferingResponseHandlerTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/DescribeReservedInstancesOfferingResponseHandlerTest.java index da9c2475c2..2f27a2b59a 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeReservedInstancesOfferingResponseHandlerTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/DescribeReservedInstancesOfferingResponseHandlerTest.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import static org.easymock.EasyMock.expect; import static org.easymock.classextension.EasyMock.createMock; @@ -27,6 +27,7 @@ import static org.testng.Assert.assertEquals; import java.io.InputStream; import org.jclouds.ec2.domain.ReservedInstancesOffering; +import org.jclouds.ec2.xml.BaseEC2HandlerTest; import org.jclouds.http.functions.ParseSax; import org.jclouds.rest.internal.GeneratedHttpRequest; import org.testng.annotations.Test; diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/xml/MonitoringStateHandlerTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/MonitoringStateHandlerTest.java similarity index 92% rename from apis/ec2/src/test/java/org/jclouds/ec2/xml/MonitoringStateHandlerTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/MonitoringStateHandlerTest.java index 02fac61471..23f1778902 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/xml/MonitoringStateHandlerTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/MonitoringStateHandlerTest.java @@ -17,14 +17,15 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import static org.testng.Assert.assertEquals; import java.io.InputStream; import java.util.Map; -import org.jclouds.ec2.domain.MonitoringState; +import org.jclouds.aws.ec2.domain.MonitoringState; +import org.jclouds.aws.ec2.xml.MonitoringStateHandler; import org.jclouds.http.functions.BaseHandlerTest; import org.testng.annotations.Test; diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/xml/ProductCodesHandlerTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/ProductCodesHandlerTest.java similarity index 95% rename from apis/ec2/src/test/java/org/jclouds/ec2/xml/ProductCodesHandlerTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/ProductCodesHandlerTest.java index 64996fa507..0db3680dd1 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/xml/ProductCodesHandlerTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/ProductCodesHandlerTest.java @@ -17,13 +17,14 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import static org.testng.Assert.assertEquals; import java.io.InputStream; import java.util.Set; +import org.jclouds.aws.ec2.xml.ProductCodesHandler; import org.jclouds.http.functions.BaseHandlerTest; import org.testng.annotations.Test; diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/RunInstancesResponseHandlerTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/RunInstancesResponseHandlerTest.java new file mode 100644 index 0000000000..77cee3c388 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/RunInstancesResponseHandlerTest.java @@ -0,0 +1,117 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.xml; + +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; + +import org.jclouds.aws.ec2.domain.AWSRunningInstance; +import org.jclouds.aws.ec2.domain.MonitoringState; +import org.jclouds.date.DateService; +import org.jclouds.ec2.domain.AvailabilityZone; +import org.jclouds.ec2.domain.InstanceState; +import org.jclouds.ec2.domain.InstanceType; +import org.jclouds.ec2.domain.Reservation; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.xml.BaseEC2HandlerTest; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.config.SaxParserModule; +import org.jclouds.location.Region; +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; + +/** + * Tests behavior of {@code RunInstancesResponseHandler} + * + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "RunInstancesResponseHandlerTest") +public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest { + + private DateService dateService; + + @BeforeTest + @Override + protected void setUpInjector() { + injector = Guice.createInjector(new SaxParserModule(), new AbstractModule() { + + @Override + protected void configure() { + bind(String.class).annotatedWith(Region.class).toInstance("us-east-1"); + bind(RunningInstance.Builder.class).to(AWSRunningInstance.Builder.class); + } + + }); + factory = injector.getInstance(ParseSax.Factory.class); + dateService = injector.getInstance(DateService.class); + assert dateService != null; + } + + public void testApplyInputStream() { + + InputStream is = getClass().getResourceAsStream("/run_instances.xml"); + + Reservation expected = new Reservation(defaultRegion, + ImmutableSet.of("default"), ImmutableSet.of( + + new AWSRunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("0").imageId( + "ami-60a54009").instanceId("i-2ba64342").instanceState(InstanceState.PENDING).instanceType( + InstanceType.M1_SMALL).keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:51:50.000Z")).monitoringState( + MonitoringState.ENABLED).availabilityZone(AvailabilityZone.US_EAST_1B).build(), + + new AWSRunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("1").imageId( + "ami-60a54009").instanceId("i-2bc64242").instanceState(InstanceState.PENDING).instanceType( + InstanceType.M1_SMALL).keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:51:50.000Z")).monitoringState( + MonitoringState.ENABLED).availabilityZone(AvailabilityZone.US_EAST_1B).build(), + + new AWSRunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("2").imageId( + "ami-60a54009").instanceId("i-2be64332").instanceState(InstanceState.PENDING).instanceType( + InstanceType.M1_SMALL).keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:51:50.000Z")).monitoringState( + MonitoringState.ENABLED).availabilityZone(AvailabilityZone.US_EAST_1B).build()) + + , "AIDADH4IGTRXXKCD", null, "r-47a5402e"); + + AWSRunInstancesResponseHandler handler = injector.getInstance(AWSRunInstancesResponseHandler.class); + addDefaultRegionToHandler(handler); + Reservation result = factory.create(handler).parse(is); + assertEquals(result, expected); + } + + private void addDefaultRegionToHandler(ParseSax.HandlerWithResult handler) { + GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); + expect(request.getArgs()).andReturn(ImmutableList. of()).atLeastOnce(); + replay(request); + handler.setContext(request); + } +} diff --git a/apis/ec2/src/test/resources/describe_image_attribute_productCodes.xml b/providers/aws-ec2/src/test/resources/describe_image_attribute_productCodes.xml similarity index 100% rename from apis/ec2/src/test/resources/describe_image_attribute_productCodes.xml rename to providers/aws-ec2/src/test/resources/describe_image_attribute_productCodes.xml diff --git a/apis/ec2/src/test/resources/describe_placement_groups.xml b/providers/aws-ec2/src/test/resources/describe_placement_groups.xml similarity index 100% rename from apis/ec2/src/test/resources/describe_placement_groups.xml rename to providers/aws-ec2/src/test/resources/describe_placement_groups.xml diff --git a/apis/ec2/src/test/resources/describe_reserved_instances_offerings.xml b/providers/aws-ec2/src/test/resources/describe_reserved_instances_offerings.xml similarity index 100% rename from apis/ec2/src/test/resources/describe_reserved_instances_offerings.xml rename to providers/aws-ec2/src/test/resources/describe_reserved_instances_offerings.xml diff --git a/apis/ec2/src/test/resources/monitoring.xml b/providers/aws-ec2/src/test/resources/monitoring.xml similarity index 100% rename from apis/ec2/src/test/resources/monitoring.xml rename to providers/aws-ec2/src/test/resources/monitoring.xml diff --git a/providers/eucalyptus-partnercloud-ec2/pom.xml b/providers/eucalyptus-partnercloud-ec2/pom.xml index d1c9c17be8..6511371856 100644 --- a/providers/eucalyptus-partnercloud-ec2/pom.xml +++ b/providers/eucalyptus-partnercloud-ec2/pom.xml @@ -39,6 +39,8 @@ 2010-06-15 FIXME_IDENTITY FIXME_CREDENTIAL + + kvm @@ -134,6 +136,10 @@ test.eucalyptus-partnercloud-ec2.credential ${test.eucalyptus-partnercloud-ec2.credential} + + test.eucalyptus-partnercloud-ec2.virtualization-type + ${test.eucalyptus-partnercloud-ec2.virtualization-type} + diff --git a/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/EucalyptusPartnerCloudPropertiesBuilder.java b/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/EucalyptusPartnerCloudPropertiesBuilder.java index 558a44af07..06183ae7a8 100644 --- a/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/EucalyptusPartnerCloudPropertiesBuilder.java +++ b/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/EucalyptusPartnerCloudPropertiesBuilder.java @@ -34,6 +34,7 @@ public class EucalyptusPartnerCloudPropertiesBuilder extends EucalyptusPropertie @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); + properties.setProperty("eucalyptus-partnercloud-ec2.virtualization-type", "kvm"); properties.setProperty(PROPERTY_ENDPOINT, "http://partnercloud.eucalyptus.com:8773/services/Eucalyptus"); return properties; } diff --git a/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/config/EucalyptusPartnerCloudComputeServiceContextModule.java b/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/config/EucalyptusPartnerCloudComputeServiceContextModule.java index b98308ac77..e840573ffc 100644 --- a/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/config/EucalyptusPartnerCloudComputeServiceContextModule.java +++ b/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/config/EucalyptusPartnerCloudComputeServiceContextModule.java @@ -27,6 +27,8 @@ import org.jclouds.ec2.compute.strategy.ReviseParsedImage; import org.jclouds.epc.strategy.EucalyptusPartnerCloudReviseParsedImage; import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.name.Names; /** * @@ -36,7 +38,9 @@ public class EucalyptusPartnerCloudComputeServiceContextModule extends EC2Comput @Override protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) { - return template.osFamily(CENTOS).locationId("xen-cluster").osDescriptionMatches("xen"); + String virt = injector.getInstance(Key.get(String.class, Names + .named("eucalyptus-partnercloud-ec2.virtualization-type"))); + return template.osFamily(CENTOS).locationId(virt + "-cluster").osDescriptionMatches(virt); } @Override diff --git a/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest.java b/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest.java index ac2adc6b76..3f93f1c81d 100644 --- a/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest.java +++ b/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest.java @@ -19,12 +19,9 @@ package org.jclouds.epc.compute; -import static org.jclouds.compute.util.ComputeServiceUtils.getCores; -import static org.testng.Assert.assertEquals; +import java.util.Properties; -import org.jclouds.compute.domain.OsFamily; -import org.jclouds.compute.domain.Template; -import org.jclouds.ec2.compute.EC2ComputeServiceLiveTest; +import org.jclouds.eucalyptus.compute.EucalyptusComputeServiceLiveTest; import org.testng.annotations.Test; /** @@ -32,7 +29,7 @@ import org.testng.annotations.Test; * @author Adrian Cole */ @Test(groups = "live", sequential = true, testName = "EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest") -public class EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest extends EC2ComputeServiceLiveTest { +public class EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest extends EucalyptusComputeServiceLiveTest { public EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest() { provider = "eucalyptus-partnercloud-ec2"; @@ -41,23 +38,11 @@ public class EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest extends EC2C } @Override - @Test(enabled = false) - public void testExtendedOptionsAndLogin() throws Exception { - // euc does not support monitoring + protected Properties setupProperties() { + Properties overrides = super.setupProperties(); + if (System.getProperties().containsKey("test.eucalyptus-partnercloud-ec2.virtualization-type")) + overrides.setProperty("eucalyptus-partnercloud-ec2.virtualization-type", System + .getProperty("test.eucalyptus-partnercloud-ec2.virtualization-type")); + return overrides; } - - @Override - @Test(enabled = false) - public void testExtendedOptionsNoKeyPair() throws Exception { - // euc does not support multiple security groups - } - - @Override - protected void assertDefaultWorks() { - Template defaultTemplate = client.templateBuilder().build(); - assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); - assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS); - assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); - } - } diff --git a/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusTemplateBuilderLiveTest.java b/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusTemplateBuilderLiveTest.java index 23bce83fd2..ec7612aeca 100644 --- a/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusTemplateBuilderLiveTest.java +++ b/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusTemplateBuilderLiveTest.java @@ -68,7 +68,7 @@ public class EucalyptusPartnerCloudEucalyptusTemplateBuilderLiveTest extends Bas assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS); assertEquals(defaultTemplate.getImage().getUserMetadata().get("rootDeviceType"), "instance-store"); - assertEquals(defaultTemplate.getLocation().getId(), "xen-cluster"); + assertEquals(defaultTemplate.getLocation().getId(), "kvm-cluster"); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InterpretableStatement.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InterpretableStatement.java index e9de1ee074..a423a105f9 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InterpretableStatement.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InterpretableStatement.java @@ -72,4 +72,9 @@ public class InterpretableStatement implements Statement { return false; return true; } + + @Override + public String toString() { + return "[statements=" + Arrays.toString(statements) + "]"; + } } \ No newline at end of file