Merge branch 'master' of git@github.com:jclouds/jclouds

* 'master' of git@github.com:jclouds/jclouds:
  changed single instance spot syntax to only return a single value
  fix for duplicate key exception
  Issue 308 finished provider api and testing of ec2 spot instances
  started code for ec2 spot instances
This commit is contained in:
Adrian Cole 2011-03-08 07:44:29 -08:00
commit 79a5edd1e2
41 changed files with 3848 additions and 125 deletions

View File

@ -21,6 +21,7 @@ package org.jclouds.ec2.binders;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
@ -34,11 +35,22 @@ import org.jclouds.rest.Binder;
*/ */
@Singleton @Singleton
public class IfNotNullBindAvailabilityZoneToFormParam implements Binder { public class IfNotNullBindAvailabilityZoneToFormParam implements Binder {
private final String param;
@Inject
protected IfNotNullBindAvailabilityZoneToFormParam() {
this("Placement.AvailabilityZone");
}
protected IfNotNullBindAvailabilityZoneToFormParam(String param) {
this.param = param;
}
@Override @Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) { public <R extends HttpRequest> R bindToRequest(R request, Object input) {
if (input != null) { if (input != null) {
checkArgument(input instanceof String, "this binder is only valid for AvailabilityZone!"); checkArgument(input instanceof String, "this binder is only valid for String!");
return ModifyRequest.addFormParam(request, "Placement.AvailabilityZone", (String) input); return ModifyRequest.addFormParam(request, param, (String) input);
} }
return request; return request;
} }

View File

@ -66,8 +66,8 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.ImmutableMultimap.Builder;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
/** /**
@ -177,12 +177,12 @@ public class EC2ComputeService extends BaseComputeService {
@Override @Override
public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) { public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
Set<? extends NodeMetadata> deadOnes = super.destroyNodesMatching(filter); Set<? extends NodeMetadata> deadOnes = super.destroyNodesMatching(filter);
Builder<String, String> regionGroups = ImmutableMap.<String, String> builder(); Builder<String, String> regionGroups = ImmutableMultimap.<String, String> builder();
for (NodeMetadata nodeMetadata : deadOnes) { for (NodeMetadata nodeMetadata : deadOnes) {
if (nodeMetadata.getGroup() != null) if (nodeMetadata.getGroup() != null)
regionGroups.put(AWSUtils.parseHandle(nodeMetadata.getId())[0], nodeMetadata.getGroup()); regionGroups.put(AWSUtils.parseHandle(nodeMetadata.getId())[0], nodeMetadata.getGroup());
} }
for (Entry<String, String> regionGroup : regionGroups.build().entrySet()) { for (Entry<String, String> regionGroup : regionGroups.build().entries()) {
cleanUpIncidentalResources(regionGroup); cleanUpIncidentalResources(regionGroup);
} }
return deadOnes; return deadOnes;

View File

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

View File

@ -30,7 +30,64 @@ import org.jclouds.util.Preconditions2;
* *
* @author Lili Nadar * @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 deviceName;
private final String virtualName; private final String virtualName;
private final String snapshotId; private final String snapshotId;
@ -43,14 +100,14 @@ public class BlockDeviceMapping {
private static final Integer VOLUME_SIZE_MAX_VALUE = 1000; private static final Integer VOLUME_SIZE_MAX_VALUE = 1000;
BlockDeviceMapping(String deviceName, @Nullable String virtualName, @Nullable String snapshotId, 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"); checkNotNull(deviceName, "deviceName cannot be null");
Preconditions2.checkNotEmpty(deviceName, "the deviceName must be non-empty"); Preconditions2.checkNotEmpty(deviceName, "the deviceName must be non-empty");
if (sizeInGib != null) { if (sizeInGib != null) {
checkArgument((sizeInGib >= VOLUME_SIZE_MIN_VALUE && sizeInGib <= VOLUME_SIZE_MAX_VALUE), String.format( checkArgument((sizeInGib >= VOLUME_SIZE_MIN_VALUE && sizeInGib <= VOLUME_SIZE_MAX_VALUE),
"Size in Gib must be between %s and %s GB", VOLUME_SIZE_MIN_VALUE, 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.deviceName = deviceName;
this.virtualName = virtualName; this.virtualName = virtualName;
@ -142,13 +199,13 @@ public class BlockDeviceMapping {
@Override @Override
public String toString() { public String toString() {
return "[deviceName=" + deviceName + ", virtualName=" + virtualName + ", snapshotId=" + snapshotId 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 static class MapEBSSnapshotToDevice extends BlockDeviceMapping {
public MapEBSSnapshotToDevice(String deviceName, String snapshotId, @Nullable Integer sizeInGib, public MapEBSSnapshotToDevice(String deviceName, String snapshotId, @Nullable Integer sizeInGib,
@Nullable Boolean deleteOnTermination) { @Nullable Boolean deleteOnTermination) {
super(deviceName, null, snapshotId, sizeInGib, null, deleteOnTermination); super(deviceName, null, snapshotId, sizeInGib, null, deleteOnTermination);
checkNotNull(snapshotId, "snapshotId cannot be null"); checkNotNull(snapshotId, "snapshotId cannot be null");
Preconditions2.checkNotEmpty(snapshotId, "the snapshotId must be non-empty"); Preconditions2.checkNotEmpty(snapshotId, "the snapshotId must be non-empty");
@ -175,4 +232,9 @@ public class BlockDeviceMapping {
super(deviceName, null, null, null, true, null); 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; return this;
} }
String getKeyName() {
return getFirstFormOrNull("KeyName");
}
/** /**
* Attach multiple security groups * Attach multiple security groups
*/ */
@ -88,10 +84,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return withSecurityGroups(securityGroup); return withSecurityGroups(securityGroup);
} }
String getSecurityGroup() {
return getFirstFormOrNull("SecurityGroup.1");
}
/** /**
* Unencoded data * Unencoded data
*/ */
@ -103,10 +95,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return this; return this;
} }
String getUserData() {
return getFirstFormOrNull("UserData");
}
/** /**
* Specifies the instance type. default small; * Specifies the instance type. default small;
*/ */
@ -115,10 +103,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return this; return this;
} }
String getType() {
return getFirstFormOrNull("InstanceType");
}
/** /**
* The ID of the kernel with which to launch the instance. * The ID of the kernel with which to launch the instance.
*/ */
@ -127,10 +111,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return this; return this;
} }
String getKernelId() {
return getFirstFormOrNull("KernelId");
}
/** /**
* The ID of the RAM disk with which to launch the instance. Some kernels require additional * 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 * 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; return this;
} }
String getRamdiskId() {
return getFirstFormOrNull("RamdiskId");
}
/** /**
* Specifies the Block Device Mapping for the instance * Specifies the Block Device Mapping for the instance
* *
*/ */
public RunInstancesOptions withBlockDeviceMappings(Set<? extends BlockDeviceMapping> mappings) { public RunInstancesOptions withBlockDeviceMappings(Set<? extends BlockDeviceMapping> mappings) {
int i = 1; int i = 1;
for (BlockDeviceMapping mapping : checkNotNull(mappings, "mappings")) { for (BlockDeviceMapping mapping : checkNotNull(mappings, "mappings")) {
@ -161,15 +136,14 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
if (mapping.getEbsSnapshotId() != null) if (mapping.getEbsSnapshotId() != null)
formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.SnapshotId", i), mapping.getEbsSnapshotId()); formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.SnapshotId", i), mapping.getEbsSnapshotId());
if (mapping.getEbsVolumeSize() != null) if (mapping.getEbsVolumeSize() != null)
formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.VolumeSize", i), String.valueOf(mapping formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.VolumeSize", i),
.getEbsVolumeSize())); String.valueOf(mapping.getEbsVolumeSize()));
if (mapping.getEbsNoDevice() != null) if (mapping.getEbsNoDevice() != null)
formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.NoDevice", i), String.valueOf(mapping formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.NoDevice", i),
.getEbsNoDevice())); String.valueOf(mapping.getEbsNoDevice()));
if (mapping.getEbsDeleteOnTermination() != null) if (mapping.getEbsDeleteOnTermination() != null)
formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.DeleteOnTermination", i), String formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.DeleteOnTermination", i),
.valueOf(mapping.getEbsDeleteOnTermination())); String.valueOf(mapping.getEbsDeleteOnTermination()));
i++; i++;
} }
return this; return this;

