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

View File

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

View File

@ -29,8 +29,6 @@ import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Provider; 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.collect.Memoized;
import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image; 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.domain.internal.TemplateBuilderImpl;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Location; 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.base.Supplier;
import com.google.common.collect.ComputationException; import com.google.common.collect.ComputationException;
@ -73,6 +73,7 @@ public class EC2TemplateBuilderImpl extends TemplateBuilderImpl {
eTo.noKeyPair(); eTo.noKeyPair();
if (eFrom.getSubnetId() != null) if (eFrom.getSubnetId() != null)
eTo.subnetId(eFrom.getSubnetId()); eTo.subnetId(eFrom.getSubnetId());
eTo.blockDeviceMappings(eFrom.getBlockDeviceMappings());
if (eFrom.isMonitoringEnabled()) if (eFrom.isMonitoringEnabled())
eTo.enableMonitoring(); eTo.enableMonitoring();
if (eFrom.getUserData() != null) 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 static com.google.common.base.Preconditions.checkState;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Credentials; 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.io.Payload;
import org.jclouds.scriptbuilder.domain.Statement; import org.jclouds.scriptbuilder.domain.Statement;
import org.jclouds.util.Preconditions2; import org.jclouds.util.Preconditions2;
@ -43,7 +51,7 @@ import com.google.common.collect.Iterables;
* needed): * needed):
* <p/> * <p/>
* <code> * <code>
* import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.*; * import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.*;
* <p/> * <p/>
* ComputeService client = // get connection * ComputeService client = // get connection
* templateBuilder.options(inboundPorts(22, 80, 8080, 443)); * templateBuilder.options(inboundPorts(22, 80, 8080, 443));
@ -62,6 +70,7 @@ public class EC2TemplateOptions extends TemplateOptions {
private boolean noPlacementGroup; private boolean noPlacementGroup;
private String subnetId; private String subnetId;
private byte[] userData; private byte[] userData;
private Set<BlockDeviceMapping> blockDeviceMappings = ImmutableSet.of();
public static final EC2TemplateOptions NONE = new EC2TemplateOptions(); public static final EC2TemplateOptions NONE = new EC2TemplateOptions();
@ -94,7 +103,6 @@ public class EC2TemplateOptions extends TemplateOptions {
return this; return this;
} }
/** /**
* Unencoded data * Unencoded data
*/ */
@ -155,6 +163,81 @@ public class EC2TemplateOptions extends TemplateOptions {
return this; 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 { public static class Builder {
/** /**
@ -277,7 +360,6 @@ public class EC2TemplateOptions extends TemplateOptions {
EC2TemplateOptions options = new EC2TemplateOptions(); EC2TemplateOptions options = new EC2TemplateOptions();
return EC2TemplateOptions.class.cast(options.subnetId(subnetId)); return EC2TemplateOptions.class.cast(options.subnetId(subnetId));
} }
} }
// methods that only facilitate returning the correct object type // methods that only facilitate returning the correct object type
@ -462,18 +544,27 @@ public class EC2TemplateOptions extends TemplateOptions {
return userData; return userData;
} }
/**
* @return BlockDeviceMapping to use when running the instance or null.
*/
public Set<BlockDeviceMapping> getBlockDeviceMappings() {
return blockDeviceMappings;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = super.hashCode(); int result = super.hashCode();
result = prime * result + ((blockDeviceMappings == null) ? 0 : blockDeviceMappings.hashCode());
result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode()); result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode());
result = prime * result + ((keyPair == null) ? 0 : keyPair.hashCode()); result = prime * result + ((keyPair == null) ? 0 : keyPair.hashCode());
result = prime * result + (monitoringEnabled ? 1231 : 1237);
result = prime * result + (noKeyPair ? 1231 : 1237); result = prime * result + (noKeyPair ? 1231 : 1237);
result = prime * result + (noPlacementGroup ? 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 + ((placementGroup == null) ? 0 : placementGroup.hashCode());
result = prime * result + ((subnetId == null) ? 0 : subnetId.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; return result;
} }
@ -486,6 +577,11 @@ public class EC2TemplateOptions extends TemplateOptions {
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
EC2TemplateOptions other = (EC2TemplateOptions) obj; 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 (groupIds == null) {
if (other.groupIds != null) if (other.groupIds != null)
return false; return false;
@ -496,12 +592,12 @@ public class EC2TemplateOptions extends TemplateOptions {
return false; return false;
} else if (!keyPair.equals(other.keyPair)) } else if (!keyPair.equals(other.keyPair))
return false; return false;
if (monitoringEnabled != other.monitoringEnabled)
return false;
if (noKeyPair != other.noKeyPair) if (noKeyPair != other.noKeyPair)
return false; return false;
if (noPlacementGroup != other.noPlacementGroup) if (noPlacementGroup != other.noPlacementGroup)
return false; return false;
if (monitoringEnabled != other.monitoringEnabled)
return false;
if (placementGroup == null) { if (placementGroup == null) {
if (other.placementGroup != null) if (other.placementGroup != null)
return false; return false;
@ -512,21 +608,19 @@ public class EC2TemplateOptions extends TemplateOptions {
return false; return false;
} else if (!subnetId.equals(other.subnetId)) } else if (!subnetId.equals(other.subnetId))
return false; return false;
if (userData == null) { if (!Arrays.equals(userData, other.userData))
if (other.userData != null)
return false;
} else if (!userData.equals(other.userData))
return false; return false;
return true; return true;
} }
@Override @Override
public String toString() { public String toString() {
return "[groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair + ", placementGroup="
+ placementGroup + ", noPlacementGroup=" + noPlacementGroup + ", monitoringEnabled=" + monitoringEnabled return "EC2TemplateOptions [groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair
+ ", inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null) + ", monitoringEnabled=" + monitoringEnabled + ", placementGroup=" + placementGroup + ", noPlacementGroup="
+ ", publicKey=" + (publicKey != null) + ", runScript=" + (script != null) + ", port:seconds=" + port + noPlacementGroup + ", subnetId=" + subnetId + ", userData=" + Arrays.toString(userData)
+ ":" + seconds + ", subnetId=" + subnetId + ", metadata/details: " + includeMetadata + "]"; + ", blockDeviceMappings=" + blockDeviceMappings + "]";
} }
} }

