Issue 448: merged in ebs functionality

This commit is contained in:
Adrian Cole 2011-01-18 14:32:22 -08:00
commit 93b488f52d
24 changed files with 727 additions and 358 deletions

View File

@ -23,14 +23,17 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.ec2.domain.RunningInstance;
import java.util.Map;
import java.util.Map.Entry;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.utils.ModifyRequest;
import org.jclouds.rest.Binder;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableMultimap.Builder;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
/**
* @author Oleksiy Yarmula
@ -44,29 +47,22 @@ public class BindBlockDeviceMappingToIndexedFormParams implements Binder {
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
checkArgument(checkNotNull(input, "input") instanceof BlockDeviceMapping,
"this binder is only valid for BlockDeviceMapping");
BlockDeviceMapping blockDeviceMapping = (BlockDeviceMapping) input;
checkArgument(checkNotNull(input, "input") instanceof Map, "this binder is only valid for Map");
@SuppressWarnings("unchecked")
Map<String, BlockDevice> blockDeviceMapping = (Map<String, BlockDevice>) input;
Builder<String, String> builder = ImmutableMultimap.<String, String> builder();
com.google.common.collect.ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String> builder();
int amazonOneBasedIndex = 1; // according to docs, counters must start with 1
for (String ebsBlockDeviceName : blockDeviceMapping.getEbsBlockDevices().keySet()) {
for (RunningInstance.EbsBlockDevice ebsBlockDevice : blockDeviceMapping.getEbsBlockDevices().get(
ebsBlockDeviceName)) {
for (Entry<String, BlockDevice> ebsBlockDeviceName : blockDeviceMapping.entrySet()) {
// not null by contract
builder.put(format(volumeIdPattern, amazonOneBasedIndex), ebsBlockDeviceName.getValue().getVolumeId());
builder.put(format(deviceNamePattern, amazonOneBasedIndex), ebsBlockDeviceName.getKey());
builder.put(format(deleteOnTerminationPattern, amazonOneBasedIndex),
String.valueOf(ebsBlockDeviceName.getValue().isDeleteOnTermination()));
// not null by contract
builder.put(format(volumeIdPattern, amazonOneBasedIndex), ebsBlockDevice.getVolumeId());
if (ebsBlockDeviceName != null) {
builder.put(format(deviceNamePattern, amazonOneBasedIndex), ebsBlockDeviceName);
}
builder.put(format(deleteOnTerminationPattern, amazonOneBasedIndex),
String.valueOf(ebsBlockDevice.isDeleteOnTermination()));
amazonOneBasedIndex++;
}
amazonOneBasedIndex++;
}
ImmutableMultimap<String, String> forms = builder.build();
Multimap<String, String> forms = Multimaps.forMap(builder.build());
return forms.size() == 0 ? request : ModifyRequest.putFormParams(request, forms);
}

View File

@ -32,10 +32,10 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.ec2.compute.domain.RegionAndName;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.RootDeviceType;
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.ec2.domain.RunningInstance.EbsBlockDevice;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder;
@ -131,10 +131,10 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
@VisibleForTesting
static List<Volume> addEBS(final RunningInstance instance, Iterable<? extends Volume> volumes) {
Iterable<Volume> ebsVolumes = Iterables.transform(instance.getEbsBlockDevices().entrySet(),
new Function<Entry<String, EbsBlockDevice>, Volume>() {
new Function<Entry<String, BlockDevice>, Volume>() {
@Override
public Volume apply(Entry<String, EbsBlockDevice> from) {
public Volume apply(Entry<String, BlockDevice> from) {
return new VolumeImpl(from.getValue().getVolumeId(), Volume.Type.SAN, null, from.getKey(),
instance.getRootDeviceName() != null
&& instance.getRootDeviceName().equals(from.getKey()), true);

View File

@ -29,8 +29,6 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import org.jclouds.ec2.compute.domain.RegionAndName;
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
@ -38,6 +36,8 @@ import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.internal.TemplateBuilderImpl;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Location;
import org.jclouds.ec2.compute.domain.RegionAndName;
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
import com.google.common.base.Supplier;
import com.google.common.collect.ComputationException;
@ -73,6 +73,7 @@ public class EC2TemplateBuilderImpl extends TemplateBuilderImpl {
eTo.noKeyPair();
if (eFrom.getSubnetId() != null)
eTo.subnetId(eFrom.getSubnetId());
eTo.blockDeviceMappings(eFrom.getBlockDeviceMappings());
if (eFrom.isMonitoringEnabled())
eTo.enableMonitoring();
if (eFrom.getUserData() != null)

View File

@ -24,10 +24,18 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Credentials;
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 org.jclouds.ec2.domain.BlockDeviceMapping.UnmapDeviceNamed;
import org.jclouds.io.Payload;
import org.jclouds.scriptbuilder.domain.Statement;
import org.jclouds.util.Preconditions2;
@ -43,7 +51,7 @@ import com.google.common.collect.Iterables;
* needed):
* <p/>
* <code>
* import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.*;
* import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.*;
* <p/>
* ComputeService client = // get connection
* templateBuilder.options(inboundPorts(22, 80, 8080, 443));
@ -62,6 +70,7 @@ public class EC2TemplateOptions extends TemplateOptions {
private boolean noPlacementGroup;
private String subnetId;
private byte[] userData;
private Set<BlockDeviceMapping> blockDeviceMappings = ImmutableSet.of();
public static final EC2TemplateOptions NONE = new EC2TemplateOptions();
@ -94,17 +103,16 @@ public class EC2TemplateOptions extends TemplateOptions {
return this;
}
/**
* Unencoded data
*/
public EC2TemplateOptions userData(byte[] unencodedData) {
checkArgument(checkNotNull(unencodedData, "unencodedData").length <= 16 * 1024,
"userData cannot be larger than 16kb");
"userData cannot be larger than 16kb");
this.userData = unencodedData;
return this;
}
/**
* Specifies the keypair used to run instances with
*/
@ -155,6 +163,81 @@ public class EC2TemplateOptions extends TemplateOptions {
return this;
}
/**
* Specifies the block device mappings to be used to run the instance
*/
public EC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId,
@Nullable Integer sizeInGib, @Nullable Boolean deleteOnTermination) {
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);
MapEBSSnapshotToDevice mapping = new MapEBSSnapshotToDevice(deviceName, snapshotId, 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 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) {
this.blockDeviceMappings = ImmutableSet.copyOf(checkNotNull(blockDeviceMappings, "blockDeviceMappings"));
return this;
}
public static class Builder {
/**
@ -180,7 +263,7 @@ public class EC2TemplateOptions extends TemplateOptions {
EC2TemplateOptions options = new EC2TemplateOptions();
return EC2TemplateOptions.class.cast(options.keyPair(keyPair));
}
/**
* @see EC2TemplateOptions#userData
*/
@ -277,7 +360,6 @@ public class EC2TemplateOptions extends TemplateOptions {
EC2TemplateOptions options = new EC2TemplateOptions();
return EC2TemplateOptions.class.cast(options.subnetId(subnetId));
}
}
// methods that only facilitate returning the correct object type
@ -454,7 +536,7 @@ public class EC2TemplateOptions extends TemplateOptions {
public String getSubnetId() {
return subnetId;
}
/**
* @return unencoded user data.
*/
@ -462,18 +544,27 @@ public class EC2TemplateOptions extends TemplateOptions {
return userData;
}
/**
* @return BlockDeviceMapping to use when running the instance or null.
*/
public Set<BlockDeviceMapping> getBlockDeviceMappings() {
return blockDeviceMappings;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((blockDeviceMappings == null) ? 0 : blockDeviceMappings.hashCode());
result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode());
result = prime * result + ((keyPair == null) ? 0 : keyPair.hashCode());
result = prime * result + (monitoringEnabled ? 1231 : 1237);
result = prime * result + (noKeyPair ? 1231 : 1237);
result = prime * result + (noPlacementGroup ? 1231 : 1237);
result = prime * result + (monitoringEnabled ? 1231 : 1237);
result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode());
result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode());
result = prime * result + ((userData == null) ? 0 : userData.hashCode());
result = prime * result + Arrays.hashCode(userData);
return result;
}
@ -486,6 +577,11 @@ public class EC2TemplateOptions extends TemplateOptions {
if (getClass() != obj.getClass())
return false;
EC2TemplateOptions other = (EC2TemplateOptions) obj;
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;
@ -496,12 +592,12 @@ public class EC2TemplateOptions extends TemplateOptions {
return false;
} else if (!keyPair.equals(other.keyPair))
return false;
if (monitoringEnabled != other.monitoringEnabled)
return false;
if (noKeyPair != other.noKeyPair)
return false;
if (noPlacementGroup != other.noPlacementGroup)
return false;
if (monitoringEnabled != other.monitoringEnabled)
return false;
if (placementGroup == null) {
if (other.placementGroup != null)
return false;
@ -512,21 +608,19 @@ public class EC2TemplateOptions extends TemplateOptions {
return false;
} else if (!subnetId.equals(other.subnetId))
return false;
if (userData == null) {
if (other.userData != null)
return false;
} else if (!userData.equals(other.userData))
if (!Arrays.equals(userData, other.userData))
return false;
return true;
}
@Override
public String toString() {
return "[groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair + ", placementGroup="
+ placementGroup + ", noPlacementGroup=" + noPlacementGroup + ", monitoringEnabled=" + monitoringEnabled
+ ", inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null)
+ ", publicKey=" + (publicKey != null) + ", runScript=" + (script != null) + ", port:seconds=" + port
+ ":" + seconds + ", subnetId=" + subnetId + ", metadata/details: " + includeMetadata + "]";
return "EC2TemplateOptions [groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair
+ ", monitoringEnabled=" + monitoringEnabled + ", placementGroup=" + placementGroup + ", noPlacementGroup="
+ noPlacementGroup + ", subnetId=" + subnetId + ", userData=" + Arrays.toString(userData)
+ ", blockDeviceMappings=" + blockDeviceMappings + "]";
}
}

