Issue 308 finished provider api and testing of ec2 spot instances

This commit is contained in:
Adrian Cole 2011-03-08 00:03:40 -08:00
parent ab46268ca2
commit 46a214b54b
34 changed files with 2290 additions and 396 deletions

View File

@ -89,7 +89,7 @@ public class EC2TemplateOptions extends TemplateOptions implements Cloneable {
private String keyPair = null;
private boolean noKeyPair;
private byte[] userData;
private Set<BlockDeviceMapping> blockDeviceMappings = ImmutableSet.of();
private ImmutableSet.Builder<BlockDeviceMapping> blockDeviceMappings = ImmutableSet.<BlockDeviceMapping> builder();
public static final EC2TemplateOptions NONE = new EC2TemplateOptions();
@ -142,80 +142,29 @@ public class EC2TemplateOptions extends TemplateOptions implements Cloneable {
return this;
}
/**
* Specifies the block device mappings to be used to run the instance
*/
public EC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId,
@Nullable Integer sizeInGib, boolean deleteOnTermination) {
checkNotNull(deviceName, "deviceName cannot be null");
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
checkNotNull(snapshotId, "snapshotId cannot be null");
Preconditions2.checkNotEmpty(snapshotId, "snapshotId must be non-empty");
com.google.common.collect.ImmutableSet.Builder<BlockDeviceMapping> mappings = ImmutableSet
.<BlockDeviceMapping> builder();
mappings.addAll(blockDeviceMappings);
MapEBSSnapshotToDevice mapping = new MapEBSSnapshotToDevice(deviceName, snapshotId, sizeInGib,
deleteOnTermination);
mappings.add(mapping);
blockDeviceMappings = mappings.build();
blockDeviceMappings.add(new MapEBSSnapshotToDevice(deviceName, snapshotId, sizeInGib, deleteOnTermination));
return this;
}
/**
* Specifies the block device mappings to be used to run the instance
*/
public EC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, int sizeInGib, boolean deleteOnTermination) {
checkNotNull(deviceName, "deviceName cannot be null");
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
com.google.common.collect.ImmutableSet.Builder<BlockDeviceMapping> mappings = ImmutableSet
.<BlockDeviceMapping> builder();
mappings.addAll(blockDeviceMappings);
MapNewVolumeToDevice mapping = new MapNewVolumeToDevice(deviceName, sizeInGib, deleteOnTermination);
mappings.add(mapping);
blockDeviceMappings = mappings.build();
blockDeviceMappings.add(new MapNewVolumeToDevice(deviceName, sizeInGib, deleteOnTermination));
return this;
}
/**
* Specifies the block device mappings to be used to run the instance
*/
public EC2TemplateOptions mapEphemeralDeviceToDeviceName(String deviceName, String virtualName) {
checkNotNull(deviceName, "deviceName cannot be null");
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
checkNotNull(virtualName, "virtualName cannot be null");
Preconditions2.checkNotEmpty(virtualName, "virtualName must be non-empty");
com.google.common.collect.ImmutableSet.Builder<BlockDeviceMapping> mappings = ImmutableSet
.<BlockDeviceMapping> builder();
mappings.addAll(blockDeviceMappings);
MapEphemeralDeviceToDevice mapping = new MapEphemeralDeviceToDevice(deviceName, virtualName);
mappings.add(mapping);
blockDeviceMappings = mappings.build();
blockDeviceMappings.add(new MapEphemeralDeviceToDevice(deviceName, virtualName));
return this;
}
/**
* Specifies the block device mappings to be used to run the instance
*/
public EC2TemplateOptions unmapDeviceNamed(String deviceName) {
checkNotNull(deviceName, "deviceName cannot be null");
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
com.google.common.collect.ImmutableSet.Builder<BlockDeviceMapping> mappings = ImmutableSet
.<BlockDeviceMapping> builder();
mappings.addAll(blockDeviceMappings);
UnmapDeviceNamed mapping = new UnmapDeviceNamed(deviceName);
mappings.add(mapping);
blockDeviceMappings = mappings.build();
blockDeviceMappings.add(new UnmapDeviceNamed(deviceName));
return this;
}
/**
* Specifies the block device mappings to be used to run the instance
*/
public EC2TemplateOptions blockDeviceMappings(Set<? extends BlockDeviceMapping> blockDeviceMappings) {
this.blockDeviceMappings = ImmutableSet.copyOf(checkNotNull(blockDeviceMappings, "blockDeviceMappings"));
public EC2TemplateOptions blockDeviceMappings(Iterable<? extends BlockDeviceMapping> blockDeviceMappings) {
this.blockDeviceMappings.addAll(checkNotNull(blockDeviceMappings, "blockDeviceMappings"));
return this;
}
@ -511,7 +460,7 @@ public class EC2TemplateOptions extends TemplateOptions implements Cloneable {
* @return BlockDeviceMapping to use when running the instance or null.
*/
public Set<BlockDeviceMapping> getBlockDeviceMappings() {
return blockDeviceMappings;
return blockDeviceMappings.build();
}
@Override

View File

@ -30,7 +30,64 @@ import org.jclouds.util.Preconditions2;
*
* @author Lili Nadar
*/
public class BlockDeviceMapping {
public class BlockDeviceMapping implements Comparable<BlockDeviceMapping>{
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String deviceName;
private String virtualName;
private String snapshotId;
private Integer sizeInGib;
private Boolean noDevice;
private Boolean deleteOnTermination;
public Builder deviceName(String deviceName) {
this.deviceName = deviceName;
return this;
}
public Builder virtualName(String virtualName) {
this.virtualName = virtualName;
return this;
}
public Builder snapshotId(String snapshotId) {
this.snapshotId = snapshotId;
return this;
}
public Builder sizeInGib(Integer sizeInGib) {
this.sizeInGib = sizeInGib;
return this;
}
public Builder noDevice(Boolean noDevice) {
this.noDevice = noDevice;
return this;
}
public Builder deleteOnTermination(Boolean deleteOnTermination) {
this.deleteOnTermination = deleteOnTermination;
return this;
}
public BlockDeviceMapping build() {
return new BlockDeviceMapping(deviceName, virtualName, snapshotId, sizeInGib, noDevice, deleteOnTermination);
}
public Builder clear() {
this.deviceName = null;
this.virtualName = null;
this.snapshotId = null;
this.sizeInGib = null;
this.noDevice = null;
this.deleteOnTermination = null;
return this;
}
}
private final String deviceName;
private final String virtualName;
private final String snapshotId;
@ -43,14 +100,14 @@ public class BlockDeviceMapping {
private static final Integer VOLUME_SIZE_MAX_VALUE = 1000;
BlockDeviceMapping(String deviceName, @Nullable String virtualName, @Nullable String snapshotId,
@Nullable Integer sizeInGib, @Nullable Boolean noDevice, @Nullable Boolean deleteOnTermination) {
@Nullable Integer sizeInGib, @Nullable Boolean noDevice, @Nullable Boolean deleteOnTermination) {
checkNotNull(deviceName, "deviceName cannot be null");
Preconditions2.checkNotEmpty(deviceName, "the deviceName must be non-empty");
if (sizeInGib != null) {
checkArgument((sizeInGib >= VOLUME_SIZE_MIN_VALUE && sizeInGib <= VOLUME_SIZE_MAX_VALUE), String.format(
"Size in Gib must be between %s and %s GB", VOLUME_SIZE_MIN_VALUE, VOLUME_SIZE_MAX_VALUE));
checkArgument((sizeInGib >= VOLUME_SIZE_MIN_VALUE && sizeInGib <= VOLUME_SIZE_MAX_VALUE),
String.format("Size in Gib must be between %s and %s GB", VOLUME_SIZE_MIN_VALUE, VOLUME_SIZE_MAX_VALUE));
}
this.deviceName = deviceName;
this.virtualName = virtualName;
@ -142,13 +199,13 @@ public class BlockDeviceMapping {
@Override
public String toString() {
return "[deviceName=" + deviceName + ", virtualName=" + virtualName + ", snapshotId=" + snapshotId
+ ", sizeInGib=" + sizeInGib + ", noDevice=" + noDevice + ", deleteOnTermination=" + deleteOnTermination
+ "]";
+ ", sizeInGib=" + sizeInGib + ", noDevice=" + noDevice + ", deleteOnTermination=" + deleteOnTermination
+ "]";
}
public static class MapEBSSnapshotToDevice extends BlockDeviceMapping {
public MapEBSSnapshotToDevice(String deviceName, String snapshotId, @Nullable Integer sizeInGib,
@Nullable Boolean deleteOnTermination) {
@Nullable Boolean deleteOnTermination) {
super(deviceName, null, snapshotId, sizeInGib, null, deleteOnTermination);
checkNotNull(snapshotId, "snapshotId cannot be null");
Preconditions2.checkNotEmpty(snapshotId, "the snapshotId must be non-empty");
@ -175,4 +232,9 @@ public class BlockDeviceMapping {
super(deviceName, null, null, null, true, null);
}
}
@Override
public int compareTo(BlockDeviceMapping arg0) {
return deviceName.compareTo(arg0.deviceName);
}
}

View File

@ -58,10 +58,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return this;
}
String getKeyName() {
return getFirstFormOrNull("KeyName");
}
/**
* Attach multiple security groups
*/
@ -88,10 +84,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return withSecurityGroups(securityGroup);
}
String getSecurityGroup() {
return getFirstFormOrNull("SecurityGroup.1");
}
/**
* Unencoded data
*/
@ -103,10 +95,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return this;
}
String getUserData() {
return getFirstFormOrNull("UserData");
}
/**
* Specifies the instance type. default small;
*/
@ -115,10 +103,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return this;
}
String getType() {
return getFirstFormOrNull("InstanceType");
}
/**
* The ID of the kernel with which to launch the instance.
*/
@ -127,10 +111,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return this;
}
String getKernelId() {
return getFirstFormOrNull("KernelId");
}
/**
* The ID of the RAM disk with which to launch the instance. Some kernels require additional
* drivers at l aunch. Check the kernel requirements for information on whether you need to
@ -142,15 +122,10 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return this;
}
String getRamdiskId() {
return getFirstFormOrNull("RamdiskId");
}
/**
* Specifies the Block Device Mapping for the instance
*
*/
public RunInstancesOptions withBlockDeviceMappings(Set<? extends BlockDeviceMapping> mappings) {
int i = 1;
for (BlockDeviceMapping mapping : checkNotNull(mappings, "mappings")) {
@ -161,15 +136,14 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
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()));
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()));
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()));
formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.DeleteOnTermination", i),
String.valueOf(mapping.getEbsDeleteOnTermination()));
i++;
}
return this;

View File

@ -26,8 +26,9 @@ import java.util.Set;
import org.jclouds.http.options.BaseHttpRequestOptions;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
*
@ -51,7 +52,7 @@ public class BaseEC2RequestOptions extends BaseHttpRequestOptions {
}
protected Set<String> getFormValuesWithKeysPrefixedBy(final String prefix) {
Set<String> values = Sets.newLinkedHashSet();
Builder<String> values = ImmutableSet.<String> builder();
for (String key : Iterables.filter(formParameters.keySet(), new Predicate<String>() {
public boolean apply(String input) {
@ -59,10 +60,9 @@ public class BaseEC2RequestOptions extends BaseHttpRequestOptions {
}
})) {
values.add(formParameters.get(key).iterator().next());
values.add(Iterables.get(formParameters.get(key), 0));
}
return values;
return values.build();
}
}

