mirror of https://github.com/apache/jclouds.git
Replaced string representation of BlockDeviceMapping with the class for Instance(Async)Client#setBlockDeviceMappingForInstanceInRegion, getBlockDeviceMappingForInstanceInRegion
Fixed the tests and some logic for BlockDeviceMapping. NOTE: Now it receives and returns instances of RunningInstance.EbsBlockDevice
This commit is contained in:
parent
118129714c
commit
0097a2ded6
|
@ -0,0 +1,53 @@
|
|||
package org.jclouds.aws.ec2.binders;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.BlockDeviceMapping;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||
import org.jclouds.aws.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.Binder;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* @author Oleksiy Yarmula
|
||||
*/
|
||||
public class BindBlockDeviceMappingToIndexedFormParams implements Binder {
|
||||
|
||||
private final String deviceNamePattern = "BlockDeviceMapping.%d.DeviceName";
|
||||
private final String volumeIdPattern = "BlockDeviceMapping.%d.Ebs.VolumeId";
|
||||
private final String deleteOnTerminationPattern = "BlockDeviceMapping.%d.Ebs.DeleteOnTermination";
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void bindToRequest(HttpRequest request, Object input) {
|
||||
checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest,
|
||||
"this binder is only valid for GeneratedHttpRequests");
|
||||
checkArgument(checkNotNull(input, "input") instanceof BlockDeviceMapping,
|
||||
"this binder is only valid for BlockDeviceMapping");
|
||||
BlockDeviceMapping blockDeviceMapping = (BlockDeviceMapping) input;
|
||||
GeneratedHttpRequest generatedRequest = (GeneratedHttpRequest) request;
|
||||
|
||||
int amazonOneBasedIndex = 1; //according to docs, counters must start with 1
|
||||
for(RunningInstance.EbsBlockDevice ebsBlockDevice : blockDeviceMapping.getEbsBlockDevices()) {
|
||||
|
||||
//not null by contract
|
||||
generatedRequest.addFormParam(format(volumeIdPattern, amazonOneBasedIndex),
|
||||
ebsBlockDevice.getVolumeId());
|
||||
|
||||
if(ebsBlockDevice.getDeviceName() != null) {
|
||||
generatedRequest.addFormParam(format(deviceNamePattern, amazonOneBasedIndex),
|
||||
ebsBlockDevice.getDeviceName());
|
||||
}
|
||||
|
||||
generatedRequest.addFormParam(format(deleteOnTerminationPattern, amazonOneBasedIndex),
|
||||
String.valueOf(ebsBlockDevice.isDeleteOnTermination()));
|
||||
|
||||
|
||||
amazonOneBasedIndex++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
package org.jclouds.aws.ec2.domain;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Defines the mapping of volumes for
|
||||
* {@link org.jclouds.aws.ec2.services.InstanceClient#setBlockDeviceMappingForInstanceInRegion}.
|
||||
*
|
||||
* @author Oleksiy Yarmula
|
||||
*/
|
||||
public class BlockDeviceMapping {
|
||||
|
||||
private final List<RunningInstance.EbsBlockDevice> ebsBlockDevices = Lists.newArrayList();
|
||||
|
||||
public BlockDeviceMapping() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates block device mapping from the list of {@link RunningInstance.EbsBlockDevice devices}.
|
||||
*
|
||||
* This method copies the values of the list.
|
||||
* @param ebsBlockDevices
|
||||
* devices to be changed for the volume
|
||||
*/
|
||||
public BlockDeviceMapping(List<RunningInstance.EbsBlockDevice> ebsBlockDevices) {
|
||||
this.ebsBlockDevices.addAll(checkNotNull(ebsBlockDevices,
|
||||
/*or throw*/ "EbsBlockDevices can't be null"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link RunningInstance.EbsBlockDevice} to the mapping.
|
||||
* @param ebsBlockDevice
|
||||
* ebsBlockDevice to be added
|
||||
* @return the same instance for method chaining purposes
|
||||
*/
|
||||
public BlockDeviceMapping addEbsBlockDevice(RunningInstance.EbsBlockDevice ebsBlockDevice) {
|
||||
this.ebsBlockDevices.add(checkNotNull(ebsBlockDevice,
|
||||
/*or throw*/ "EbsBlockDevice can't be null"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<RunningInstance.EbsBlockDevice> getEbsBlockDevices() {
|
||||
return ImmutableList.copyOf(ebsBlockDevices);
|
||||
}
|
||||
|
||||
public static class EbsBlockDevice2 {
|
||||
private final String volumeId;
|
||||
private final String deviceName;
|
||||
private final Boolean deleteOnTermination;
|
||||
private final Attachment.Status attachmentStatus;
|
||||
private final Date attachTime;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param volumeId
|
||||
* required parameter (can not be null)
|
||||
* @param deviceName
|
||||
* name of the device (ie "/dev/sda1")
|
||||
* @param deleteOnTermination
|
||||
* whether the volume will be deleted on instance termination
|
||||
*/
|
||||
public EbsBlockDevice2(String volumeId, @Nullable String deviceName,
|
||||
@Nullable Boolean deleteOnTermination) {
|
||||
this(volumeId, deviceName, null, null, deleteOnTermination);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param volumeId
|
||||
* required parameter (can not be null)
|
||||
* @param deviceName
|
||||
* name of the device (ie "/dev/sda1")
|
||||
* @param attachmentStatus
|
||||
* whether the device is attached, detached
|
||||
* @param attachTime
|
||||
* when the device was attached
|
||||
* @param deleteOnTermination
|
||||
* whether the volume will be deleted on instance termination
|
||||
*/
|
||||
public EbsBlockDevice2(String volumeId, @Nullable String deviceName,
|
||||
@Nullable Attachment.Status attachmentStatus,
|
||||
@Nullable Date attachTime, @Nullable Boolean deleteOnTermination) {
|
||||
this.volumeId = checkNotNull(volumeId, /*or throw*/ "VolumeId is required");
|
||||
this.deviceName = deviceName;
|
||||
this.deleteOnTermination = deleteOnTermination;
|
||||
this.attachmentStatus = attachmentStatus;
|
||||
this.attachTime = attachTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume id
|
||||
* @return volume id. This value is never null
|
||||
*/
|
||||
public String getVolumeId() {
|
||||
return volumeId;
|
||||
}
|
||||
|
||||
public String getDeviceName() {
|
||||
return deviceName;
|
||||
}
|
||||
|
||||
public Boolean isDeleteOnTermination() {
|
||||
return deleteOnTermination;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((volumeId == null) ? 0 : volumeId.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;
|
||||
EbsBlockDevice2 other = (EbsBlockDevice2) obj;
|
||||
if (volumeId == null) {
|
||||
if (other.volumeId != null)
|
||||
return false;
|
||||
} else if (!volumeId.equals(other.volumeId))
|
||||
return false;
|
||||
if (attachTime == null) {
|
||||
if (other.attachTime != null)
|
||||
return false;
|
||||
} else if (!attachTime.equals(other.attachTime))
|
||||
return false;
|
||||
if (attachmentStatus == null) {
|
||||
if (other.attachmentStatus != null)
|
||||
return false;
|
||||
} else if (!attachmentStatus.equals(other.attachmentStatus))
|
||||
return false;
|
||||
return deleteOnTermination == other.deleteOnTermination;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -41,17 +41,30 @@ public class RunningInstance implements Comparable<RunningInstance> {
|
|||
|
||||
public static class EbsBlockDevice {
|
||||
private final String volumeId;
|
||||
private final String deviceName;
|
||||
private final Attachment.Status attachmentStatus;
|
||||
private final Date attachTime;
|
||||
private final boolean deleteOnTermination;
|
||||
|
||||
public EbsBlockDevice(String volumeId, Status attachmentStatus, Date attachTime,
|
||||
boolean deleteOnTermination) {
|
||||
this(volumeId, null, attachmentStatus, attachTime, deleteOnTermination);
|
||||
}
|
||||
|
||||
public EbsBlockDevice(String volumeId, String deviceName,
|
||||
Status attachmentStatus, Date attachTime,
|
||||
boolean deleteOnTermination) {
|
||||
super();
|
||||
this.volumeId = volumeId;
|
||||
this.attachmentStatus = attachmentStatus;
|
||||
this.attachTime = attachTime;
|
||||
this.deleteOnTermination = deleteOnTermination;
|
||||
this.deviceName = deviceName;
|
||||
}
|
||||
|
||||
public EbsBlockDevice(String volumeId, String deviceName,
|
||||
boolean deleteOnTermination) {
|
||||
this(volumeId, deviceName, null, null, deleteOnTermination);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -98,6 +111,10 @@ public class RunningInstance implements Comparable<RunningInstance> {
|
|||
return volumeId;
|
||||
}
|
||||
|
||||
public String getDeviceName() {
|
||||
return deviceName;
|
||||
}
|
||||
|
||||
public Attachment.Status getAttachmentStatus() {
|
||||
return attachmentStatus;
|
||||
}
|
||||
|
|
|
@ -30,13 +30,10 @@ import javax.ws.rs.POST;
|
|||
import javax.ws.rs.Path;
|
||||
|
||||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.binders.BindBlockDeviceMappingToIndexedFormParams;
|
||||
import org.jclouds.aws.ec2.binders.BindInstanceIdsToIndexedFormParams;
|
||||
import org.jclouds.aws.ec2.binders.IfNotNullBindAvailabilityZoneToFormParam;
|
||||
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
||||
import org.jclouds.aws.ec2.domain.InstanceStateChange;
|
||||
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||
import org.jclouds.aws.ec2.domain.Reservation;
|
||||
import org.jclouds.aws.ec2.domain.Image.EbsBlockDevice;
|
||||
import org.jclouds.aws.ec2.domain.*;
|
||||
import org.jclouds.aws.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
|
||||
import org.jclouds.aws.ec2.functions.ConvertUnencodedBytesToBase64EncodedString;
|
||||
import org.jclouds.aws.ec2.functions.RegionToEndpoint;
|
||||
|
@ -222,14 +219,14 @@ public interface InstanceAsyncClient {
|
|||
@FormParam("InstanceId") String instanceId);
|
||||
|
||||
/**
|
||||
* @see AMIClient#getBlockDeviceMappingForInstanceInRegion
|
||||
* @see InstanceClient#getBlockDeviceMappingForInstanceInRegion
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute",
|
||||
"blockDeviceMapping" })
|
||||
@XMLResponseParser(BlockDeviceMappingHandler.class)
|
||||
ListenableFuture<? extends Map<String, EbsBlockDevice>> getBlockDeviceMappingForInstanceInRegion(
|
||||
ListenableFuture<? extends Map<String, Image.EbsBlockDevice>> getBlockDeviceMappingForInstanceInRegion(
|
||||
@EndpointParam(parser = RegionToEndpoint.class) Region region,
|
||||
@FormParam("InstanceId") String instanceId);
|
||||
|
||||
|
@ -320,15 +317,14 @@ public interface InstanceAsyncClient {
|
|||
@FormParam("Value") InstanceInitiatedShutdownBehavior instanceInitiatedShutdownBehavior);
|
||||
|
||||
/**
|
||||
* @see AMIClient#setBlockDeviceMappingForInstanceInRegion
|
||||
* @see InstanceClient#setBlockDeviceMappingForInstanceInRegion
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute",
|
||||
"blockDeviceMapping" })
|
||||
@FormParams(keys = { ACTION }, values = { "ModifyInstanceAttribute" })
|
||||
ListenableFuture<Void> setBlockDeviceMappingForInstanceInRegion(
|
||||
@EndpointParam(parser = RegionToEndpoint.class) Region region,
|
||||
@FormParam("InstanceId") String instanceId,
|
||||
@FormParam("Value") String blockDeviceMapping);
|
||||
@BinderParam(BindBlockDeviceMappingToIndexedFormParams.class) BlockDeviceMapping blockDeviceMapping);
|
||||
|
||||
}
|
||||
|
|
|
@ -25,12 +25,8 @@ import java.util.concurrent.TimeUnit;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
||||
import org.jclouds.aws.ec2.domain.InstanceState;
|
||||
import org.jclouds.aws.ec2.domain.InstanceStateChange;
|
||||
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||
import org.jclouds.aws.ec2.domain.Reservation;
|
||||
import org.jclouds.aws.ec2.domain.Image.EbsBlockDevice;
|
||||
import org.jclouds.aws.ec2.domain.*;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance.EbsBlockDevice;
|
||||
import org.jclouds.aws.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
|
||||
import org.jclouds.aws.ec2.options.RunInstancesOptions;
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
|
@ -499,7 +495,7 @@ public interface InstanceClient {
|
|||
InstanceInitiatedShutdownBehavior instanceInitiatedShutdownBehavior);
|
||||
|
||||
/**
|
||||
* Sets the blockDeviceMapping used for starting the instance.
|
||||
* Sets the blockDeviceMapping used for an instance.
|
||||
* <p/>
|
||||
* The instance needs to be in a {@link InstanceState#STOPPED} state, which implies two things:
|
||||
* <ol>
|
||||
|
@ -508,20 +504,16 @@ public interface InstanceClient {
|
|||
* {@link InstanceState#STOPPING} to {@link InstanceState#STOPPED}</li>
|
||||
* </ol>
|
||||
*
|
||||
* The {@code blockDeviceMapping} option takes a value in the following format:
|
||||
* <device-name>=<snapshot-id>[:<volume-size>[:<deleteOnTermination>]]
|
||||
* To create the instances of {@link RunningInstance.EbsBlockDevice},
|
||||
* the constructor can be used with the following parameters:
|
||||
* {@link RunningInstance.EbsBlockDevice#EbsBlockDevice(String, String, boolean)},
|
||||
* that are:
|
||||
* <ol>
|
||||
* <li>device-name - this is the device name as it should be exposed to the instance, for example
|
||||
* /dev/sdb. This is the same as the device field specified in the AttachVolume call today. This
|
||||
* field also serves as the key for the structure.</li>
|
||||
* <li>snapshot-id - the ID of the EBS snapshot to be used when creating the volume. This field
|
||||
* is optional. If it is not specified, the volume-size field must be present to create a blank
|
||||
* volume of the specified size.</li>
|
||||
* <li>volume-size - the size (GiBs) of the volume. This field is optional unless no snapshot-id
|
||||
* is present. If a snapshot-id is present, the size must be equal to or larger than the
|
||||
* snapshot's volume size.</li>
|
||||
* <li>delete-on-termination - this indicates whether the volume should be deleted on
|
||||
* termination. It defaults to ' true '.</li>
|
||||
* <li>Volume id (required), for instance, "vol-blah"</li>
|
||||
* <li>Device name (optional), for instance, "/dev/sda1". To find out more about
|
||||
* device names, read the next paragraph.</li>
|
||||
* <li>Delete on termination flag (optional), which defines whether the volume will be
|
||||
* deleted upon instance's termination.</li>
|
||||
* </ol>
|
||||
* <p/>
|
||||
* Note that the device names between Linux and Windows differ. For Linux, ensure that your
|
||||
|
@ -532,31 +524,10 @@ public interface InstanceClient {
|
|||
* that they are in the form /xvd[c-p] . For example, /xvde , /xvdf and /xvdp are all valid
|
||||
* Windows device names.
|
||||
* <p/>
|
||||
* Here are a few extra examples on how this functionality can be used.
|
||||
*
|
||||
* <ol>
|
||||
* <li>
|
||||
* resize the root volume: @{code /dev/sda1=:100}</li>
|
||||
* <li>
|
||||
* don't delete the root volume: {@code /dev/sda1=:100:false}</li>
|
||||
* <li>
|
||||
* TODO: unverified: create and attach an additional volume at launch: {@code
|
||||
* /dev/sdb=snap-e8a23d81,/dev/sdc=:200}
|
||||
* <p/>
|
||||
* The above example will create and attach the following EBS volumes at launch time:
|
||||
* <ol>
|
||||
* <li>
|
||||
* /dev/sdb - a 10 GiBs EBS volume containing an ext3 file system; this is an Amazon shared
|
||||
* snapshot.</li>
|
||||
* <li>
|
||||
* /dev/sdc - an empty 200 GiB EBS volume.</li>
|
||||
* </ol>
|
||||
* </li>
|
||||
* <li>
|
||||
* TODO: unverified: cresize the root partition of a Windows 2008 image and add an additional 100
|
||||
* GiB device: {@code /dev/sda1=:100,/dev/xvdc=:100}</li>
|
||||
* </ol>
|
||||
*
|
||||
* <b>NOTE</b>: As of now 02/20/2010, this command only works to change the
|
||||
* DeleteOnTermination property of the device. The volume must be <i>attached</i> to a
|
||||
* stopped instance.
|
||||
*
|
||||
* @param region
|
||||
* Instances are tied to Availability Zones. However, the instance ID is tied to the
|
||||
* Region.
|
||||
|
@ -568,5 +539,5 @@ public interface InstanceClient {
|
|||
* />
|
||||
*/
|
||||
void setBlockDeviceMappingForInstanceInRegion(Region region, String instanceId,
|
||||
String blockDeviceMapping);
|
||||
BlockDeviceMapping blockDeviceMapping);
|
||||
}
|
||||
|
|
|
@ -18,16 +18,19 @@
|
|||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.Image;
|
||||
import org.jclouds.aws.ec2.domain.Image.EbsBlockDevice;
|
||||
import com.google.inject.Inject;
|
||||
import org.jclouds.aws.ec2.domain.Attachment;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance.EbsBlockDevice;
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BlockDeviceMappingHandler extends
|
||||
|
@ -36,9 +39,17 @@ public class BlockDeviceMappingHandler extends
|
|||
|
||||
private Map<String, EbsBlockDevice> ebsBlockDevices = Maps.newHashMap();
|
||||
private String deviceName;
|
||||
private String snapshotId;
|
||||
private int volumeSize;
|
||||
private String volumeId;
|
||||
private boolean deleteOnTermination = true;// correct default is true.
|
||||
private Attachment.Status attachmentStatus;
|
||||
private Date attachTime;
|
||||
|
||||
protected final DateService dateService;
|
||||
|
||||
@Inject
|
||||
public BlockDeviceMappingHandler(DateService dateService) {
|
||||
this.dateService = dateService;
|
||||
}
|
||||
|
||||
public Map<String, EbsBlockDevice> getResult() {
|
||||
return ebsBlockDevices;
|
||||
|
@ -47,18 +58,22 @@ public class BlockDeviceMappingHandler extends
|
|||
public void endElement(String uri, String name, String qName) {
|
||||
if (qName.equals("deviceName")) {
|
||||
deviceName = currentText.toString().trim();
|
||||
} else if (qName.equals("snapshotId")) {
|
||||
snapshotId = currentText.toString().trim();
|
||||
} else if (qName.equals("volumeSize")) {
|
||||
volumeSize = Integer.parseInt(currentText.toString().trim());
|
||||
} else if (qName.equals("volumeId")) {
|
||||
volumeId = currentText.toString().trim();
|
||||
} else if (qName.equals("deleteOnTermination")) {
|
||||
deleteOnTermination = Boolean.parseBoolean(currentText.toString().trim());
|
||||
} else if (qName.equals("status")) {
|
||||
attachmentStatus = Attachment.Status.fromValue(currentText.toString().trim());
|
||||
} else if (qName.equals("attachTime")) {
|
||||
attachTime = dateService.iso8601DateParse(currentText.toString().trim());
|
||||
} else if (qName.equals("item")) {
|
||||
ebsBlockDevices.put(deviceName, new Image.EbsBlockDevice(snapshotId, volumeSize,
|
||||
deleteOnTermination));
|
||||
this.snapshotId = null;
|
||||
this.volumeSize = 0;
|
||||
this.deleteOnTermination = true;
|
||||
ebsBlockDevices.put(deviceName, new EbsBlockDevice(volumeId, deviceName,
|
||||
attachmentStatus, attachTime, deleteOnTermination));
|
||||
this.volumeId = null;
|
||||
this.deviceName = null;
|
||||
this.deleteOnTermination = true;
|
||||
this.attachmentStatus = null;
|
||||
this.attachTime = null;
|
||||
}
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
|
|
@ -36,13 +36,7 @@ import java.util.concurrent.TimeoutException;
|
|||
|
||||
import org.jclouds.aws.AWSResponseException;
|
||||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.domain.InstanceState;
|
||||
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||
import org.jclouds.aws.ec2.domain.IpProtocol;
|
||||
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||
import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair;
|
||||
import org.jclouds.aws.ec2.domain.Reservation;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||
import org.jclouds.aws.ec2.domain.*;
|
||||
import org.jclouds.aws.ec2.domain.Image.EbsBlockDevice;
|
||||
import org.jclouds.aws.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
|
||||
import org.jclouds.aws.ec2.predicates.InstanceHasIpAddress;
|
||||
|
@ -276,9 +270,10 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
}
|
||||
|
||||
private void setBlockDeviceMappingForInstanceInRegion() {
|
||||
BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping();
|
||||
try {
|
||||
client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(Region.DEFAULT,
|
||||
instanceId, "whoopie");
|
||||
instanceId, blockDeviceMapping);
|
||||
assert false : "shouldn't be allowed, as instance needs to be ebs based-ami";
|
||||
} catch (AWSResponseException e) {
|
||||
assertEquals("InvalidParameterCombination", e.getError().getCode());
|
||||
|
|
|
@ -30,6 +30,7 @@ import java.io.ByteArrayInputStream;
|
|||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -37,19 +38,8 @@ import java.util.concurrent.TimeoutException;
|
|||
|
||||
import org.jclouds.aws.AWSResponseException;
|
||||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.domain.Attachment;
|
||||
import org.jclouds.aws.ec2.domain.Image;
|
||||
import org.jclouds.aws.ec2.domain.InstanceState;
|
||||
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||
import org.jclouds.aws.ec2.domain.IpProtocol;
|
||||
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||
import org.jclouds.aws.ec2.domain.Reservation;
|
||||
import org.jclouds.aws.ec2.domain.RootDeviceType;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||
import org.jclouds.aws.ec2.domain.Snapshot;
|
||||
import org.jclouds.aws.ec2.domain.Volume;
|
||||
import org.jclouds.aws.ec2.domain.*;
|
||||
import org.jclouds.aws.ec2.domain.Image.Architecture;
|
||||
import org.jclouds.aws.ec2.domain.Image.EbsBlockDevice;
|
||||
import org.jclouds.aws.ec2.domain.Image.ImageType;
|
||||
import org.jclouds.aws.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
|
||||
import org.jclouds.aws.ec2.predicates.InstanceStateRunning;
|
||||
|
@ -457,15 +447,24 @@ public class EBSBootEC2ClientLiveTest {
|
|||
.getInstanceTypeForInstanceInRegion(Region.DEFAULT, ebsInstance.getId()));
|
||||
}
|
||||
|
||||
private void setBlockDeviceMappingForInstanceInRegion() { // TODO: determine the correct
|
||||
// blockDeviceMapping format
|
||||
private void setBlockDeviceMappingForInstanceInRegion() {
|
||||
BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping();
|
||||
blockDeviceMapping.addEbsBlockDevice
|
||||
(new RunningInstance.EbsBlockDevice(volume.getId(), "/dev/sda1", false));
|
||||
try {
|
||||
client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(Region.DEFAULT,
|
||||
ebsInstance.getId(), "whoopie");
|
||||
ebsInstance.getId(), blockDeviceMapping);
|
||||
|
||||
assertEquals(ImmutableMap.<String, EbsBlockDevice> of("whoopie", null), client
|
||||
Map<String, RunningInstance.EbsBlockDevice> devices = client
|
||||
.getInstanceServices().getBlockDeviceMappingForInstanceInRegion(Region.DEFAULT,
|
||||
ebsInstance.getId()));
|
||||
ebsInstance.getId());
|
||||
assertEquals(devices.size(), 1);
|
||||
RunningInstance.EbsBlockDevice device = Iterables.getOnlyElement(devices.values());
|
||||
|
||||
assertEquals(device.getVolumeId(), volume.getId());
|
||||
assertEquals(device.getDeviceName(), "/dev/sda1");
|
||||
assertEquals(device.isDeleteOnTermination(), false);
|
||||
|
||||
System.out.println("OK: setBlockDeviceMappingForInstanceInRegion");
|
||||
} catch (Exception e) {
|
||||
System.err.println("setBlockDeviceMappingForInstanceInRegion");
|
||||
|
|
|
@ -31,7 +31,9 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.EC2;
|
||||
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
||||
import org.jclouds.aws.ec2.domain.BlockDeviceMapping;
|
||||
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||
import org.jclouds.aws.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
|
||||
import org.jclouds.aws.ec2.options.RunInstancesOptions;
|
||||
import org.jclouds.aws.ec2.xml.BlockDeviceMappingHandler;
|
||||
|
@ -523,20 +525,24 @@ public class InstanceAsyncClientTest extends RestClientTest<InstanceAsyncClient>
|
|||
NoSuchMethodException, IOException {
|
||||
Method method = InstanceAsyncClient.class
|
||||
.getMethod("setBlockDeviceMappingForInstanceInRegion", Region.class, String.class,
|
||||
String.class);
|
||||
BlockDeviceMapping.class);
|
||||
|
||||
BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping();
|
||||
blockDeviceMapping.addEbsBlockDevice
|
||||
(new RunningInstance.EbsBlockDevice("/dev/sda1", "vol-test1", true));
|
||||
GeneratedHttpRequest<InstanceAsyncClient> httpMethod = processor.createRequest(method,
|
||||
Region.DEFAULT, "1", "test");
|
||||
Region.DEFAULT, "1", blockDeviceMapping);
|
||||
|
||||
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod,
|
||||
"Content-Length: 102\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
|
||||
"Content-Length: 62\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
|
||||
assertPayloadEquals(
|
||||
httpMethod,
|
||||
"Version=2009-11-30&Action=ModifyInstanceAttribute&Attribute=blockDeviceMapping&Value=test&InstanceId=1");
|
||||
"Version=2009-11-30&Action=ModifyInstanceAttribute&InstanceId=1&BlockDeviceMapping.1.Ebs.VolumeId=%2Fdev%2Fsda1&BlockDeviceMapping.1.DeviceName=vol-test1&BlockDeviceMapping.1.Ebs.DeleteOnTermination=true");
|
||||
filter.filter(httpMethod);// ensure encoding worked properly
|
||||
assertPayloadEquals(
|
||||
httpMethod,
|
||||
"Action=ModifyInstanceAttribute&Attribute=blockDeviceMapping&InstanceId=1&Signature=KNCKfLATSmpXGuIBpXOx3lBmHv9tyu17Cxrfi%2FTzQHE%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Value=test&Version=2009-11-30&AWSAccessKeyId=user");
|
||||
"Action=ModifyInstanceAttribute&BlockDeviceMapping.1.DeviceName=vol-test1&BlockDeviceMapping.1.Ebs.DeleteOnTermination=true&BlockDeviceMapping.1.Ebs.VolumeId=%2Fdev%2Fsda1&InstanceId=1&Signature=Htpx4bm6v0O%2FcYxrsGb74NbTzCJfPtKWeuB8l2TpL%2B0%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2009-11-30&AWSAccessKeyId=user");
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, CloseContentAndReturn.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
|
|
|
@ -21,9 +21,12 @@ package org.jclouds.aws.ec2.xml;
|
|||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.Image.EbsBlockDevice;
|
||||
import org.jclouds.aws.ec2.domain.Attachment;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance.EbsBlockDevice;
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -41,9 +44,16 @@ public class BlockDeviceMappingHandlerTest extends BaseHandlerTest {
|
|||
InputStream is = getClass().getResourceAsStream(
|
||||
"/ec2/describe_image_attribute_blockDeviceMapping.xml");
|
||||
|
||||
DateService dateService = injector.getInstance(DateService.class);
|
||||
Map<String, EbsBlockDevice> expected = ImmutableMap.<String, EbsBlockDevice> of("/dev/sda1",
|
||||
new EbsBlockDevice("snap-d01272b9", 30, true), "xvdf", new EbsBlockDevice(
|
||||
"snap-d31272ba", 250, false));
|
||||
new EbsBlockDevice("vol-d74b82be", "/dev/sda1",
|
||||
Attachment.Status.ATTACHED,
|
||||
dateService.iso8601DateParse("2010-02-20T18:25:26.000Z"), true),
|
||||
"/dev/sdf",
|
||||
new EbsBlockDevice("vol-another", "/dev/sdf",
|
||||
Attachment.Status.DETACHED,
|
||||
dateService.iso8601DateParse("2010-02-20T19:26:26.000Z"), false)
|
||||
);
|
||||
|
||||
Map<String, EbsBlockDevice> result = factory.create(
|
||||
injector.getInstance(BlockDeviceMappingHandler.class)).parse(is);
|
||||
|
|
|
@ -1,22 +1,24 @@
|
|||
<DescribeImageAttributeResponse
|
||||
xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
|
||||
<imageId>ami-61a54008</imageId>
|
||||
<DescribeInstanceAttributeResponse
|
||||
xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
|
||||
<instanceId>i-7f629614</instanceId>
|
||||
<blockDeviceMapping>
|
||||
<item>
|
||||
<deviceName>/dev/sda1</deviceName>
|
||||
<ebs>
|
||||
<snapshotId>snap-d01272b9</snapshotId>
|
||||
<volumeSize>30</volumeSize>
|
||||
<volumeId>vol-d74b82be</volumeId>
|
||||
<status>attached</status>
|
||||
<attachTime>2010-02-20T18:25:26.000Z</attachTime>
|
||||
<deleteOnTermination>true</deleteOnTermination>
|
||||
</ebs>
|
||||
</item>
|
||||
<item>
|
||||
<deviceName>xvdf</deviceName>
|
||||
<deviceName>/dev/sdf</deviceName>
|
||||
<ebs>
|
||||
<snapshotId>snap-d31272ba</snapshotId>
|
||||
<volumeSize>250</volumeSize>
|
||||
<volumeId>vol-another</volumeId>
|
||||
<status>detached</status>
|
||||
<attachTime>2010-02-20T19:26:26.000Z</attachTime>
|
||||
<deleteOnTermination>false</deleteOnTermination>
|
||||
</ebs>
|
||||
</item>
|
||||
</blockDeviceMapping>
|
||||
</DescribeImageAttributeResponse>
|
||||
</DescribeInstanceAttributeResponse>
|
Loading…
Reference in New Issue