View File

@ -26,8 +26,9 @@ import java.util.Set;
import org.jclouds.http.options.BaseHttpRequestOptions; import org.jclouds.http.options.BaseHttpRequestOptions;
import com.google.common.base.Predicate; 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.Iterables;
import com.google.common.collect.Sets;
/** /**
* *
@ -51,7 +52,7 @@ public class BaseEC2RequestOptions extends BaseHttpRequestOptions {
} }
protected Set<String> getFormValuesWithKeysPrefixedBy(final String prefix) { 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>() { for (String key : Iterables.filter(formParameters.keySet(), new Predicate<String>() {
public boolean apply(String input) { 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); TemplateBuilder defaultTemplate = createMock(TemplateBuilder.class);
expect(templateBuilderProvider.get()).andReturn(defaultTemplate); expect(templateBuilderProvider.get()).andReturn(defaultTemplate);
expect(defaultTemplate.options(options)).andReturn(defaultTemplate); expect(defaultTemplate.options(from)).andReturn(defaultTemplate);
expect(defaultTemplate.build()).andReturn(null); expect(defaultTemplate.build()).andReturn(null);
expect(optionsProvider.get()).andReturn(from).atLeastOnce(); expect(optionsProvider.get()).andReturn(from).atLeastOnce();

View File

@ -24,6 +24,7 @@ import org.jclouds.aws.ec2.services.AWSInstanceAsyncClient;
import org.jclouds.aws.ec2.services.AWSKeyPairAsyncClient; import org.jclouds.aws.ec2.services.AWSKeyPairAsyncClient;
import org.jclouds.aws.ec2.services.MonitoringAsyncClient; import org.jclouds.aws.ec2.services.MonitoringAsyncClient;
import org.jclouds.aws.ec2.services.PlacementGroupAsyncClient; import org.jclouds.aws.ec2.services.PlacementGroupAsyncClient;
import org.jclouds.aws.ec2.services.SpotInstanceAsyncClient;
import org.jclouds.ec2.EC2AsyncClient; import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
@ -67,4 +68,10 @@ public interface AWSEC2AsyncClient extends EC2AsyncClient {
@Delegate @Delegate
@Override @Override
AWSKeyPairAsyncClient getKeyPairServices(); AWSKeyPairAsyncClient getKeyPairServices();
/**
* Provides asynchronous access to SpotInstance services.
*/
@Delegate
SpotInstanceAsyncClient getSpotInstanceServices();
} }

View File

@ -26,6 +26,7 @@ import org.jclouds.aws.ec2.services.AWSInstanceClient;
import org.jclouds.aws.ec2.services.AWSKeyPairClient; import org.jclouds.aws.ec2.services.AWSKeyPairClient;
import org.jclouds.aws.ec2.services.MonitoringClient; import org.jclouds.aws.ec2.services.MonitoringClient;
import org.jclouds.aws.ec2.services.PlacementGroupClient; import org.jclouds.aws.ec2.services.PlacementGroupClient;
import org.jclouds.aws.ec2.services.SpotInstanceClient;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.EC2Client;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
@ -70,4 +71,10 @@ public interface AWSEC2Client extends EC2Client {
@Delegate @Delegate
@Override @Override
AWSKeyPairClient getKeyPairServices(); AWSKeyPairClient getKeyPairServices();
/**
* Provides synchronous access to SpotInstance services.
*/
@Delegate
SpotInstanceClient getSpotInstanceServices();
} }

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

@ -0,0 +1,40 @@
/**
*
* 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 javax.inject.Singleton;
import org.jclouds.aws.util.AWSUtils;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
/**
* Binds the String [] to form parameters named with SpotInstanceRequestId.index
*
* @author Adrian Cole
*/
@Singleton
public class BindSpotInstanceRequestIdsToIndexedFormParams implements Binder {
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
return AWSUtils.indexStringArrayToFormValuesWithPrefix(request, "SpotInstanceRequestId", input);
}
}

View File

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

View File

