code changes based on 2nd round of review

This commit is contained in:
Lili Nader 2011-01-17 17:44:08 -08:00
parent e8d4825ae5
commit 7fed3ec695
5 changed files with 229 additions and 207 deletions

View File

@ -27,8 +27,14 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.aws.cloudwatch.CloudWatchClient;
import org.jclouds.aws.ec2.options.RunInstancesOptions.BlockDeviceMapping;
import org.jclouds.aws.ec2.options.BlockDeviceMapping;
import org.jclouds.aws.ec2.options.BlockDeviceMapping.MapEBSSnapshotToDevice;
import org.jclouds.aws.ec2.options.BlockDeviceMapping.MapEphemeralDeviceToDevice;
import org.jclouds.aws.ec2.options.BlockDeviceMapping.MapNewVolumeToDevice;
import org.jclouds.aws.ec2.options.BlockDeviceMapping.UnmapDeviceNamed;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Credentials;
import org.jclouds.io.Payload;
@ -162,15 +168,16 @@ public class EC2TemplateOptions extends TemplateOptions {
/**
* Specifies the block device mappings to be used to run the instance
*/
public EC2TemplateOptions blockDeviceMapping(String deviceName,
String virtualName, String ebsSnapShotId,
Integer ebsVolumeSize, Boolean ebsNoDevice,
Boolean ebsNoDeviceebsDeleteOnTermination) {
public EC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName,
String snapshotId, @Nullable Integer sizeInGib,
@Nullable Boolean deleteOnTermination) {
checkNotNull(deviceName, "deviceName cannot be null");
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
checkNotNull(snapshotId, "snapshotId cannot be null");
Preconditions2.checkNotEmpty(snapshotId, "snapshotId must be non-empty");
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
mappings.addAll(blockDeviceMappings);
BlockDeviceMapping mapping = new BlockDeviceMapping(deviceName, virtualName, ebsSnapShotId, ebsVolumeSize, ebsNoDevice, ebsNoDeviceebsDeleteOnTermination);
MapEBSSnapshotToDevice mapping = new MapEBSSnapshotToDevice(deviceName, snapshotId, sizeInGib, deleteOnTermination);
mappings.add(mapping);
blockDeviceMappings = ImmutableSet.copyOf(mappings);
return this;
@ -179,7 +186,57 @@ public class EC2TemplateOptions extends TemplateOptions {
/**
* Specifies the block device mappings to be used to run the instance
*/
public EC2TemplateOptions blockDeviceMappings(Set<BlockDeviceMapping> blockDeviceMappings) {
public EC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, Integer sizeInGib,
@Nullable Boolean deleteOnTermination) {
checkNotNull(deviceName, "deviceName cannot be null");
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
checkNotNull(sizeInGib, "sizeInGib cannot be null");
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
mappings.addAll(blockDeviceMappings);
MapNewVolumeToDevice mapping = new MapNewVolumeToDevice(deviceName, sizeInGib, deleteOnTermination);
mappings.add(mapping);
blockDeviceMappings = ImmutableSet.copyOf(mappings);
return this;
}
/**
* Specifies the block device mappings to be used to run the instance
*/
public EC2TemplateOptions mapEphemeralDeviceToDeviceName(String deviceName, String virtualName) {
checkNotNull(deviceName, "deviceName cannot be null");
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
checkNotNull(virtualName, "virtualName cannot be null");
Preconditions2.checkNotEmpty(virtualName, "virtualName must be non-empty");
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
mappings.addAll(blockDeviceMappings);
MapEphemeralDeviceToDevice mapping = new MapEphemeralDeviceToDevice(deviceName, virtualName);
mappings.add(mapping);
blockDeviceMappings = ImmutableSet.copyOf(mappings);
return this;
}
/**
* Specifies the block device mappings to be used to run the instance
*/
public EC2TemplateOptions unmapDeviceNamed(String deviceName) {
checkNotNull(deviceName, "deviceName cannot be null");
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
mappings.addAll(blockDeviceMappings);
UnmapDeviceNamed mapping = new UnmapDeviceNamed(deviceName);
mappings.add(mapping);
blockDeviceMappings = ImmutableSet.copyOf(mappings);
return this;
}
/**
* Specifies the block device mappings to be used to run the instance
*/
public EC2TemplateOptions blockDeviceMappings(Set<? extends BlockDeviceMapping> blockDeviceMappings) {
checkArgument(Iterables.size(blockDeviceMappings) > 0, "you must specify at least one block device mapping");
this.blockDeviceMappings = ImmutableSet.copyOf(blockDeviceMappings);
return this;
@ -307,20 +364,6 @@ public class EC2TemplateOptions extends TemplateOptions {
EC2TemplateOptions options = new EC2TemplateOptions();
return EC2TemplateOptions.class.cast(options.subnetId(subnetId));
}
/**
* @see EC2TemplateOptions#blockDeviceMapping
*/
public static EC2TemplateOptions blockDeviceMapping(String deviceName,
String virtualName, String ebsSnapShotId,
Integer ebsVolumeSize, Boolean ebsNoDevice,
Boolean ebsNoDeviceebsDeleteOnTermination) {
EC2TemplateOptions options = new EC2TemplateOptions();
return options.blockDeviceMapping(deviceName,
virtualName, ebsSnapShotId, ebsVolumeSize, ebsNoDevice,
ebsNoDeviceebsDeleteOnTermination);
}
}
// methods that only facilitate returning the correct object type

View File

@ -19,6 +19,7 @@
package org.jclouds.aws.ec2.compute.strategy;
import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.asType;
import java.util.Map;
@ -36,11 +37,11 @@ import org.jclouds.aws.ec2.compute.functions.CreateSecurityGroupIfNeeded;
import org.jclouds.aws.ec2.compute.functions.CreateUniqueKeyPair;
import org.jclouds.aws.ec2.compute.options.EC2TemplateOptions;
import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.options.BlockDeviceMapping;
import org.jclouds.aws.ec2.options.RunInstancesOptions;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.location.Provider;
import org.jclouds.aws.ec2.options.RunInstancesOptions.BlockDeviceMapping;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;
@ -116,6 +117,8 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions
instanceOptions.withUserData(userData);
Set<BlockDeviceMapping> blockDeviceMappings = EC2TemplateOptions.class.cast(template.getOptions()).getBlockDeviceMappings();
if(blockDeviceMappings != null)
checkState("ebs".equals(template.getImage().getUserMetadata().get("rootDeviceType")), "BlockDeviceMapping only available on ebs boot");
instanceOptions.withBlockDeviceMappings(blockDeviceMappings);
return instanceOptions;

View File

@ -0,0 +1,158 @@
package org.jclouds.aws.ec2.options;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Nullable;
import org.jclouds.util.Preconditions2;
public class BlockDeviceMapping
{
private final String deviceName;
private final String virtualName;
private final String snapshotId;
private final Integer sizeInGib;
private final Boolean noDevice;
private final Boolean deleteOnTermination;
// values expressed in GB
private static final Integer VOLUME_SIZE_MIN_VALUE = 1;
private static final Integer VOLUME_SIZE_MAX_VALUE = 1000;
public BlockDeviceMapping(String deviceName, @Nullable String virtualName,
@Nullable String snapshotId, @Nullable Integer sizeInGib,
@Nullable Boolean noDevice, @Nullable Boolean deleteOnTermination)
{
checkNotNull(deviceName, "deviceName cannot be null");
Preconditions2.checkNotEmpty(deviceName,
"the deviceName must be non-empty");
if (sizeInGib != null)
{
checkArgument(
(sizeInGib >= VOLUME_SIZE_MIN_VALUE && sizeInGib <= VOLUME_SIZE_MAX_VALUE),
String.format("Size in Gib must be between %s and %s GB",
VOLUME_SIZE_MIN_VALUE, VOLUME_SIZE_MAX_VALUE));
}
this.deviceName = deviceName;
this.virtualName = virtualName;
this.snapshotId = snapshotId;
this.sizeInGib = sizeInGib;
this.noDevice = noDevice;
this.deleteOnTermination = deleteOnTermination;
}
public String getDeviceName()
{
return deviceName;
}
public String getVirtualName()
{
return virtualName;
}
public String getEbsSnapshotId()
{
return snapshotId;
}
public Integer getEbsVolumeSize()
{
return sizeInGib;
}
public Boolean getEbsNoDevice()
{
return noDevice;
}
public Boolean getEbsDeleteOnTermination()
{
return deleteOnTermination;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result
+ ((deviceName == null) ? 0 : deviceName.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;
BlockDeviceMapping other = (BlockDeviceMapping) obj;
if (deviceName == null)
{
if (other.deviceName != null)
return false;
}
else if (!deviceName.equals(other.deviceName))
return false;
return true;
}
@Override
public String toString()
{
return "BlockDeviceMapping [deviceName=" + deviceName
+ ", virtualName=" + virtualName + ", snapshotId=" + snapshotId
+ ", sizeInGib=" + sizeInGib + ", noDevice=" + noDevice
+ ", deleteOnTermination=" + deleteOnTermination + "]";
}
public static class MapEBSSnapshotToDevice extends BlockDeviceMapping
{
public MapEBSSnapshotToDevice(String deviceName, String snapshotId,
@Nullable Integer sizeInGib,
@Nullable Boolean deleteOnTermination)
{
super(deviceName, null, snapshotId, sizeInGib, null,
deleteOnTermination);
checkNotNull(snapshotId, "snapshotId cannot be null");
Preconditions2.checkNotEmpty(snapshotId,
"the snapshotId must be non-empty");
}
}
public static class MapNewVolumeToDevice extends BlockDeviceMapping
{
public MapNewVolumeToDevice(String deviceName, Integer sizeInGib,
@Nullable Boolean deleteOnTermination)
{
super(deviceName, null, null, sizeInGib, null, deleteOnTermination);
checkNotNull(sizeInGib, "sizeInGib cannot be null");
}
}
public static class MapEphemeralDeviceToDevice extends BlockDeviceMapping
{
public MapEphemeralDeviceToDevice(String deviceName, String virtualName)
{
super(deviceName, virtualName, null, null, null, null);
checkNotNull(virtualName, "virtualName cannot be null");
Preconditions2.checkNotEmpty(virtualName,
"the virtualName must be non-empty");
}
}
public static class UnmapDeviceNamed extends BlockDeviceMapping
{
public UnmapDeviceNamed(String deviceName)
{
super(deviceName, null, null, null, true, null);
}
}
}

View File

@ -21,12 +21,12 @@ package org.jclouds.aws.ec2.options;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.options.internal.BaseEC2RequestOptions;
import org.jclouds.encryption.internal.Base64;
import org.jclouds.util.Preconditions2;
/**
* Contains options supported in the Form API for the RunInstances operation. <h2>
@ -162,30 +162,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return getFirstFormOrNull("RamdiskId");
}
/**
* The virtual name.
*/
public RunInstancesOptions withVirtualName(String virtualName) {
formParameters.put("BlockDeviceMapping.VirtualName", checkNotNull(virtualName, "virtualName"));
return this;
}
String getVirtualName() {
return getFirstFormOrNull("BlockDeviceMapping.VirtualName");
}
/**
* The device name (e.g., /dev/sdh).
*/
public RunInstancesOptions withDeviceName(String deviceName) {
formParameters.put("BlockDeviceMapping.DeviceName", checkNotNull(deviceName, "deviceName"));
return this;
}
String getDeviceName() {
return getFirstFormOrNull("BlockDeviceMapping.DeviceName");
}
/**
* Enables monitoring for the instance.
*/
@ -216,7 +192,7 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
*
*/
public RunInstancesOptions withBlockDeviceMappings(Set<BlockDeviceMapping> mappings) {
public RunInstancesOptions withBlockDeviceMappings(Set<? extends BlockDeviceMapping> mappings) {
int i = 1;
for(BlockDeviceMapping mapping: mappings)
{
@ -288,14 +264,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return options.withKernelId(kernelId);
}
/**
* @see RunInstancesOptions#withDeviceName(String)
*/
public static RunInstancesOptions withDeviceName(String deviceName) {
RunInstancesOptions options = new RunInstancesOptions();
return options.withDeviceName(deviceName);
}
/**
* @see RunInstancesOptions#enableMonitoring()
*/
@ -319,115 +287,14 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
RunInstancesOptions options = new RunInstancesOptions();
return options.withRamdisk(ramdiskId);
}
/**
* @see RunInstancesOptions#withVirtualName(String)
*/
public static RunInstancesOptions withVirtualName(String virtualName) {
RunInstancesOptions options = new RunInstancesOptions();
return options.withVirtualName(virtualName);
}
/**
* @see RunInstancesOptions#withBlockDeviceMappings(Set<BlockDeviceMapping> mappings)
*/
public static RunInstancesOptions withBlockDeviceMappings(Set<BlockDeviceMapping> mappings) {
public static RunInstancesOptions withBlockDeviceMappings(Set<? extends BlockDeviceMapping> mappings) {
RunInstancesOptions options = new RunInstancesOptions();
return options.withBlockDeviceMappings(mappings);
}
}
public static class BlockDeviceMapping
{
private final String deviceName;
private final String virtualName;
private final String ebsSnapshotId;
private final Integer ebsVolumeSize;
private final Boolean ebsNoDevice;
private final Boolean ebsDeleteOnTermination;
//values expressed in GB
private static final Integer VOLUME_SIZE_MIN_VALUE = 1;
private static final Integer VOLUME_SIZE_MAX_VALUE = 1000;
public BlockDeviceMapping(String deviceName, String virtualName,
String ebsSnapshotId, Integer ebsVolumeSize,
Boolean ebsNoDevice, Boolean ebsDeleteOnTermination){
checkNotNull(deviceName, "deviceName cannot be null");
Preconditions2.checkNotEmpty(deviceName, "the deviceName must be non-empty");
if(ebsVolumeSize != null)
{
checkArgument((ebsVolumeSize >=VOLUME_SIZE_MIN_VALUE && ebsVolumeSize <= VOLUME_SIZE_MAX_VALUE),
String.format("EBS Volume Size must be between %s and %s GB", VOLUME_SIZE_MIN_VALUE, VOLUME_SIZE_MAX_VALUE));
}
this.deviceName = deviceName;
this.virtualName = virtualName;
this.ebsSnapshotId = ebsSnapshotId;
this.ebsVolumeSize = ebsVolumeSize;
this.ebsNoDevice = ebsNoDevice;
this.ebsDeleteOnTermination = ebsDeleteOnTermination;
}
public String getDeviceName(){
return deviceName;
}
public String getVirtualName() {
return virtualName;
}
public String getEbsSnapshotId() {
return ebsSnapshotId;
}
public Integer getEbsVolumeSize() {
return ebsVolumeSize;
}
public Boolean getEbsNoDevice() {
return ebsNoDevice;
}
public Boolean getEbsDeleteOnTermination() {
return ebsDeleteOnTermination;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result
+ ((deviceName == null) ? 0 : deviceName.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;
BlockDeviceMapping other = (BlockDeviceMapping) obj;
if (deviceName == null)
{
if (other.deviceName != null)
return false;
}
else if (!deviceName.equals(other.deviceName))
return false;
return true;
}
@Override
public String toString() {
return "BlockDeviceMapping [deviceName=" + deviceName
+ ", virtualName=" + virtualName + ", ebsSnapshotId="
+ ebsSnapshotId + ", ebsVolumeSize=" + ebsVolumeSize
+ ", ebsNoDevice=" + ebsNoDevice
+ ", ebsDeleteOnTermination=" + ebsDeleteOnTermination
+ "]";
}
}
}

View File

@ -21,14 +21,12 @@ package org.jclouds.aws.ec2.options;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.asType;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.enableMonitoring;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withDeviceName;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKernelId;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKeyName;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withRamdisk;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withSecurityGroup;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withSubnetId;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withUserData;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withVirtualName;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withBlockDeviceMappings;
import static org.testng.Assert.assertEquals;
@ -37,7 +35,6 @@ import java.util.HashSet;
import java.util.Set;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.options.RunInstancesOptions.BlockDeviceMapping;
import org.jclouds.http.options.HttpRequestOptions;
import org.testng.annotations.Test;
@ -185,32 +182,6 @@ public class RunInstancesOptionsTest {
withKernelId(null);
}
@Test
public void testWithDeviceName() {
RunInstancesOptions options = new RunInstancesOptions();
options.withDeviceName("test");
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.DeviceName"),
Collections.singletonList("test"));
}
@Test
public void testNullWithDeviceName() {
RunInstancesOptions options = new RunInstancesOptions();
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.DeviceName"), Collections.EMPTY_LIST);
}
@Test
public void testWithDeviceNameStatic() {
RunInstancesOptions options = withDeviceName("test");
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.DeviceName"),
Collections.singletonList("test"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testWithDeviceNameNPE() {
withDeviceName(null);
}
@Test
public void testWithMonitoringEnabled() {
RunInstancesOptions options = new RunInstancesOptions();
@ -278,31 +249,11 @@ public class RunInstancesOptionsTest {
withRamdisk(null);
}
@Test
public void testWithVirtualName() {
RunInstancesOptions options = new RunInstancesOptions();
options.withVirtualName("test");
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"),
Collections.singletonList("test"));
}
@Test
public void testNullWithVirtualName() {
RunInstancesOptions options = new RunInstancesOptions();
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"), Collections.EMPTY_LIST);
}
@Test
public void testWithVirtualNameStatic() {
RunInstancesOptions options = withVirtualName("test");
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"),
Collections.singletonList("test"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testWithVirtualNameNPE() {
withVirtualName(null);
}
@Test
public void testWithBlockDeviceMapping() {