View File

@ -19,6 +19,7 @@
package org.jclouds.ec2.compute.strategy; package org.jclouds.ec2.compute.strategy;
import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.asType; import static org.jclouds.ec2.options.RunInstancesOptions.Builder.asType;
import java.util.Map; import java.util.Map;
@ -29,16 +30,17 @@ import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; 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.RegionAndName;
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules; import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
import org.jclouds.ec2.compute.functions.CreatePlacementGroupIfNeeded; import org.jclouds.ec2.compute.functions.CreatePlacementGroupIfNeeded;
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
import org.jclouds.ec2.compute.options.EC2TemplateOptions; import org.jclouds.ec2.compute.options.EC2TemplateOptions;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.ec2.domain.KeyPair; import org.jclouds.ec2.domain.KeyPair;
import org.jclouds.ec2.options.RunInstancesOptions; import org.jclouds.ec2.options.RunInstancesOptions;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.location.Provider; import org.jclouds.location.Provider;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
@ -114,6 +116,13 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions
if (userData != null) if (userData != null)
instanceOptions.withUserData(userData); 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; return instanceOptions;
} }

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; package org.jclouds.ec2.domain;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.google.common.collect.ImmutableMultimap; import org.jclouds.util.Preconditions2;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
/** /**
* Defines the mapping of volumes for
* {@link org.jclouds.ec2.services.InstanceClient#setBlockDeviceMappingForInstanceInRegion}.
* *
* @author Oleksiy Yarmula * @author Lili Nadar
*/ */
public class BlockDeviceMapping { 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 // values expressed in GB
.create(); 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;
} }
/** public String getDeviceName() {
* Creates block device mapping from the list of {@link RunningInstance.EbsBlockDevice devices}. return deviceName;
*
* 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 getVirtualName() {
* Adds a {@link RunningInstance.EbsBlockDevice} to the mapping. return virtualName;
*
* @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 Multimap<String, RunningInstance.EbsBlockDevice> getEbsBlockDevices() { public String getEbsSnapshotId() {
return ImmutableMultimap.<String, RunningInstance.EbsBlockDevice> builder().putAll( return snapshotId;
ebsBlockDevices).build(); }
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 javax.annotation.Nullable;
import org.jclouds.ec2.domain.Attachment.Status;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
@ -41,82 +40,6 @@ import com.google.common.collect.Sets;
*/ */
public class RunningInstance implements Comparable<RunningInstance> { 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 String region;
private final Set<String> groupIds = Sets.newLinkedHashSet(); private final Set<String> groupIds = Sets.newLinkedHashSet();
@ -159,7 +82,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
private final RootDeviceType rootDeviceType; private final RootDeviceType rootDeviceType;
@Nullable @Nullable
private final String rootDeviceName; 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) { public int compareTo(RunningInstance o) {
return (this == o) ? 0 : getId().compareTo(o.getId()); 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 privateIpAddress, Set<String> productCodes, @Nullable String ramdiskId,
@Nullable String reason, @Nullable String subnetId, @Nullable String spotInstanceRequestId, @Nullable String reason, @Nullable String subnetId, @Nullable String spotInstanceRequestId,
@Nullable String vpcId, RootDeviceType rootDeviceType, @Nullable String rootDeviceName, @Nullable String vpcId, RootDeviceType rootDeviceType, @Nullable String rootDeviceName,
Map<String, EbsBlockDevice> ebsBlockDevices) { Map<String, BlockDevice> ebsBlockDevices) {
Iterables.addAll(this.groupIds, checkNotNull(groupIds, "groupIds")); Iterables.addAll(this.groupIds, checkNotNull(groupIds, "groupIds"));
this.region = checkNotNull(region, "region"); this.region = checkNotNull(region, "region");
this.amiLaunchIndex = amiLaunchIndex; // nullable on runinstances. this.amiLaunchIndex = amiLaunchIndex; // nullable on runinstances.
@ -389,7 +312,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
/** /**
* EBS volumes associated with the instance. * EBS volumes associated with the instance.
*/ */
public Map<String, EbsBlockDevice> getEbsBlockDevices() { public Map<String, BlockDevice> getEbsBlockDevices() {
return ebsBlockDevices; 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.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; 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.domain.InstanceType;
import org.jclouds.ec2.options.internal.BaseEC2RequestOptions; import org.jclouds.ec2.options.internal.BaseEC2RequestOptions;
import org.jclouds.encryption.internal.Base64; import org.jclouds.encryption.internal.Base64;
@ -33,7 +36,7 @@ import org.jclouds.encryption.internal.Base64;
* mutator (if needed): * mutator (if needed):
* <p/> * <p/>
* <code> * <code>
* import static org.jclouds.ec2.options.RunInstancesOptions.Builder.* * import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.*
* <p/> * <p/>
* EC2Client connection = // get connection * EC2Client connection = // get connection
* Future<ReservationInfo> instances = connection.runInstances(executableBy("123125").imageIds(1000, 1004)); * Future<ReservationInfo> instances = connection.runInstances(executableBy("123125").imageIds(1000, 1004));
@ -160,30 +163,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return getFirstFormOrNull("RamdiskId"); 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. * Enables monitoring for the instance.
*/ */
@ -209,6 +188,34 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return getFirstFormOrNull("SubnetId"); 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 { public static class Builder {
/** /**
* @see RunInstancesOptions#withKeyName(String) * @see RunInstancesOptions#withKeyName(String)
@ -258,14 +265,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
return options.withKernelId(kernelId); 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() * @see RunInstancesOptions#enableMonitoring()
*/ */
@ -291,11 +290,11 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
} }
/** /**
* @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(); 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.BindBlockDeviceMappingToIndexedFormParams;
import org.jclouds.ec2.binders.BindInstanceIdsToIndexedFormParams; import org.jclouds.ec2.binders.BindInstanceIdsToIndexedFormParams;
import org.jclouds.ec2.binders.IfNotNullBindAvailabilityZoneToFormParam; 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.InstanceStateChange;
import org.jclouds.ec2.domain.Reservation; import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RunningInstance; import org.jclouds.ec2.domain.RunningInstance;
@ -94,7 +94,8 @@ public interface InstanceAsyncClient {
@Path("/") @Path("/")
@FormParams(keys = ACTION, values = "RunInstances") @FormParams(keys = ACTION, values = "RunInstances")
@XMLResponseParser(RunInstancesResponseHandler.class) @XMLResponseParser(RunInstancesResponseHandler.class)
ListenableFuture<Reservation<? extends RunningInstance>> runInstancesInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, ListenableFuture<Reservation<? extends RunningInstance>> runInstancesInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@Nullable @BinderParam(IfNotNullBindAvailabilityZoneToFormParam.class) String nullableAvailabilityZone, @Nullable @BinderParam(IfNotNullBindAvailabilityZoneToFormParam.class) String nullableAvailabilityZone,
@FormParam("ImageId") String imageId, @FormParam("MinCount") int minCount, @FormParam("ImageId") String imageId, @FormParam("MinCount") int minCount,
@FormParam("MaxCount") int maxCount, RunInstancesOptions... options); @FormParam("MaxCount") int maxCount, RunInstancesOptions... options);
@ -105,7 +106,8 @@ public interface InstanceAsyncClient {
@POST @POST
@Path("/") @Path("/")
@FormParams(keys = ACTION, values = "RebootInstances") @FormParams(keys = ACTION, values = "RebootInstances")
ListenableFuture<Void> rebootInstancesInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, ListenableFuture<Void> rebootInstancesInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds); @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
/** /**
@ -127,7 +129,8 @@ public interface InstanceAsyncClient {
@FormParams(keys = ACTION, values = "StopInstances") @FormParams(keys = ACTION, values = "StopInstances")
@XMLResponseParser(InstanceStateChangeHandler.class) @XMLResponseParser(InstanceStateChangeHandler.class)
ListenableFuture<Set<? extends InstanceStateChange>> stopInstancesInRegion( ListenableFuture<Set<? extends InstanceStateChange>> stopInstancesInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("Force") boolean force, @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("Force") boolean force,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds); @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
/** /**
@ -181,7 +184,8 @@ public interface InstanceAsyncClient {
@Path("/") @Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "kernel" }) @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "kernel" })
@XMLResponseParser(StringValueHandler.class) @XMLResponseParser(StringValueHandler.class)
ListenableFuture<String> getKernelForInstanceInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, ListenableFuture<String> getKernelForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId); @FormParam("InstanceId") String instanceId);
/** /**
@ -225,7 +229,7 @@ public interface InstanceAsyncClient {
@Path("/") @Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "blockDeviceMapping" }) @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "blockDeviceMapping" })
@XMLResponseParser(BlockDeviceMappingHandler.class) @XMLResponseParser(BlockDeviceMappingHandler.class)
ListenableFuture<? extends Map<String, RunningInstance.EbsBlockDevice>> getBlockDeviceMappingForInstanceInRegion( ListenableFuture<? extends Map<String, BlockDevice>> getBlockDeviceMappingForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId); @FormParam("InstanceId") String instanceId);
@ -245,7 +249,8 @@ public interface InstanceAsyncClient {
@POST @POST
@Path("/") @Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "ResetInstanceAttribute", "kernel" }) @FormParams(keys = { ACTION, "Attribute" }, values = { "ResetInstanceAttribute", "kernel" })
ListenableFuture<Void> resetKernelForInstanceInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, ListenableFuture<Void> resetKernelForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId); @FormParam("InstanceId") String instanceId);
/** /**
@ -254,7 +259,8 @@ public interface InstanceAsyncClient {
@POST @POST
@Path("/") @Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "userData" }) @FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "userData" })
ListenableFuture<Void> setUserDataForInstanceInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, ListenableFuture<Void> setUserDataForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId, @FormParam("InstanceId") String instanceId,
@FormParam("Value") @ParamParser(ConvertUnencodedBytesToBase64EncodedString.class) byte[] unencodedData); @FormParam("Value") @ParamParser(ConvertUnencodedBytesToBase64EncodedString.class) byte[] unencodedData);
@ -264,7 +270,8 @@ public interface InstanceAsyncClient {
@POST @POST
@Path("/") @Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "ramdisk" }) @FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "ramdisk" })
ListenableFuture<Void> setRamdiskForInstanceInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, ListenableFuture<Void> setRamdiskForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId, @FormParam("Value") String ramdisk); @FormParam("InstanceId") String instanceId, @FormParam("Value") String ramdisk);
/** /**
@ -273,7 +280,8 @@ public interface InstanceAsyncClient {
@POST @POST
@Path("/") @Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "kernel" }) @FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "kernel" })
ListenableFuture<Void> setKernelForInstanceInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, ListenableFuture<Void> setKernelForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId, @FormParam("Value") String kernel); @FormParam("InstanceId") String instanceId, @FormParam("Value") String kernel);
/** /**
@ -317,6 +325,6 @@ public interface InstanceAsyncClient {
ListenableFuture<Void> setBlockDeviceMappingForInstanceInRegion( ListenableFuture<Void> setBlockDeviceMappingForInstanceInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("InstanceId") String instanceId, @FormParam("InstanceId") String instanceId,
@BinderParam(BindBlockDeviceMappingToIndexedFormParams.class) BlockDeviceMapping blockDeviceMapping); @BinderParam(BindBlockDeviceMappingToIndexedFormParams.class) Map<String, BlockDevice> blockDeviceMapping);
} }

View File

@ -25,11 +25,14 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.jclouds.ec2.domain.*; import org.jclouds.concurrent.Timeout;
import org.jclouds.ec2.domain.RunningInstance.EbsBlockDevice; 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.domain.Volume.InstanceInitiatedShutdownBehavior;
import org.jclouds.ec2.options.RunInstancesOptions; import org.jclouds.ec2.options.RunInstancesOptions;
import org.jclouds.concurrent.Timeout;
/** /**
* Provides access to EC2 via their REST API. * 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 * @return Describes the mapping that defines native device names to use when
* exposing virtual devices. * exposing virtual devices.
*/ */
Map<String, EbsBlockDevice> getBlockDeviceMappingForInstanceInRegion( Map<String, BlockDevice> getBlockDeviceMappingForInstanceInRegion(
@Nullable String region, String instanceId); @Nullable String region, String instanceId);
/** /**
@ -536,9 +539,9 @@ public interface InstanceClient {
* {@link InstanceState#STOPPING} to {@link InstanceState#STOPPED}</li> * {@link InstanceState#STOPPING} to {@link InstanceState#STOPPED}</li>
* </ol> * </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: * constructor can be used with the following parameters:
* {@link RunningInstance.EbsBlockDevice#EbsBlockDevice(String, String, boolean)} * {@link BlockDevice#EbsBlockDevice(String, String, boolean)}
* , that are: * , that are:
* <ol> * <ol>
* <li>Volume id (required), for instance, "vol-blah"</li> * <li>Volume id (required), for instance, "vol-blah"</li>
@ -571,5 +574,5 @@ public interface InstanceClient {
* /> * />
*/ */
void setBlockDeviceMappingForInstanceInRegion(@Nullable String region, 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 javax.inject.Inject;
import org.jclouds.ec2.domain.Attachment; import org.jclouds.ec2.domain.Attachment;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.InstanceState; import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.MonitoringState; import org.jclouds.ec2.domain.MonitoringState;
import org.jclouds.ec2.domain.Reservation; import org.jclouds.ec2.domain.Reservation;
@ -95,7 +96,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
protected boolean inMonitoring; protected boolean inMonitoring;
private boolean inBlockDeviceMapping; private boolean inBlockDeviceMapping;
private Map<String, RunningInstance.EbsBlockDevice> ebsBlockDevices = Maps.newHashMap(); private Map<String, BlockDevice> ebsBlockDevices = Maps.newHashMap();
private String volumeId; private String volumeId;
private Attachment.Status attachmentStatus; private Attachment.Status attachmentStatus;
@ -229,7 +230,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
protected void inItem() { protected void inItem() {
if (inBlockDeviceMapping) { if (inBlockDeviceMapping) {
ebsBlockDevices.put(deviceName, new RunningInstance.EbsBlockDevice(volumeId, attachmentStatus, attachTime, ebsBlockDevices.put(deviceName, new BlockDevice(volumeId, attachmentStatus, attachTime,
deleteOnTermination)); deleteOnTermination));
this.deviceName = null; this.deviceName = null;
this.volumeId = null; this.volumeId = null;

View File

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

View File

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

View File

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

View File

@ -24,15 +24,16 @@ import static org.testng.Assert.assertEquals;
import java.io.File; import java.io.File;
import java.net.URI; import java.net.URI;
import java.util.Date; import java.util.Date;
import java.util.Map;
import javax.ws.rs.HttpMethod; import javax.ws.rs.HttpMethod;
import org.jclouds.ec2.domain.Attachment.Status; import org.jclouds.ec2.domain.Attachment.Status;
import org.jclouds.ec2.domain.BlockDeviceMapping; import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.Maps;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
@ -48,11 +49,10 @@ public class BindBlockDeviceMappingToIndexedFormParamsTest {
.getInstance(BindBlockDeviceMappingToIndexedFormParams.class); .getInstance(BindBlockDeviceMappingToIndexedFormParams.class);
public void testMapping() { public void testMapping() {
BlockDeviceMapping mapping = new BlockDeviceMapping(); Map<String, BlockDevice> mapping = Maps.newLinkedHashMap();
mapping.addEbsBlockDevice("apple", new RunningInstance.EbsBlockDevice("appleId", true)); mapping.put("apple", new BlockDevice("appleId", true));
Date date = new Date(999999l); Date date = new Date(999999l);
mapping.addEbsBlockDevice("cranberry", new RunningInstance.EbsBlockDevice("cranberry", Status.ATTACHED, date, mapping.put("cranberry", new BlockDevice("cranberry", Status.ATTACHED, date, false));
false));
HttpRequest request = HttpRequest.builder().method("POST").endpoint(URI.create("http://localhost")).build(); HttpRequest request = HttpRequest.builder().method("POST").endpoint(URI.create("http://localhost")).build();
request = binder.bindToRequest(request, mapping); 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.CreateSecurityGroupIfNeeded;
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
import org.jclouds.ec2.compute.options.EC2TemplateOptions; import org.jclouds.ec2.compute.options.EC2TemplateOptions;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.ec2.domain.KeyPair; import org.jclouds.ec2.domain.KeyPair;
import org.jclouds.ec2.domain.PlacementGroup; import org.jclouds.ec2.domain.PlacementGroup;
import org.jclouds.ec2.options.RunInstancesOptions; import org.jclouds.ec2.options.RunInstancesOptions;
@ -86,6 +87,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup expectations // setup expectations
expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getHardware()).andReturn(size).atLeastOnce();
expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce();
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
systemGeneratedKeyPairName); systemGeneratedKeyPairName);
expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups);
@ -142,6 +144,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup expectations // setup expectations
expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getHardware()).andReturn(size).atLeastOnce();
expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce();
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
systemGeneratedKeyPairName); systemGeneratedKeyPairName);
expect(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( expect(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
@ -201,6 +204,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup expectations // setup expectations
expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getHardware()).andReturn(size).atLeastOnce();
expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce();
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
systemGeneratedKeyPairName); systemGeneratedKeyPairName);
expect(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( expect(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
@ -258,6 +262,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup expectations // setup expectations
expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getHardware()).andReturn(size).atLeastOnce();
expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce();
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
systemGeneratedKeyPairName); systemGeneratedKeyPairName);
expect(options.getSubnetId()).andReturn("1"); expect(options.getSubnetId()).andReturn("1");
@ -313,6 +318,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup expectations // setup expectations
expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getHardware()).andReturn(size).atLeastOnce();
expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce();
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
systemGeneratedKeyPairName); systemGeneratedKeyPairName);
expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); 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.asType;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.enableMonitoring; 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.withKernelId;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withKeyName; 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.withRamdisk;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withSecurityGroup; 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.withSubnetId;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withUserData; 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 static org.testng.Assert.assertEquals;
import java.util.Collections; 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.ec2.domain.InstanceType;
import org.jclouds.http.options.HttpRequestOptions; import org.jclouds.http.options.HttpRequestOptions;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -181,32 +183,6 @@ public class RunInstancesOptionsTest {
withKernelId(null); 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 @Test
public void testWithMonitoringEnabled() { public void testWithMonitoringEnabled() {
RunInstancesOptions options = new RunInstancesOptions(); RunInstancesOptions options = new RunInstancesOptions();
@ -274,14 +250,6 @@ public class RunInstancesOptionsTest {
withRamdisk(null); withRamdisk(null);
} }
@Test
public void testWithVirtualName() {
RunInstancesOptions options = new RunInstancesOptions();
options.withVirtualName("test");
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"),
Collections.singletonList("test"));
}
@Test @Test
public void testNullWithVirtualName() { public void testNullWithVirtualName() {
RunInstancesOptions options = new RunInstancesOptions(); RunInstancesOptions options = new RunInstancesOptions();
@ -289,15 +257,37 @@ public class RunInstancesOptionsTest {
} }
@Test @Test
public void testWithVirtualNameStatic() { public void testWithBlockDeviceMapping() {
RunInstancesOptions options = withVirtualName("test"); RunInstancesOptions options = new RunInstancesOptions();
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"), BlockDeviceMapping mapping = new BlockDeviceMapping("/dev/sda1", null, null, 120, null, true);
Collections.singletonList("test")); 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 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) @Test(expectedExceptions = NullPointerException.class)
public void testWithVirtualNameNPE() { public void testWithBlockDeviceMappingNPE() {
withVirtualName(null); withBlockDeviceMappings(null);
} }
} }

View File

@ -22,12 +22,12 @@ package org.jclouds.ec2.services;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Map;
import org.jclouds.aws.domain.Region; import org.jclouds.aws.domain.Region;
import org.jclouds.ec2.domain.AvailabilityZone; 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.InstanceType;
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior; import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
import org.jclouds.ec2.options.RunInstancesOptions; import org.jclouds.ec2.options.RunInstancesOptions;
import org.jclouds.ec2.xml.BlockDeviceMappingHandler; import org.jclouds.ec2.xml.BlockDeviceMappingHandler;
@ -46,6 +46,7 @@ import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.Maps;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
/** /**
@ -468,11 +469,11 @@ public class InstanceAsyncClientTest extends BaseEC2AsyncClientTest<InstanceAsyn
public void testSetBlockDeviceMappingForInstanceInRegion() throws SecurityException, NoSuchMethodException, public void testSetBlockDeviceMappingForInstanceInRegion() throws SecurityException, NoSuchMethodException,
IOException { IOException {
Method method = InstanceAsyncClient.class.getMethod("setBlockDeviceMappingForInstanceInRegion", String.class, Method method = InstanceAsyncClient.class.getMethod("setBlockDeviceMappingForInstanceInRegion", String.class,
String.class, BlockDeviceMapping.class); String.class, Map.class);
BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping(); Map<String, BlockDevice> mapping = Maps.newLinkedHashMap();
blockDeviceMapping.addEbsBlockDevice("/dev/sda1", new RunningInstance.EbsBlockDevice("vol-test1", true)); mapping.put("/dev/sda1", new BlockDevice("vol-test1", true));
HttpRequest request = processor.createRequest(method, null, "1", blockDeviceMapping); HttpRequest request = processor.createRequest(method, null, "1", mapping);
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); 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 java.util.Map;
import org.jclouds.ec2.domain.Attachment; 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.date.DateService;
import org.jclouds.http.functions.BaseHandlerTest; import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -46,13 +46,13 @@ public class BlockDeviceMappingHandlerTest extends BaseHandlerTest {
"/describe_image_attribute_blockDeviceMapping.xml"); "/describe_image_attribute_blockDeviceMapping.xml");
DateService dateService = injector.getInstance(DateService.class); DateService dateService = injector.getInstance(DateService.class);
Map<String, EbsBlockDevice> expected = ImmutableMap.<String, EbsBlockDevice> of("/dev/sda1", Map<String, BlockDevice> expected = ImmutableMap.<String, BlockDevice> of("/dev/sda1",
new EbsBlockDevice("vol-d74b82be", Attachment.Status.ATTACHED, dateService new BlockDevice("vol-d74b82be", Attachment.Status.ATTACHED, dateService
.iso8601DateParse("2010-02-20T18:25:26.000Z"), true), "/dev/sdf", .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)); .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); injector.getInstance(BlockDeviceMappingHandler.class)).parse(is);
assertEquals(result, expected); assertEquals(result, expected);

View File

@ -27,13 +27,13 @@ import java.util.Set;
import org.jclouds.ec2.domain.Attachment; import org.jclouds.ec2.domain.Attachment;
import org.jclouds.ec2.domain.AvailabilityZone; import org.jclouds.ec2.domain.AvailabilityZone;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.InstanceState; import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.InstanceType; import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.ec2.domain.MonitoringState; import org.jclouds.ec2.domain.MonitoringState;
import org.jclouds.ec2.domain.Reservation; import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RootDeviceType; import org.jclouds.ec2.domain.RootDeviceType;
import org.jclouds.ec2.domain.RunningInstance; import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.ec2.domain.RunningInstance.EbsBlockDevice;
import org.jclouds.date.DateService; import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.config.SaxParserModule; 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, .iso8601DateParse("2009-11-09T03:00:34.000Z"), MonitoringState.DISABLED,
AvailabilityZone.US_EAST_1C, null, "paravirtual", null, "ip-10-243-42-70.ec2.internal", 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, "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")); null, "r-a3c508cb"));
Set<Reservation<? extends RunningInstance>> result = parseRunningInstances("/describe_instances_running.xml"); 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, .iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED,
AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-132.ec2.internal", null, 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, 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", new RunningInstance(defaultRegion, ImmutableSet.of("default"), "23",
"ec2-72-44-33-6.compute-1.amazonaws.com", "ami-6ea54007", "i-28a64435", InstanceState.RUNNING, "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 InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3", "example-key-name", dateService
.iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED, .iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED,
AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-134.ec2.internal", null, 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, 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")); "r-44a5402d"));
Set<Reservation<? extends RunningInstance>> result = parseRunningInstances("/describe_instances.xml"); 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, "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", "open", null, "paravirtual", null, "10.7.0.179", null, ImmutableSet.<String> of(), "eri-A97113E4",
null, null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap 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"); 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 InstanceState.TERMINATED, InstanceType.M1_SMALL, null, null, "nebulatanimislam", dateService
.iso8601SecondsDateParse("2010-09-09T18:09:42Z"), null, null, null, "paravirtual", null, null, .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, "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")); "r-opqeylmj"));
Set<Reservation<? extends RunningInstance>> result = parseRunningInstances("/describe_instances_nova.xml"); 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, .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", 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, "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", "/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, .iso8601DateParse("2009-12-30T04:06:29.000Z"), true)))), "993194456877", null,
"r-596dd731")); "r-596dd731"));

View File

@ -27,13 +27,13 @@ import static org.testng.Assert.assertEquals;
import java.io.InputStream; import java.io.InputStream;
import org.jclouds.ec2.domain.AvailabilityZone; import org.jclouds.ec2.domain.AvailabilityZone;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.InstanceState; import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.InstanceType; import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.ec2.domain.MonitoringState; import org.jclouds.ec2.domain.MonitoringState;
import org.jclouds.ec2.domain.Reservation; import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RootDeviceType; import org.jclouds.ec2.domain.RootDeviceType;
import org.jclouds.ec2.domain.RunningInstance; import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.ec2.domain.RunningInstance.EbsBlockDevice;
import org.jclouds.date.DateService; import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest; 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, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), MonitoringState.ENABLED,
AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, Sets AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, Sets
.<String> newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, .<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, .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"), (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, MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null,
Sets.<String> newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, 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, .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"), (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, MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null,
Sets.<String> newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, 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"); ), "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 * Configure this template to start in a specific location
* *
* @throws NoSuchElementException * @throws NoSuchElementException
* if location matches the id specified * if no location matches the id specified
*/ */
TemplateBuilder locationId(String locationId); TemplateBuilder locationId(String locationId);