@ -37,6 +37,8 @@ import org.jclouds.aws.ec2.services.MonitoringAsyncClient;
import org.jclouds.aws.ec2.services.MonitoringClient; import org.jclouds.aws.ec2.services.MonitoringClient;
import org.jclouds.aws.ec2.services.PlacementGroupAsyncClient; import org.jclouds.aws.ec2.services.PlacementGroupAsyncClient;
import org.jclouds.aws.ec2.services.PlacementGroupClient; import org.jclouds.aws.ec2.services.PlacementGroupClient;
import org.jclouds.aws.ec2.services.SpotInstanceAsyncClient;
import org.jclouds.aws.ec2.services.SpotInstanceClient;
import org.jclouds.ec2.EC2AsyncClient; import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.EC2Client;
import org.jclouds.ec2.config.EC2RestClientModule; import org.jclouds.ec2.config.EC2RestClientModule;
@ -82,6 +84,7 @@ public class AWSEC2RestClientModule extends EC2RestClientModule<AWSEC2Client, AW
.put(WindowsClient.class, WindowsAsyncClient.class)// .put(WindowsClient.class, WindowsAsyncClient.class)//
.put(AvailabilityZoneAndRegionClient.class, AvailabilityZoneAndRegionAsyncClient.class)// .put(AvailabilityZoneAndRegionClient.class, AvailabilityZoneAndRegionAsyncClient.class)//
.put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)// .put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)//
.put(SpotInstanceClient.class, SpotInstanceAsyncClient.class)//
.build(); .build();
public AWSEC2RestClientModule() { public AWSEC2RestClientModule() {

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

@ -0,0 +1,406 @@
/**
*
* 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;
import com.google.common.base.CaseFormat;
/**
*
* @author Adrian Cole
*/
public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String region;
private String availabilityZoneGroup;
private Date createTime;
private String faultCode;
private String faultMessage;
private String instanceId;
private String launchGroup;
private LaunchSpecification launchSpecification;
private String productDescription;
private String id;
private float spotPrice;
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;
}
public Builder availabilityZoneGroup(String availabilityZoneGroup) {
this.availabilityZoneGroup = availabilityZoneGroup;
return this;
}
public Builder createTime(Date createTime) {
this.createTime = createTime;
return this;
}
public Builder faultCode(String faultCode) {
this.faultCode = faultCode;
return this;
}
public Builder faultMessage(String faultMessage) {
this.faultMessage = faultMessage;
return this;
}
public Builder instanceId(String instanceId) {
this.instanceId = instanceId;
return this;
}
public Builder launchGroup(String launchGroup) {
this.launchGroup = launchGroup;
return this;
}
public Builder launchSpecification(LaunchSpecification launchSpecification) {
this.launchSpecification = launchSpecification;
return this;
}
public Builder productDescription(String productDescription) {
this.productDescription = productDescription;
return this;
}
public Builder id(String id) {
this.id = id;
return this;
}
public Builder spotPrice(float spotPrice) {
this.spotPrice = spotPrice;
return this;
}
public Builder state(State state) {
this.state = state;
return this;
}
public Builder type(Type type) {
this.type = type;
return this;
}
public Builder validFrom(Date validFrom) {
this.validFrom = validFrom;
return this;
}
public Builder validUntil(Date validUntil) {
this.validUntil = validUntil;
return this;
}
public SpotInstanceRequest build() {
return new SpotInstanceRequest(region, availabilityZoneGroup, createTime, faultCode, faultMessage, instanceId,
launchGroup, launchSpecification, productDescription, id, spotPrice, state, type, validFrom, validUntil);
}
}
public enum Type {
ONE_TIME, PERSISTENT, UNRECOGNIZED;
public String value() {
return (CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name()));
}
@Override
public String toString() {
return value();
}
public static Type fromValue(String type) {
try {
return valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(type, "type")));
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}
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 faultCode;
private final String faultMessage;
private final String instanceId;
private final String launchGroup;
private final LaunchSpecification launchSpecification;
private final String productDescription;
private final String id;
private final float spotPrice;
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 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.faultCode = faultCode;
this.faultMessage = faultMessage;
this.instanceId = instanceId;
this.launchGroup = launchGroup;
this.launchSpecification = launchSpecification;
this.productDescription = productDescription;
this.id = checkNotNull(id, "id");
this.spotPrice = spotPrice;
this.state = checkNotNull(state, "state");
this.type = checkNotNull(type, "type");
this.validFrom = validFrom;
this.validUntil = validUntil;
}
/**
* @return spot instance requests are in a region
*/
public String getRegion() {
return region;
}
public String getAvailabilityZoneGroup() {
return availabilityZoneGroup;
}
public Date getCreateTime() {
return createTime;
}
public String getFaultCode() {
return faultCode;
}
public String getFaultMessage() {
return faultMessage;
}
public String getInstanceId() {
return instanceId;
}
public String getLaunchGroup() {
return launchGroup;
}
public LaunchSpecification getLaunchSpecification() {
return launchSpecification;
}
public String getProductDescription() {
return productDescription;
}
public String getId() {
return id;
}
public float getSpotPrice() {
return spotPrice;
}
public State getState() {
return state;
}
public Type getType() {
return type;
}
public Date getValidFrom() {
return validFrom;
}
public Date getValidUntil() {
return validUntil;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((availabilityZoneGroup == null) ? 0 : availabilityZoneGroup.hashCode());
result = prime * result + ((createTime == null) ? 0 : createTime.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());
result = prime * result + ((launchSpecification == null) ? 0 : launchSpecification.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 + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((validFrom == null) ? 0 : validFrom.hashCode());
result = prime * result + ((validUntil == null) ? 0 : validUntil.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;
SpotInstanceRequest other = (SpotInstanceRequest) obj;
if (availabilityZoneGroup == null) {
if (other.availabilityZoneGroup != null)
return false;
} else if (!availabilityZoneGroup.equals(other.availabilityZoneGroup))
return false;
if (createTime == null) {
if (other.createTime != null)
return false;
} else if (!createTime.equals(other.createTime))
return false;
if (faultCode == null) {
if (other.faultCode != null)
return false;
} 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)
return false;
} else if (!id.equals(other.id))
return false;
if (instanceId == null) {
if (other.instanceId != null)
return false;
} else if (!instanceId.equals(other.instanceId))
return false;
if (launchGroup == null) {
if (other.launchGroup != null)
return false;
} else if (!launchGroup.equals(other.launchGroup))
return false;
if (launchSpecification == null) {
if (other.launchSpecification != null)
return false;
} else if (!launchSpecification.equals(other.launchSpecification))
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 (type != other.type)
return false;
if (validFrom == null) {
if (other.validFrom != null)
return false;
} else if (!validFrom.equals(other.validFrom))
return false;
if (validUntil == null) {
if (other.validUntil != null)
return false;
} else if (!validUntil.equals(other.validUntil))
return false;
return true;
}
@Override
public String toString() {
return "[region=" + region + ", id=" + id + ", spotPrice=" + spotPrice + ", state=" + state
+ ", availabilityZoneGroup=" + availabilityZoneGroup + ", createTime=" + createTime + ", faultCode="
+ faultCode + ", type=" + type + ", instanceId=" + instanceId + ", launchGroup=" + launchGroup
+ ", launchSpecification=" + launchSpecification + ", productDescription=" + productDescription
+ ", validFrom=" + validFrom + ", validUntil=" + validUntil + "]";
}
@Override
public int compareTo(SpotInstanceRequest arg0) {
return createTime.compareTo(arg0.createTime);
}
}