View File

@ -301,7 +301,7 @@ public class TemplateBuilderImplTest {
TemplateBuilder defaultTemplate = createMock(TemplateBuilder.class);
expect(templateBuilderProvider.get()).andReturn(defaultTemplate);
expect(defaultTemplate.options(options)).andReturn(defaultTemplate);
expect(defaultTemplate.options(from)).andReturn(defaultTemplate);
expect(defaultTemplate.build()).andReturn(null);
expect(optionsProvider.get()).andReturn(from).atLeastOnce();

View File

@ -0,0 +1,65 @@
package org.jclouds.aws.ec2.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import java.util.Map.Entry;
import javax.inject.Singleton;
import org.jclouds.aws.ec2.domain.LaunchSpecification;
import org.jclouds.aws.ec2.options.AWSRunInstancesOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.utils.ModifyRequest;
import org.jclouds.rest.Binder;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.Multimaps;
/**
*
* @author Adrian Cole
*/
@Singleton
public class BindLaunchSpecificationToFormParams implements Binder, Function<LaunchSpecification, Map<String, String>> {
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
checkArgument(input instanceof LaunchSpecification, "this binder is only valid for LaunchSpecifications!");
LaunchSpecification launchSpec = LaunchSpecification.class.cast(input);
return ModifyRequest.putFormParams(request, Multimaps.forMap(apply(launchSpec)));
}
@Override
public Map<String, String> apply(LaunchSpecification launchSpec) {
Builder<String, String> builder = ImmutableMap.<String, String> builder();
builder.put("LaunchSpecification.ImageId", checkNotNull(launchSpec.getImageId(), "imageId"));
if (launchSpec.getAvailabilityZone() != null)
builder.put("LaunchSpecification.Placement.AvailabilityZone", launchSpec.getAvailabilityZone());
AWSRunInstancesOptions options = new AWSRunInstancesOptions();
if (launchSpec.getBlockDeviceMappings().size() > 0)
options.withBlockDeviceMappings(launchSpec.getBlockDeviceMappings());
if (launchSpec.getGroupIds().size() > 0)
options.withSecurityGroups(launchSpec.getGroupIds());
options.asType(checkNotNull(launchSpec.getInstanceType(), "instanceType"));
if (launchSpec.getKernelId() != null)
options.withKernelId(launchSpec.getKernelId());
if (launchSpec.getKeyName() != null)
options.withKeyName(launchSpec.getKeyName());
if (launchSpec.getRamdiskId() != null)
options.withRamdisk(launchSpec.getRamdiskId());
if (Boolean.TRUE.equals(launchSpec.isMonitoringEnabled()))
options.enableMonitoring();
if (launchSpec.getUserData() != null)
options.withUserData(launchSpec.getUserData());
for (Entry<String, String> entry : options.buildFormParameters().entries()) {
builder.put("LaunchSpecification." + entry.getKey(), entry.getValue());
}
return builder.build();
}
}

View File

@ -1,21 +0,0 @@
package org.jclouds.aws.ec2.binders;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.ec2.binders.IfNotNullBindAvailabilityZoneToFormParam;
/**
* Binds the AvailabilityZone to a form parameter if set.
*
* @author Adrian Cole
*/
@Singleton
public class IfNotNullBindAvailabilityZoneToLaunchSpecificationFormParam extends IfNotNullBindAvailabilityZoneToFormParam {
@Inject
protected IfNotNullBindAvailabilityZoneToLaunchSpecificationFormParam() {
super("LaunchSpecification.Placement.AvailabilityZone");
}
}

View File

@ -294,7 +294,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions implements Cloneab
* {@inheritDoc}
*/
@Override
public AWSEC2TemplateOptions blockDeviceMappings(Set<? extends BlockDeviceMapping> blockDeviceMappings) {
public AWSEC2TemplateOptions blockDeviceMappings(Iterable<? extends BlockDeviceMapping> blockDeviceMappings) {
return AWSEC2TemplateOptions.class.cast(super.blockDeviceMappings(blockDeviceMappings));
}

View File

@ -0,0 +1,350 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.Arrays;
import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.ec2.domain.BlockDeviceMapping.MapEBSSnapshotToDevice;
import org.jclouds.ec2.domain.BlockDeviceMapping.MapEphemeralDeviceToDevice;
import org.jclouds.ec2.domain.BlockDeviceMapping.MapNewVolumeToDevice;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
/**
*
* @see <a href=
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RequestSpotInstances.html"
* />
* @author Adrian Cole
*/
public class LaunchSpecification {
public static Builder builder() {
return new Builder();
}
public static class Builder {
protected ImmutableSet.Builder<String> groupIds = ImmutableSet.<String> builder();
protected String imageId;
protected String instanceType;
protected String kernelId;
protected String keyName;
protected String availabilityZone;
protected String ramdiskId;
protected Boolean monitoringEnabled;
protected ImmutableSet.Builder<BlockDeviceMapping> blockDeviceMappings = ImmutableSet
.<BlockDeviceMapping> builder();
protected byte[] userData;
public void clear() {
groupIds = ImmutableSet.<String> builder();
imageId = null;
instanceType = null;
kernelId = null;
keyName = null;
availabilityZone = null;
ramdiskId = null;
monitoringEnabled = false;
blockDeviceMappings = ImmutableSet.<BlockDeviceMapping> builder();
userData = null;
}
public Builder groupIds(Iterable<String> groupIds) {
this.groupIds.addAll(checkNotNull(groupIds, "groupIds"));
return this;
}
public Builder groupId(String groupId) {
if (groupId != null)
this.groupIds.add(groupId);
return this;
}
public Builder imageId(String imageId) {
this.imageId = imageId;
return this;
}
public Builder monitoringEnabled(Boolean monitoringEnabled) {
this.monitoringEnabled = monitoringEnabled;
return this;
}
public Builder instanceType(String instanceType) {
this.instanceType = instanceType;
return this;
}
public Builder kernelId(String kernelId) {
this.kernelId = kernelId;
return this;
}
public Builder keyName(String keyName) {
this.keyName = keyName;
return this;
}
public Builder availabilityZone(String availabilityZone) {
this.availabilityZone = availabilityZone;
return this;
}
public Builder ramdiskId(String ramdiskId) {
this.ramdiskId = ramdiskId;
return this;
}
public Builder mapEBSSnapshotToDevice(String deviceName, String snapshotId, @Nullable Integer sizeInGib,
boolean deleteOnTermination) {
blockDeviceMappings.add(new MapEBSSnapshotToDevice(deviceName, snapshotId, sizeInGib, deleteOnTermination));
return this;
}
public Builder mapNewVolumeToDevice(String deviceName, int sizeInGib, boolean deleteOnTermination) {
blockDeviceMappings.add(new MapNewVolumeToDevice(deviceName, sizeInGib, deleteOnTermination));
return this;
}
public Builder mapEphemeralDeviceToDevice(String deviceName, String virtualName) {
blockDeviceMappings.add(new MapEphemeralDeviceToDevice(deviceName, virtualName));
return this;
}
public Builder blockDeviceMapping(BlockDeviceMapping blockDeviceMapping) {
this.blockDeviceMappings.add(checkNotNull(blockDeviceMapping, "blockDeviceMapping"));
return this;
}
public Builder blockDeviceMappings(Iterable<? extends BlockDeviceMapping> blockDeviceMappings) {
this.blockDeviceMappings.addAll(checkNotNull(blockDeviceMappings, "blockDeviceMappings"));
return this;
}
public Builder userData(byte[] userData) {
this.userData = userData;
return this;
}
public LaunchSpecification build() {
return new LaunchSpecification(instanceType, imageId, kernelId, ramdiskId, availabilityZone, keyName,
groupIds.build(), blockDeviceMappings.build(), monitoringEnabled, userData);
}
public static Builder fromLaunchSpecification(LaunchSpecification in) {
return new Builder().instanceType(in.getInstanceType()).imageId(in.getImageId()).kernelId(in.getKernelId())
.ramdiskId(in.getRamdiskId()).availabilityZone(in.getAvailabilityZone()).keyName(in.getKeyName())
.groupIds(in.getGroupIds()).blockDeviceMappings(in.getBlockDeviceMappings())
.monitoringEnabled(in.isMonitoringEnabled()).userData(in.getUserData());
}
}
protected final String instanceType;
protected final String imageId;
protected final String kernelId;
protected final String ramdiskId;
protected final String availabilityZone;
protected final String keyName;
protected final Set<String> groupIds;
protected final Set<? extends BlockDeviceMapping> blockDeviceMappings;
protected final Boolean monitoringEnabled;
protected final byte[] userData;
public LaunchSpecification(String instanceType, String imageId, String kernelId, String ramdiskId,
String availabilityZone, String keyName, Iterable<String> groupIds,
Iterable<? extends BlockDeviceMapping> blockDeviceMappings, Boolean monitoringEnabled, byte[] userData) {
this.instanceType = checkNotNull(instanceType, "instanceType");
this.imageId = checkNotNull(imageId, "imageId");
this.kernelId = kernelId;
this.ramdiskId = ramdiskId;
this.availabilityZone = availabilityZone;
this.keyName = keyName;
this.groupIds = ImmutableSortedSet.copyOf(checkNotNull(groupIds, "groupIds"));
this.blockDeviceMappings = ImmutableSortedSet.copyOf(checkNotNull(blockDeviceMappings, "blockDeviceMappings"));
this.monitoringEnabled = monitoringEnabled;
this.userData = userData;
}
/**
* Image ID of the AMI used to launch the instance.
*/
public String getImageId() {
return imageId;
}
/**
* CloudWatch support
*/
public Boolean isMonitoringEnabled() {
return monitoringEnabled;
}
/**
* The instance type.
*/
public String getInstanceType() {
return instanceType;
}
/**
* Optional. Kernel associated with this instance.
*/
public String getKernelId() {
return kernelId;
}
/**
* If this instance was launched with an associated key pair, this displays the key pair name.
*/
public String getKeyName() {
return keyName;
}
/**
* The location where the instance launched.
*/
public String getAvailabilityZone() {
return availabilityZone;
}
/**
* Optional. RAM disk associated with this instance.
*/
public String getRamdiskId() {
return ramdiskId;
}
/**
* volumes mappings associated with the instance.
*/
public Set<? extends BlockDeviceMapping> getBlockDeviceMappings() {
return blockDeviceMappings;
}
/**
* Names of the security groups.
*/
public Set<String> getGroupIds() {
return groupIds;
}
/**
* User Data
*/
public byte[] getUserData() {
return userData;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((availabilityZone == null) ? 0 : availabilityZone.hashCode());
result = prime * result + ((blockDeviceMappings == null) ? 0 : blockDeviceMappings.hashCode());
result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode());
result = prime * result + ((imageId == null) ? 0 : imageId.hashCode());
result = prime * result + ((instanceType == null) ? 0 : instanceType.hashCode());
result = prime * result + ((kernelId == null) ? 0 : kernelId.hashCode());
result = prime * result + ((keyName == null) ? 0 : keyName.hashCode());
result = prime * result + ((monitoringEnabled == null) ? 0 : monitoringEnabled.hashCode());
result = prime * result + ((ramdiskId == null) ? 0 : ramdiskId.hashCode());
result = prime * result + Arrays.hashCode(userData);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LaunchSpecification other = (LaunchSpecification) obj;
if (availabilityZone == null) {
if (other.availabilityZone != null)
return false;
} else if (!availabilityZone.equals(other.availabilityZone))
return false;
if (blockDeviceMappings == null) {
if (other.blockDeviceMappings != null)
return false;
} else if (!blockDeviceMappings.equals(other.blockDeviceMappings))
return false;
if (groupIds == null) {
if (other.groupIds != null)
return false;
} else if (!groupIds.equals(other.groupIds))
return false;
if (imageId == null) {
if (other.imageId != null)
return false;
} else if (!imageId.equals(other.imageId))
return false;
if (instanceType == null) {
if (other.instanceType != null)
return false;
} else if (!instanceType.equals(other.instanceType))
return false;
if (kernelId == null) {
if (other.kernelId != null)
return false;
} else if (!kernelId.equals(other.kernelId))
return false;
if (keyName == null) {
if (other.keyName != null)
return false;
} else if (!keyName.equals(other.keyName))
return false;
if (monitoringEnabled == null) {
if (other.monitoringEnabled != null)
return false;
} else if (!monitoringEnabled.equals(other.monitoringEnabled))
return false;
if (ramdiskId == null) {
if (other.ramdiskId != null)
return false;
} else if (!ramdiskId.equals(other.ramdiskId))
return false;
if (!Arrays.equals(userData, other.userData))
return false;
return true;
}
public Builder toBuilder() {
return Builder.fromLaunchSpecification(this);
}
@Override
public String toString() {
return "[instanceType=" + instanceType + ", imageId=" + imageId + ", kernelId=" + kernelId + ", ramdiskId="
+ ramdiskId + ", availabilityZone=" + availabilityZone + ", keyName=" + keyName + ", groupIds=" + groupIds
+ ", blockDeviceMappings=" + blockDeviceMappings + ", monitoringEnabled=" + monitoringEnabled
+ ", userData=" + (userData != null) + "]";
}
}