View File

@ -19,6 +19,7 @@
package org.jclouds.ec2.compute.strategy;
import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.asType;
import java.util.Map;
@ -29,16 +30,17 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.ec2.compute.domain.RegionAndName;
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
import org.jclouds.ec2.compute.functions.CreatePlacementGroupIfNeeded;
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.ec2.domain.KeyPair;
import org.jclouds.ec2.options.RunInstancesOptions;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.location.Provider;
import com.google.common.annotations.VisibleForTesting;
@ -114,6 +116,13 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions
if (userData != null)
instanceOptions.withUserData(userData);
Set<BlockDeviceMapping> blockDeviceMappings = EC2TemplateOptions.class.cast(template.getOptions())
.getBlockDeviceMappings();
if (blockDeviceMappings != null && blockDeviceMappings.size() > 0) {
checkState("ebs".equals(template.getImage().getUserMetadata().get("rootDeviceType")),
"BlockDeviceMapping only available on ebs boot");
instanceOptions.withBlockDeviceMappings(blockDeviceMappings);
}
return instanceOptions;
}
@ -189,4 +198,4 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions
}
return groups;
}
}
}

View File

@ -0,0 +1,107 @@
/**
*
* 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.ec2.domain;
import java.util.Date;
import org.jclouds.ec2.domain.Attachment.Status;
/**
*
* @see <a href=
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-RunningInstancesItemType.html"
* />
* @author Adrian Cole
*/
public class BlockDevice {
private final String volumeId;
private final Attachment.Status attachmentStatus;
private final Date attachTime;
private final boolean deleteOnTermination;
public BlockDevice(String volumeId, Status attachmentStatus, Date attachTime, boolean deleteOnTermination) {
super();
this.volumeId = volumeId;
this.attachmentStatus = attachmentStatus;
this.attachTime = attachTime;
this.deleteOnTermination = deleteOnTermination;
}
public BlockDevice(String volumeId, boolean deleteOnTermination) {
this(volumeId, null, null, deleteOnTermination);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((attachTime == null) ? 0 : attachTime.hashCode());
result = prime * result + ((attachmentStatus == null) ? 0 : attachmentStatus.hashCode());
result = prime * result + (deleteOnTermination ? 1231 : 1237);
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;
BlockDevice other = (BlockDevice) obj;
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;
if (deleteOnTermination != other.deleteOnTermination)
return false;
if (volumeId == null) {
if (other.volumeId != null)
return false;
} else if (!volumeId.equals(other.volumeId))
return false;
return true;
}
public String getVolumeId() {
return volumeId;
}
public Attachment.Status getAttachmentStatus() {
return attachmentStatus;
}
public Date getAttachTime() {
return attachTime;
}
public boolean isDeleteOnTermination() {
return deleteOnTermination;
}
}