View File

@ -0,0 +1,119 @@
/**
*
* 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.options;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Date;
import org.jclouds.date.DateService;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.ec2.options.internal.BaseEC2RequestOptions;
/**
* Contains options supported in the Form API for the DescribeSpotPriceHistory operation. <h2>
* Usage</h2> The recommended way to instantiate a DescribeSpotPriceHistoryOptions object is to
* statically import DescribeSpotPriceHistoryOptions.Builder.* and invoke a static creation method
* followed by an instance mutator (if needed):
* <p/>
* <code>
* import static org.jclouds.aws.ec2.options.DescribeSpotPriceHistoryOptions.Builder.*
* <p/>
* AWSEC2Client client = // get connection
* history = client.getSpotInstanceServices().describeSpotPriceHistoryInRegion(from(yesterday).instanceType("m1.small"));
* <code>
*
* @author Adrian Cole
* @see <a href=
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-form-DescribeSpotPriceHistory.html"
* />
*/
public class DescribeSpotPriceHistoryOptions extends BaseEC2RequestOptions {
public static final DescribeSpotPriceHistoryOptions NONE = new DescribeSpotPriceHistoryOptions();
private static final DateService service = new SimpleDateFormatDateService();
/**
* Start date and time of the Spot Instance price history data.
*/
public DescribeSpotPriceHistoryOptions from(Date start) {
formParameters.put("StartTime", service.iso8601DateFormat(checkNotNull(start, "start")));
return this;
}
/**
* End date and time of the Spot Instance price history data.
*/
public DescribeSpotPriceHistoryOptions to(Date end) {
formParameters.put("EndTime", service.iso8601DateFormat(checkNotNull(end, "end")));
return this;
}
/**
* Specifies the instance type to return.
*/
public DescribeSpotPriceHistoryOptions instanceType(String type) {
formParameters.put("InstanceType.1", checkNotNull(type, "type"));
return this;
}
/**
* The description of the AMI.
*/
public DescribeSpotPriceHistoryOptions productDescription(String description) {
formParameters.put("ProductDescription", checkNotNull(description, "description"));
return this;
}
public static class Builder {
/**
* @see DescribeSpotPriceHistoryOptions#from
*/
public static DescribeSpotPriceHistoryOptions from(Date start) {
DescribeSpotPriceHistoryOptions options = new DescribeSpotPriceHistoryOptions();
return options.from(start);
}
/**
* @see DescribeSpotPriceHistoryOptions#to
*/
public static DescribeSpotPriceHistoryOptions to(Date end) {
DescribeSpotPriceHistoryOptions options = new DescribeSpotPriceHistoryOptions();
return options.to(end);
}
/**
* @see DescribeSpotPriceHistoryOptions#instanceType(InstanceType)
*/
public static DescribeSpotPriceHistoryOptions instanceType(String instanceType) {
DescribeSpotPriceHistoryOptions options = new DescribeSpotPriceHistoryOptions();
return options.instanceType(instanceType);
}
/**
* @see DescribeSpotPriceHistoryOptions#productDescription(String)
*/
public static DescribeSpotPriceHistoryOptions productDescription(String description) {
DescribeSpotPriceHistoryOptions options = new DescribeSpotPriceHistoryOptions();
return options.productDescription(description);
}
}
}

View File