View File

@ -0,0 +1,173 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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;
/**
* @see <a href=
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSpotPriceHistory.html"
* />
* @author Adrian Cole
*/
public class Spot implements Comparable<Spot> {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String region;
private String instanceType;
private String productDescription;
private float spotPrice;
private Date timestamp;
public void clear() {
this.region = null;
this.instanceType = null;
this.productDescription = null;
this.spotPrice = 0.0f;
this.timestamp = null;
}
public Builder region(String region) {
this.region = region;
return this;
}
public Builder instanceType(String instanceType) {
this.instanceType = instanceType;
return this;
}
public Builder productDescription(String productDescription) {
this.productDescription = productDescription;
return this;
}
public Builder spotPrice(float spotPrice) {
this.spotPrice = spotPrice;
return this;
}
public Builder timestamp(Date timestamp) {
this.timestamp = timestamp;
return this;
}
public Spot build() {
return new Spot(region, instanceType, productDescription, spotPrice, timestamp);
}
}
private final String region;
private final String instanceType;
private final String productDescription;
private final float spotPrice;
private final Date timestamp;
public Spot(String region, String instanceType, String productDescription, float spotPrice, Date timestamp) {
this.region = checkNotNull(region, "region");
this.instanceType = checkNotNull(instanceType, "instanceType");
this.productDescription = checkNotNull(productDescription, "productDescription");
this.spotPrice = spotPrice;
this.timestamp = checkNotNull(timestamp, "timestamp");
}
public String getRegion() {
return region;
}
public String getInstanceType() {
return instanceType;
}
public String getProductDescription() {
return productDescription;
}
public float getSpotPrice() {
return spotPrice;
}
public Date getTimestamp() {
return timestamp;
}
@Override
public int compareTo(Spot o) {
return Float.compare(spotPrice, o.spotPrice);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((instanceType == null) ? 0 : instanceType.hashCode());
result = prime * result + ((productDescription == null) ? 0 : productDescription.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + Float.floatToIntBits(spotPrice);
result = prime * result + ((timestamp == null) ? 0 : timestamp.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Spot other = (Spot) obj;
if (instanceType == null) {
if (other.instanceType != null)
return false;
} else if (!instanceType.equals(other.instanceType))
return false;
if (productDescription == null) {
if (other.productDescription != null)
return false;
} else if (!productDescription.equals(other.productDescription))
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
if (Float.floatToIntBits(spotPrice) != Float.floatToIntBits(other.spotPrice))
return false;
if (timestamp == null) {
if (other.timestamp != null)
return false;
} else if (!timestamp.equals(other.timestamp))
return false;
return true;
}
@Override
public String toString() {
return "[region=" + region + ", instanceType=" + instanceType + ", productDescription=" + productDescription
+ ", spotPrice=" + spotPrice + ", timestamp=" + timestamp + "]";
}
}

View File

@ -38,18 +38,38 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
private String region;
private String availabilityZoneGroup;
private Date createTime;
private String fault;
private String faultCode;
private String faultMessage;
private String instanceId;
private String launchGroup;
private String launchSpecification;
private LaunchSpecification launchSpecification;
private String productDescription;
private String id;
private float spotPrice;
private String state;
private State state;
private Type type;
private Date validFrom;
private Date validUntil;
public Builder clear() {
this.region = null;
this.availabilityZoneGroup = null;
this.createTime = null;
this.faultCode = null;
this.faultMessage = null;
this.instanceId = null;
this.launchGroup = null;
this.launchSpecification = null;
this.productDescription = null;
this.id = null;
this.spotPrice = 0;
this.state = null;
this.type = null;
this.validFrom = null;
this.validUntil = null;
return this;
}
public Builder region(String region) {
this.region = region;
return this;
@ -65,8 +85,13 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
return this;
}
public Builder fault(String fault) {
this.fault = fault;
public Builder faultCode(String faultCode) {
this.faultCode = faultCode;
return this;
}
public Builder faultMessage(String faultMessage) {
this.faultMessage = faultMessage;
return this;
}
@ -80,7 +105,7 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
return this;
}
public Builder launchSpecification(String launchSpecification) {
public Builder launchSpecification(LaunchSpecification launchSpecification) {
this.launchSpecification = launchSpecification;
return this;
}
@ -100,7 +125,7 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
return this;
}
public Builder state(String state) {
public Builder state(State state) {
this.state = state;
return this;
}
@ -121,8 +146,8 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
}
public SpotInstanceRequest build() {
return new SpotInstanceRequest(region, availabilityZoneGroup, createTime, fault, instanceId, launchGroup,
launchSpecification, productDescription, id, spotPrice, state, type, validFrom, validUntil);
return new SpotInstanceRequest(region, availabilityZoneGroup, createTime, faultCode, faultMessage, instanceId,
launchGroup, launchSpecification, productDescription, id, spotPrice, state, type, validFrom, validUntil);
}
}
@ -147,28 +172,51 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
}
}
public enum State {
OPEN, ACTIVE, CANCELLED, UNRECOGNIZED;
public String value() {
return (CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name()));
}
@Override
public String toString() {
return value();
}
public static State fromValue(String state) {
try {
return valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(state, "type")));
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}
private final String region;
private final String availabilityZoneGroup;
private final Date createTime;
private final String fault;
private final String faultCode;
private final String faultMessage;
private final String instanceId;
private final String launchGroup;
private final String launchSpecification;
private final LaunchSpecification launchSpecification;
private final String productDescription;
private final String id;
private final float spotPrice;
private final String state;
private final State state;
private final Type type;
private final Date validFrom;
private final Date validUntil;
public SpotInstanceRequest(String region, String availabilityZoneGroup, Date createTime, String fault,
String instanceId, String launchGroup, String launchSpecification, String productDescription, String id,
float spotPrice, String state, Type type, Date validFrom, Date validUntil) {
public SpotInstanceRequest(String region, String availabilityZoneGroup, Date createTime, String faultCode,
String faultMessage, String instanceId, String launchGroup, LaunchSpecification launchSpecification,
String productDescription, String id, float spotPrice, State state, Type type, Date validFrom, Date validUntil) {
this.region = checkNotNull(region, "region");
this.availabilityZoneGroup = availabilityZoneGroup;
this.createTime = createTime;
this.fault = fault;
this.faultCode = faultCode;
this.faultMessage = faultMessage;
this.instanceId = instanceId;
this.launchGroup = launchGroup;
this.launchSpecification = launchSpecification;
@ -196,8 +244,12 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
return createTime;
}
public String getFault() {
return fault;
public String getFaultCode() {
return faultCode;
}
public String getFaultMessage() {
return faultMessage;
}
public String getInstanceId() {
@ -208,7 +260,7 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
return launchGroup;
}
public String getLaunchSpecification() {
public LaunchSpecification getLaunchSpecification() {
return launchSpecification;
}
@ -224,7 +276,7 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
return spotPrice;
}
public String getState() {
public State getState() {
return state;
}
@ -246,7 +298,8 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
int result = 1;
result = prime * result + ((availabilityZoneGroup == null) ? 0 : availabilityZoneGroup.hashCode());
result = prime * result + ((createTime == null) ? 0 : createTime.hashCode());
result = prime * result + ((fault == null) ? 0 : fault.hashCode());
result = prime * result + ((faultCode == null) ? 0 : faultCode.hashCode());
result = prime * result + ((faultMessage == null) ? 0 : faultMessage.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
result = prime * result + ((launchGroup == null) ? 0 : launchGroup.hashCode());
@ -279,10 +332,15 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
return false;
} else if (!createTime.equals(other.createTime))
return false;
if (fault == null) {
if (other.fault != null)
if (faultCode == null) {
if (other.faultCode != null)
return false;
} else if (!fault.equals(other.fault))
} else if (!faultCode.equals(other.faultCode))
return false;
if (faultMessage == null) {
if (other.faultMessage != null)
return false;
} else if (!faultMessage.equals(other.faultMessage))
return false;
if (id == null) {
if (other.id != null)
@ -334,8 +392,8 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
@Override
public String toString() {
return "[region=" + region + ", id=" + id + ", spotPrice=" + spotPrice + ", state=" + state
+ ", availabilityZoneGroup=" + availabilityZoneGroup + ", createTime=" + createTime + ", fault=" + fault
+ ", type=" + type + ", instanceId=" + instanceId + ", launchGroup=" + launchGroup
+ ", availabilityZoneGroup=" + availabilityZoneGroup + ", createTime=" + createTime + ", faultCode="
+ faultCode + ", type=" + type + ", instanceId=" + instanceId + ", launchGroup=" + launchGroup
+ ", launchSpecification=" + launchSpecification + ", productDescription=" + productDescription
+ ", validFrom=" + validFrom + ", validUntil=" + validUntil + "]";
}

View File

@ -22,12 +22,10 @@ package org.jclouds.aws.ec2.options;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Date;
import java.util.Map.Entry;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
import org.jclouds.date.DateService;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.ec2.options.RunInstancesOptions;
import org.jclouds.ec2.options.internal.BaseEC2RequestOptions;
/**
@ -99,18 +97,6 @@ public class RequestSpotInstancesOptions extends BaseEC2RequestOptions {
return this;
}
/**
* Specifies the Availability Zone group. If you specify the same Availability Zone group for all
* Spot Instance requests, all Spot Instances are launched in the same Availability Zone.
*/
public RequestSpotInstancesOptions launchSpecification(RunInstancesOptions launchSpecification) {
for (Entry<String, String> entry : checkNotNull(launchSpecification, "launchSpecification").buildFormParameters()
.entries()) {
formParameters.put("LaunchSpecification." + entry.getKey(), entry.getValue());
}
return this;
}
public static class Builder {
/**
* @see RequestSpotInstancesOptions#validFrom
@ -152,12 +138,5 @@ public class RequestSpotInstancesOptions extends BaseEC2RequestOptions {
return options.availabilityZoneGroup(availabilityZoneGroup);
}
/**
* @see RequestSpotInstancesOptions#launchSpecification
*/
public static RequestSpotInstancesOptions launchSpecification(RunInstancesOptions launchSpecification) {
RequestSpotInstancesOptions options = new RequestSpotInstancesOptions();
return options.launchSpecification(launchSpecification);
}
}
}

View File

@ -0,0 +1,83 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.predicates;
import java.util.NoSuchElementException;
import java.util.concurrent.ExecutionException;
import javax.annotation.Resource;
import javax.inject.Singleton;
import org.jclouds.aws.ec2.AWSEC2Client;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
import org.jclouds.logging.Logger;
import org.jclouds.rest.ResourceNotFoundException;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import com.google.inject.Inject;
/**
*
*
* @author Adrian Cole
*/
@Singleton
public class SpotInstanceRequestActive implements Predicate<SpotInstanceRequest> {
private final AWSEC2Client client;
@Resource
protected Logger logger = Logger.NULL;
@Inject
public SpotInstanceRequestActive(AWSEC2Client client) {
this.client = client;
}
public boolean apply(SpotInstanceRequest spot) {
logger.trace("looking for state on spot %s", spot);
try {
spot = refresh(spot);
logger.trace("%s: looking for spot state %s: currently: %s", spot.getId(), SpotInstanceRequest.State.ACTIVE,
spot.getState());
if (spot.getState() == SpotInstanceRequest.State.CANCELLED)
Throwables.propagate(new ExecutionException(String.format("spot request %s cancelled", spot.getId())) {
private static final long serialVersionUID = 1L;
});
if (spot.getFaultCode() != null)
Throwables.propagate(new ExecutionException(String.format("spot request %s fault code(%s) message(%s)",
spot.getId(), spot.getFaultCode(), spot.getFaultMessage())) {
private static final long serialVersionUID = 1L;
});
return spot.getState() == SpotInstanceRequest.State.ACTIVE;
} catch (ResourceNotFoundException e) {
return false;
} catch (NoSuchElementException e) {
return false;
}
}
private SpotInstanceRequest refresh(SpotInstanceRequest spot) {
return Iterables.getOnlyElement(client.getSpotInstanceServices().describeSpotInstanceRequestsInRegion(
spot.getRegion(), spot.getId()));
}
}

View File

@ -22,23 +22,34 @@ 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.binders.BindLaunchSpecificationToFormParams;
import org.jclouds.aws.ec2.binders.BindSpotInstanceRequestIdsToIndexedFormParams;
import org.jclouds.aws.ec2.binders.IfNotNullBindAvailabilityZoneToLaunchSpecificationFormParam;
import org.jclouds.aws.ec2.domain.LaunchSpecification;
import org.jclouds.aws.ec2.domain.Spot;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
import org.jclouds.aws.ec2.options.DescribeSpotPriceHistoryOptions;
import org.jclouds.aws.ec2.options.RequestSpotInstancesOptions;
import org.jclouds.aws.ec2.xml.SpotInstanceRequestsResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeSpotPriceHistoryResponseHandler;
import org.jclouds.aws.filters.FormSigner;
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 org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
@ -59,20 +70,36 @@ public interface SpotInstanceAsyncClient {
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeSpotInstanceRequests")
ListenableFuture<String> describeSpotInstanceRequestsInRegion(
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
@XMLResponseParser(SpotInstanceRequestsResponseHandler.class)
ListenableFuture<? extends Set<SpotInstanceRequest>> describeSpotInstanceRequestsInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindSpotInstanceRequestIdsToIndexedFormParams.class) String... requestIds);
/**
* @see SpotInstanceClient#requestSpotInstancesInRegion
* @see SpotInstanceClient#requestSpotInstancesInRegion(String,float,String,String)
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "RequestSpotInstances")
ListenableFuture<String> requestSpotInstancesInRegion(
@XMLResponseParser(SpotInstanceRequestsResponseHandler.class)
ListenableFuture<? extends Set<SpotInstanceRequest>> requestSpotInstancesInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@Nullable @BinderParam(IfNotNullBindAvailabilityZoneToLaunchSpecificationFormParam.class) String nullableAvailabilityZone,
@FormParam("LaunchSpecification.ImageId") String imageId,@FormParam("InstanceCount") int instanceCount, @FormParam("SpotPrice") float spotPrice,
@FormParam("SpotPrice") float spotPrice, @FormParam("LaunchSpecification.ImageId") String imageId,
@FormParam("LaunchSpecification.InstanceType") String instanceType);
/**
* @see SpotInstanceClient#requestSpotInstancesInRegion(String,float,int,
* LaunchSpecification,RequestSpotInstancesOptions[])
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "RequestSpotInstances")
@XMLResponseParser(SpotInstanceRequestsResponseHandler.class)
ListenableFuture<? extends Set<SpotInstanceRequest>> requestSpotInstancesInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("SpotPrice") float spotPrice, @FormParam("InstanceCount") int instanceCount,
@BinderParam(BindLaunchSpecificationToFormParams.class) LaunchSpecification launchSpec,
RequestSpotInstancesOptions... options);
/**
@ -81,7 +108,9 @@ public interface SpotInstanceAsyncClient {
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeSpotPriceHistory")
ListenableFuture<String> describeSpotPriceHistoryInRegion(
@XMLResponseParser(DescribeSpotPriceHistoryResponseHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<Spot>> describeSpotPriceHistoryInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
DescribeSpotPriceHistoryOptions... options);
@ -91,7 +120,8 @@ public interface SpotInstanceAsyncClient {
@POST
@Path("/")
@FormParams(keys = ACTION, values = "CancelSpotInstanceRequests")
ListenableFuture<String> cancelSpotInstanceRequestsInRegion(
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> cancelSpotInstanceRequestsInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindSpotInstanceRequestIdsToIndexedFormParams.class) String... requestIds);

View File

@ -19,10 +19,14 @@
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.LaunchSpecification;
import org.jclouds.aws.ec2.domain.Spot;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
import org.jclouds.aws.ec2.options.DescribeSpotPriceHistoryOptions;
import org.jclouds.aws.ec2.options.RequestSpotInstancesOptions;
import org.jclouds.concurrent.Timeout;
@ -56,7 +60,7 @@ public interface SpotInstanceClient {
* />
* @return TODO
*/
String describeSpotInstanceRequestsInRegion(@Nullable String region, String... requestIds);
Set<SpotInstanceRequest> describeSpotInstanceRequestsInRegion(@Nullable String region, String... requestIds);
/**
* Creates a Spot Instance request. Spot Instances are instances that Amazon EC2 starts on your
@ -67,18 +71,13 @@ public interface SpotInstanceClient {
*
* @param region
* Region where the spot instance service is running
* @param nullableAvailabilityZone
* The availability zone to launch the instances in, or null to let the system choose
* @param imageId
* The AMI ID.
* @param instanceCount
* The maximum number of Spot Instances to launch.
* @param spotPrice
* Specifies the maximum hourly price for any Spot Instance launched to fulfill the
* request.
* @param options
* control the duration of the request, grouping, and the size and parameters of the
* server to run
* @param imageId
* The AMI ID.
* @param instanceType
* The instance type (ex. m1.small)
*
* @see #describeSpotInstanceRequestsInRegion
* @see #cancelSpotInstanceRequestsInRegion
@ -88,8 +87,10 @@ public interface SpotInstanceClient {
* />
* @return TODO
*/
String requestSpotInstancesInRegion(@Nullable String region, @Nullable String nullableAvailabilityZone,
String imageId, int instanceCount, float spotPrice, RequestSpotInstancesOptions... options);
Set<SpotInstanceRequest> requestSpotInstancesInRegion(@Nullable String region, float spotPrice, String imageId, String instanceType);
Set<SpotInstanceRequest> requestSpotInstancesInRegion(@Nullable String region, float spotPrice, int instanceCount,
LaunchSpecification launchSpec, RequestSpotInstancesOptions... options);
/**
*
@ -112,7 +113,8 @@ public interface SpotInstanceClient {
* />
* @return TODO
*/
String describeSpotPriceHistoryInRegion(@Nullable String region, DescribeSpotPriceHistoryOptions... options);
@Timeout(duration = 2, timeUnit = TimeUnit.MINUTES)
Set<Spot> describeSpotPriceHistoryInRegion(@Nullable String region, DescribeSpotPriceHistoryOptions... options);
/**
* Cancels one or more Spot Instance requests. Spot Instances are instances that Amazon EC2

View File

@ -0,0 +1,79 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.aws.ec2.domain.Spot;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
/**
* @author Adrian Cole
*/
public class DescribeSpotPriceHistoryResponseHandler extends
ParseSax.HandlerWithResult<Set<Spot>> {
private Builder<Spot> spots = ImmutableSet.<Spot>builder();
private final SpotHandler spotHandler;
@Inject
public DescribeSpotPriceHistoryResponseHandler(SpotHandler spotHandler) {
this.spotHandler = spotHandler;
}
public Set<Spot> getResult() {
return spots.build();
}
@Override
public HandlerWithResult<Set<Spot>> setContext(HttpRequest request) {
spotHandler.setContext(request);
return super.setContext(request);
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
if (!qName.equals("item"))
spotHandler.startElement(uri, localName, qName, attributes);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equals("item")) {
spots.add(spotHandler.getResult());
}
spotHandler.endElement(uri, localName, qName);
}
public void characters(char ch[], int start, int length) {
spotHandler.characters(ch, start, length);
}
}

View File

@ -0,0 +1,115 @@
package org.jclouds.aws.ec2.xml;
import javax.annotation.Resource;
import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.LaunchSpecification;
import org.jclouds.aws.ec2.domain.LaunchSpecification.Builder;
import org.jclouds.date.DateService;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.http.functions.ParseSax.HandlerForGeneratedRequestWithResult;
import org.jclouds.location.Region;
import org.jclouds.logging.Logger;
import org.xml.sax.Attributes;
/**
*
* @author Adrian Cole
*/
public class LaunchSpecificationHandler extends HandlerForGeneratedRequestWithResult<LaunchSpecification> {
@Resource
protected Logger logger = Logger.NULL;
protected final DateService dateService;
protected final String defaultRegion;
protected final Builder builder;
protected final BlockDeviceMapping.Builder blockDeviceMappingBuilder;
@Inject
public LaunchSpecificationHandler(DateService dateService, @Region String defaultRegion,
LaunchSpecification.Builder builder, BlockDeviceMapping.Builder blockDeviceMappingBuilder) {
this.dateService = dateService;
this.defaultRegion = defaultRegion;
this.builder = builder;
this.blockDeviceMappingBuilder = blockDeviceMappingBuilder;
}
protected String currentOrNull() {
String returnVal = currentText.toString().trim();
return returnVal.equals("") ? null : returnVal;
}
protected StringBuilder currentText = new StringBuilder();
private boolean inBlockDeviceMapping;
public void startElement(String uri, String name, String qName, Attributes attrs) {
if (qName.equals("blockDeviceMapping")) {
inBlockDeviceMapping = true;
}
}
public void endElement(String uri, String name, String qName) {
if (qName.equals("blockDeviceMapping")) {
inBlockDeviceMapping = false;
} else if (qName.equals("item") && inBlockDeviceMapping) {
try {
builder.blockDeviceMapping(blockDeviceMappingBuilder.build());
} finally {
blockDeviceMappingBuilder.clear();
}
} else if (qName.equals("deviceName")) {
blockDeviceMappingBuilder.deviceName(currentOrNull());
} else if (qName.equals("virtualName")) {
blockDeviceMappingBuilder.virtualName(currentOrNull());
} else if (qName.equals("snapshotId")) {
blockDeviceMappingBuilder.snapshotId(currentOrNull());
} else if (qName.equals("volumeSize")) {
String volumeSize = currentOrNull();
if (volumeSize != null)
blockDeviceMappingBuilder.sizeInGib(Integer.parseInt(volumeSize));
} else if (qName.equals("noDevice")) {
String noDevice = currentOrNull();
if (noDevice != null)
blockDeviceMappingBuilder.noDevice(Boolean.parseBoolean(noDevice));
} else if (qName.equals("deleteOnTermination")) {
String deleteOnTermination = currentOrNull();
if (deleteOnTermination != null)
blockDeviceMappingBuilder.deleteOnTermination(Boolean.parseBoolean(deleteOnTermination));
} else if (qName.equals("groupId")) {
builder.groupId(currentOrNull());
} else if (qName.equals("imageId")) {
builder.imageId(currentOrNull());
} else if (qName.equals("instanceType")) {
builder.instanceType(currentOrNull());
} else if (qName.equals("kernelId")) {
builder.kernelId(currentOrNull());
} else if (qName.equals("keyName")) {
builder.keyName(currentOrNull());
} else if (qName.equals("availabilityZone")) {
builder.availabilityZone(currentOrNull());
} else if (qName.equals("ramdiskId")) {
builder.ramdiskId(currentOrNull());
} else if (qName.equals("enabled")) {
String monitoringEnabled = currentOrNull();
if (monitoringEnabled != null)
builder.monitoringEnabled(new Boolean(monitoringEnabled));
}
currentText = new StringBuilder();
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
@Override
public LaunchSpecification getResult() {
try {
return builder.build();
} finally {
builder.clear();
}
}
}

View File

@ -24,7 +24,6 @@ import javax.inject.Inject;
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;
import org.jclouds.location.Region;
@ -36,8 +35,6 @@ public class PlacementGroupHandler extends
ParseSax.HandlerForGeneratedRequestWithResult<PlacementGroup> {
private StringBuilder currentText = new StringBuilder();
@Inject
protected DateService dateService;
@Inject
@Region
String defaultRegion;

View File

@ -0,0 +1,75 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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 javax.inject.Inject;
import org.jclouds.aws.ec2.domain.Spot;
import org.jclouds.aws.util.AWSUtils;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.location.Region;
/**
*
* @author Adrian Cole
*/
public class SpotHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Spot> {
private StringBuilder currentText = new StringBuilder();
protected final DateService dateService;
protected final String defaultRegion;
@Inject
public SpotHandler(DateService dateService, @Region String defaultRegion) {
this.dateService = dateService;
this.defaultRegion = defaultRegion;
}
private Spot.Builder builder = Spot.builder();
public Spot getResult() {
try {
String region = getRequest() == null ? null : AWSUtils.findRegionInArgsOrNull(getRequest());
if (region == null)
region = defaultRegion;
return builder.region(region).build();
} finally {
builder.clear();
}
}
public void endElement(String uri, String name, String qName) {
if (qName.equals("instanceType")) {
builder.instanceType(currentText.toString().trim());
} else if (qName.equals("productDescription")) {
builder.productDescription(currentText.toString().trim());
} else if (qName.equals("spotPrice")) {
builder.spotPrice(Float.parseFloat(currentText.toString().trim()));
} else if (qName.equals("timestamp")) {
builder.timestamp(dateService.iso8601DateParse(currentText.toString().trim()));
}
currentText = new StringBuilder();
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -19,79 +19,107 @@
package org.jclouds.aws.ec2.xml;
import java.util.Date;
import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest.Type;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest.Builder;
import org.jclouds.aws.util.AWSUtils;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.location.Region;
import org.xml.sax.Attributes;
/**
*
* @author Adrian Cole
*/
// TODO finish
public class SpotInstanceRequestHandler extends ParseSax.HandlerForGeneratedRequestWithResult<SpotInstanceRequest> {
private StringBuilder currentText = new StringBuilder();
protected final DateService dateService;
protected final String defaultRegion;
protected final Builder builder;
protected boolean inLaunchSpecification;
protected final LaunchSpecificationHandler launchSpecificationHandler;
@Inject
protected DateService dateService;
@Inject
@Region
private String defaultRegion;
private String availabilityZoneGroup;
private Date createTime;
private String fault;
private String instanceId;
private String launchGroup;
private String launchSpecification;
private String productDescription;
private String id;
private float spotPrice;
private String state;
private Type type;
private Date validFrom;
private Date validUntil;
public SpotInstanceRequestHandler(DateService dateService, @Region String defaultRegion,
LaunchSpecificationHandler launchSpecificationHandler, SpotInstanceRequest.Builder builder) {
this.dateService = dateService;
this.defaultRegion = defaultRegion;
this.launchSpecificationHandler = launchSpecificationHandler;
this.builder = builder;
}
protected String currentOrNull() {
String returnVal = currentText.toString().trim();
return returnVal.equals("") ? null : returnVal;
}
public SpotInstanceRequest getResult() {
String region = AWSUtils.findRegionInArgsOrNull(getRequest());
if (region == null)
region = defaultRegion;
SpotInstanceRequest returnVal = new SpotInstanceRequest(region, availabilityZoneGroup, createTime, fault,
instanceId, launchGroup, launchSpecification, productDescription, id, spotPrice, state, type, validFrom,
validUntil);
this.availabilityZoneGroup = null;
this.createTime = null;
this.fault = null;
this.instanceId = null;
this.launchGroup = null;
this.launchSpecification = null;
this.productDescription = null;
this.id = null;
this.spotPrice = -1;
this.state = null;
this.type = null;
this.validFrom = null;
this.validUntil = null;
return returnVal;
try {
String region = getRequest() != null ? AWSUtils.findRegionInArgsOrNull(getRequest()) : null;
if (region == null)
region = defaultRegion;
return builder.region(region).build();
} finally {
builder.clear();
}
}
public void startElement(String uri, String name, String qName, Attributes attrs) {
if (qName.equals("launchSpecification")) {
inLaunchSpecification = true;
}
if (inLaunchSpecification)
launchSpecificationHandler.startElement(uri, name, qName, attrs);
}
public void endElement(String uri, String name, String qName) {
if (qName.equals("availabilityZoneGroup")) {
this.availabilityZoneGroup = currentText.toString().trim();
} else if (qName.equals("createTime")) {
createTime = this.dateService.iso8601DateParse(currentText.toString().trim());
if (qName.equals("launchSpecification")) {
inLaunchSpecification = false;
builder.launchSpecification(launchSpecificationHandler.getResult());
}
if (inLaunchSpecification) {
launchSpecificationHandler.endElement(uri, name, qName);
} else if (qName.equals("spotInstanceRequestId")) {
builder.id(currentOrNull());
} else if (qName.equals("instanceId")) {
builder.instanceId(currentOrNull());
} else if (qName.equals("availabilityZoneGroup")) {
builder.availabilityZoneGroup(currentOrNull());
} else if (qName.equals("launchGroup")) {
builder.launchGroup(currentOrNull());
} else if (qName.equals("code")) {
builder.faultCode(currentOrNull());
} else if (qName.equals("message")) {
builder.faultMessage(currentOrNull());
} else if (qName.equals("spotPrice")) {
String price = currentOrNull();
if (price != null)
builder.spotPrice(Float.parseFloat(price));
} else if (qName.equals("type")) {
type = SpotInstanceRequest.Type.fromValue(currentText.toString().trim());
String type = currentOrNull();
if (type != null)
builder.type(SpotInstanceRequest.Type.fromValue(type));
} else if (qName.equals("state")) {
String state = currentOrNull();
if (state != null)
builder.state(SpotInstanceRequest.State.fromValue(state));
} else if (qName.equals("createTime")) {
String createTime = currentOrNull();
if (createTime != null)
builder.createTime(dateService.iso8601DateParse(createTime));
} else if (qName.equals("productDescription")) {
builder.productDescription(currentOrNull());
}
currentText = new StringBuilder();
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
if (inLaunchSpecification)
launchSpecificationHandler.characters(ch, start, length);
else
currentText.append(ch, start, length);
}
}

View File

@ -30,25 +30,25 @@ import org.jclouds.http.functions.ParseSax.HandlerWithResult;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import com.google.common.collect.Sets;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
/**
* @author Adrian Cole
*/
//TODO finish
public class DescribeSpotInstanceRequestsResponseHandler extends
ParseSax.HandlerWithResult<Set<SpotInstanceRequest>> {
public class SpotInstanceRequestsResponseHandler extends ParseSax.HandlerWithResult<Set<SpotInstanceRequest>> {
private Set<SpotInstanceRequest> spotRequests = Sets.newLinkedHashSet();
private final Builder<SpotInstanceRequest> spotRequests = ImmutableSet.<SpotInstanceRequest> builder();
private final SpotInstanceRequestHandler spotRequestHandler;
private int itemDepth;
@Inject
public DescribeSpotInstanceRequestsResponseHandler(SpotInstanceRequestHandler spotRequestHandler) {
public SpotInstanceRequestsResponseHandler(SpotInstanceRequestHandler spotRequestHandler) {
this.spotRequestHandler = spotRequestHandler;
}
public Set<SpotInstanceRequest> getResult() {
return spotRequests;
return spotRequests.build();
}
@Override
@ -58,22 +58,27 @@ public class DescribeSpotInstanceRequestsResponseHandler extends
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
if (!qName.equals("item"))
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equals("item"))
itemDepth++;
if (itemDepth >= 1)
spotRequestHandler.startElement(uri, localName, qName, attributes);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equals("item")) {
if (qName.equals("item") && itemDepth == 1) {
spotRequests.add(spotRequestHandler.getResult());
}
spotRequestHandler.endElement(uri, localName, qName);
if (qName.equals("item"))
itemDepth--;
if (itemDepth >= 1)
spotRequestHandler.endElement(uri, localName, qName);
}
public void characters(char ch[], int start, int length) {
spotRequestHandler.characters(ch, start, length);
if (itemDepth >= 1)
spotRequestHandler.characters(ch, start, length);
}
}

View File

@ -0,0 +1,60 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.binders;
import static org.testng.Assert.assertEquals;
import java.net.UnknownHostException;
import org.jclouds.aws.ec2.domain.LaunchSpecification;
import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.encryption.internal.Base64;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
/**
* @author Adrian Cole
*/
@Test(groups = "unit")
public class BindLaunchSpecificationToFormParamsTest {
BindLaunchSpecificationToFormParams binder = new BindLaunchSpecificationToFormParams();
@Test
public void testApplyWithBlockDeviceMappings() throws UnknownHostException {
LaunchSpecification spec = LaunchSpecification.builder().instanceType(InstanceType.T1_MICRO).imageId("ami-123")
.mapNewVolumeToDevice("/dev/sda1", 120, true).build();
assertEquals(binder.apply(spec), ImmutableMap.of("LaunchSpecification.InstanceType", "t1.micro",
"LaunchSpecification.ImageId", "ami-123", "LaunchSpecification.BlockDeviceMapping.1.DeviceName",
"/dev/sda1", "LaunchSpecification.BlockDeviceMapping.1.Ebs.VolumeSize", "120",
"LaunchSpecification.BlockDeviceMapping.1.Ebs.DeleteOnTermination", "true"));
}
@Test
public void testApplyWithUserData() throws UnknownHostException {
LaunchSpecification spec = LaunchSpecification.builder().instanceType(InstanceType.T1_MICRO).imageId("ami-123")
.userData("hello".getBytes()).build();
assertEquals(binder.apply(spec), ImmutableMap.of("LaunchSpecification.InstanceType", "t1.micro",
"LaunchSpecification.ImageId", "ami-123", "LaunchSpecification.UserData",
Base64.encodeBytes("hello".getBytes())));
}
}

View File

@ -21,7 +21,6 @@ package org.jclouds.aws.ec2.options;
import static org.jclouds.aws.ec2.options.RequestSpotInstancesOptions.Builder.availabilityZoneGroup;
import static org.jclouds.aws.ec2.options.RequestSpotInstancesOptions.Builder.launchGroup;
import static org.jclouds.aws.ec2.options.RequestSpotInstancesOptions.Builder.launchSpecification;
import static org.jclouds.aws.ec2.options.RequestSpotInstancesOptions.Builder.type;
import static org.jclouds.aws.ec2.options.RequestSpotInstancesOptions.Builder.validFrom;
import static org.jclouds.aws.ec2.options.RequestSpotInstancesOptions.Builder.validUntil;
@ -31,13 +30,9 @@ import java.util.Collections;
import java.util.Date;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.ec2.options.RunInstancesOptions;
import org.jclouds.http.options.HttpRequestOptions;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
* Tests possible uses of RequestSpotInstancesOptions and RequestSpotInstancesOptions.Builder.*
*
@ -147,33 +142,4 @@ public class RequestSpotInstancesOptionsTest {
validUntil(null);
}
RunInstancesOptions launchSpec = new RunInstancesOptions().withBlockDeviceMappings(ImmutableSet
.<BlockDeviceMapping> of(new BlockDeviceMapping.MapNewVolumeToDevice("/dev/sda1", 120, true)));
@Test
public void testLaunchSpecification() {
RequestSpotInstancesOptions options = new RequestSpotInstancesOptions();
options.launchSpecification(launchSpec);
verifyLaunchSpec(options);
}
protected void verifyLaunchSpec(RequestSpotInstancesOptions options) {
assertEquals(options.buildFormParameters().get("LaunchSpecification.BlockDeviceMapping.1.DeviceName"),
Collections.singletonList("/dev/sda1"));
assertEquals(options.buildFormParameters().get("LaunchSpecification.BlockDeviceMapping.1.Ebs.VolumeSize"),
Collections.singletonList("120"));
assertEquals(options.buildFormParameters()
.get("LaunchSpecification.BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections.singletonList("true"));
}
@Test
public void testLaunchSpecificationStatic() {
RequestSpotInstancesOptions options = launchSpecification(launchSpec);
verifyLaunchSpec(options);
}
@Test(expectedExceptions = NullPointerException.class)
public void testLaunchSpecificationNPE() {
launchSpecification(null);
}
}

View File

@ -100,7 +100,7 @@ public class AMIClientLiveTest {
setupCredentials();
Properties overrides = setupProperties();
context = new ComputeServiceContextFactory().createContext(provider,
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
client = context.getApi().getAMIServices();
}
@ -135,7 +135,7 @@ public class AMIClientLiveTest {
String imageRegisteredId = client.registerImageFromManifestInRegion(null, "jcloudstest1", DEFAULT_MANIFEST);
imagesToDeregister.add(imageRegisteredId);
Image imageRegisteredFromManifest = Iterables.getOnlyElement(client.describeImagesInRegion(null,
imageIds(imageRegisteredId)));
imageIds(imageRegisteredId)));
assertEquals(imageRegisteredFromManifest.getName(), "jcloudstest1");
assertEquals(imageRegisteredFromManifest.getImageLocation(), DEFAULT_MANIFEST);
assertEquals(imageRegisteredFromManifest.getImageType(), ImageType.MACHINE);
@ -146,10 +146,10 @@ public class AMIClientLiveTest {
@Test(enabled = false)
public void testRegisterImageFromManifestOptions() {
String imageRegisteredWithOptionsId = client.registerImageFromManifestInRegion(null, "jcloudstest2",
DEFAULT_MANIFEST, withDescription("adrian"));
DEFAULT_MANIFEST, withDescription("adrian"));
imagesToDeregister.add(imageRegisteredWithOptionsId);
Image imageRegisteredFromManifestWithOptions = Iterables.getOnlyElement(client.describeImagesInRegion(null,
imageIds(imageRegisteredWithOptionsId)));
imageIds(imageRegisteredWithOptionsId)));
assertEquals(imageRegisteredFromManifestWithOptions.getName(), "jcloudstest2");
assertEquals(imageRegisteredFromManifestWithOptions.getImageLocation(), DEFAULT_MANIFEST);
assertEquals(imageRegisteredFromManifestWithOptions.getImageType(), ImageType.MACHINE);
@ -164,7 +164,7 @@ public class AMIClientLiveTest {
String imageRegisteredId = client.registerUnixImageBackedByEbsInRegion(null, "jcloudstest1", DEFAULT_MANIFEST);
imagesToDeregister.add(imageRegisteredId);
Image imageRegistered = Iterables
.getOnlyElement(client.describeImagesInRegion(null, imageIds(imageRegisteredId)));
.getOnlyElement(client.describeImagesInRegion(null, imageIds(imageRegisteredId)));
assertEquals(imageRegistered.getName(), "jcloudstest1");
assertEquals(imageRegistered.getImageType(), ImageType.MACHINE);
assertEquals(imageRegistered.getRootDeviceType(), RootDeviceType.EBS);
@ -175,18 +175,19 @@ public class AMIClientLiveTest {
// 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"));
DEFAULT_SNAPSHOT, addNewBlockDevice("/dev/sda2", "myvirtual", 1).withDescription("adrian"));
imagesToDeregister.add(imageRegisteredWithOptionsId);
Image imageRegisteredWithOptions = Iterables.getOnlyElement(client.describeImagesInRegion(null,
imageIds(imageRegisteredWithOptionsId)));
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());
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)
@ -216,6 +217,7 @@ public class AMIClientLiveTest {
// TODO client.resetLaunchPermissionsOnImageInRegion(null, imageId);
}
@Test(enabled = false)
public void testGetLaunchPermissionForImage() {
System.out.println(client.getLaunchPermissionForImageInRegion(null, imageId));
}

View File

@ -23,11 +23,16 @@ import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Date;
import org.jclouds.aws.ec2.domain.LaunchSpecification;
import org.jclouds.aws.ec2.options.DescribeSpotPriceHistoryOptions;
import org.jclouds.aws.ec2.options.RequestSpotInstancesOptions;
import org.jclouds.ec2.options.RunInstancesOptions;
import org.jclouds.aws.ec2.xml.DescribeSpotPriceHistoryResponseHandler;
import org.jclouds.aws.ec2.xml.SpotInstanceRequestsResponseHandler;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ReturnStringIf2xx;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
@ -43,18 +48,18 @@ import com.google.inject.TypeLiteral;
public class SpotInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<SpotInstanceAsyncClient> {
public void testRequestSpotInstances() throws SecurityException, NoSuchMethodException, IOException {
Method method = SpotInstanceAsyncClient.class.getMethod("requestSpotInstancesInRegion", String.class,
String.class, String.class, int.class, float.class, RequestSpotInstancesOptions[].class);
HttpRequest request = processor.createRequest(method, null, null, "ami-voo", 1, 0.01);
float.class, String.class, String.class);
HttpRequest request = processor.createRequest(method, null, 0.01f, "m1.small", "ami-voo");
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-11-15&Action=RequestSpotInstances&LaunchSpecification.ImageId=ami-voo&InstanceCount=1&SpotPrice=0.01",
"Version=2010-11-15&Action=RequestSpotInstances&LaunchSpecification.ImageId=m1.small&SpotPrice=0.01&LaunchSpecification.InstanceType=ami-voo",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReturnStringIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, SpotInstanceRequestsResponseHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
@ -62,31 +67,21 @@ public class SpotInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<SpotI
public void testRequestSpotInstancesOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = SpotInstanceAsyncClient.class.getMethod("requestSpotInstancesInRegion", String.class,
String.class, String.class, int.class, float.class, RequestSpotInstancesOptions[].class);
HttpRequest request = processor.createRequest(
method,
"eu-west-1",
"eu-west-1a",
"ami-voo",
1,
0.01,
new RequestSpotInstancesOptions()
.validFrom(from)
.validUntil(to)
.availabilityZoneGroup("availabilityZoneGroup")
.launchGroup("launchGroup")
.launchSpecification(
RunInstancesOptions.Builder.withKernelId("kernelId").withSecurityGroups("group1", "group2")));
float.class, int.class, LaunchSpecification.class, RequestSpotInstancesOptions[].class);
HttpRequest request = processor.createRequest(method, "eu-west-1", 0.01, 3,
LaunchSpecification.builder().instanceType("m1.small").imageId("ami-voo").availabilityZone("eu-west-1a")
.kernelId("kernelId").groupId("group1").build(), new RequestSpotInstancesOptions().validFrom(from)
.validUntil(to).availabilityZoneGroup("availabilityZoneGroup").launchGroup("launchGroup"));
assertRequestLineEquals(request, "POST https://ec2.eu-west-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.eu-west-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-11-15&Action=RequestSpotInstances&LaunchSpecification.ImageId=ami-voo&InstanceCount=1&SpotPrice=0.01&ValidFrom=1970-05-23T21%3A21%3A18.910Z&ValidUntil=2009-02-13T23%3A31%3A31.011Z&AvailabilityZoneGroup=availabilityZoneGroup&LaunchGroup=launchGroup&LaunchSpecification.KernelId=kernelId&LaunchSpecification.SecurityGroup.1=group1&LaunchSpecification.SecurityGroup.2=group2&LaunchSpecification.Placement.AvailabilityZone=eu-west-1a",
"Version=2010-11-15&Action=RequestSpotInstances&InstanceCount=3&SpotPrice=0.01&ValidFrom=1970-05-23T21%3A21%3A18.910Z&ValidUntil=2009-02-13T23%3A31%3A31.011Z&AvailabilityZoneGroup=availabilityZoneGroup&LaunchGroup=launchGroup&LaunchSpecification.ImageId=ami-voo&LaunchSpecification.Placement.AvailabilityZone=eu-west-1a&LaunchSpecification.SecurityGroup.1=group1&LaunchSpecification.InstanceType=m1.small&LaunchSpecification.KernelId=kernelId",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReturnStringIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, SpotInstanceRequestsResponseHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
@ -102,9 +97,9 @@ public class SpotInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<SpotI
assertPayloadEquals(request, "Version=2010-11-15&Action=CancelSpotInstanceRequests&SpotInstanceRequestId.1=id",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReturnStringIf2xx.class);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnVoidOnNotFoundOr404.class);
checkFilters(request);
}
@ -119,9 +114,9 @@ public class SpotInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<SpotI
assertPayloadEquals(request, "Version=2010-11-15&Action=DescribeSpotInstanceRequests",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReturnStringIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, SpotInstanceRequestsResponseHandler.class);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
@ -138,9 +133,9 @@ public class SpotInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<SpotI
"Version=2010-11-15&Action=DescribeSpotInstanceRequests&SpotInstanceRequestId.1=1&SpotInstanceRequestId.2=2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReturnStringIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, SpotInstanceRequestsResponseHandler.class);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
@ -155,9 +150,9 @@ public class SpotInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<SpotI
assertPayloadEquals(request, "Version=2010-11-15&Action=DescribeSpotPriceHistory",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReturnStringIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeSpotPriceHistoryResponseHandler.class);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
@ -178,9 +173,9 @@ public class SpotInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<SpotI
"Version=2010-11-15&Action=DescribeSpotPriceHistory&StartTime=1970-05-23T21%3A21%3A18.910Z&EndTime=2009-02-13T23%3A31%3A31.011Z&ProductDescription=description&InstanceType.1=m1.small",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReturnStringIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeSpotPriceHistoryResponseHandler.class);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}

View File

@ -20,22 +20,32 @@
package org.jclouds.aws.ec2.services;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.in;
import static com.google.common.collect.Iterables.getOnlyElement;
import static org.jclouds.aws.ec2.options.DescribeSpotPriceHistoryOptions.Builder.from;
import static org.jclouds.aws.ec2.options.RequestSpotInstancesOptions.Builder.launchGroup;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Date;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import java.util.concurrent.TimeUnit;
import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.AWSEC2Client;
import org.jclouds.aws.ec2.domain.AWSRunningInstance;
import org.jclouds.aws.ec2.domain.LaunchSpecification;
import org.jclouds.aws.ec2.domain.Spot;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
import org.jclouds.aws.ec2.options.AWSRunInstancesOptions;
import org.jclouds.aws.ec2.options.RequestSpotInstancesOptions;
import org.jclouds.aws.ec2.predicates.SpotInstanceRequestActive;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
@ -46,7 +56,6 @@ import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.inject.Module;
/**
@ -57,16 +66,18 @@ import com.google.inject.Module;
@Test(groups = "live", sequential = true)
public class SpotInstanceClientLiveTest {
private static final int SPOT_DELAY_SECONDS = 300;
private AWSEC2Client client;
private ComputeServiceContext context;
private RetryablePredicate<SpotInstanceRequest> availableTester;
private RetryablePredicate<SpotInstanceRequest> deletedTester;
private SpotInstanceRequest request;
private RetryablePredicate<SpotInstanceRequest> activeTester;
private Set<SpotInstanceRequest> requests;
protected String provider = "aws-ec2";
protected String identity;
protected String credential;
protected String endpoint;
protected String apiversion;
private AWSRunningInstance instance;
private long start;
@BeforeClass
protected void setupCredentials() {
@ -98,83 +109,97 @@ public class SpotInstanceClientLiveTest {
ImmutableSet.<Module> of(new Log4JLoggingModule(), new JschSshClientModule()), overrides);
client = AWSEC2Client.class.cast(context.getProviderSpecificContext().getApi());
// TODO
// availableTester = new RetryablePredicate<SpotInstanceRequest>(new
// SpotInstanceAvailable(client), 60, 1,
// TimeUnit.SECONDS);
//
// deletedTester = new RetryablePredicate<SpotInstanceRequest>(new
// SpotInstanceDeleted(client), 60, 1, TimeUnit.SECONDS);
activeTester = new RetryablePredicate<SpotInstanceRequest>(new SpotInstanceRequestActive(client),
SPOT_DELAY_SECONDS, 1, 1, TimeUnit.SECONDS);
}
@Test
void testDescribe() {
void testDescribeSpotRequestsInRegion() {
for (String region : Region.DEFAULT_REGIONS) {
String string = client.getSpotInstanceServices().describeSpotInstanceRequestsInRegion(region);
assertNotNull(string);// TODO
SortedSet<SpotInstanceRequest> allResults = ImmutableSortedSet.<SpotInstanceRequest>of(SpotInstanceRequest.builder().id("foo")
.build());
SortedSet<SpotInstanceRequest> allResults = ImmutableSortedSet.copyOf(client.getSpotInstanceServices()
.describeSpotInstanceRequestsInRegion(region));
assertNotNull(allResults);
if (allResults.size() >= 1) {
SpotInstanceRequest request = allResults.last();
string = client.getSpotInstanceServices().describeSpotInstanceRequestsInRegion(region, request.getId());
assertNotNull(string);// TODO
SortedSet<SpotInstanceRequest> result = ImmutableSortedSet.of(SpotInstanceRequest.builder().id("foo")
.build());
SortedSet<SpotInstanceRequest> result = ImmutableSortedSet.copyOf(client.getSpotInstanceServices()
.describeSpotInstanceRequestsInRegion(region, request.getId()));
assertNotNull(result);
SpotInstanceRequest compare = result.last();
assertEquals(compare, request);
}
}
for (String region : client.getAvailabilityZoneAndRegionServices().describeRegions().keySet()) {
if (!region.equals(Region.US_EAST_1))
try {
client.getSpotInstanceServices().describeSpotInstanceRequestsInRegion(region);
assert false : "should be unsupported";
} catch (UnsupportedOperationException e) {
}
}
}
@Test
void testDescribeSpotPriceHistoryInRegion() {
for (final String region : Region.DEFAULT_REGIONS) {
Set<Spot> spots = client.getSpotInstanceServices().describeSpotPriceHistoryInRegion(region, from(new Date()));
assertNotNull(spots);
assert spots.size() > 0;
for (Spot spot : spots) {
assert spot.getSpotPrice() > 0 : spots;
assertEquals(spot.getRegion(), region);
assert in(ImmutableSet.of("Linux/UNIX", "SUSE Linux", "Windows")).apply(spot.getProductDescription()) : spot;
assert in(
ImmutableSet.of("c1.medium", "c1.xlarge", "m1.large", "m1.small", "m1.xlarge", "m2.2xlarge",
"m2.4xlarge", "m2.xlarge", "t1.micro")).apply(spot.getInstanceType()) : spot;
}
}
}
@Test(enabled = true)
void testCreateSpotInstance() {
String launchGroup = PREFIX + "1";
for (SpotInstanceRequest request : ImmutableSet.<SpotInstanceRequest> of())
// client.getSpotInstanceServices().describeSpotInstanceRequestsInRegion(null);
if (request.getLaunchGroup().equals(launchGroup))
client.getSpotInstanceServices().cancelSpotInstanceRequestsInRegion(null, request.getId());
String string = client.getSpotInstanceServices().requestSpotInstancesInRegion(
null,
null,
"TODO",
for (SpotInstanceRequest request : client.getSpotInstanceServices().describeSpotInstanceRequestsInRegion(
"us-west-1"))
if (launchGroup.equals(request.getLaunchGroup()))
client.getSpotInstanceServices().cancelSpotInstanceRequestsInRegion("us-west-1", request.getId());
start = System.currentTimeMillis();
requests = client.getSpotInstanceServices().requestSpotInstancesInRegion(
"us-west-1",
0.03f,
1,
0.01f,
RequestSpotInstancesOptions.Builder.launchSpecification(AWSRunInstancesOptions.Builder.asType("m1.small"))
.launchGroup(PREFIX));
assertNotNull(string);
LaunchSpecification.builder().instanceType(InstanceType.T1_MICRO).imageId("ami-595a0a1c").build(),
launchGroup(launchGroup).availabilityZoneGroup(launchGroup).validFrom(new Date())
.validUntil(new Date(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(SPOT_DELAY_SECONDS))));
assertNotNull(requests);
verifySpotInstance(request);
for (SpotInstanceRequest request : requests)
verifySpotInstance(request);
}
private void verifySpotInstance(SpotInstanceRequest request) {
assert availableTester.apply(request) : request;
String string = client.getSpotInstanceServices().describeSpotInstanceRequestsInRegion(null, request.getId());
assertNotNull(string);// TODO
SpotInstanceRequest oneResult = Iterables.getOnlyElement(ImmutableSet.of(SpotInstanceRequest.builder().id("foo")
.build()));
assertNotNull(oneResult);
assertEquals(oneResult, request);
// TODO: more
SpotInstanceRequest spot = refresh(request);
assertNotNull(spot);
assertEquals(spot, request);
assert activeTester.apply(request) : refresh(request);
System.out.println(System.currentTimeMillis() - start);
spot = refresh(request);
assert spot.getInstanceId() != null : spot;
instance = getOnlyElement(getOnlyElement(client.getInstanceServices().describeInstancesInRegion("us-west-1",
spot.getInstanceId())));
assertEquals(instance.getSpotInstanceRequestId(), spot.getId());
}
public SpotInstanceRequest refresh(SpotInstanceRequest request) {
return getOnlyElement(client.getSpotInstanceServices().describeSpotInstanceRequestsInRegion("us-west-1",
request.getId()));
}
public static final String PREFIX = System.getProperty("user.name") + "ec2";
@AfterTest
public void shutdown() {
if (request != null) {
client.getSpotInstanceServices().cancelSpotInstanceRequestsInRegion(request.getRegion(), request.getId());
assert deletedTester.apply(request) : request;
if (requests != null) {
for (SpotInstanceRequest request : requests)
client.getSpotInstanceServices().cancelSpotInstanceRequestsInRegion(request.getRegion(), request.getId());
// assert deletedTester.apply(request) : request;
}
if (instance != null) {
client.getInstanceServices().terminateInstancesInRegion("us-west-1", instance.getId());
}
context.close();
}

View File

@ -53,7 +53,7 @@ import com.google.inject.Guice;
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "RunInstancesResponseHandlerTest")
public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest {
public class AWSRunInstancesResponseHandlerTest extends BaseEC2HandlerTest {
private DateService dateService;

View File

@ -0,0 +1,69 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com("
*
* ====================================================================
* 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.util.Set;
import org.jclouds.aws.ec2.domain.Spot;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.location.Region;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.AbstractModule;
/**
* Tests behavior of {@code DescribeSpotPriceHistoryResponseHandler}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "DescribeSpotPriceHistoryResponseHandlerTest")
public class DescribeSpotPriceHistoryResponseHandlerTest extends BaseHandlerTest {
public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream("/describe_spot_price_history.xml");
Set<Spot> expected = ImmutableSet.of(
Spot.builder().region("us-west-1").instanceType("t1.micro").productDescription("SUSE Linux").spotPrice(0.013f)
.timestamp(new SimpleDateFormatDateService().iso8601DateParse("2011-03-07T12:17:19.000Z")).build(),
Spot.builder().region("us-west-1").instanceType("m1.large").productDescription("Linux/UNIX").spotPrice(0.119f)
.timestamp(new SimpleDateFormatDateService().iso8601DateParse("2011-03-07T16:29:16.000Z")).build(),
Spot.builder().region("us-west-1").instanceType("t1.micro").productDescription("Windows").spotPrice(0.013f)
.timestamp(new SimpleDateFormatDateService().iso8601DateParse("2011-03-07T17:56:54.000Z")).build()
);
Set<Spot> result = factory.create(injector.createChildInjector(new AbstractModule(){
@Override
protected void configure() {
bindConstant().annotatedWith(Region.class).to("us-west-1");
}
}).getInstance(DescribeSpotPriceHistoryResponseHandler.class)).parse(is);
assertEquals(result, expected);
}
}

View File

@ -0,0 +1,102 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. .info@cloudconscious.com("
*
* ====================================================================
* 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.LaunchSpecification;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
import org.jclouds.date.DateService;
import org.jclouds.date.internal.SimpleDateFormatDateService;
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.inject.AbstractModule;
import com.google.inject.Guice;
/**
* Tests behavior of {@code SpotInstanceRequestHandler}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "SpotInstanceRequestHandlerTest")
public class SpotInstanceRequestHandlerTest 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");
}
});
factory = injector.getInstance(ParseSax.Factory.class);
dateService = injector.getInstance(DateService.class);
assert dateService != null;
}
public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream("/request_spot_instances-ebs.xml");
SpotInstanceRequest expected = SpotInstanceRequest
.builder()
.region("us-east-1")
.id("sir-228e6406")
.spotPrice(0.001f)
.type(SpotInstanceRequest.Type.ONE_TIME)
.state(SpotInstanceRequest.State.OPEN)
.launchSpecification(
LaunchSpecification.builder().imageId("ami-595a0a1c").groupId("default").instanceType("m1.large")
.mapNewVolumeToDevice("/dev/sda1", 1, true)
.mapEBSSnapshotToDevice("/dev/sda2", "snap-1ea27576", 1, true)
.mapEphemeralDeviceToDevice("/dev/sda3", "vre1").monitoringEnabled(false).build())
.createTime(new SimpleDateFormatDateService().iso8601DateParse("2011-03-08T03:30:36.000Z"))
.productDescription("Linux/UNIX").build();
SpotInstanceRequestHandler handler = injector.getInstance(SpotInstanceRequestHandler.class);
addDefaultRegionToHandler(handler);
SpotInstanceRequest 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.<Object> of()).atLeastOnce();
replay(request);
handler.setContext(request);
}
}

View File

@ -0,0 +1,95 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. .info@cloudconscious.com("
*
* ====================================================================
* 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 java.util.Set;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
import org.jclouds.date.DateService;
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.inject.AbstractModule;
import com.google.inject.Guice;
/**
* Tests behavior of {@code SpotInstancesRequestsResponseHandler}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "SpotInstancesRequestsResponseHandlerTest")
public class SpotInstancesRequestsResponseHandlerTest 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");
}
});
factory = injector.getInstance(ParseSax.Factory.class);
dateService = injector.getInstance(DateService.class);
assert dateService != null;
}
public void testDescribe() {
InputStream is = getClass().getResourceAsStream("/describe_spot_instance_requests.xml");
SpotInstanceRequestsResponseHandler handler = injector
.getInstance(SpotInstanceRequestsResponseHandler.class);
addDefaultRegionToHandler(handler);
Set<SpotInstanceRequest> result = factory.create(handler).parse(is);
assertEquals(result.size(), 18);
}
public void testRequest() {
InputStream is = getClass().getResourceAsStream("/request_spot_instances.xml");
SpotInstanceRequestsResponseHandler handler = injector
.getInstance(SpotInstanceRequestsResponseHandler.class);
addDefaultRegionToHandler(handler);
Set<SpotInstanceRequest> result = factory.create(handler).parse(is);
assertEquals(result.size(), 3);
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(ImmutableList.<Object> of()).atLeastOnce();
replay(request);
handler.setContext(request);
}
}

View File

@ -0,0 +1,413 @@
<DescribeSpotInstanceRequestsResponse xmlns="http://ec2.amazonaws.com/doc/2010-11-15/">
<requestId>7c4dd2bd-106d-4cd3-987c-35ee819180a6</requestId>
<spotInstanceRequestSet>
<item>
<spotInstanceRequestId>sir-067a4805</spotInstanceRequestId>
<spotPrice>0.040000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:13:07.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-aa67d410</spotInstanceRequestId>
<spotPrice>0.040000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:13:57.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-32e32810</spotInstanceRequestId>
<spotPrice>0.010000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:15:52.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-46a36210</spotInstanceRequestId>
<spotPrice>0.010000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<validUntil>2011-03-07T20:20:00.000Z</validUntil>
<launchGroup>foo</launchGroup>
<availabilityZoneGroup>azfoo</availabilityZoneGroup>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<keyName>default</keyName>
<groupSet>
<item>
<groupId>quick-start-1</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>true</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:18:25.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-91780010</spotInstanceRequestId>
<spotPrice>0.010000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<validUntil>2011-03-07T20:20:00.000Z</validUntil>
<launchGroup>foo</launchGroup>
<availabilityZoneGroup>azfoo</availabilityZoneGroup>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<keyName>default</keyName>
<groupSet>
<item>
<groupId>quick-start-1</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>true</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:18:25.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-6f1fa605</spotInstanceRequestId>
<spotPrice>0.001000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:19:27.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-a33eee10</spotInstanceRequestId>
<spotPrice>0.001000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:21:16.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-aa690410</spotInstanceRequestId>
<spotPrice>0.001000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:21:52.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-99ba4e06</spotInstanceRequestId>
<spotPrice>0.010000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<validUntil>2011-03-07T20:26:00.000Z</validUntil>
<launchGroup>doo</launchGroup>
<availabilityZoneGroup>dooo</availabilityZoneGroup>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<keyName>default</keyName>
<groupSet>
<item>
<groupId>quick-start-1</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>true</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:24:30.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-a617c406</spotInstanceRequestId>
<spotPrice>0.010000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<validUntil>2011-03-07T20:26:00.000Z</validUntil>
<launchGroup>doo</launchGroup>
<availabilityZoneGroup>dooo</availabilityZoneGroup>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<keyName>default</keyName>
<groupSet>
<item>
<groupId>quick-start-1</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>true</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:24:30.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-2147a405</spotInstanceRequestId>
<spotPrice>0.001000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:25:19.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-c441c805</spotInstanceRequestId>
<spotPrice>0.001000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:29:09.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-4658fe10</spotInstanceRequestId>
<spotPrice>0.010000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<validUntil>2011-03-07T21:10:00.000Z</validUntil>
<launchGroup>check3</launchGroup>
<availabilityZoneGroup>check3</availabilityZoneGroup>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<keyName>default</keyName>
<groupSet>
<item>
<groupId>quick-start-1</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:31:34.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-49a3ce10</spotInstanceRequestId>
<spotPrice>0.010000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<validUntil>2011-03-07T21:10:00.000Z</validUntil>
<launchGroup>check3</launchGroup>
<availabilityZoneGroup>check3</availabilityZoneGroup>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<keyName>default</keyName>
<groupSet>
<item>
<groupId>quick-start-1</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:31:34.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-91b30610</spotInstanceRequestId>
<spotPrice>0.010000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<validUntil>2011-03-07T21:10:00.000Z</validUntil>
<launchGroup>check3</launchGroup>
<availabilityZoneGroup>check3</availabilityZoneGroup>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<keyName>default</keyName>
<groupSet>
<item>
<groupId>quick-start-1</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:31:34.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-d8561606</spotInstanceRequestId>
<spotPrice>0.001000</spotPrice>
<type>one-time</type>
<state>cancelled</state>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T20:34:10.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-4cdaa406</spotInstanceRequestId>
<spotPrice>0.001000</spotPrice>
<type>persistent</type>
<state>cancelled</state>
<validUntil>2011-03-07T22:25:00.000Z</validUntil>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<keyName>default</keyName>
<groupSet>
<item>
<groupId>quick-start-1</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T22:23:19.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-e19f2206</spotInstanceRequestId>
<spotPrice>0.001000</spotPrice>
<type>one-time</type>
<state>open</state>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping/>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-07T22:32:50.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
</spotInstanceRequestSet>
</DescribeSpotInstanceRequestsResponse>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<DescribeSpotPriceHistoryResponse xmlns="http://ec2.amazonaws.com/doc/2010-11-15/">
<requestId>99777a75-2a2b-4296-a305-650c442d2d63</requestId>
<spotPriceHistorySet>
<item>
<instanceType>t1.micro</instanceType>
<productDescription>SUSE Linux</productDescription>
<spotPrice>0.013000</spotPrice>
<timestamp>2011-03-07T12:17:19.000Z</timestamp>
</item>
<item>
<instanceType>m1.large</instanceType>
<productDescription>Linux/UNIX</productDescription>
<spotPrice>0.119000</spotPrice>
<timestamp>2011-03-07T16:29:16.000Z</timestamp>
</item>
<item>
<instanceType>t1.micro</instanceType>
<productDescription>Windows</productDescription>
<spotPrice>0.013000</spotPrice>
<timestamp>2011-03-07T17:56:54.000Z</timestamp>
</item>
</spotPriceHistorySet>
</DescribeSpotPriceHistoryResponse>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<RequestSpotInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2010-11-15/">
<requestId>02401e8e-a4f5-4285-8ea8-6d742fbaadd8</requestId>
<spotInstanceRequestSet>
<item>
<spotInstanceRequestId>sir-228e6406</spotInstanceRequestId>
<spotPrice>0.001000</spotPrice>
<type>one-time</type>
<state>open</state>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instanceType>m1.large</instanceType>
<blockDeviceMapping>
<item>
<deviceName>/dev/sda1</deviceName>
<ebs>
<volumeSize>1</volumeSize>
<deleteOnTermination>true</deleteOnTermination>
</ebs>
</item>
<item>
<deviceName>/dev/sda3</deviceName>
<virtualName>vre1</virtualName>
</item>
<item>
<deviceName>/dev/sda2</deviceName>
<ebs>
<snapshotId>snap-1ea27576</snapshotId>
<volumeSize>1</volumeSize>
<deleteOnTermination>true</deleteOnTermination>
</ebs>
</item>
</blockDeviceMapping>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-08T03:30:36.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
</spotInstanceRequestSet>
</RequestSpotInstancesResponse>

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<RequestSpotInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2010-11-15/">
<requestId>2ffc645f-6835-4d23-bd18-f6f53c253067</requestId>
<spotInstanceRequestSet>
<item>
<spotInstanceRequestId>sir-7c74f805</spotInstanceRequestId>
<spotPrice>0.001000</spotPrice>
<type>one-time</type>
<state>open</state>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping>
<item>
<deviceName>/dev/sda1</deviceName>
<ebs>
<volumeSize>120</volumeSize>
<deleteOnTermination>true</deleteOnTermination>
</ebs>
</item>
</blockDeviceMapping>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-08T02:36:32.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-78ca7605</spotInstanceRequestId>
<spotPrice>0.001000</spotPrice>
<type>one-time</type>
<state>open</state>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping>
<item>
<deviceName>/dev/sda1</deviceName>
<ebs>
<volumeSize>120</volumeSize>
<deleteOnTermination>true</deleteOnTermination>
</ebs>
</item>
</blockDeviceMapping>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-08T02:36:32.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
<item>
<spotInstanceRequestId>sir-7e0f6005</spotInstanceRequestId>
<spotPrice>0.001000</spotPrice>
<type>one-time</type>
<state>open</state>
<launchSpecification>
<imageId>ami-595a0a1c</imageId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instanceType>t1.micro</instanceType>
<blockDeviceMapping>
<item>
<deviceName>/dev/sda1</deviceName>
<ebs>
<volumeSize>120</volumeSize>
<deleteOnTermination>true</deleteOnTermination>
</ebs>
</item>
</blockDeviceMapping>
<monitoring>
<enabled>false</enabled>
</monitoring>
</launchSpecification>
<createTime>2011-03-08T02:36:32.000Z</createTime>
<productDescription>Linux/UNIX</productDescription>
</item>
</spotInstanceRequestSet>
</RequestSpotInstancesResponse>