View File

@ -19,59 +19,130 @@
package org.jclouds.ec2.domain;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import org.jclouds.util.Preconditions2;
/**
* Defines the mapping of volumes for
* {@link org.jclouds.ec2.services.InstanceClient#setBlockDeviceMappingForInstanceInRegion}.
*
* @author Oleksiy Yarmula
* @author Lili Nadar
*/
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;
private final Multimap<String, RunningInstance.EbsBlockDevice> ebsBlockDevices = LinkedHashMultimap
.create();
// values expressed in GB
private static final Integer VOLUME_SIZE_MIN_VALUE = 1;
private static final Integer VOLUME_SIZE_MAX_VALUE = 1000;
public BlockDeviceMapping() {
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;
}
/**
* 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. This cannot be null.
*/
public BlockDeviceMapping(Multimap<String, RunningInstance.EbsBlockDevice> ebsBlockDevices) {
this.ebsBlockDevices.putAll(checkNotNull(ebsBlockDevices,
/* or throw */"EbsBlockDevices can't be null"));
public String getDeviceName() {
return deviceName;
}
/**
* Adds a {@link RunningInstance.EbsBlockDevice} to the mapping.
*
* @param deviceName
* name of the device to apply the mapping. Can be null.
* @param ebsBlockDevice
* ebsBlockDevice to be added. This cannot be null.
* @return the same instance for method chaining purposes
*/
public BlockDeviceMapping addEbsBlockDevice(@Nullable String deviceName,
RunningInstance.EbsBlockDevice ebsBlockDevice) {
this.ebsBlockDevices.put(deviceName, checkNotNull(ebsBlockDevice,
/* or throw */"EbsBlockDevice can't be null"));
return this;
public String getVirtualName() {
return virtualName;
}
public Multimap<String, RunningInstance.EbsBlockDevice> getEbsBlockDevices() {
return ImmutableMultimap.<String, RunningInstance.EbsBlockDevice> builder().putAll(
ebsBlockDevices).build();
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

@ -27,7 +27,6 @@ import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.ec2.domain.Attachment.Status;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
@ -41,82 +40,6 @@ import com.google.common.collect.Sets;
*/
public class RunningInstance implements Comparable<RunningInstance> {
public static class EbsBlockDevice {
private final String volumeId;
private final Attachment.Status attachmentStatus;
private final Date attachTime;
private final boolean deleteOnTermination;
public EbsBlockDevice(String volumeId, Status attachmentStatus, Date attachTime, boolean deleteOnTermination) {
super();
this.volumeId = volumeId;
this.attachmentStatus = attachmentStatus;
this.attachTime = attachTime;
this.deleteOnTermination = deleteOnTermination;
}
public EbsBlockDevice(String volumeId, boolean deleteOnTermination) {
this(volumeId, null, null, deleteOnTermination);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((attachTime == null) ? 0 : attachTime.hashCode());
result = prime * result + ((attachmentStatus == null) ? 0 : attachmentStatus.hashCode());
result = prime * result + (deleteOnTermination ? 1231 : 1237);
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;
EbsBlockDevice other = (EbsBlockDevice) obj;
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;
if (deleteOnTermination != other.deleteOnTermination)
return false;
if (volumeId == null) {
if (other.volumeId != null)
return false;
} else if (!volumeId.equals(other.volumeId))
return false;
return true;
}
public String getVolumeId() {
return volumeId;
}
public Attachment.Status getAttachmentStatus() {
return attachmentStatus;
}
public Date getAttachTime() {
return attachTime;
}
public boolean isDeleteOnTermination() {
return deleteOnTermination;
}
}
private final String region;
private final Set<String> groupIds = Sets.newLinkedHashSet();
@ -159,7 +82,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
private final RootDeviceType rootDeviceType;
@Nullable
private final String rootDeviceName;
private final Map<String, EbsBlockDevice> ebsBlockDevices = Maps.newHashMap();
private final Map<String, BlockDevice> ebsBlockDevices = Maps.newHashMap();
public int compareTo(RunningInstance o) {
return (this == o) ? 0 : getId().compareTo(o.getId());
@ -173,7 +96,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
@Nullable String privateIpAddress, Set<String> productCodes, @Nullable String ramdiskId,
@Nullable String reason, @Nullable String subnetId, @Nullable String spotInstanceRequestId,
@Nullable String vpcId, RootDeviceType rootDeviceType, @Nullable String rootDeviceName,
Map<String, EbsBlockDevice> ebsBlockDevices) {
Map<String, BlockDevice> ebsBlockDevices) {
Iterables.addAll(this.groupIds, checkNotNull(groupIds, "groupIds"));
this.region = checkNotNull(region, "region");
this.amiLaunchIndex = amiLaunchIndex; // nullable on runinstances.
@ -389,7 +312,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
/**
* EBS volumes associated with the instance.
*/
public Map<String, EbsBlockDevice> getEbsBlockDevices() {
public Map<String, BlockDevice> getEbsBlockDevices() {
return ebsBlockDevices;
}

View File

@ -22,6 +22,9 @@ package org.jclouds.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.ec2.domain.BlockDeviceMapping;
import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.ec2.options.internal.BaseEC2RequestOptions;
import org.jclouds.encryption.internal.Base64;
@ -33,7 +36,7 @@ import org.jclouds.encryption.internal.Base64;
* mutator (if needed):
* <p/>
* <code>
* import static org.jclouds.ec2.options.RunInstancesOptions.Builder.*
* import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.*
* <p/>
* EC2Client connection = // get connection
* Future<ReservationInfo> instances = connection.runInstances(executableBy("123125").imageIds(1000, 1004));
@ -160,30 +163,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.
*/
@ -208,6 +187,34 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
String getSubnetId() {
return getFirstFormOrNull("SubnetId");
}
/**
* Specifies the Block Device Mapping for the instance
*
*/
public RunInstancesOptions withBlockDeviceMappings(Set<? extends BlockDeviceMapping> mappings) {
int i = 1;
for(BlockDeviceMapping mapping: mappings)
{
checkNotNull(mapping.getDeviceName(), "deviceName");
formParameters.put(String.format("BlockDeviceMapping.%d.DeviceName", i), mapping.getDeviceName());
if(mapping.getVirtualName() != null)
formParameters.put(String.format("BlockDeviceMapping.%d.VirtualName", i), mapping.getVirtualName());
if(mapping.getEbsSnapshotId() != null)
formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.SnapshotId", i), mapping.getEbsSnapshotId());
if(mapping.getEbsVolumeSize() != null)
formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.VolumeSize", i), String.valueOf(mapping.getEbsVolumeSize()));
if(mapping.getEbsNoDevice() != null)
formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.NoDevice", i), String.valueOf(mapping.getEbsNoDevice()));
if(mapping.getEbsDeleteOnTermination() != null)
formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.DeleteOnTermination", i), String.valueOf(mapping.getEbsDeleteOnTermination()));
i++;
}
return this;
}
public static class Builder {
/**
@ -258,14 +265,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()
*/
@ -289,13 +288,13 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
RunInstancesOptions options = new RunInstancesOptions();
return options.withRamdisk(ramdiskId);
}
/**
* @see RunInstancesOptions#withVirtualName(String)
* @see RunInstancesOptions#withBlockDeviceMappings(Set<BlockDeviceMapping> mappings)
*/
public static RunInstancesOptions withVirtualName(String virtualName) {
public static RunInstancesOptions withBlockDeviceMappings(Set<? extends BlockDeviceMapping> mappings) {
RunInstancesOptions options = new RunInstancesOptions();
return options.withVirtualName(virtualName);
return options.withBlockDeviceMappings(mappings);
}
}

View File

@ -35,7 +35,7 @@ import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.binders.BindBlockDeviceMappingToIndexedFormParams;
import org.jclouds.ec2.binders.BindInstanceIdsToIndexedFormParams;
import org.jclouds.ec2.binders.IfNotNullBindAvailabilityZoneToFormParam;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.InstanceStateChange;
import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RunningInstance;
@ -84,8 +84,8 @@ public interface InstanceAsyncClient {
@XMLResponseParser(DescribeInstancesResponseHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<? extends Reservation<? extends RunningInstance>>> describeInstancesInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
/**
* @see InstanceClient#runInstancesInRegion
@ -94,10 +94,11 @@ public interface InstanceAsyncClient {
@Path("/")
@FormParams(keys = ACTION, values = "RunInstances")
@XMLResponseParser(RunInstancesResponseHandler.class)
ListenableFuture<Reservation<? extends RunningInstance>> runInstancesInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@Nullable @BinderParam(IfNotNullBindAvailabilityZoneToFormParam.class) String nullableAvailabilityZone,
@FormParam("ImageId") String imageId, @FormParam("MinCount") int minCount,
@FormParam("MaxCount") int maxCount, RunInstancesOptions... options);
ListenableFuture<Reservation<? extends RunningInstance>> runInstancesInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@Nullable @BinderParam(IfNotNullBindAvailabilityZoneToFormParam.class) String nullableAvailabilityZone,
@FormParam("ImageId") String imageId, @FormParam("MinCount") int minCount,
@FormParam("MaxCount") int maxCount, RunInstancesOptions... options);
/**
* @see InstanceClient#rebootInstancesInRegion
@ -105,8 +106,9 @@ public interface InstanceAsyncClient {
@POST
@Path("/")
@FormParams(keys = ACTION, values = "RebootInstances")
ListenableFuture<Void> rebootInstancesInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
ListenableFuture<Void> rebootInstancesInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
/**
* @see InstanceClient#terminateInstancesInRegion
@ -116,8 +118,8 @@ public interface InstanceAsyncClient {
@FormParams(keys = ACTION, values = "TerminateInstances")
@XMLResponseParser(InstanceStateChangeHandler.class)
ListenableFuture<Set<? extends InstanceStateChange>> terminateInstancesInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
/**
* @see InstanceClient#stopInstancesInRegion
@ -127,8 +129,9 @@ public interface InstanceAsyncClient {
@FormParams(keys = ACTION, values = "StopInstances")
@XMLResponseParser(InstanceStateChangeHandler.class)
ListenableFuture<Set<? extends InstanceStateChange>> stopInstancesInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("Force") boolean force,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("Force") boolean force,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
/**
* @see InstanceClient#startInstancesInRegion
@ -138,8 +141,8 @@ public interface InstanceAsyncClient {
@FormParams(keys = ACTION, values = "StartInstances")
@XMLResponseParser(InstanceStateChangeHandler.class)
ListenableFuture<Set<? extends InstanceStateChange>> startInstancesInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
/**
* @see AMIClient#getUserDataForInstanceInRegion
@ -149,8 +152,8 @@ public interface InstanceAsyncClient {
@FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "userData" })
@XMLResponseParser(UnencodeStringValueHandler.class)
ListenableFuture<String> getUserDataForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
/**
* @see AMIClient#getRootDeviceNameForInstanceInRegion
@ -160,8 +163,8 @@ public interface InstanceAsyncClient {
@FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "rootDeviceName" })
@XMLResponseParser(StringValueHandler.class)
ListenableFuture<String> getRootDeviceNameForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
/**
* @see AMIClient#getRamdiskForInstanceInRegion
@ -171,8 +174,8 @@ public interface InstanceAsyncClient {
@FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "ramdisk" })
@XMLResponseParser(StringValueHandler.class)
ListenableFuture<String> getRamdiskForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
/**
* @see AMIClient#getKernelForInstanceInRegion
@ -181,8 +184,9 @@ public interface InstanceAsyncClient {
@Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "kernel" })
@XMLResponseParser(StringValueHandler.class)
ListenableFuture<String> getKernelForInstanceInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
ListenableFuture<String> getKernelForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
/**
* @see AMIClient#isApiTerminationDisabledForInstanceInRegion
@ -192,8 +196,8 @@ public interface InstanceAsyncClient {
@FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "disableApiTermination" })
@XMLResponseParser(BooleanValueHandler.class)
ListenableFuture<Boolean> isApiTerminationDisabledForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
/**
* @see AMIClient#getInstanceTypeForInstanceInRegion
@ -203,8 +207,8 @@ public interface InstanceAsyncClient {
@FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "instanceType" })
@XMLResponseParser(InstanceTypeHandler.class)
ListenableFuture<String> getInstanceTypeForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
/**
* @see AMIClient#getInstanceInitiatedShutdownBehaviorForInstanceInRegion
@ -212,11 +216,11 @@ public interface InstanceAsyncClient {
@POST
@Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute",
"instanceInitiatedShutdownBehavior" })
"instanceInitiatedShutdownBehavior" })
@XMLResponseParser(InstanceInitiatedShutdownBehaviorHandler.class)
ListenableFuture<InstanceInitiatedShutdownBehavior> getInstanceInitiatedShutdownBehaviorForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
/**
* @see InstanceClient#getBlockDeviceMappingForInstanceInRegion
@ -225,9 +229,9 @@ public interface InstanceAsyncClient {
@Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "blockDeviceMapping" })
@XMLResponseParser(BlockDeviceMappingHandler.class)
ListenableFuture<? extends Map<String, RunningInstance.EbsBlockDevice>> getBlockDeviceMappingForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
ListenableFuture<? extends Map<String, BlockDevice>> getBlockDeviceMappingForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
/**
* @see AMIClient#resetRamdiskForInstanceInRegion
@ -236,8 +240,8 @@ public interface InstanceAsyncClient {
@Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "ResetInstanceAttribute", "ramdisk" })
ListenableFuture<Void> resetRamdiskForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
/**
* @see AMIClient#resetKernelForInstanceInRegion
@ -245,8 +249,9 @@ public interface InstanceAsyncClient {
@POST
@Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "ResetInstanceAttribute", "kernel" })
ListenableFuture<Void> resetKernelForInstanceInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
ListenableFuture<Void> resetKernelForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId);
/**
* @see AMIClient#setUserDataForInstanceInRegion
@ -254,9 +259,10 @@ public interface InstanceAsyncClient {
@POST
@Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "userData" })
ListenableFuture<Void> setUserDataForInstanceInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId,
@FormParam("Value") @ParamParser(ConvertUnencodedBytesToBase64EncodedString.class) byte[] unencodedData);
ListenableFuture<Void> setUserDataForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId,
@FormParam("Value") @ParamParser(ConvertUnencodedBytesToBase64EncodedString.class) byte[] unencodedData);
/**
* @see AMIClient#setRamdiskForInstanceInRegion
@ -264,8 +270,9 @@ public interface InstanceAsyncClient {
@POST
@Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "ramdisk" })
ListenableFuture<Void> setRamdiskForInstanceInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId, @FormParam("Value") String ramdisk);
ListenableFuture<Void> setRamdiskForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId, @FormParam("Value") String ramdisk);
/**
* @see AMIClient#setKernelForInstanceInRegion
@ -273,8 +280,9 @@ public interface InstanceAsyncClient {
@POST
@Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "kernel" })
ListenableFuture<Void> setKernelForInstanceInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId, @FormParam("Value") String kernel);
ListenableFuture<Void> setKernelForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId, @FormParam("Value") String kernel);
/**
* @see AMIClient#setApiTerminationDisabledForInstanceInRegion
@ -283,8 +291,8 @@ public interface InstanceAsyncClient {
@Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "disableApiTermination" })
ListenableFuture<Void> setApiTerminationDisabledForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId, @FormParam("Value") boolean apiTerminationDisabled);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId, @FormParam("Value") boolean apiTerminationDisabled);
/**
* @see AMIClient#setInstanceTypeForInstanceInRegion
@ -293,8 +301,8 @@ public interface InstanceAsyncClient {
@Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "instanceType" })
ListenableFuture<Void> setInstanceTypeForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId, @FormParam("Value") String instanceType);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId, @FormParam("Value") String instanceType);
/**
* @see AMIClient#setInstanceInitiatedShutdownBehaviorForInstanceInRegion
@ -302,11 +310,11 @@ public interface InstanceAsyncClient {
@POST
@Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute",
"instanceInitiatedShutdownBehavior" })
"instanceInitiatedShutdownBehavior" })
ListenableFuture<Void> setInstanceInitiatedShutdownBehaviorForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId,
@FormParam("Value") InstanceInitiatedShutdownBehavior instanceInitiatedShutdownBehavior);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId,
@FormParam("Value") InstanceInitiatedShutdownBehavior instanceInitiatedShutdownBehavior);
/**
* @see InstanceClient#setBlockDeviceMappingForInstanceInRegion
@ -315,8 +323,8 @@ public interface InstanceAsyncClient {
@Path("/")
@FormParams(keys = { ACTION }, values = { "ModifyInstanceAttribute" })
ListenableFuture<Void> setBlockDeviceMappingForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId,
@BinderParam(BindBlockDeviceMappingToIndexedFormParams.class) BlockDeviceMapping blockDeviceMapping);
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId,
@BinderParam(BindBlockDeviceMappingToIndexedFormParams.class) Map<String, BlockDevice> blockDeviceMapping);
}

View File

@ -25,11 +25,14 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import org.jclouds.ec2.domain.*;
import org.jclouds.ec2.domain.RunningInstance.EbsBlockDevice;
import org.jclouds.concurrent.Timeout;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.InstanceStateChange;
import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
import org.jclouds.ec2.options.RunInstancesOptions;
import org.jclouds.concurrent.Timeout;
/**
* Provides access to EC2 via their REST API.
@ -356,7 +359,7 @@ public interface InstanceClient {
* @return Describes the mapping that defines native device names to use when
* exposing virtual devices.
*/
Map<String, EbsBlockDevice> getBlockDeviceMappingForInstanceInRegion(
Map<String, BlockDevice> getBlockDeviceMappingForInstanceInRegion(
@Nullable String region, String instanceId);
/**
@ -536,9 +539,9 @@ public interface InstanceClient {
* {@link InstanceState#STOPPING} to {@link InstanceState#STOPPED}</li>
* </ol>
*
* To create the instances of {@link RunningInstance.EbsBlockDevice}, the
* To create the instances of {@link BlockDevice}, the
* constructor can be used with the following parameters:
* {@link RunningInstance.EbsBlockDevice#EbsBlockDevice(String, String, boolean)}
* {@link BlockDevice#EbsBlockDevice(String, String, boolean)}
* , that are:
* <ol>
* <li>Volume id (required), for instance, "vol-blah"</li>
@ -571,5 +574,5 @@ public interface InstanceClient {
* />
*/
void setBlockDeviceMappingForInstanceInRegion(@Nullable String region,
String instanceId, BlockDeviceMapping blockDeviceMapping);
String instanceId, Map<String, BlockDevice> blockDeviceMapping);
}

View File

@ -27,6 +27,7 @@ import javax.annotation.Resource;
import javax.inject.Inject;
import org.jclouds.ec2.domain.Attachment;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.MonitoringState;
import org.jclouds.ec2.domain.Reservation;
@ -95,7 +96,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
protected boolean inMonitoring;
private boolean inBlockDeviceMapping;
private Map<String, RunningInstance.EbsBlockDevice> ebsBlockDevices = Maps.newHashMap();
private Map<String, BlockDevice> ebsBlockDevices = Maps.newHashMap();
private String volumeId;
private Attachment.Status attachmentStatus;
@ -229,7 +230,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
protected void inItem() {
if (inBlockDeviceMapping) {
ebsBlockDevices.put(deviceName, new RunningInstance.EbsBlockDevice(volumeId, attachmentStatus, attachTime,
ebsBlockDevices.put(deviceName, new BlockDevice(volumeId, attachmentStatus, attachTime,
deleteOnTermination));
this.deviceName = null;
this.volumeId = null;

View File

@ -24,7 +24,7 @@ import java.util.Map;
import com.google.inject.Inject;
import org.jclouds.ec2.domain.Attachment;
import org.jclouds.ec2.domain.RunningInstance.EbsBlockDevice;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
@ -35,10 +35,10 @@ import com.google.common.collect.Maps;
* @author Adrian Cole
*/
public class BlockDeviceMappingHandler extends
ParseSax.HandlerWithResult<Map<String, EbsBlockDevice>> {
ParseSax.HandlerWithResult<Map<String, BlockDevice>> {
private StringBuilder currentText = new StringBuilder();
private Map<String, EbsBlockDevice> ebsBlockDevices = Maps.newHashMap();
private Map<String, BlockDevice> ebsBlockDevices = Maps.newHashMap();
private String deviceName;
private String volumeId;
private boolean deleteOnTermination = true;// correct default is true.
@ -52,7 +52,7 @@ public class BlockDeviceMappingHandler extends
this.dateService = dateService;
}
public Map<String, EbsBlockDevice> getResult() {
public Map<String, BlockDevice> getResult() {
return ebsBlockDevices;
}
@ -68,7 +68,7 @@ public class BlockDeviceMappingHandler extends
} else if (qName.equals("attachTime")) {
attachTime = dateService.iso8601DateParse(currentText.toString().trim());
} else if (qName.equals("item")) {
ebsBlockDevices.put(deviceName, new EbsBlockDevice(volumeId, attachmentStatus, attachTime, deleteOnTermination));
ebsBlockDevices.put(deviceName, new BlockDevice(volumeId, attachmentStatus, attachTime, deleteOnTermination));
this.volumeId = null;
this.deviceName = null;
this.deleteOnTermination = true;

View File

@ -28,6 +28,7 @@ import static org.testng.Assert.assertNotNull;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@ -37,7 +38,7 @@ import java.util.concurrent.TimeoutException;
import org.jclouds.Constants;
import org.jclouds.aws.AWSResponseException;
import org.jclouds.domain.Credentials;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.Image.EbsBlockDevice;
import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.InstanceType;
@ -67,6 +68,7 @@ import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.inject.Injector;
import com.google.inject.Module;
@ -299,9 +301,9 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
}
private void setBlockDeviceMappingForInstanceInRegion() {
BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping();
Map<String, BlockDevice> mapping = Maps.newLinkedHashMap();
try {
client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(null, instanceId, blockDeviceMapping);
client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(null, instanceId, mapping);
assert false : "shouldn't be allowed, as instance needs to be ebs based-ami";
} catch (AWSResponseException e) {
assertEquals("InvalidParameterCombination", e.getError().getCode());

View File

@ -39,7 +39,7 @@ import org.jclouds.Constants;
import org.jclouds.aws.AWSResponseException;
import org.jclouds.domain.Credentials;
import org.jclouds.ec2.domain.Attachment;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.Image;
import org.jclouds.ec2.domain.Image.Architecture;
import org.jclouds.ec2.domain.Image.ImageType;
@ -83,6 +83,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.inject.Injector;
import com.google.inject.Module;
@ -474,17 +475,16 @@ public class EBSBootEC2ClientLiveTest {
private void setBlockDeviceMappingForInstanceInRegion() {
String volumeId = ebsInstance.getEbsBlockDevices().get("/dev/sda1").getVolumeId();
BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping();
blockDeviceMapping.addEbsBlockDevice("/dev/sda1", new RunningInstance.EbsBlockDevice(volumeId, false));
Map<String, BlockDevice> mapping = Maps.newLinkedHashMap();
mapping.put("/dev/sda1", new BlockDevice(volumeId, false));
try {
client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(null, ebsInstance.getId(),
blockDeviceMapping);
client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(null, ebsInstance.getId(), mapping);
Map<String, RunningInstance.EbsBlockDevice> devices = client.getInstanceServices()
.getBlockDeviceMappingForInstanceInRegion(null, ebsInstance.getId());
Map<String, BlockDevice> devices = client.getInstanceServices().getBlockDeviceMappingForInstanceInRegion(null,
ebsInstance.getId());
assertEquals(devices.size(), 1);
String deviceName = Iterables.getOnlyElement(devices.keySet());
RunningInstance.EbsBlockDevice device = Iterables.getOnlyElement(devices.values());
BlockDevice device = Iterables.getOnlyElement(devices.values());
assertEquals(device.getVolumeId(), volumeId);
assertEquals(deviceName, "/dev/sda1");

View File

@ -24,15 +24,16 @@ import static org.testng.Assert.assertEquals;
import java.io.File;
import java.net.URI;
import java.util.Date;
import java.util.Map;
import javax.ws.rs.HttpMethod;
import org.jclouds.ec2.domain.Attachment.Status;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.http.HttpRequest;
import org.testng.annotations.Test;
import com.google.common.collect.Maps;
import com.google.inject.Guice;
import com.google.inject.Injector;
@ -48,11 +49,10 @@ public class BindBlockDeviceMappingToIndexedFormParamsTest {
.getInstance(BindBlockDeviceMappingToIndexedFormParams.class);
public void testMapping() {
BlockDeviceMapping mapping = new BlockDeviceMapping();
mapping.addEbsBlockDevice("apple", new RunningInstance.EbsBlockDevice("appleId", true));
Map<String, BlockDevice> mapping = Maps.newLinkedHashMap();
mapping.put("apple", new BlockDevice("appleId", true));
Date date = new Date(999999l);
mapping.addEbsBlockDevice("cranberry", new RunningInstance.EbsBlockDevice("cranberry", Status.ATTACHED, date,
false));
mapping.put("cranberry", new BlockDevice("cranberry", Status.ATTACHED, date, false));
HttpRequest request = HttpRequest.builder().method("POST").endpoint(URI.create("http://localhost")).build();
request = binder.bindToRequest(request, mapping);

View File

@ -41,6 +41,7 @@ import org.jclouds.ec2.compute.functions.CreatePlacementGroupIfNeeded;
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.ec2.domain.KeyPair;
import org.jclouds.ec2.domain.PlacementGroup;
import org.jclouds.ec2.options.RunInstancesOptions;
@ -86,6 +87,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup expectations
expect(template.getHardware()).andReturn(size).atLeastOnce();
expect(template.getOptions()).andReturn(options).atLeastOnce();
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
systemGeneratedKeyPairName);
expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups);
@ -142,6 +144,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup expectations
expect(template.getHardware()).andReturn(size).atLeastOnce();
expect(template.getOptions()).andReturn(options).atLeastOnce();
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
systemGeneratedKeyPairName);
expect(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
@ -201,6 +204,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup expectations
expect(template.getHardware()).andReturn(size).atLeastOnce();
expect(template.getOptions()).andReturn(options).atLeastOnce();
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
systemGeneratedKeyPairName);
expect(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
@ -258,6 +262,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup expectations
expect(template.getHardware()).andReturn(size).atLeastOnce();
expect(template.getOptions()).andReturn(options).atLeastOnce();
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
systemGeneratedKeyPairName);
expect(options.getSubnetId()).andReturn("1");
@ -313,6 +318,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup expectations
expect(template.getHardware()).andReturn(size).atLeastOnce();
expect(template.getOptions()).andReturn(options).atLeastOnce();
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
systemGeneratedKeyPairName);
expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups);

View File

@ -21,18 +21,20 @@ package org.jclouds.ec2.options;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.asType;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.enableMonitoring;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withDeviceName;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withKernelId;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withKeyName;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withRamdisk;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withSecurityGroup;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withSubnetId;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withUserData;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withVirtualName;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withBlockDeviceMappings;
import static org.testng.Assert.assertEquals;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.http.options.HttpRequestOptions;
import org.testng.annotations.Test;
@ -181,32 +183,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();
@ -274,30 +250,44 @@ 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 testWithBlockDeviceMapping() {
RunInstancesOptions options = new RunInstancesOptions();
BlockDeviceMapping mapping = new BlockDeviceMapping("/dev/sda1", null, null, 120, null, true);
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
mappings.add(mapping);
options.withBlockDeviceMappings(mappings);
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections.singletonList("/dev/sda1"));
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections.singletonList("120"));
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections.singletonList("true"));
}
@Test
public void testWithVirtualNameStatic() {
RunInstancesOptions options = withVirtualName("test");
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"),
Collections.singletonList("test"));
public void testNullWithBlockDeviceMapping() {
RunInstancesOptions options = new RunInstancesOptions();
assertEquals(options.buildFormParameters().get("BlockDeviceMapping"), Collections.EMPTY_LIST);
}
@Test
public void testWithBlockDeviceMappingStatic() {
BlockDeviceMapping mapping = new BlockDeviceMapping("/dev/sda1", null, null, 120, null, true);
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
mappings.add(mapping);
RunInstancesOptions options = withBlockDeviceMappings(mappings);
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections.singletonList("/dev/sda1"));
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections.singletonList("120"));
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections.singletonList("true"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testWithVirtualNameNPE() {
withVirtualName(null);
public void testWithBlockDeviceMappingNPE() {
withBlockDeviceMappings(null);
}
}

View File

@ -22,12 +22,12 @@ package org.jclouds.ec2.services;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Map;
import org.jclouds.aws.domain.Region;
import org.jclouds.ec2.domain.AvailabilityZone;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
import org.jclouds.ec2.options.RunInstancesOptions;
import org.jclouds.ec2.xml.BlockDeviceMappingHandler;
@ -46,6 +46,7 @@ import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
import com.google.common.collect.Maps;
import com.google.inject.TypeLiteral;
/**
@ -468,11 +469,11 @@ public class InstanceAsyncClientTest extends BaseEC2AsyncClientTest<InstanceAsyn
public void testSetBlockDeviceMappingForInstanceInRegion() throws SecurityException, NoSuchMethodException,
IOException {
Method method = InstanceAsyncClient.class.getMethod("setBlockDeviceMappingForInstanceInRegion", String.class,
String.class, BlockDeviceMapping.class);
String.class, Map.class);
BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping();
blockDeviceMapping.addEbsBlockDevice("/dev/sda1", new RunningInstance.EbsBlockDevice("vol-test1", true));
HttpRequest request = processor.createRequest(method, null, "1", blockDeviceMapping);
Map<String, BlockDevice> mapping = Maps.newLinkedHashMap();
mapping.put("/dev/sda1", new BlockDevice("vol-test1", true));
HttpRequest request = processor.createRequest(method, null, "1", mapping);
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");

View File

@ -25,7 +25,7 @@ import java.io.InputStream;
import java.util.Map;
import org.jclouds.ec2.domain.Attachment;
import org.jclouds.ec2.domain.RunningInstance.EbsBlockDevice;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test;
@ -46,13 +46,13 @@ public class BlockDeviceMappingHandlerTest extends BaseHandlerTest {
"/describe_image_attribute_blockDeviceMapping.xml");
DateService dateService = injector.getInstance(DateService.class);
Map<String, EbsBlockDevice> expected = ImmutableMap.<String, EbsBlockDevice> of("/dev/sda1",
new EbsBlockDevice("vol-d74b82be", Attachment.Status.ATTACHED, dateService
Map<String, BlockDevice> expected = ImmutableMap.<String, BlockDevice> of("/dev/sda1",
new BlockDevice("vol-d74b82be", Attachment.Status.ATTACHED, dateService
.iso8601DateParse("2010-02-20T18:25:26.000Z"), true), "/dev/sdf",
new EbsBlockDevice("vol-another", Attachment.Status.DETACHED, dateService
new BlockDevice("vol-another", Attachment.Status.DETACHED, dateService
.iso8601DateParse("2010-02-20T19:26:26.000Z"), false));
Map<String, EbsBlockDevice> result = factory.create(
Map<String, BlockDevice> result = factory.create(
injector.getInstance(BlockDeviceMappingHandler.class)).parse(is);
assertEquals(result, expected);

View File

@ -27,13 +27,13 @@ import java.util.Set;
import org.jclouds.ec2.domain.Attachment;
import org.jclouds.ec2.domain.AvailabilityZone;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.ec2.domain.MonitoringState;
import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RootDeviceType;
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.ec2.domain.RunningInstance.EbsBlockDevice;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.config.SaxParserModule;
@ -77,7 +77,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
.iso8601DateParse("2009-11-09T03:00:34.000Z"), MonitoringState.DISABLED,
AvailabilityZone.US_EAST_1C, null, "paravirtual", null, "ip-10-243-42-70.ec2.internal",
"10.243.42.70", ImmutableSet.<String> of(), "ari-a51cf9cc", null, null, null, null,
RootDeviceType.INSTANCE_STORE, null, ImmutableMap.<String, EbsBlockDevice> of())), "993194456877",
RootDeviceType.INSTANCE_STORE, null, ImmutableMap.<String, BlockDevice> of())), "993194456877",
null, "r-a3c508cb"));
Set<Reservation<? extends RunningInstance>> result = parseRunningInstances("/describe_instances_running.xml");
@ -96,14 +96,14 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
.iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED,
AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-132.ec2.internal", null,
ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null, null, RootDeviceType.INSTANCE_STORE,
null, ImmutableMap.<String, EbsBlockDevice> of()),
null, ImmutableMap.<String, BlockDevice> of()),
new RunningInstance(defaultRegion, ImmutableSet.of("default"), "23",
"ec2-72-44-33-6.compute-1.amazonaws.com", "ami-6ea54007", "i-28a64435", InstanceState.RUNNING,
InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3", "example-key-name", dateService
.iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED,
AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-134.ec2.internal", null,
ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null, null, RootDeviceType.INSTANCE_STORE,
null, ImmutableMap.<String, EbsBlockDevice> of())), "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null,
null, ImmutableMap.<String, BlockDevice> of())), "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null,
"r-44a5402d"));
Set<Reservation<? extends RunningInstance>> result = parseRunningInstances("/describe_instances.xml");
@ -123,7 +123,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
"jclouds#euc-17", dateService.iso8601DateParse("2010-06-16T03:06:19.000Z"), MonitoringState.DISABLED,
"open", null, "paravirtual", null, "10.7.0.179", null, ImmutableSet.<String> of(), "eri-A97113E4",
null, null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap
.<String, EbsBlockDevice> of())), "jclouds", null, "r-4D2A08AD"));
.<String, BlockDevice> of())), "jclouds", null, "r-4D2A08AD"));
Set<Reservation<? extends RunningInstance>> result = parseRunningInstances("/describe_instances_euc.xml");
@ -138,7 +138,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
InstanceState.TERMINATED, InstanceType.M1_SMALL, null, null, "nebulatanimislam", dateService
.iso8601SecondsDateParse("2010-09-09T18:09:42Z"), null, null, null, "paravirtual", null, null,
"10.128.207.5", ImmutableSet.<String> of("None"), null, null, null, null, null,
RootDeviceType.INSTANCE_STORE, null, ImmutableMap.<String, EbsBlockDevice> of())), "tislam1", null,
RootDeviceType.INSTANCE_STORE, null, ImmutableMap.<String, BlockDevice> of())), "tislam1", null,
"r-opqeylmj"));
Set<Reservation<? extends RunningInstance>> result = parseRunningInstances("/describe_instances_nova.xml");
@ -157,9 +157,9 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
.iso8601DateParse("2009-12-30T04:06:23.000Z"), MonitoringState.DISABLED,
AvailabilityZone.US_EAST_1B, "placement", "hvm", null, "domU-12-31-39-09-CE-53.compute-1.internal",
"10.210.209.157", ImmutableSet.<String> of(), "ari-a51cf9cc", null, null, null, null,
RootDeviceType.EBS, "/dev/sda1", ImmutableMap.<String, EbsBlockDevice> of(
RootDeviceType.EBS, "/dev/sda1", ImmutableMap.<String, BlockDevice> of(
"/dev/sda1",
new EbsBlockDevice("vol-dc6ca8b5", Attachment.Status.ATTACHED, dateService
new BlockDevice("vol-dc6ca8b5", Attachment.Status.ATTACHED, dateService
.iso8601DateParse("2009-12-30T04:06:29.000Z"), true)))), "993194456877", null,
"r-596dd731"));

View File

@ -27,13 +27,13 @@ import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.ec2.domain.AvailabilityZone;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.ec2.domain.MonitoringState;
import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RootDeviceType;
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.ec2.domain.RunningInstance.EbsBlockDevice;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
@ -74,17 +74,17 @@ public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest {
"example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), MonitoringState.ENABLED,
AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, Sets
.<String> newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE,
null, ImmutableMap.<String, EbsBlockDevice> of()), new RunningInstance(defaultRegion, ImmutableSet
null, ImmutableMap.<String, BlockDevice> of()), new RunningInstance(defaultRegion, ImmutableSet
.of("default"), "1", null, "ami-60a54009", "i-2bc64242", InstanceState.PENDING, InstanceType.M1_SMALL,
(String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"),
MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null,
Sets.<String> newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, null,
ImmutableMap.<String, EbsBlockDevice> of()), new RunningInstance(defaultRegion, ImmutableSet
ImmutableMap.<String, BlockDevice> of()), new RunningInstance(defaultRegion, ImmutableSet
.of("default"), "2", null, "ami-60a54009", "i-2be64332", InstanceState.PENDING, InstanceType.M1_SMALL,
(String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"),
MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null,
Sets.<String> newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, null,
ImmutableMap.<String, EbsBlockDevice> of())
ImmutableMap.<String, BlockDevice> of())
), "AIDADH4IGTRXXKCD", null, "r-47a5402e");

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

@ -78,7 +78,7 @@ public interface TemplateBuilder {
* Configure this template to start in a specific location
*
* @throws NoSuchElementException
* if location matches the id specified
* if no location matches the id specified
*/
TemplateBuilder locationId(String locationId);