@ -0,0 +1,142 @@
/**
*
* 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 validUntil in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.options;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Date;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
import org.jclouds.date.DateService;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.ec2.options.internal.BaseEC2RequestOptions;
/**
* Contains options supported in the Form API for the RequestSpotInstances operation. <h2>
* Usage</h2> The recommended way validUntil instantiate a RequestSpotInstancesOptions object is
* validUntil statically import RequestSpotInstancesOptions.Builder.* and invoke a static creation
* method followed by an instance mutator (if needed):
* <p/>
* <code>
* import static org.jclouds.aws.ec2.options.RequestSpotInstancesOptions.Builder.*
* <p/>
* AWSEC2Client client = // get connection
* history = client.getSpotInstanceServices().requestSpotInstancesInRegion("us-east-1",validFrom(yesterday).type("m1.small"));
* <code>
*
* @author Adrian Cole
* @see <a href=
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-form-RequestSpotInstances.html"
* />
*/
public class RequestSpotInstancesOptions extends BaseEC2RequestOptions {
public static final RequestSpotInstancesOptions NONE = new RequestSpotInstancesOptions();
private static final DateService service = new SimpleDateFormatDateService();
/**
* Start date of the request. If this is a one-time request, the request becomes active at this
* date and time and remains active until all instances launch, the request expires, or the
* request is canceled. If the request is persistent, the request becomes active at this date and
* time and remains active until it expires or is canceled.
*/
public RequestSpotInstancesOptions validFrom(Date start) {
formParameters.put("ValidFrom", service.iso8601DateFormat(checkNotNull(start, "start")));
return this;
}
/**
* End date of the request. If this is a one-time request, the request remains active until all
* instances launch, the request is canceled, or this date is reached. If the request is
* persistent, it remains active until it is canceled or this date and time is reached.
*/
public RequestSpotInstancesOptions validUntil(Date end) {
formParameters.put("ValidUntil", service.iso8601DateFormat(checkNotNull(end, "end")));
return this;
}
/**
* Specifies the Spot Instance type.
*/
public RequestSpotInstancesOptions type(SpotInstanceRequest.Type type) {
formParameters.put("Type", checkNotNull(type, "type").toString());
return this;
}
/**
* Specifies the instance launch group. Launch groups are Spot Instances that launch together and
* terminate together.
*/
public RequestSpotInstancesOptions launchGroup(String launchGroup) {
formParameters.put("LaunchGroup", checkNotNull(launchGroup, "launchGroup"));
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 availabilityZoneGroup(String availabilityZoneGroup) {
formParameters.put("AvailabilityZoneGroup", checkNotNull(availabilityZoneGroup, "availabilityZoneGroup"));
return this;
}
public static class Builder {
/**
* @see RequestSpotInstancesOptions#validFrom
*/
public static RequestSpotInstancesOptions validFrom(Date start) {
RequestSpotInstancesOptions options = new RequestSpotInstancesOptions();
return options.validFrom(start);
}
/**
* @see RequestSpotInstancesOptions#validUntil
*/
public static RequestSpotInstancesOptions validUntil(Date end) {
RequestSpotInstancesOptions options = new RequestSpotInstancesOptions();
return options.validUntil(end);
}
/**
* @see RequestSpotInstancesOptions#type
*/
public static RequestSpotInstancesOptions type(SpotInstanceRequest.Type type) {
RequestSpotInstancesOptions options = new RequestSpotInstancesOptions();
return options.type(type);
}
/**
* @see RequestSpotInstancesOptions#launchGroup(String)
*/
public static RequestSpotInstancesOptions launchGroup(String launchGroup) {
RequestSpotInstancesOptions options = new RequestSpotInstancesOptions();
return options.launchGroup(launchGroup);
}
/**
* @see RequestSpotInstancesOptions#availabilityZoneGroup
*/
public static RequestSpotInstancesOptions availabilityZoneGroup(String availabilityZoneGroup) {
RequestSpotInstancesOptions options = new RequestSpotInstancesOptions();
return options.availabilityZoneGroup(availabilityZoneGroup);
}
}
}

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

@ -0,0 +1,128 @@
/**
*
* 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.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.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.DescribeSpotPriceHistoryResponseHandler;
import org.jclouds.aws.ec2.xml.SpotInstanceHandler;
import org.jclouds.aws.ec2.xml.SpotInstancesHandler;
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;
/**
* Provides access to EC2 Spot Instances via their REST API.
* <p/>
*
* @author Adrian Cole
*/
@RequestFilters(FormSigner.class)
@FormParams(keys = VERSION, values = AWSEC2AsyncClient.VERSION)
@VirtualHost
public interface SpotInstanceAsyncClient {
/**
* @see SpotInstanceClient#describeSpotInstanceRequestsInRegion
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeSpotInstanceRequests")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
@XMLResponseParser(SpotInstancesHandler.class)
ListenableFuture<? extends Set<SpotInstanceRequest>> describeSpotInstanceRequestsInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindSpotInstanceRequestIdsToIndexedFormParams.class) String... requestIds);
/**
* @see SpotInstanceClient#requestSpotInstanceInRegion
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "RequestSpotInstances")
@XMLResponseParser(SpotInstanceHandler.class)
ListenableFuture<SpotInstanceRequest> requestSpotInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("SpotPrice") float spotPrice, @FormParam("LaunchSpecification.ImageId") String imageId,
@FormParam("LaunchSpecification.InstanceType") String instanceType);
/**
* @see SpotInstanceClient#requestSpotInstancesInRegion
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "RequestSpotInstances")
@XMLResponseParser(SpotInstancesHandler.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);
/**
* @see SpotInstanceClient#describeSpotPriceHistoryInRegion
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeSpotPriceHistory")
@XMLResponseParser(DescribeSpotPriceHistoryResponseHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<Spot>> describeSpotPriceHistoryInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
DescribeSpotPriceHistoryOptions... options);
/**
* @see SpotInstanceClient#cancelSpotInstanceRequestsInRegion
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "CancelSpotInstanceRequests")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> cancelSpotInstanceRequestsInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindSpotInstanceRequestIdsToIndexedFormParams.class) String... requestIds);
}

View File

@ -0,0 +1,159 @@
/**
*
* 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.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;
/**
* Provides Spot Instance services for EC2. For more information, refer to the Amazon EC2 Developer
* Guide.
* <p/>
*
* @author Adrian Cole
*/
@Timeout(duration = 45, timeUnit = TimeUnit.SECONDS)
public interface SpotInstanceClient {
/**
* Describes Spot Instance requests. Spot Instances are instances that Amazon EC2 starts on your
* behalf when the maximum price that you specify exceeds the current Spot Price. Amazon EC2
* periodically sets the Spot Price based on available Spot Instance capacity and current spot
* instance requests. For conceptual information about Spot Instances, refer to the Amazon
* Elastic Compute Cloud Developer Guide or Amazon Elastic Compute Cloud User Guide.
*
* @param region
* Region where the spot instance service is running
* @param requestIds
* Specifies the ID of the Spot Instance request.
*
* @see #requestSpotInstancesInRegion
* @see #cancelSpotInstanceRequestsInRegion
* @see #describeSpotPriceHistoryInRegion
* @see <a href=
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSpotInstanceRequests.html"
* />
* @return TODO
*/
Set<SpotInstanceRequest> describeSpotInstanceRequestsInRegion(@Nullable String region, String... requestIds);
/**
* request a single spot instance
*
* @param region
* Region where the spot instance service is running
* @param spotPrice
* Specifies the maximum hourly price for any Spot Instance launched to fulfill the
* request.
* @param imageId
* The AMI ID.
* @param instanceType
* The instance type (ex. m1.small)
* @return spot instance request
* @see #requestSpotInstancesInRegion
*/
SpotInstanceRequest requestSpotInstanceInRegion(@Nullable String region, float spotPrice, String imageId,
String instanceType);
/**
* Creates a Spot Instance request. Spot Instances are instances that Amazon EC2 starts on your
* behalf when the maximum price that you specify exceeds the current Spot Price. Amazon EC2
* periodically sets the Spot Price based on available Spot Instance capacity and current spot
* instance requests. For conceptual information about Spot Instances, refer to the Amazon
* Elastic Compute Cloud Developer Guide or Amazon Elastic Compute Cloud User Guide.
*
* @param region
* Region where the spot instance service is running
* @param spotPrice
* Specifies the maximum hourly price for any Spot Instance launched to fulfill the
* request.
* @param instanceCount
* number of instances to request
* @param launchSpec
* includes at least The AMI ID and instance type (ex. m1.small)
* @param options
* options including expiration time or grouping
*
* @see #describeSpotInstanceRequestsInRegion
* @see #cancelSpotInstanceRequestsInRegion
* @see #describeSpotPriceHistoryInRegion
* @see <a href=
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RequestSpotInstances.html"
* />
* @return set of spot instance requests
*/
Set<SpotInstanceRequest> requestSpotInstancesInRegion(@Nullable String region, float spotPrice, int instanceCount,
LaunchSpecification launchSpec, RequestSpotInstancesOptions... options);
/**
*
* Describes Spot Price history. Spot Instances are instances that Amazon EC2 starts on your
* behalf when the maximum price that you specify exceeds the current Spot Price. Amazon EC2
* periodically sets the Spot Price based on available Spot Instance capacity and current spot
* instance requests. For conceptual information about Spot Instances, refer to the Amazon
* Elastic Compute Cloud Developer Guide or Amazon Elastic Compute Cloud User Guide.
*
* @param region
* Region where the spot instance service is running
* @param options
* options to control the list
*
* @see #describeSpotInstanceRequestsInRegion
* @see #requestSpotInstancesInRegion
* @see #cancelSpotInstanceRequestsInRegion
* @see <a href=
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSpotInstanceRequests.html"
* />
* @return TODO
*/
@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
* starts on your behalf when the maximum price that you specify exceeds the current Spot Price.
* Amazon EC2 periodically sets the Spot Price based on available Spot Instance capacity and
* current spot instance requests. For conceptual information about Spot Instances, refer to the
* Amazon Elastic Compute Cloud Developer Guide or Amazon Elastic Compute Cloud User Guide.
*
* @param region
* Region where the spot instance service is running
* @param requestIds
* Specifies the ID of the Spot Instance request.
*
* @see #describeSpotInstanceRequestsInRegion
* @see #requestSpotInstancesInRegion
* @see #describeSpotPriceHistoryInRegion
* @see <a href=
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CancelSpotInstanceRequests.html"
* />
* @return TODO
*/
String cancelSpotInstanceRequestsInRegion(@Nullable String region, String... requestIds);
}

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;
import org.jclouds.aws.ec2.domain.PlacementGroup.State; import org.jclouds.aws.ec2.domain.PlacementGroup.State;
import org.jclouds.aws.util.AWSUtils; import org.jclouds.aws.util.AWSUtils;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.location.Region; import org.jclouds.location.Region;
@ -36,8 +35,6 @@ public class PlacementGroupHandler extends
ParseSax.HandlerForGeneratedRequestWithResult<PlacementGroup> { ParseSax.HandlerForGeneratedRequestWithResult<PlacementGroup> {
private StringBuilder currentText = new StringBuilder(); private StringBuilder currentText = new StringBuilder();
@Inject
protected DateService dateService;
@Inject @Inject
@Region @Region
String defaultRegion; 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

@ -0,0 +1,125 @@
/**
*
* 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.SpotInstanceRequest;
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
*/
public class SpotInstanceHandler 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
public SpotInstanceHandler(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() {
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("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")) {
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) {
if (inLaunchSpecification)
launchSpecificationHandler.characters(ch, start, length);
else
currentText.append(ch, start, length);
}
}

View File

@ -0,0 +1,84 @@
/**
*
* 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.SpotInstanceRequest;
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 SpotInstancesHandler extends ParseSax.HandlerWithResult<Set<SpotInstanceRequest>> {
private final Builder<SpotInstanceRequest> spotRequests = ImmutableSet.<SpotInstanceRequest> builder();
private final SpotInstanceHandler spotRequestHandler;
private int itemDepth;
@Inject
public SpotInstancesHandler(SpotInstanceHandler spotRequestHandler) {
this.spotRequestHandler = spotRequestHandler;
}
public Set<SpotInstanceRequest> getResult() {
return spotRequests.build();
}
@Override
public HandlerWithResult<Set<SpotInstanceRequest>> setContext(HttpRequest request) {
spotRequestHandler.setContext(request);
return super.setContext(request);
}
@Override
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") && itemDepth == 1) {
spotRequests.add(spotRequestHandler.getResult());
}
if (qName.equals("item"))
itemDepth--;
if (itemDepth >= 1)
spotRequestHandler.endElement(uri, localName, qName);
}
public void characters(char ch[], int start, int 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

@ -0,0 +1,122 @@
/**
*
* 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.options;
import static org.jclouds.aws.ec2.options.DescribeSpotPriceHistoryOptions.Builder.from;
import static org.jclouds.aws.ec2.options.DescribeSpotPriceHistoryOptions.Builder.instanceType;
import static org.jclouds.aws.ec2.options.DescribeSpotPriceHistoryOptions.Builder.productDescription;
import static org.jclouds.aws.ec2.options.DescribeSpotPriceHistoryOptions.Builder.to;
import static org.testng.Assert.assertEquals;
import java.util.Collections;
import java.util.Date;
import org.jclouds.http.options.HttpRequestOptions;
import org.testng.annotations.Test;
/**
* Tests possible uses of DescribeSpotPriceHistoryOptions and
* DescribeSpotPriceHistoryOptions.Builder.*
*
* @author Adrian Cole
*/
public class DescribeSpotPriceHistoryOptionsTest {
@Test
public void testAssignability() {
assert HttpRequestOptions.class.isAssignableFrom(DescribeSpotPriceHistoryOptions.class);
assert !String.class.isAssignableFrom(DescribeSpotPriceHistoryOptions.class);
}
@Test
public void testDescription() {
DescribeSpotPriceHistoryOptions options = new DescribeSpotPriceHistoryOptions();
options.productDescription("test");
assertEquals(options.buildFormParameters().get("ProductDescription"), Collections.singletonList("test"));
}
@Test
public void testDescriptionStatic() {
DescribeSpotPriceHistoryOptions options = productDescription("test");
assertEquals(options.buildFormParameters().get("ProductDescription"), Collections.singletonList("test"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testDescriptionNPE() {
productDescription(null);
}
@Test
public void testInstanceType() {
DescribeSpotPriceHistoryOptions options = new DescribeSpotPriceHistoryOptions();
options.instanceType("test");
assertEquals(options.buildFormParameters().get("InstanceType.1"), Collections.singletonList("test"));
}
@Test
public void testInstanceTypeStatic() {
DescribeSpotPriceHistoryOptions options = instanceType("test");
assertEquals(options.buildFormParameters().get("InstanceType.1"), Collections.singletonList("test"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testInstanceTypeNPE() {
instanceType(null);
}
@Test
public void testFrom() {
DescribeSpotPriceHistoryOptions options = new DescribeSpotPriceHistoryOptions();
options.from(test);
assertEquals(options.buildFormParameters().get("StartTime"), Collections.singletonList("1970-05-23T21:21:18.910Z"));
}
Date test = new Date(12345678910l);
@Test
public void testFromStatic() {
DescribeSpotPriceHistoryOptions options = from(test);
assertEquals(options.buildFormParameters().get("StartTime"), Collections.singletonList("1970-05-23T21:21:18.910Z"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testFromNPE() {
from(null);
}
@Test
public void testTo() {
DescribeSpotPriceHistoryOptions options = new DescribeSpotPriceHistoryOptions();
options.to(test);
assertEquals(options.buildFormParameters().get("EndTime"), Collections.singletonList("1970-05-23T21:21:18.910Z"));
}
@Test
public void testToStatic() {
DescribeSpotPriceHistoryOptions options = to(test);
assertEquals(options.buildFormParameters().get("EndTime"), Collections.singletonList("1970-05-23T21:21:18.910Z"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testToNPE() {
to(null);
}
}

View File

@ -0,0 +1,145 @@
/**
*
* 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 validUntil in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.options;
import static org.jclouds.aws.ec2.options.RequestSpotInstancesOptions.Builder.availabilityZoneGroup;
import static org.jclouds.aws.ec2.options.RequestSpotInstancesOptions.Builder.launchGroup;
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;
import static org.testng.Assert.assertEquals;
import java.util.Collections;
import java.util.Date;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
import org.jclouds.http.options.HttpRequestOptions;
import org.testng.annotations.Test;
/**
* Tests possible uses of RequestSpotInstancesOptions and RequestSpotInstancesOptions.Builder.*
*
* @author Adrian Cole
*/
public class RequestSpotInstancesOptionsTest {
@Test
public void testAssignability() {
assert HttpRequestOptions.class.isAssignableFrom(RequestSpotInstancesOptions.class);
assert !String.class.isAssignableFrom(RequestSpotInstancesOptions.class);
}
@Test
public void testAvailabilityZoneGroup() {
RequestSpotInstancesOptions options = new RequestSpotInstancesOptions();
options.availabilityZoneGroup("test");
assertEquals(options.buildFormParameters().get("AvailabilityZoneGroup"), Collections.singletonList("test"));
}
@Test
public void testAvailabilityZoneGroupStatic() {
RequestSpotInstancesOptions options = availabilityZoneGroup("test");
assertEquals(options.buildFormParameters().get("AvailabilityZoneGroup"), Collections.singletonList("test"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testAvailabilityZoneGroupNPE() {
availabilityZoneGroup(null);
}
@Test
public void testLaunchGroup() {
RequestSpotInstancesOptions options = new RequestSpotInstancesOptions();
options.launchGroup("test");
assertEquals(options.buildFormParameters().get("LaunchGroup"), Collections.singletonList("test"));
}
@Test
public void testLaunchGroupStatic() {
RequestSpotInstancesOptions options = launchGroup("test");
assertEquals(options.buildFormParameters().get("LaunchGroup"), Collections.singletonList("test"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testLaunchGroupNPE() {
launchGroup(null);
}
@Test
public void testInstanceType() {
RequestSpotInstancesOptions options = new RequestSpotInstancesOptions();
options.type(SpotInstanceRequest.Type.PERSISTENT);
assertEquals(options.buildFormParameters().get("Type"), Collections.singletonList("persistent"));
}
@Test
public void testInstanceTypeStatic() {
RequestSpotInstancesOptions options = type(SpotInstanceRequest.Type.PERSISTENT);
assertEquals(options.buildFormParameters().get("Type"), Collections.singletonList("persistent"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testInstanceTypeNPE() {
type(null);
}
@Test
public void testFrom() {
RequestSpotInstancesOptions options = new RequestSpotInstancesOptions();
options.validFrom(test);
assertEquals(options.buildFormParameters().get("ValidFrom"),
Collections.singletonList("1970-05-23T21:21:18.910Z"));
}
Date test = new Date(12345678910l);
@Test
public void testFromStatic() {
RequestSpotInstancesOptions options = validFrom(test);
assertEquals(options.buildFormParameters().get("ValidFrom"),
Collections.singletonList("1970-05-23T21:21:18.910Z"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testFromNPE() {
validFrom(null);
}
@Test
public void testTo() {
RequestSpotInstancesOptions options = new RequestSpotInstancesOptions();
options.validUntil(test);
assertEquals(options.buildFormParameters().get("ValidUntil"),
Collections.singletonList("1970-05-23T21:21:18.910Z"));
}
@Test
public void testToStatic() {
RequestSpotInstancesOptions options = validUntil(test);
assertEquals(options.buildFormParameters().get("ValidUntil"),
Collections.singletonList("1970-05-23T21:21:18.910Z"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testToNPE() {
validUntil(null);
}
}

View File

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

View File

@ -0,0 +1,190 @@
/**
*
* 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.services;
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.aws.ec2.xml.DescribeSpotPriceHistoryResponseHandler;
import org.jclouds.aws.ec2.xml.SpotInstanceHandler;
import org.jclouds.aws.ec2.xml.SpotInstancesHandler;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code SpotInstanceAsyncClient}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "SpotInstanceAsyncClientTest")
public class SpotInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<SpotInstanceAsyncClient> {
public void testRequestSpotInstance() throws SecurityException, NoSuchMethodException, IOException {
Method method = SpotInstanceAsyncClient.class.getMethod("requestSpotInstanceInRegion", String.class,
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=m1.small&SpotPrice=0.01&LaunchSpecification.InstanceType=ami-voo",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, SpotInstanceHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testRequestSpotInstancesOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = SpotInstanceAsyncClient.class.getMethod("requestSpotInstancesInRegion", String.class,
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&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, ParseSax.class);
assertSaxResponseParserClassEquals(method, SpotInstancesHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testCancelSpotInstanceRequests() throws SecurityException, NoSuchMethodException, IOException {
Method method = SpotInstanceAsyncClient.class.getMethod("cancelSpotInstanceRequestsInRegion", String.class,
String[].class);
HttpRequest request = processor.createRequest(method, null, "id");
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=CancelSpotInstanceRequests&SpotInstanceRequestId.1=id",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnVoidOnNotFoundOr404.class);
checkFilters(request);
}
public void testDescribeSpotInstanceRequests() throws SecurityException, NoSuchMethodException, IOException {
Method method = SpotInstanceAsyncClient.class.getMethod("describeSpotInstanceRequestsInRegion", String.class,
String[].class);
HttpRequest request = processor.createRequest(method, (String) null);
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-11-15&Action=DescribeSpotInstanceRequests",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, SpotInstancesHandler.class);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testDescribeSpotInstanceRequestsArgs() throws SecurityException, NoSuchMethodException, IOException {
Method method = SpotInstanceAsyncClient.class.getMethod("describeSpotInstanceRequestsInRegion", String.class,
String[].class);
HttpRequest request = processor.createRequest(method, null, "1", "2");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-11-15&Action=DescribeSpotInstanceRequests&SpotInstanceRequestId.1=1&SpotInstanceRequestId.2=2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, SpotInstancesHandler.class);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testDescribeSpotPriceHistory() throws SecurityException, NoSuchMethodException, IOException {
Method method = SpotInstanceAsyncClient.class.getMethod("describeSpotPriceHistoryInRegion", String.class,
DescribeSpotPriceHistoryOptions[].class);
HttpRequest request = processor.createRequest(method, (String) null);
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-11-15&Action=DescribeSpotPriceHistory",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeSpotPriceHistoryResponseHandler.class);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
Date from = new Date(12345678910l);
Date to = new Date(1234567891011l);
public void testDescribeSpotPriceHistoryArgs() throws SecurityException, NoSuchMethodException, IOException {
Method method = SpotInstanceAsyncClient.class.getMethod("describeSpotPriceHistoryInRegion", String.class,
DescribeSpotPriceHistoryOptions[].class);
HttpRequest request = processor.createRequest(method, null, DescribeSpotPriceHistoryOptions.Builder.from(from)
.to(to).productDescription("description").instanceType("m1.small"));
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=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, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeSpotPriceHistoryResponseHandler.class);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<SpotInstanceAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<SpotInstanceAsyncClient>>() {
};
}
}

View File

@ -0,0 +1,207 @@
/**
*
* 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.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.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;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.inject.Module;
/**
* Tests behavior of {@code SpotInstanceClient}
*
* @author Adrian Cole
*/
@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> 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() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = System.getProperty("test." + provider + ".credential");
endpoint = System.getProperty("test." + provider + ".endpoint");
apiversion = System.getProperty("test." + provider + ".apiversion");
}
protected Properties setupProperties() {
Properties overrides = new Properties();
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
overrides.setProperty(provider + ".identity", identity);
if (credential != null)
overrides.setProperty(provider + ".credential", credential);
if (endpoint != null)
overrides.setProperty(provider + ".endpoint", endpoint);
if (apiversion != null)
overrides.setProperty(provider + ".apiversion", apiversion);
return overrides;
}
@BeforeGroups(groups = { "live" })
public void setupClient() throws FileNotFoundException, IOException {
setupCredentials();
Properties overrides = setupProperties();
context = new ComputeServiceContextFactory().createContext(provider,
ImmutableSet.<Module> of(new Log4JLoggingModule(), new JschSshClientModule()), overrides);
client = AWSEC2Client.class.cast(context.getProviderSpecificContext().getApi());
activeTester = new RetryablePredicate<SpotInstanceRequest>(new SpotInstanceRequestActive(client),
SPOT_DELAY_SECONDS, 1, 1, TimeUnit.SECONDS);
}
@Test
void testDescribeSpotRequestsInRegion() {
for (String region : Region.DEFAULT_REGIONS) {
SortedSet<SpotInstanceRequest> allResults = ImmutableSortedSet.copyOf(client.getSpotInstanceServices()
.describeSpotInstanceRequestsInRegion(region));
assertNotNull(allResults);
if (allResults.size() >= 1) {
SpotInstanceRequest request = allResults.last();
SortedSet<SpotInstanceRequest> result = ImmutableSortedSet.copyOf(client.getSpotInstanceServices()
.describeSpotInstanceRequestsInRegion(region, request.getId()));
assertNotNull(result);
SpotInstanceRequest compare = result.last();
assertEquals(compare, request);
}
}
}
@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 : 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,
LaunchSpecification.builder().imageId("ami-595a0a1c").instanceType(InstanceType.T1_MICRO).build(),
launchGroup(launchGroup).availabilityZoneGroup(launchGroup).validFrom(new Date())
.validUntil(new Date(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(SPOT_DELAY_SECONDS))));
assertNotNull(requests);
for (SpotInstanceRequest request : requests)
verifySpotInstance(request);
}
private void verifySpotInstance(SpotInstanceRequest request) {
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 (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 // NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "RunInstancesResponseHandlerTest") @Test(groups = "unit", testName = "RunInstancesResponseHandlerTest")
public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest { public class AWSRunInstancesResponseHandlerTest extends BaseEC2HandlerTest {
private DateService dateService; 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 SpotInstanceHandler}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "SpotInstanceHandlerTest")
public class SpotInstanceHandlerTest 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();
SpotInstanceHandler handler = injector.getInstance(SpotInstanceHandler.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 SpotInstancesHandler}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "SpotInstancesHandlerTest")
public class SpotInstancesHandlerTest 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");
SpotInstancesHandler handler = injector
.getInstance(SpotInstancesHandler.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");
SpotInstancesHandler handler = injector
.getInstance(SpotInstancesHandler.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>