Issue 29: completed EBS support

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2533 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-12-29 05:26:12 +00:00
parent 719aa3483b
commit 0f158c95f2
64 changed files with 2456 additions and 263 deletions

View File

@ -32,6 +32,8 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.aws.ec2.EC2;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.AvailabilityZoneInfo;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.filters.FormSigner;
@ -71,6 +73,7 @@ import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientFactory;
import com.google.common.base.Predicate;
import com.google.common.collect.Maps;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@ -100,6 +103,19 @@ public class EC2RestClientModule extends AbstractModule {
return client.describeRegions();
}
@Provides
@Singleton
Map<AvailabilityZone, Region> provideAvailabilityZoneToRegions(
AvailabilityZoneAndRegionClient client, Map<Region, URI> regions) {
Map<AvailabilityZone, Region> map = Maps.newHashMap();
for (Region region : regions.keySet()) {
for (AvailabilityZoneInfo zoneInfo : client.describeAvailabilityZonesInRegion(region)) {
map.put(zoneInfo.getZone(), region);
}
}
return map;
}
@Provides
@TimeStamp
protected String provideTimeStamp(final DateService dateService,

View File

@ -51,14 +51,16 @@ public class Attachment {
}
}
private final Region region;
private final String volumeId;
private final String instanceId;
private final String device;
private final Status status;
private final Date attachTime;
public Attachment(String volumeId, String instanceId, String device, Status status,
Date attachTime) {
public Attachment(Region region, String volumeId, String instanceId, String device,
Status status, Date attachTime) {
this.region = checkNotNull(region, "region");
this.volumeId = volumeId;
this.instanceId = instanceId;
this.device = device;
@ -66,22 +68,45 @@ public class Attachment {
this.attachTime = attachTime;
}
/**
* Snapshots are tied to Regions and can only be used for volumes within the same Region.
*
*/
public Region getRegion() {
return region;
}
/**
* The ID of the volume.
*/
public String getVolumeId() {
return volumeId;
}
/**
* The ID of the instance.
*/
public String getInstanceId() {
return instanceId;
}
/**
* The device as it is exposed to the instance.
*/
public String getDevice() {
return device;
}
/**
* Volume state.
*/
public Status getStatus() {
return status;
}
/**
* Time stamp when the attachment initiated.
*/
public Date getAttachTime() {
return attachTime;
}
@ -93,6 +118,7 @@ public class Attachment {
result = prime * result + ((attachTime == null) ? 0 : attachTime.hashCode());
result = prime * result + ((device == null) ? 0 : device.hashCode());
result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + ((status == null) ? 0 : status.hashCode());
result = prime * result + ((volumeId == null) ? 0 : volumeId.hashCode());
return result;
@ -122,6 +148,11 @@ public class Attachment {
return false;
} else if (!instanceId.equals(other.instanceId))
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
if (status == null) {
if (other.status != null)
return false;
@ -137,8 +168,9 @@ public class Attachment {
@Override
public String toString() {
return "Attachment [attachTime=" + attachTime + ", device=" + device + ", instanceId="
+ instanceId + ", status=" + status + ", volumeId=" + volumeId + "]";
return "Attachment [region=" + region + ", volumeId=" + volumeId + ", instanceId="
+ instanceId + ", device=" + device + ", attachTime=" + attachTime + ", status="
+ status + "]";
}
}

View File

@ -42,6 +42,7 @@ import com.google.inject.internal.Nullable;
*/
public class Image implements Comparable<Image> {
private final Region region;
private final Architecture architecture;
@Nullable
private final String name;
@ -65,12 +66,13 @@ public class Image implements Comparable<Image> {
private final String rootDeviceName;
private final Map<String, EbsBlockDevice> ebsBlockDevices = Maps.newHashMap();
public Image(Architecture architecture, @Nullable String name, @Nullable String description,
String imageId, String imageLocation, String imageOwnerId, ImageState imageState,
ImageType imageType, boolean isPublic, Iterable<String> productCodes,
@Nullable String kernelId, @Nullable String platform, @Nullable String ramdiskId,
RootDeviceType rootDeviceType, String rootDeviceName,
public Image(Region region, Architecture architecture, @Nullable String name,
@Nullable String description, String imageId, String imageLocation,
String imageOwnerId, ImageState imageState, ImageType imageType, boolean isPublic,
Iterable<String> productCodes, @Nullable String kernelId, @Nullable String platform,
@Nullable String ramdiskId, RootDeviceType rootDeviceType, String rootDeviceName,
Map<String, EbsBlockDevice> ebsBlockDevices) {
this.region = checkNotNull(region, "region");
this.architecture = checkNotNull(architecture, "architecture");
this.imageId = checkNotNull(imageId, "imageId");
this.name = name;
@ -217,6 +219,14 @@ public class Image implements Comparable<Image> {
}
/**
* AMIs are tied to the Region where its files are located within Amazon S3.
*
*/
public Region getRegion() {
return region;
}
/**
* The architecture of the image (i386 or x86_64).
*/
@ -322,6 +332,7 @@ public class Image implements Comparable<Image> {
result = prime * result + ((platform == null) ? 0 : platform.hashCode());
result = prime * result + ((productCodes == null) ? 0 : productCodes.hashCode());
result = prime * result + ((ramdiskId == null) ? 0 : ramdiskId.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + ((rootDeviceName == null) ? 0 : rootDeviceName.hashCode());
result = prime * result + ((rootDeviceType == null) ? 0 : rootDeviceType.hashCode());
return result;
@ -403,6 +414,11 @@ public class Image implements Comparable<Image> {
return false;
} else if (!ramdiskId.equals(other.ramdiskId))
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
if (rootDeviceName == null) {
if (other.rootDeviceName != null)
return false;
@ -444,8 +460,9 @@ public class Image implements Comparable<Image> {
+ ", imageLocation=" + imageLocation + ", imageOwnerId=" + imageOwnerId
+ ", imageState=" + imageState + ", imageType=" + imageType + ", isPublic="
+ isPublic + ", kernelId=" + kernelId + ", name=" + name + ", platform=" + platform
+ ", productCodes=" + productCodes + ", ramdiskId=" + ramdiskId
+ ", rootDeviceName=" + rootDeviceName + ", rootDeviceType=" + rootDeviceType + "]";
+ ", productCodes=" + productCodes + ", ramdiskId=" + ramdiskId + ", region="
+ region + ", rootDeviceName=" + rootDeviceName + ", rootDeviceType="
+ rootDeviceType + "]";
}
public Map<String, EbsBlockDevice> getEbsBlockDevices() {

View File

@ -35,17 +35,26 @@ import com.google.inject.internal.Nullable;
* @author Adrian Cole
*/
public class KeyPair implements Comparable<KeyPair> {
private final Region region;
private final String keyName;
private final String keyFingerprint;
@Nullable
private final String keyMaterial;
public KeyPair(String keyName, String keyFingerprint, @Nullable String keyMaterial) {
public KeyPair(Region region, String keyName, String keyFingerprint, @Nullable String keyMaterial) {
this.region = checkNotNull(region, "region");
this.keyName = checkNotNull(keyName, "keyName");
this.keyFingerprint = checkNotNull(keyFingerprint, "keyFingerprint");
this.keyMaterial = keyMaterial;// nullable on list
}
/**
* Key pairs (to connect to instances) are Region-specific.
*/
public Region getRegion() {
return region;
}
/**
* {@inheritDoc}
*/
@ -81,6 +90,7 @@ public class KeyPair implements Comparable<KeyPair> {
result = prime * result + ((keyFingerprint == null) ? 0 : keyFingerprint.hashCode());
result = prime * result + ((keyMaterial == null) ? 0 : keyMaterial.hashCode());
result = prime * result + ((keyName == null) ? 0 : keyName.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
return result;
}
@ -108,6 +118,11 @@ public class KeyPair implements Comparable<KeyPair> {
return false;
} else if (!keyName.equals(other.keyName))
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
return true;
}

View File

@ -36,11 +36,11 @@ import com.google.common.collect.Sets;
* />
* @author Adrian Cole
*/
public class LaunchPermission {
public class Permission {
private final Set<String> groups = Sets.newHashSet();
private final Set<String> userIds = Sets.newHashSet();
public LaunchPermission(Iterable<String> userIds, Iterable<String> groups) {
public Permission(Iterable<String> userIds, Iterable<String> groups) {
Iterables.addAll(this.userIds, checkNotNull(userIds, "userIds"));
Iterables.addAll(this.groups, checkNotNull(groups, "groups"));
}
@ -62,7 +62,7 @@ public class LaunchPermission {
return false;
if (getClass() != obj.getClass())
return false;
LaunchPermission other = (LaunchPermission) obj;
Permission other = (Permission) obj;
if (groups == null) {
if (other.groups != null)
return false;

View File

@ -36,15 +36,25 @@ import com.google.inject.internal.Nullable;
* @author Adrian Cole
*/
public class PublicIpInstanceIdPair implements Comparable<PublicIpInstanceIdPair> {
private final Region region;
@Nullable
private final String instanceId;
private final InetAddress publicIp;
public PublicIpInstanceIdPair(InetAddress publicIp, @Nullable String instanceId) {
public PublicIpInstanceIdPair(Region region, InetAddress publicIp, @Nullable String instanceId) {
this.region = checkNotNull(region, "region");
this.instanceId = instanceId;
this.publicIp = checkNotNull(publicIp, "publicIp");
}
/**
* Elastic IP addresses are tied to a Region and cannot be mapped across Regions.
*/
public Region getRegion() {
return region;
}
/**
* {@inheritDoc}
*/
@ -73,6 +83,7 @@ public class PublicIpInstanceIdPair implements Comparable<PublicIpInstanceIdPair
int result = 1;
result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
result = prime * result + ((publicIp == null) ? 0 : publicIp.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
return result;
}
@ -95,6 +106,11 @@ public class PublicIpInstanceIdPair implements Comparable<PublicIpInstanceIdPair
return false;
} else if (!publicIp.equals(other.publicIp))
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
return true;
}

View File

@ -25,7 +25,7 @@ package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.SortedSet;
import java.util.Set;
import com.google.inject.internal.Nullable;
@ -36,8 +36,20 @@ import com.google.inject.internal.Nullable;
* @author Adrian Cole
*/
public class Reservation implements Comparable<Reservation> {
public Reservation(SortedSet<String> groupIds, SortedSet<RunningInstance> instances,
private final Region region;
private final Set<String> groupIds;
private final Set<RunningInstance> instances;
private final @Nullable
String ownerId;
private final @Nullable
String requesterId;
private final @Nullable
String reservationId;
public Reservation(Region region, Set<String> groupIds, Set<RunningInstance> instances,
@Nullable String ownerId, @Nullable String requesterId, @Nullable String reservationId) {
this.region = checkNotNull(region, "region");
this.groupIds = checkNotNull(groupIds, "groupIds");
this.instances = checkNotNull(instances, "instances");
this.ownerId = ownerId;
@ -45,14 +57,12 @@ public class Reservation implements Comparable<Reservation> {
this.reservationId = reservationId;
}
private final SortedSet<String> groupIds;
private final SortedSet<RunningInstance> instances;
private final @Nullable
String ownerId;
private final @Nullable
String requesterId;
private final @Nullable
String reservationId;
/**
* Instances are tied to Availability Zones. However, the instance ID is tied to the Region.
*/
public Region getRegion() {
return region;
}
public int compareTo(Reservation o) {
return (this == o) ? 0 : getReservationId().compareTo(o.getReservationId());
@ -61,11 +71,11 @@ public class Reservation implements Comparable<Reservation> {
/**
* Names of the security groups.
*/
public SortedSet<String> getGroupIds() {
public Set<String> getGroupIds() {
return groupIds;
}
public SortedSet<RunningInstance> getRunningInstances() {
public Set<RunningInstance> getRunningInstances() {
return instances;
}
@ -97,6 +107,7 @@ public class Reservation implements Comparable<Reservation> {
result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode());
result = prime * result + ((instances == null) ? 0 : instances.hashCode());
result = prime * result + ((ownerId == null) ? 0 : ownerId.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + ((requesterId == null) ? 0 : requesterId.hashCode());
result = prime * result + ((reservationId == null) ? 0 : reservationId.hashCode());
return result;
@ -126,6 +137,11 @@ public class Reservation implements Comparable<Reservation> {
return false;
} else if (!ownerId.equals(other.ownerId))
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
if (requesterId == null) {
if (other.requesterId != null)
return false;

View File

@ -53,8 +53,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
private final String keyName;
private final Date launchTime;
private final boolean monitoring;
@Nullable
private final String availabilityZone;
private final AvailabilityZone availabilityZone;
@Nullable
private final String platform;
@Nullable
@ -78,7 +77,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
public RunningInstance(String amiLaunchIndex, @Nullable String dnsName, String imageId,
String instanceId, InstanceState instanceState, InstanceType instanceType,
@Nullable InetAddress ipAddress, @Nullable String kernelId, @Nullable String keyName,
Date launchTime, boolean monitoring, @Nullable String availabilityZone,
Date launchTime, boolean monitoring, AvailabilityZone availabilityZone,
@Nullable String platform, @Nullable String privateDnsName,
@Nullable InetAddress privateIpAddress, Set<String> productCodes,
@Nullable String ramdiskId, @Nullable String reason, @Nullable String subnetId,
@ -94,7 +93,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
this.keyName = keyName;
this.launchTime = checkNotNull(launchTime, "launchTime");
this.monitoring = checkNotNull(monitoring, "monitoring");
this.availabilityZone = availabilityZone;
this.availabilityZone = checkNotNull(availabilityZone, "availabilityZone");
this.platform = platform;
this.privateDnsName = privateDnsName; // nullable on runinstances.
this.privateIpAddress = privateIpAddress;
@ -190,7 +189,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
/**
* The location where the instance launched.
*/
public String getAvailabilityZone() {
public AvailabilityZone getAvailabilityZone() {
return availabilityZone;
}

View File

@ -23,7 +23,9 @@
*/
package org.jclouds.aws.ec2.domain;
import java.util.SortedSet;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
/**
*
@ -32,19 +34,31 @@ import java.util.SortedSet;
* @author Adrian Cole
*/
public class SecurityGroup implements Comparable<SecurityGroup> {
private final Region region;
private final String name;
private final String ownerId;
private final String description;
private final SortedSet<IpPermission> ipPermissions;
private final Set<IpPermission> ipPermissions;
public SecurityGroup(String name, String ownerId, String description,
SortedSet<IpPermission> ipPermissions) {
public SecurityGroup(Region region, String name, String ownerId, String description,
Set<IpPermission> ipPermissions) {
this.region = checkNotNull(region, "region");
this.name = name;
this.ownerId = ownerId;
this.description = description;
this.ipPermissions = ipPermissions;
}
/**
* Security groups are not copied across Regions. Instances within the Region cannot communicate
* with instances outside the Region using group-based firewall rules. Traffic from instances in
* another Region is seen as WAN bandwidth.
*/
public Region getRegion() {
return region;
}
/**
* {@inheritDoc}
*/
@ -76,7 +90,7 @@ public class SecurityGroup implements Comparable<SecurityGroup> {
/**
* Set of IP permissions associated with the security group.
*/
public SortedSet<IpPermission> getIpPermissions() {
public Set<IpPermission> getIpPermissions() {
return ipPermissions;
}
@ -88,6 +102,7 @@ public class SecurityGroup implements Comparable<SecurityGroup> {
result = prime * result + ((ipPermissions == null) ? 0 : ipPermissions.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((ownerId == null) ? 0 : ownerId.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
return result;
}
@ -120,6 +135,11 @@ public class SecurityGroup implements Comparable<SecurityGroup> {
return false;
} else if (!ownerId.equals(other.ownerId))
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
return true;
}
}

View File

@ -0,0 +1,235 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Date;
/**
*
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateSnapshot.html"
* />
* @author Adrian Cole
*/
public class Snapshot implements Comparable<Snapshot> {
public static enum Status {
PENDING, COMPLETED, ERROR;
public String value() {
return name().toLowerCase();
}
@Override
public String toString() {
return value();
}
public static Status fromValue(String status) {
return valueOf(checkNotNull(status, "status").toUpperCase());
}
}
private final Region region;
private final String id;
private final String volumeId;
private final int volumeSize;
private final Status status;
private final Date startTime;
private final int progress;
private final String ownerId;
private final String description;
private final String ownerAlias;
public Snapshot(Region region, String id, String volumeId, int volumeSize, Status status,
Date startTime, int progress, String ownerId, String description, String ownerAlias) {
this.region = checkNotNull(region, "region");
this.id = id;
this.volumeId = volumeId;
this.volumeSize = volumeSize;
this.status = status;
this.startTime = startTime;
this.progress = progress;
this.ownerId = ownerId;
this.description = description;
this.ownerAlias = ownerAlias;
}
/**
* Snapshots are tied to Regions and can only be used for volumes within the same Region.
*/
public Region getRegion() {
return region;
}
/**
* The ID of the snapshot.
*/
public String getId() {
return id;
}
/**
* The ID of the volume.
*/
public String getVolumeId() {
return volumeId;
}
/**
* The size of the volume, in GiB.
*/
public int getVolumeSize() {
return volumeSize;
}
/**
* Snapshot state (e.g., pending, completed, or error)
*/
public Status getStatus() {
return status;
}
/**
* Time stamp when the snapshot was initiated.
*/
public Date getStartTime() {
return startTime;
}
/**
* The progress of the snapshot, in percentage.
*/
public int getProgress() {
return progress;
}
/**
* AWS Access Key ID of the user who owns the snapshot.
*/
public String getOwnerId() {
return ownerId;
}
/**
* Description of the snapshot.
*/
public String getDescription() {
return description;
}
/**
* The AWS account alias (e.g., "amazon", "redhat", "self", etc.) or AWS account ID that owns the
* AMI.
*/
public String getOwnerAlias() {
return ownerAlias;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((ownerAlias == null) ? 0 : ownerAlias.hashCode());
result = prime * result + ((ownerId == null) ? 0 : ownerId.hashCode());
result = prime * result + progress;
result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + ((startTime == null) ? 0 : startTime.hashCode());
result = prime * result + ((status == null) ? 0 : status.hashCode());
result = prime * result + ((volumeId == null) ? 0 : volumeId.hashCode());
result = prime * result + volumeSize;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Snapshot other = (Snapshot) obj;
if (description == null) {
if (other.description != null)
return false;
} else if (!description.equals(other.description))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (ownerAlias == null) {
if (other.ownerAlias != null)
return false;
} else if (!ownerAlias.equals(other.ownerAlias))
return false;
if (ownerId == null) {
if (other.ownerId != null)
return false;
} else if (!ownerId.equals(other.ownerId))
return false;
if (progress != other.progress)
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
if (startTime == null) {
if (other.startTime != null)
return false;
} else if (!startTime.equals(other.startTime))
return false;
if (status == null) {
if (other.status != null)
return false;
} else if (!status.equals(other.status))
return false;
if (volumeId == null) {
if (other.volumeId != null)
return false;
} else if (!volumeId.equals(other.volumeId))
return false;
if (volumeSize != other.volumeSize)
return false;
return true;
}
@Override
public String toString() {
return "Snapshot [description=" + description + ", id=" + id + ", ownerAlias=" + ownerAlias
+ ", ownerId=" + ownerId + ", progress=" + progress + ", startTime=" + startTime
+ ", status=" + status + ", volumeId=" + volumeId + ", volumeSize=" + volumeSize
+ "]";
}
@Override
public int compareTo(Snapshot o) {
return startTime.compareTo(o.startTime);
}
}

View File

@ -23,6 +23,8 @@
*/
package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull;
/**
*
@ -32,6 +34,7 @@ package org.jclouds.aws.ec2.domain;
*/
public class TerminatedInstance implements Comparable<TerminatedInstance> {
private final Region region;
private final String instanceId;
private final InstanceState shutdownState;
private final InstanceState previousState;
@ -40,13 +43,21 @@ public class TerminatedInstance implements Comparable<TerminatedInstance> {
return (this == o) ? 0 : getInstanceId().compareTo(o.getInstanceId());
}
public TerminatedInstance(String instanceId, InstanceState shutdownState,
public TerminatedInstance(Region region, String instanceId, InstanceState shutdownState,
InstanceState previousState) {
this.region = checkNotNull(region, "region");
this.instanceId = instanceId;
this.shutdownState = shutdownState;
this.previousState = previousState;
}
/**
* Instances are tied to Availability Zones. However, the instance ID is tied to the Region.
*/
public Region getRegion() {
return region;
}
public String getInstanceId() {
return instanceId;
}
@ -65,6 +76,7 @@ public class TerminatedInstance implements Comparable<TerminatedInstance> {
int result = 1;
result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
result = prime * result + ((previousState == null) ? 0 : previousState.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + ((shutdownState == null) ? 0 : shutdownState.hashCode());
return result;
}
@ -88,6 +100,11 @@ public class TerminatedInstance implements Comparable<TerminatedInstance> {
return false;
} else if (!previousState.equals(other.previousState))
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
if (shutdownState == null) {
if (other.shutdownState != null)
return false;

View File

@ -60,6 +60,7 @@ public class Volume implements Comparable<Volume> {
}
}
private final Region region;
private final String id;
private final int size;
@Nullable
@ -69,9 +70,10 @@ public class Volume implements Comparable<Volume> {
private final Date createTime;
private final Set<Attachment> attachments = Sets.newLinkedHashSet();
public Volume(String id, int size, String snapshotId, AvailabilityZone availabilityZone,
org.jclouds.aws.ec2.domain.Volume.Status status, Date createTime,
public Volume(Region region, String id, int size, String snapshotId,
AvailabilityZone availabilityZone, Volume.Status status, Date createTime,
Iterable<Attachment> attachments) {
this.region = checkNotNull(region, "region");
this.id = id;
this.size = size;
this.snapshotId = snapshotId;
@ -81,6 +83,14 @@ public class Volume implements Comparable<Volume> {
Iterables.addAll(this.attachments, attachments);
}
/**
* An Amazon EBS volume must be located within the same Availability Zone as the instance to
* which it attaches.
*/
public Region getRegion() {
return region;
}
public String getId() {
return id;
}
@ -117,6 +127,7 @@ public class Volume implements Comparable<Volume> {
result = prime * result + ((availabilityZone == null) ? 0 : availabilityZone.hashCode());
result = prime * result + ((createTime == null) ? 0 : createTime.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + size;
result = prime * result + ((snapshotId == null) ? 0 : snapshotId.hashCode());
result = prime * result + ((status == null) ? 0 : status.hashCode());
@ -152,6 +163,11 @@ public class Volume implements Comparable<Volume> {
return false;
} else if (!id.equals(other.id))
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
if (size != other.size)
return false;
if (snapshotId == null) {
@ -175,7 +191,7 @@ public class Volume implements Comparable<Volume> {
@Override
public String toString() {
return "Volume [attachments=" + attachments + ", availabilityZone=" + availabilityZone
+ ", createTime=" + createTime + ", id=" + id + ", size=" + size + ", snapshotId="
+ snapshotId + ", status=" + status + "]";
+ ", createTime=" + createTime + ", id=" + id + ", region=" + region + ", size="
+ size + ", snapshotId=" + snapshotId + ", status=" + status + "]";
}
}

View File

@ -0,0 +1,57 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.functions;
import java.net.URI;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.Region;
import com.google.common.base.Function;
/**
*
* @author Adrian Cole
*/
@Singleton
public class AvailabilityZoneToEndpoint implements Function<Object, URI> {
private final Map<AvailabilityZone, Region> availabilityZoneToRegion;
private final Map<Region, URI> regionToEndpoint;
@Inject
public AvailabilityZoneToEndpoint(Map<Region, URI> regionToEndpoint,
Map<AvailabilityZone, Region> availabilityZoneToRegion) {
this.regionToEndpoint = regionToEndpoint;
this.availabilityZoneToRegion = availabilityZoneToRegion;
}
public URI apply(Object from) {
return regionToEndpoint.get(availabilityZoneToRegion.get(from));
}
}

View File

@ -0,0 +1,77 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.options;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.aws.ec2.options.internal.BaseEC2RequestOptions;
/**
* Contains options supported in the Form API for the CreateSnapshot operation. <h2>
* Usage</h2> The recommended way to instantiate a CreateSnapshotOptions object is to statically
* import CreateSnapshotOptions.Builder.* and invoke a static creation method followed by an
* instance mutator (if needed):
* <p/>
* <code>
* import static org.jclouds.aws.ec2.options.CreateSnapshotOptions.Builder.*
* <p/>
* EC2Client connection = // get connection
* Snapshot snapshot = connection.getElasticBlockStoreServices().createSnapshotInRegion(volumeId, withDescription("123125"));
* <code>
*
* @author Adrian Cole
* @see <a
* href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-form-CreateSnapshot.html"
* />
*/
public class CreateSnapshotOptions extends BaseEC2RequestOptions {
/**
* Description of the Amazon EBS snapshot.
* <p/>
*
* Up to 255 characters
*/
public CreateSnapshotOptions withDescription(String description) {
formParameters.put("Description", checkNotNull(description, "description"));
return this;
}
public String getDescription() {
return getFirstFormOrNull("Description");
}
public static class Builder {
/**
* @see CreateSnapshotOptions#withDescription(String )
*/
public static CreateSnapshotOptions withDescription(String accountId) {
CreateSnapshotOptions options = new CreateSnapshotOptions();
return options.withDescription(accountId);
}
}
}

View File

@ -0,0 +1,116 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.options;
import java.util.Set;
import org.jclouds.aws.ec2.options.internal.BaseEC2RequestOptions;
/**
* Contains options supported in the Form API for the DescribeSnapshots operation. <h2>
* Usage</h2> The recommended way to instantiate a DescribeSnapshotsOptions object is to statically
* import DescribeSnapshotsOptions.Builder.* and invoke a static creation method followed by an
* instance mutator (if needed):
* <p/>
* <code>
* import static org.jclouds.aws.ec2.options.DescribeSnapshotsOptions.Builder.*
* <p/>
* EC2Client connection = // get connection
* Set<Snapshot> snapshots = connection.getElasticBlockStoreServices().describeSnapshots(restorableBy("123125").snapshotIds(1000, 1004));
* <code>
*
* @author Adrian Cole
* @see <a
* href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-form-DescribeSnapshots.html"
* />
*/
public class DescribeSnapshotsOptions extends BaseEC2RequestOptions {
/**
* Account ID of a user that can create volumes from the snapshot.
*
*/
public DescribeSnapshotsOptions restorableBy(String... accountIds) {
indexFormValuesWithPrefix("RestorableBy", accountIds);
return this;
}
public String getRestorableBy() {
return getFirstFormOrNull("RestorableBy");
}
/**
* The ID of the Amazon EBS snapshot.
*/
public DescribeSnapshotsOptions snapshotIds(String... snapshotIds) {
indexFormValuesWithPrefix("SnapshotId", snapshotIds);
return this;
}
public Set<String> getSnapshotIds() {
return getFormValuesWithKeysPrefixedBy("SnapshotId.");
}
/**
* Returns snapshots owned by the specified owner. Multiple owners can be specified.
* <p/>
* Valid Values: self | amazon | AWS Account ID
*/
public DescribeSnapshotsOptions ownedBy(String... owners) {
indexFormValuesWithPrefix("Owner", owners);
return this;
}
public Set<String> getOwners() {
return getFormValuesWithKeysPrefixedBy("Owner.");
}
public static class Builder {
/**
* @see DescribeSnapshotsOptions#restorableBy(String[] )
*/
public static DescribeSnapshotsOptions restorableBy(String... accountIds) {
DescribeSnapshotsOptions options = new DescribeSnapshotsOptions();
return options.restorableBy(accountIds);
}
/**
* @see DescribeSnapshotsOptions#snapshotIds(String[] )
*/
public static DescribeSnapshotsOptions snapshotIds(String... snapshotIds) {
DescribeSnapshotsOptions options = new DescribeSnapshotsOptions();
return options.snapshotIds(snapshotIds);
}
/**
* @see DescribeSnapshotsOptions#ownedBy(String[] )
*/
public static DescribeSnapshotsOptions ownedBy(String... owners) {
DescribeSnapshotsOptions options = new DescribeSnapshotsOptions();
return options.ownedBy(owners);
}
}
}

View File

@ -0,0 +1,48 @@
package org.jclouds.aws.ec2.predicates;
import java.util.Map;
import javax.annotation.Resource;
import javax.inject.Singleton;
import static org.jclouds.aws.ec2.options.DescribeSnapshotsOptions.Builder.snapshotIds;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Snapshot;
import org.jclouds.aws.ec2.services.ElasticBlockStoreClient;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
import com.google.inject.Inject;
import com.google.inject.internal.Iterables;
/**
*
* Tests to see if a snapshot is completed.
*
* @author Adrian Cole
*/
@Singleton
public class SnapshotCompleted implements Predicate<Snapshot> {
private final ElasticBlockStoreClient client;
@Resource
protected Logger logger = Logger.NULL;
@Inject
public SnapshotCompleted(ElasticBlockStoreClient client,
Map<AvailabilityZone, Region> availabilityZoneToRegion) {
this.client = client;
}
public boolean apply(Snapshot snapshot) {
logger.trace("looking for status on snapshot %s", snapshot.getId());
snapshot = Iterables.getOnlyElement(client.describeSnapshotsInRegion(snapshot.getRegion(),
snapshotIds(snapshot.getId())));
logger.trace("%s: looking for status %s: currently: %s; progress %d/100", snapshot,
Snapshot.Status.COMPLETED, snapshot.getStatus(), snapshot.getProgress());
return snapshot.getStatus() == Snapshot.Status.COMPLETED;
}
}

View File

@ -0,0 +1,47 @@
package org.jclouds.aws.ec2.predicates;
import java.util.Map;
import javax.annotation.Resource;
import javax.inject.Singleton;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Volume;
import org.jclouds.aws.ec2.services.ElasticBlockStoreClient;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
import com.google.inject.Inject;
import com.google.inject.internal.Iterables;
/**
*
* Tests to see if a volume is completed.
*
* @author Adrian Cole
*/
@Singleton
public class VolumeAvailable implements Predicate<Volume> {
private final ElasticBlockStoreClient client;
@Resource
protected Logger logger = Logger.NULL;
@Inject
public VolumeAvailable(ElasticBlockStoreClient client,
Map<AvailabilityZone, Region> availabilityZoneToRegion) {
this.client = client;
}
public boolean apply(Volume volume) {
logger.trace("looking for status on volume %s", volume.getId());
volume = Iterables.getOnlyElement(client.describeVolumesInRegion(volume.getRegion(), volume
.getId()));
logger.trace("%s: looking for status %s: currently: %s", volume, Volume.Status.AVAILABLE,
volume.getStatus());
return volume.getStatus() == Volume.Status.AVAILABLE;
}
}

View File

@ -38,7 +38,7 @@ import org.jclouds.aws.ec2.binders.BindProductCodesToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindUserGroupsToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindUserIdsToIndexedFormParams;
import org.jclouds.aws.ec2.domain.Image;
import org.jclouds.aws.ec2.domain.LaunchPermission;
import org.jclouds.aws.ec2.domain.Permission;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Image.EbsBlockDevice;
import org.jclouds.aws.ec2.filters.FormSigner;
@ -50,7 +50,7 @@ import org.jclouds.aws.ec2.options.RegisterImageOptions;
import org.jclouds.aws.ec2.xml.BlockDeviceMappingHandler;
import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandler;
import org.jclouds.aws.ec2.xml.ImageIdHandler;
import org.jclouds.aws.ec2.xml.LaunchPermissionHandler;
import org.jclouds.aws.ec2.xml.PermissionHandler;
import org.jclouds.aws.ec2.xml.ProductCodesHandler;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.EndpointParam;
@ -172,8 +172,8 @@ public interface AMIAsyncClient {
@Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeImageAttribute",
"launchPermission" })
@XMLResponseParser(LaunchPermissionHandler.class)
Future<LaunchPermission> getLaunchPermissionForImageInRegion(
@XMLResponseParser(PermissionHandler.class)
Future<Permission> getLaunchPermissionForImageInRegion(
@EndpointParam(parser = RegionToEndpoint.class) Region region,
@FormParam("ImageId") String imageId);

View File

@ -28,7 +28,7 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.aws.ec2.domain.Image;
import org.jclouds.aws.ec2.domain.LaunchPermission;
import org.jclouds.aws.ec2.domain.Permission;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Image.EbsBlockDevice;
import org.jclouds.aws.ec2.options.CreateImageOptions;
@ -63,22 +63,6 @@ public interface AMIClient {
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
Set<Image> describeImagesInRegion(Region region, DescribeImagesOptions... options);
/**
* Returns the {@link LaunchPermission}s of an image.
*
* @param region
* AMIs are tied to the Region where its files are located within Amazon S3.
* @param imageId
* The ID of the AMI for which an attribute will be described
* @see #describeImages
* @see #modifyImageAttribute
* @see #resetImageAttribute
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeImageAttribute.html"
* />
* @see DescribeImagesOptions
*/
LaunchPermission getLaunchPermissionForImageInRegion(Region region, String imageId);
/**
* Returns the Product Codes of an image.
*
@ -221,6 +205,22 @@ public interface AMIClient {
String registerImageBackedByEbsInRegion(Region region, String name, String ebsSnapshotId,
RegisterImageBackedByEbsOptions... options);
/**
* Returns the {@link Permission}s of an image.
*
* @param region
* AMIs are tied to the Region where its files are located within Amazon S3.
* @param imageId
* The ID of the AMI for which an attribute will be described
* @see #describeImages
* @see #modifyImageAttribute
* @see #resetImageAttribute
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeImageAttribute.html"
* />
* @see DescribeImagesOptions
*/
Permission getLaunchPermissionForImageInRegion(Region region, String imageId);
/**
* Adds {@code launchPermission}s to an AMI.
*

View File

@ -33,20 +33,28 @@ import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.ec2.EC2;
import org.jclouds.aws.ec2.binders.BindUserGroupsToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindUserIdsToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindVolumeIdsToIndexedFormParams;
import org.jclouds.aws.ec2.domain.Attachment;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.Permission;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Snapshot;
import org.jclouds.aws.ec2.domain.Volume;
import org.jclouds.aws.ec2.filters.FormSigner;
import org.jclouds.aws.ec2.functions.AvailabilityZoneToEndpoint;
import org.jclouds.aws.ec2.functions.RegionToEndpoint;
import org.jclouds.aws.ec2.options.CreateSnapshotOptions;
import org.jclouds.aws.ec2.options.DescribeSnapshotsOptions;
import org.jclouds.aws.ec2.options.DetachVolumeOptions;
import org.jclouds.aws.ec2.xml.AttachmentHandler;
import org.jclouds.aws.ec2.xml.CreateVolumeResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeSnapshotsResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeVolumesResponseHandler;
import org.jclouds.aws.ec2.xml.PermissionHandler;
import org.jclouds.aws.ec2.xml.SnapshotHandler;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
@ -69,12 +77,10 @@ public interface ElasticBlockStoreAsyncClient {
*/
@POST
@Path("/")
@Endpoint(EC2.class)
// TODO: remove
@FormParams(keys = ACTION, values = "CreateVolume")
@XMLResponseParser(CreateVolumeResponseHandler.class)
Future<Volume> createVolumeFromSnapshotInAvailabilityZone(
@FormParam("AvailabilityZone") AvailabilityZone availabilityZone,
@EndpointParam(parser = AvailabilityZoneToEndpoint.class) @FormParam("AvailabilityZone") AvailabilityZone availabilityZone,
@FormParam("SnapshotId") String snapshotId);
/**
@ -82,12 +88,10 @@ public interface ElasticBlockStoreAsyncClient {
*/
@POST
@Path("/")
@Endpoint(EC2.class)
// TODO: remove
@FormParams(keys = ACTION, values = "CreateVolume")
@XMLResponseParser(CreateVolumeResponseHandler.class)
Future<Volume> createVolumeInAvailabilityZone(
@FormParam("AvailabilityZone") AvailabilityZone availabilityZone,
@EndpointParam(parser = AvailabilityZoneToEndpoint.class) @FormParam("AvailabilityZone") AvailabilityZone availabilityZone,
@FormParam("Size") int size);
/**
@ -133,4 +137,84 @@ public interface ElasticBlockStoreAsyncClient {
@FormParam("VolumeId") String volumeId, @FormParam("InstanceId") String instanceId,
@FormParam("Device") String device);
/**
* @see ElasticBlockStoreClient#createSnapshotInRegion
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "CreateSnapshot")
@XMLResponseParser(SnapshotHandler.class)
Future<Snapshot> createSnapshotInRegion(
@EndpointParam(parser = RegionToEndpoint.class) Region region,
@FormParam("VolumeId") String volumeId, CreateSnapshotOptions... options);
/**
* @see ElasticBlockStoreClient#describeSnapshotsInRegion
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeSnapshots")
@XMLResponseParser(DescribeSnapshotsResponseHandler.class)
Future<? extends Set<Snapshot>> describeSnapshotsInRegion(
@EndpointParam(parser = RegionToEndpoint.class) Region region,
DescribeSnapshotsOptions... options);
/**
* @see ElasticBlockStoreClient#deleteSnapshotInRegion
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DeleteSnapshot")
Future<Void> deleteSnapshotInRegion(
@EndpointParam(parser = RegionToEndpoint.class) Region region,
@FormParam("SnapshotId") String snapshotId);
/**
* @see ElasticBlockStoreClient#addCreateVolumePermissionsToSnapshotInRegion
*/
@POST
@Path("/")
@FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = {
"ModifySnapshotAttribute", "add", "createVolumePermission" })
Future<Void> addCreateVolumePermissionsToSnapshotInRegion(
@EndpointParam(parser = RegionToEndpoint.class) Region region,
@BinderParam(BindUserIdsToIndexedFormParams.class) Iterable<String> userIds,
@BinderParam(BindUserGroupsToIndexedFormParams.class) Iterable<String> userGroups,
@FormParam("SnapshotId") String snapshotId);
/**
* @see ElasticBlockStoreClient#removeCreateVolumePermissionsToSnapshotInRegion
*/
@POST
@Path("/")
@FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = {
"ModifySnapshotAttribute", "remove", "createVolumePermission" })
Future<Void> removeCreateVolumePermissionsFromSnapshotInRegion(
@EndpointParam(parser = RegionToEndpoint.class) Region region,
@BinderParam(BindUserIdsToIndexedFormParams.class) Iterable<String> userIds,
@BinderParam(BindUserGroupsToIndexedFormParams.class) Iterable<String> userGroups,
@FormParam("SnapshotId") String snapshotId);
/**
* @see ElasticBlockStoreClient#getCreateVolumePermissionForSnapshotInRegion
*/
@POST
@Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeSnapshotAttribute",
"createVolumePermission" })
@XMLResponseParser(PermissionHandler.class)
Future<Permission> getCreateVolumePermissionForSnapshotInRegion(
@EndpointParam(parser = RegionToEndpoint.class) Region region,
@FormParam("SnapshotId") String snapshotId);
/**
* @see ElasticBlockStoreClient#resetCreateVolumePermissionsOnSnapshotInRegion
*/
@POST
@Path("/")
@FormParams(keys = { ACTION, "Attribute" }, values = { "ResetSnapshotAttribute", "createVolumePermission" })
Future<Void> resetCreateVolumePermissionsOnSnapshotInRegion(
@EndpointParam(parser = RegionToEndpoint.class) Region region,
@FormParam("SnapshotId") String snapshotId);
}

View File

@ -28,8 +28,12 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.aws.ec2.domain.Attachment;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.Permission;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Snapshot;
import org.jclouds.aws.ec2.domain.Volume;
import org.jclouds.aws.ec2.options.CreateSnapshotOptions;
import org.jclouds.aws.ec2.options.DescribeSnapshotsOptions;
import org.jclouds.aws.ec2.options.DetachVolumeOptions;
import org.jclouds.concurrent.Timeout;
@ -193,4 +197,196 @@ public interface ElasticBlockStoreClient {
* />
*/
Attachment attachVolumeInRegion(Region region, String volumeId, String instanceId, String device);
/**
* Creates a snapshot of an Amazon EBS volume and stores it in Amazon S3. You can use snapshots
* for backups, to make identical copies of instance devices, and to save data before shutting
* down an instance. For more information about Amazon EBS, go to the Amazon Elastic Compute
* Cloud Developer Guide or Amazon Elastic Compute Cloud User Guide.
* <p/>
* When taking a snapshot of a file system, we recommend unmounting it first. This ensures the
* file system metadata is in a consistent state, that the 'mounted indicator' is cleared, and
* that all applications using that file system are stopped and in a consistent state. Some file
* systems, such as xfs, can freeze and unfreeze activity so a snapshot can be made without
* unmounting.
* <p/>
* For Linux/UNIX, enter the following command from the command line.
*
* <pre>
* umount - d / dev / sdh
* </pre>
* <p/>
* For Windows, open Disk Management, right-click the volume to unmount, and select Change Drive
* Letter and Path. Then, select the mount point to remove and click Remove.
*
* @param region
* Snapshots are tied to Regions and can only be used for volumes within the same
* Region.
* @param volumeId
* The ID of the Amazon EBS volume of which to take a snapshot.
* @param options
* options like passing a description.
* @return the Snapshot in progress
*
* @see #describeSnapshotsInRegion
* @see #deleteSnapshotInRegion
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateSnapshot.html"
* />
*/
Snapshot createSnapshotInRegion(Region region, String volumeId, CreateSnapshotOptions... options);
/**
* Returns information about Amazon EBS snapshots available to the user. Information returned
* includes volume ID, status, start time, progress, owner ID, volume size, and description.
* Snapshots available to the user include public snapshots available for any user to
* createVolume, private snapshots owned by the user making the request, and private snapshots
* owned by other users for which the user granted explicit create volume permissions.
* <p/>
* The create volume permissions fall into 3 categories:
* <p/>
* <table>
* <tr>
* <td>Permission</td>
* <td>Description</td>
* </tr>
* <tr>
* <td>public</td>
* <td>The owner of the snapshot granted create volume permissions for the snapshot to the all
* group. All users have create volume permissions for these snapshots.</td>
* </tr>
* <tr>
* <td>explicit</td>
* <td>The owner of the snapshot granted create volume permissions to a specific user.</td>
* </tr>
* <tr>
* <td>implicit</td>
* <td>A user has implicit create volume permissions for all snapshots he or she owns.</td>
* </tr>
* </table>
* <p/>
*
* The list of snapshots returned can be modified by specifying snapshot IDs, snapshot owners, or
* users with create volume permissions. If no options are specified, Amazon EC2 returns all
* snapshots for which the user has create volume permissions.
* <p/>
* If you specify one or more snapshot IDs, only snapshots that have the specified IDs are
* returned. If you specify an invalid snapshot ID, a fault is returned. If you specify a
* snapshot ID for which you do not have access, it will not be included in the returned results.
* <p/>
* If you specify one or more snapshot owners, only snapshots from the specified owners and for
* which you have access are returned. The results can include the AWS Account IDs of the
* specified owners, amazon for snapshots owned by Amazon or self for snapshots that you own.
* <p/>
* If you specify a list of restorable users, only users that have create snapshot permissions
* for the snapshots are returned. You can specify AWS Account IDs (if you own the snapshot(s)),
* self for snapshots for which you own or have explicit permissions, or all for public
* snapshots.
*
* @param region
* Snapshots are tied to Regions and can only be used for volumes within the same
* Region.
* @param options
* specify the snapshot ids or other parameters to clarify the list.
* @return matching snapshots.
*
* @see #createSnapshotsInRegion
* @see #deleteSnapshotInRegion
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSnapshots.html"
* />
*/
Set<Snapshot> describeSnapshotsInRegion(Region region, DescribeSnapshotsOptions... options);
/**
* Deletes a snapshot of an Amazon EBS volume that you own. For more information, go to the
* Amazon Elastic Compute Cloud Developer Guide or Amazon Elastic Compute Cloud User Guide.
*
* @param region
* Snapshots are tied to Regions and can only be used for volumes within the same
* Region.
* @param snapshotId
* The ID of the Amazon EBS snapshot to delete.
*
* @see #createSnapshotInRegion
* @see #deleteSnapshotInRegion
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteSnapshot.html"
* />
*/
void deleteSnapshotInRegion(Region region, String snapshotId);
/**
* Returns the {@link Permission}s of an snapshot.
*
* @param region
* AMIs are tied to the Region where its files are located within Amazon S3.
* @param snapshotId
* The ID of the AMI for which an attribute will be described
* @see #describeSnapshots
* @see #modifySnapshotAttribute
* @see #resetSnapshotAttribute
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSnapshotAttribute.html"
* />
* @see DescribeSnapshotsOptions
*/
Permission getCreateVolumePermissionForSnapshotInRegion(Region region, String snapshotId);
/**
* Adds {@code createVolumePermission}s to an EBS snapshot.
*
* @param region
* Snapshots are tied to Regions and can only be used for volumes within the same
* Region.
* @param userIds
* AWS Access Key ID.
* @param userGroups
* Name of the groups. Currently supports \"all.\""
* @param snapshotId
* The ID of the Amazon EBS snapshot.
*
* @see #removeCreateVolumePermissionsFromSnapshot
* @see #describeSnapshotAttribute
* @see #resetSnapshotAttribute
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifySnapshotAttribute.html"
* />
*/
void addCreateVolumePermissionsToSnapshotInRegion(Region region, Iterable<String> userIds,
Iterable<String> userGroups, String snapshotId);
/**
* Resets the {@code createVolumePermission}s on an EBS snapshot.
*
* @param region
* Snapshots are tied to Regions and can only be used for volumes within the same
* Region.
* @param snapshotId
* The ID of the Amazon EBS snapshot.
*
* @see #addCreateVolumePermissionsToSnapshot
* @see #describeSnapshotAttribute
* @see #removeProductCodesFromSnapshot
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ResetSnapshotAttribute.html"
* />
*/
void resetCreateVolumePermissionsOnSnapshotInRegion(Region region, String snapshotId);
/**
* Removes {@code createVolumePermission}s from an EBS snapshot.
*
* @param region
* Snapshots are tied to Regions and can only be used for volumes within the same
* Region.
* @param userIds
* AWS Access Key ID.
* @param userGroups
* Name of the groups. Currently supports \"all.\""
* @param snapshotId
* The ID of the Amazon EBS snapshot.
*
* @see #addCreateVolumePermissionsToSnapshot
* @see #describeSnapshotAttribute
* @see #resetSnapshotAttribute
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifySnapshotAttribute.html"
* />
*/
void removeCreateVolumePermissionsFromSnapshotInRegion(Region region, Iterable<String> userIds,
Iterable<String> userGroups, String snapshotId);
}

View File

@ -26,7 +26,7 @@ package org.jclouds.aws.ec2.services;
import static org.jclouds.aws.ec2.reference.EC2Parameters.ACTION;
import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION;
import java.util.SortedSet;
import java.util.Set;
import java.util.concurrent.Future;
import javax.annotation.Nullable;
@ -71,7 +71,7 @@ public interface InstanceAsyncClient {
@Path("/")
@FormParams(keys = ACTION, values = "DescribeInstances")
@XMLResponseParser(DescribeInstancesResponseHandler.class)
Future<? extends SortedSet<Reservation>> describeInstancesInRegion(
Future<? extends Set<Reservation>> describeInstancesInRegion(
@EndpointParam(parser = RegionToEndpoint.class) Region region,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
@ -95,7 +95,7 @@ public interface InstanceAsyncClient {
@Path("/")
@FormParams(keys = ACTION, values = "TerminateInstances")
@XMLResponseParser(TerminateInstancesResponseHandler.class)
Future<? extends SortedSet<TerminatedInstance>> terminateInstancesInRegion(
Future<? extends Set<TerminatedInstance>> terminateInstancesInRegion(
@EndpointParam(parser = RegionToEndpoint.class) Region region,
@FormParam("InstanceId.0") String instanceId,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);

View File

@ -23,7 +23,7 @@
*/
package org.jclouds.aws.ec2.services;
import java.util.SortedSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
@ -65,7 +65,7 @@ public interface InstanceClient {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html"
* />
*/
SortedSet<Reservation> describeInstancesInRegion(Region region, String... instanceIds);
Set<Reservation> describeInstancesInRegion(Region region, String... instanceIds);
/**
* Launches a specified number of instances of an AMI for which you have permissions.
@ -158,7 +158,7 @@ public interface InstanceClient {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-TerminateInstances.html"
* />
*/
SortedSet<TerminatedInstance> terminateInstancesInRegion(Region region, String instanceId,
Set<TerminatedInstance> terminateInstancesInRegion(Region region, String instanceId,
String... instanceIds);
}

View File

@ -26,6 +26,8 @@ package org.jclouds.aws.ec2.util;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.rest.internal.GeneratedHttpRequest;
/**
@ -56,4 +58,22 @@ public class EC2Utils {
+ "s[" + i + "]"));
}
}
public static Region findRegionInArgsOrNull(GeneratedHttpRequest<?> gRequest) {
for (Object arg : gRequest.getArgs()) {
if (arg instanceof Region) {
return (Region) arg;
}
}
return null;
}
public static AvailabilityZone findAvailabilityZoneInArgsOrNull(GeneratedHttpRequest<?> gRequest) {
for (Object arg : gRequest.getArgs()) {
if (arg instanceof AvailabilityZone) {
return (AvailabilityZone) arg;
}
}
return null;
}
}

View File

@ -29,6 +29,7 @@ import javax.annotation.Resource;
import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.Attachment;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.logging.Logger;
@ -52,7 +53,8 @@ public class AttachmentHandler extends ParseSax.HandlerWithResult<Attachment> {
private Date attachTime;
public Attachment getResult() {
return new Attachment(volumeId, instanceId, device, attachmentStatus, attachTime);
return new Attachment(EC2Utils.findRegionInArgsOrNull(request), volumeId, instanceId, device,
attachmentStatus, attachTime);
}
public void endElement(String uri, String name, String qName) {

View File

@ -31,10 +31,12 @@ import java.util.SortedSet;
import javax.annotation.Resource;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
import org.jclouds.logging.Logger;
@ -69,7 +71,7 @@ public abstract class BaseReservationHandler<T> extends HandlerWithResult<T> {
private String keyName;
private Date launchTime;
private boolean monitoring;
private String availabilityZone;
private AvailabilityZone availabilityZone;
private String platform;
private String privateDnsName;
private InetAddress privateIpAddress;
@ -129,7 +131,7 @@ public abstract class BaseReservationHandler<T> extends HandlerWithResult<T> {
} else if (qName.equals("enabled")) {
monitoring = Boolean.parseBoolean(currentOrNull());
} else if (qName.equals("availabilityZone")) {
availabilityZone = currentOrNull();
availabilityZone = AvailabilityZone.fromValue(currentOrNull());
} else if (qName.equals("platform")) {
platform = currentOrNull();
} else if (qName.equals("privateDnsName")) {
@ -206,7 +208,8 @@ public abstract class BaseReservationHandler<T> extends HandlerWithResult<T> {
}
protected Reservation newReservation() {
Reservation info = new Reservation(groupIds, instances, ownerId, requesterId, reservationId);
Reservation info = new Reservation(EC2Utils.findRegionInArgsOrNull(request), groupIds,
instances, ownerId, requesterId, reservationId);
this.groupIds = Sets.newTreeSet();
this.instances = Sets.newTreeSet();
this.ownerId = null;

View File

@ -23,7 +23,11 @@
*/
package org.jclouds.aws.ec2.xml;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
@ -31,10 +35,13 @@ import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.Attachment;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Volume;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.logging.Logger;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.xml.sax.Attributes;
import com.google.common.collect.Sets;
@ -50,6 +57,8 @@ public class CreateVolumeResponseHandler extends ParseSax.HandlerWithResult<Volu
protected Logger logger = Logger.NULL;
@Inject
protected DateService dateService;
@Inject
protected Map<AvailabilityZone, Region> availabilityZoneToRegion;
private String id;
private int size;
@ -67,6 +76,8 @@ public class CreateVolumeResponseHandler extends ParseSax.HandlerWithResult<Volu
private boolean inAttachmentSet;
private Region region;
public Volume getResult() {
return newVolume();
}
@ -112,14 +123,18 @@ public class CreateVolumeResponseHandler extends ParseSax.HandlerWithResult<Volu
inAttachmentSet = false;
} else if (qName.equals("instanceId")) {
instanceId = currentText.toString().trim();
} else if (qName.equals("snapshotId")) {
snapshotId = currentText.toString().trim();
if (snapshotId.equals(""))
snapshotId = null;
} else if (qName.equals("device")) {
device = currentText.toString().trim();
} else if (qName.equals("attachTime")) {
attachTime = dateService.iso8601DateParse(currentText.toString().trim());
} else if (qName.equals("item")) {
if (inAttachmentSet) {
attachments.add(new Attachment(volumeId, instanceId, device, attachmentStatus,
attachTime));
attachments.add(new Attachment(EC2Utils.findRegionInArgsOrNull(request), volumeId,
instanceId, device, attachmentStatus, attachTime));
volumeId = null;
instanceId = null;
device = null;
@ -132,8 +147,8 @@ public class CreateVolumeResponseHandler extends ParseSax.HandlerWithResult<Volu
}
private Volume newVolume() {
Volume volume = new Volume(id, size, snapshotId, availabilityZone, volumeStatus, createTime,
attachments);
Volume volume = new Volume(region, id, size, snapshotId, availabilityZone, volumeStatus,
createTime, attachments);
id = null;
size = 0;
snapshotId = null;
@ -147,4 +162,16 @@ public class CreateVolumeResponseHandler extends ParseSax.HandlerWithResult<Volu
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
@Override
public void setContext(GeneratedHttpRequest<?> request) {
super.setContext(request);
region = EC2Utils.findRegionInArgsOrNull(request);
if (region == null) {
AvailabilityZone zone = checkNotNull(EC2Utils.findAvailabilityZoneInArgsOrNull(request),
"zone not in args: " + Arrays.asList(request.getArgs()));
region = checkNotNull(availabilityZoneToRegion.get(zone), String.format(
"zone %s not in %s", zone, availabilityZoneToRegion));
}
}
}

View File

@ -30,6 +30,7 @@ import java.util.Set;
import javax.annotation.Resource;
import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
import org.jclouds.logging.Logger;
@ -61,7 +62,8 @@ public class DescribeAddressesResponseHandler extends
} else if (qName.equals("instanceId")) {
instanceId = currentOrNull();
} else if (qName.equals("item")) {
pairs.add(new PublicIpInstanceIdPair(ipAddress, instanceId));
pairs.add(new PublicIpInstanceIdPair(EC2Utils.findRegionInArgsOrNull(request), ipAddress,
instanceId));
ipAddress = null;
instanceId = null;
}

View File

@ -34,6 +34,7 @@ import org.jclouds.aws.ec2.domain.Image.EbsBlockDevice;
import org.jclouds.aws.ec2.domain.Image.ImageState;
import org.jclouds.aws.ec2.domain.Image.ImageType;
import org.jclouds.aws.ec2.domain.Image.RootDeviceType;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.logging.Logger;
import org.xml.sax.Attributes;
@ -145,9 +146,10 @@ public class DescribeImagesResponseHandler extends ParseSax.HandlerWithResult<Se
this.deleteOnTermination = true;
} else if (!inProductCodes) {
try {
contents.add(new Image(architecture, this.name, description, imageId, imageLocation,
imageOwnerId, imageState, imageType, isPublic, productCodes, kernelId,
platform, ramdiskId, rootDeviceType, rootDeviceName, ebsBlockDevices));
contents.add(new Image(EC2Utils.findRegionInArgsOrNull(request), architecture,
this.name, description, imageId, imageLocation, imageOwnerId, imageState,
imageType, isPublic, productCodes, kernelId, platform, ramdiskId,
rootDeviceType, rootDeviceName, ebsBlockDevices));
} catch (NullPointerException e) {
logger.warn(e, "malformed image: %s", imageId);
}

View File

@ -26,6 +26,7 @@ package org.jclouds.aws.ec2.xml;
import java.util.Set;
import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.http.functions.ParseSax;
import com.google.common.collect.Sets;
@ -53,7 +54,8 @@ public class DescribeKeyPairsResponseHandler extends ParseSax.HandlerWithResult<
if (qName.equals("keyFingerprint")) {
this.keyFingerprint = currentText.toString().trim();
} else if (qName.equals("item")) {
keyPairs.add(new KeyPair(keyName, keyFingerprint, null));
keyPairs.add(new KeyPair(EC2Utils.findRegionInArgsOrNull(request), keyName,
keyFingerprint, null));
} else if (qName.equals("keyName")) {
this.keyName = currentText.toString().trim();
}

View File

@ -29,6 +29,7 @@ import org.jclouds.aws.ec2.domain.IpPermission;
import org.jclouds.aws.ec2.domain.IpProtocol;
import org.jclouds.aws.ec2.domain.SecurityGroup;
import org.jclouds.aws.ec2.domain.UserIdGroupPair;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.http.functions.ParseSax;
import org.xml.sax.Attributes;
@ -115,8 +116,8 @@ public class DescribeSecurityGroupsResponseHandler extends
this.userId = null;
this.userIdGroupName = null;
} else if (!inIpPermissions && !inIpRanges && !inGroups) {
securtyGroups
.add(new SecurityGroup(groupName, ownerId, groupDescription, ipPermissions));
securtyGroups.add(new SecurityGroup(EC2Utils.findRegionInArgsOrNull(request),
groupName, ownerId, groupDescription, ipPermissions));
this.groupName = null;
this.ownerId = null;
this.groupDescription = null;

View File

@ -0,0 +1,78 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.xml;
import java.util.Set;
import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.Snapshot;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import com.google.common.collect.Sets;
/**
* @author Adrian Cole
*/
public class DescribeSnapshotsResponseHandler extends ParseSax.HandlerWithResult<Set<Snapshot>> {
private Set<Snapshot> snapshots = Sets.newLinkedHashSet();
private final SnapshotHandler snapshotHandler;
@Inject
public DescribeSnapshotsResponseHandler(SnapshotHandler snapshotHandler) {
this.snapshotHandler = snapshotHandler;
}
public Set<Snapshot> getResult() {
return snapshots;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
snapshotHandler.startElement(uri, localName, qName, attributes);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
snapshotHandler.endElement(uri, localName, qName);
if (qName.equals("item")) {
this.snapshots.add(snapshotHandler.getResult());
}
}
public void characters(char ch[], int start, int length) {
snapshotHandler.characters(ch, start, length);
}
@Override
public void setContext(GeneratedHttpRequest<?> request) {
snapshotHandler.setContext(request);
super.setContext(request);
}
}

View File

@ -29,6 +29,7 @@ import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.Volume;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
@ -75,4 +76,10 @@ public class DescribeVolumesResponseHandler extends ParseSax.HandlerWithResult<S
public void characters(char ch[], int start, int length) {
volumeHandler.characters(ch, start, length);
}
@Override
public void setContext(GeneratedHttpRequest<?> request) {
volumeHandler.setContext(request);
super.setContext(request);
}
}

View File

@ -24,6 +24,7 @@
package org.jclouds.aws.ec2.xml;
import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.http.functions.ParseSax;
/**
@ -41,7 +42,8 @@ public class KeyPairResponseHandler extends ParseSax.HandlerWithResult<KeyPair>
private String keyName;
public KeyPair getResult() {
return new KeyPair(keyName, keyFingerprint, keyMaterial);
return new KeyPair(EC2Utils.findRegionInArgsOrNull(request), keyName, keyFingerprint,
keyMaterial);
}
public void endElement(String uri, String name, String qName) {

View File

@ -25,7 +25,7 @@ package org.jclouds.aws.ec2.xml;
import java.util.Set;
import org.jclouds.aws.ec2.domain.LaunchPermission;
import org.jclouds.aws.ec2.domain.Permission;
import org.jclouds.http.functions.ParseSax;
import com.google.common.collect.Sets;
@ -36,14 +36,14 @@ import com.google.common.collect.Sets;
* />
* @author Adrian Cole
*/
public class LaunchPermissionHandler extends ParseSax.HandlerWithResult<LaunchPermission> {
public class PermissionHandler extends ParseSax.HandlerWithResult<Permission> {
private StringBuilder currentText = new StringBuilder();
private Set<String> userIds = Sets.newHashSet();
private Set<String> groups = Sets.newHashSet();
public LaunchPermission getResult() {
return new LaunchPermission(userIds, groups);
public Permission getResult() {
return new Permission(userIds, groups);
}
public void endElement(String uri, String name, String qName) {

View File

@ -0,0 +1,100 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.xml;
import java.util.Date;
import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.Snapshot;
import org.jclouds.aws.ec2.domain.Snapshot.Status;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
/**
*
* @author Adrian Cole
*/
public class SnapshotHandler extends ParseSax.HandlerWithResult<Snapshot> {
private StringBuilder currentText = new StringBuilder();
@Inject
protected DateService dateService;
private String id;
private String volumeId;
private int volumeSize;
private Status status;
private Date startTime;
private int progress;
private String ownerId;
private String description;
private String ownerAlias;
public Snapshot getResult() {
Snapshot snapshot = new Snapshot(EC2Utils.findRegionInArgsOrNull(request), id, volumeId,
volumeSize, status, startTime, progress, ownerId, description, ownerAlias);
this.id = null;
this.volumeId = null;
this.volumeSize = 0;
this.status = null;
this.startTime = null;
this.progress = 0;
this.ownerId = null;
this.description = null;
this.ownerAlias = null;
return snapshot;
}
public void endElement(String uri, String name, String qName) {
if (qName.equals("snapshotId")) {
id = currentText.toString().trim();
} else if (qName.equals("volumeId")) {
volumeId = currentText.toString().trim();
} else if (qName.equals("volumeSize")) {
volumeSize = Integer.parseInt(currentText.toString().trim());
} else if (qName.equals("status")) {
status = Snapshot.Status.fromValue(currentText.toString().trim());
} else if (qName.equals("startTime")) {
startTime = dateService.iso8601DateParse(currentText.toString().trim());
} else if (qName.equals("progress")) {
String progressString = currentText.toString().trim();
if (!progressString.equals("")) {
progressString = progressString.substring(0, progressString.length() - 1);
progress = Integer.parseInt(progressString);
}
} else if (qName.equals("ownerId")) {
ownerId = currentText.toString().trim();
} else if (qName.equals("description")) {
description = currentText.toString().trim();
} else if (qName.equals("ownerAlias")) {
ownerAlias = currentText.toString().trim();
}
currentText = new StringBuilder();
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -27,6 +27,7 @@ import java.util.SortedSet;
import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.TerminatedInstance;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
import org.xml.sax.Attributes;
@ -82,7 +83,8 @@ public class TerminateInstancesResponseHandler extends
previousState = InstanceState.fromValue(currentOrNull());
}
} else if (qName.equals("item")) {
instances.add(new TerminatedInstance(instanceId, shutdownState, previousState));
instances.add(new TerminatedInstance(EC2Utils.findRegionInArgsOrNull(request), instanceId,
shutdownState, previousState));
this.instanceId = null;
this.shutdownState = null;
this.previousState = null;

View File

@ -185,11 +185,12 @@ public class ExpensiveEC2ClientLiveTest {
assertEquals(compare.getPublicIp(), address);
assertEquals(compare.getInstanceId(), serverId);
Reservation reservation = client.getInstanceServices().describeInstancesInRegion(
Region.DEFAULT, serverId).last();
Reservation reservation = Iterables.getOnlyElement(client.getInstanceServices()
.describeInstancesInRegion(Region.DEFAULT, serverId));
assertNotNull(reservation.getRunningInstances().last().getIpAddress());
assertFalse(reservation.getRunningInstances().last().getIpAddress().equals(address));
assertNotNull(Iterables.getOnlyElement(reservation.getRunningInstances()).getIpAddress());
assertFalse(Iterables.getOnlyElement(reservation.getRunningInstances()).getIpAddress()
.equals(address));
doCheckKey(address);
@ -201,8 +202,8 @@ public class ExpensiveEC2ClientLiveTest {
assertEquals(compare.getPublicIp(), address);
assert compare.getInstanceId() == null;
reservation = client.getInstanceServices()
.describeInstancesInRegion(Region.DEFAULT, serverId).last();
reservation = Iterables.getOnlyElement(client.getInstanceServices()
.describeInstancesInRegion(Region.DEFAULT, serverId));
// assert reservation.getRunningInstances().last().getIpAddress() == null; TODO
}
@ -270,8 +271,9 @@ public class ExpensiveEC2ClientLiveTest {
private RunningInstance getRunningInstance(String serverId) throws InterruptedException,
ExecutionException, TimeoutException {
return client.getInstanceServices().describeInstancesInRegion(Region.DEFAULT, serverId)
.first().getRunningInstances().first();
return Iterables.getOnlyElement(Iterables.getOnlyElement(
client.getInstanceServices().describeInstancesInRegion(Region.DEFAULT, serverId))
.getRunningInstances());
}
}

View File

@ -37,7 +37,7 @@ import org.testng.annotations.Test;
*
* @author Adrian Cole
*/
public class CreateImagesOptionsTest {
public class CreateImageOptionsTest {
@Test
public void testAssignability() {

View File

@ -0,0 +1,73 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.options;
import static org.jclouds.aws.ec2.options.CreateSnapshotOptions.Builder.withDescription;
import static org.testng.Assert.assertEquals;
import java.util.Collections;
import org.jclouds.http.options.HttpRequestOptions;
import org.testng.annotations.Test;
/**
* Tests possible uses of CreateSnapshotOptions and CreateSnapshotOptions.Builder.*
*
* @author Adrian Cole
*/
public class CreateSnapshotOptionsTest {
@Test
public void testAssignability() {
assert HttpRequestOptions.class.isAssignableFrom(CreateSnapshotOptions.class);
assert !String.class.isAssignableFrom(CreateSnapshotOptions.class);
}
@Test
public void testWithDescription() {
CreateSnapshotOptions options = new CreateSnapshotOptions();
options.withDescription("test");
assertEquals(options.buildFormParameters().get("Description"), Collections
.singletonList("test"));
}
@Test
public void testNullWithDescription() {
CreateSnapshotOptions options = new CreateSnapshotOptions();
assertEquals(options.buildFormParameters().get("Description"), Collections.EMPTY_LIST);
}
@Test
public void testWithDescriptionStatic() {
CreateSnapshotOptions options = withDescription("test");
assertEquals(options.buildFormParameters().get("Description"), Collections
.singletonList("test"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testWithDescriptionNPE() {
withDescription(null);
}
}

View File

@ -0,0 +1,136 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.options;
import static org.jclouds.aws.ec2.options.DescribeSnapshotsOptions.Builder.ownedBy;
import static org.jclouds.aws.ec2.options.DescribeSnapshotsOptions.Builder.restorableBy;
import static org.jclouds.aws.ec2.options.DescribeSnapshotsOptions.Builder.snapshotIds;
import static org.testng.Assert.assertEquals;
import java.util.Collections;
import org.jclouds.http.options.HttpRequestOptions;
import org.testng.annotations.Test;
/**
* Tests possible uses of DescribeSnapshotsOptions and DescribeSnapshotsOptions.Builder.*
*
* @author Adrian Cole
*/
public class DescribeSnapshotsOptionsTest {
@Test
public void testAssignability() {
assert HttpRequestOptions.class.isAssignableFrom(DescribeSnapshotsOptions.class);
assert !String.class.isAssignableFrom(DescribeSnapshotsOptions.class);
}
@Test
public void testRestorableBy() {
DescribeSnapshotsOptions options = new DescribeSnapshotsOptions();
options.restorableBy("test");
assertEquals(options.buildFormParameters().get("RestorableBy.1"), Collections
.singletonList("test"));
}
@Test
public void testNullRestorableBy() {
DescribeSnapshotsOptions options = new DescribeSnapshotsOptions();
assertEquals(options.buildFormParameters().get("RestorableBy.1"), Collections.EMPTY_LIST);
}
@Test
public void testRestorableByStatic() {
DescribeSnapshotsOptions options = restorableBy("test");
assertEquals(options.buildFormParameters().get("RestorableBy.1"), Collections
.singletonList("test"));
}
@Test
public void testOwners() {
DescribeSnapshotsOptions options = new DescribeSnapshotsOptions();
options.ownedBy("test");
assertEquals(options.buildFormParameters().get("Owner.1"), Collections.singletonList("test"));
}
@Test
public void testMultipleOwners() {
DescribeSnapshotsOptions options = new DescribeSnapshotsOptions();
options.ownedBy("test", "trouble");
assertEquals(options.buildFormParameters().get("Owner.1"), Collections.singletonList("test"));
assertEquals(options.buildFormParameters().get("Owner.2"), Collections
.singletonList("trouble"));
}
@Test
public void testNullOwners() {
DescribeSnapshotsOptions options = new DescribeSnapshotsOptions();
assertEquals(options.buildFormParameters().get("Owner.1"), Collections.EMPTY_LIST);
}
@Test
public void testOwnersStatic() {
DescribeSnapshotsOptions options = ownedBy("test");
assertEquals(options.buildFormParameters().get("Owner.1"), Collections.singletonList("test"));
}
public void testNoOwners() {
ownedBy();
}
@Test
public void testSnapshotIds() {
DescribeSnapshotsOptions options = new DescribeSnapshotsOptions();
options.snapshotIds("test");
assertEquals(options.buildFormParameters().get("SnapshotId.1"), Collections
.singletonList("test"));
}
@Test
public void testMultipleSnapshotIds() {
DescribeSnapshotsOptions options = new DescribeSnapshotsOptions();
options.snapshotIds("test", "trouble");
assertEquals(options.buildFormParameters().get("SnapshotId.1"), Collections
.singletonList("test"));
assertEquals(options.buildFormParameters().get("SnapshotId.2"), Collections
.singletonList("trouble"));
}
@Test
public void testNullSnapshotIds() {
DescribeSnapshotsOptions options = new DescribeSnapshotsOptions();
assertEquals(options.buildFormParameters().get("SnapshotId.1"), Collections.EMPTY_LIST);
}
@Test
public void testSnapshotIdsStatic() {
DescribeSnapshotsOptions options = snapshotIds("test");
assertEquals(options.buildFormParameters().get("SnapshotId.1"), Collections
.singletonList("test"));
}
public void testNoSnapshotIds() {
snapshotIds();
}
}

View File

@ -44,7 +44,7 @@ import org.jclouds.aws.ec2.options.RegisterImageOptions;
import org.jclouds.aws.ec2.xml.BlockDeviceMappingHandler;
import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandler;
import org.jclouds.aws.ec2.xml.ImageIdHandler;
import org.jclouds.aws.ec2.xml.LaunchPermissionHandler;
import org.jclouds.aws.ec2.xml.PermissionHandler;
import org.jclouds.aws.ec2.xml.ProductCodesHandler;
import org.jclouds.aws.reference.AWSConstants;
import org.jclouds.date.TimeStamp;
@ -266,26 +266,6 @@ public class AMIAsyncClientTest extends RestClientTest<AMIAsyncClient> {
checkFilters(httpMethod);
}
public void testGetLaunchPermissionForImage() throws SecurityException, NoSuchMethodException,
IOException {
Method method = AMIAsyncClient.class.getMethod("getLaunchPermissionForImageInRegion",
Region.class, String.class);
GeneratedHttpRequest<AMIAsyncClient> httpMethod = processor.createRequest(method,
Region.DEFAULT, "imageId");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 91\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertPayloadEquals(httpMethod,
"Version=2009-11-30&Action=DescribeImageAttribute&Attribute=launchPermission&ImageId=imageId");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, LaunchPermissionHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testGetProductCodesForImage() throws SecurityException, NoSuchMethodException,
IOException {
Method method = AMIAsyncClient.class.getMethod("getProductCodesForImageInRegion",
@ -326,6 +306,26 @@ public class AMIAsyncClientTest extends RestClientTest<AMIAsyncClient> {
checkFilters(httpMethod);
}
public void testGetLaunchPermissionForImage() throws SecurityException, NoSuchMethodException,
IOException {
Method method = AMIAsyncClient.class.getMethod("getLaunchPermissionForImageInRegion",
Region.class, String.class);
GeneratedHttpRequest<AMIAsyncClient> httpMethod = processor.createRequest(method,
Region.DEFAULT, "imageId");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 91\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertPayloadEquals(httpMethod,
"Version=2009-11-30&Action=DescribeImageAttribute&Attribute=launchPermission&ImageId=imageId");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, PermissionHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testAddLaunchPermissionsToImage() throws SecurityException, NoSuchMethodException,
IOException {
Method method = AMIAsyncClient.class.getMethod("addLaunchPermissionsToImageInRegion",

View File

@ -164,14 +164,14 @@ public class AMIClientLiveTest {
}
@Test(enabled = false)
public void testAddLaunchPermissionsToImage() {
// TODO client.addLaunchPermissionsToImageInRegion(Region.DEFAULT, userIds, userGroups,
// imageId);
public void testAddProductCodesToImage() {
// TODO client.addProductCodesToImageInRegion(Region.DEFAULT, productCodes, imageId);
}
@Test(enabled = false)
public void testAddProductCodesToImage() {
// TODO client.addProductCodesToImageInRegion(Region.DEFAULT, productCodes, imageId);
public void testAddLaunchPermissionsToImage() {
// TODO client.addLaunchPermissionsToImageInRegion(Region.DEFAULT, userIds, userGroups,
// imageId);
}
@Test(enabled = false)

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.aws.ec2.services;
import static org.jclouds.aws.ec2.options.DescribeSnapshotsOptions.Builder.ownedBy;
import static org.jclouds.aws.ec2.options.DetachVolumeOptions.Builder.fromInstance;
import static org.testng.Assert.assertEquals;
@ -38,10 +39,15 @@ import org.jclouds.aws.ec2.EC2;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.filters.FormSigner;
import org.jclouds.aws.ec2.options.CreateSnapshotOptions;
import org.jclouds.aws.ec2.options.DescribeSnapshotsOptions;
import org.jclouds.aws.ec2.options.DetachVolumeOptions;
import org.jclouds.aws.ec2.xml.AttachmentHandler;
import org.jclouds.aws.ec2.xml.CreateVolumeResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeSnapshotsResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeVolumesResponseHandler;
import org.jclouds.aws.ec2.xml.PermissionHandler;
import org.jclouds.aws.ec2.xml.SnapshotHandler;
import org.jclouds.aws.reference.AWSConstants;
import org.jclouds.date.TimeStamp;
import org.jclouds.http.functions.ParseSax;
@ -54,6 +60,7 @@ import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.Jsr330;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
@ -172,7 +179,8 @@ public class ElasticBlockStoreAsyncClientTest extends RestClientTest<ElasticBloc
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 89\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertPayloadEquals(httpMethod, "Version=2009-11-30&Action=AttachVolume&InstanceId=instanceId&VolumeId=id&Device=%2Fdevice");
assertPayloadEquals(httpMethod,
"Version=2009-11-30&Action=AttachVolume&InstanceId=instanceId&VolumeId=id&Device=%2Fdevice");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, AttachmentHandler.class);
@ -223,6 +231,173 @@ public class ElasticBlockStoreAsyncClientTest extends RestClientTest<ElasticBloc
checkFilters(httpMethod);
}
public void testCreateSnapshot() throws SecurityException, NoSuchMethodException, IOException {
Method method = ElasticBlockStoreAsyncClient.class.getMethod("createSnapshotInRegion",
Region.class, String.class, Array.newInstance(CreateSnapshotOptions.class, 0)
.getClass());
GeneratedHttpRequest<ElasticBlockStoreAsyncClient> httpMethod = processor.createRequest(
method, Region.DEFAULT, "volumeId");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 58\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertPayloadEquals(httpMethod, "Version=2009-11-30&Action=CreateSnapshot&VolumeId=volumeId");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, SnapshotHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testCreateSnapshotOptions() throws SecurityException, NoSuchMethodException,
IOException {
Method method = ElasticBlockStoreAsyncClient.class.getMethod("createSnapshotInRegion",
Region.class, String.class, Array.newInstance(CreateSnapshotOptions.class, 0)
.getClass());
GeneratedHttpRequest<ElasticBlockStoreAsyncClient> httpMethod = processor.createRequest(
method, Region.DEFAULT, "volumeId", CreateSnapshotOptions.Builder
.withDescription("description"));
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 82\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertPayloadEquals(httpMethod,
"Version=2009-11-30&Action=CreateSnapshot&VolumeId=volumeId&Description=description");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, SnapshotHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testDescribeSnapshots() throws SecurityException, NoSuchMethodException, IOException {
Method method = ElasticBlockStoreAsyncClient.class.getMethod("describeSnapshotsInRegion",
Region.class, Array.newInstance(DescribeSnapshotsOptions.class, 0).getClass());
GeneratedHttpRequest<ElasticBlockStoreAsyncClient> httpMethod = processor.createRequest(
method, Region.DEFAULT);
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 43\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertPayloadEquals(httpMethod, "Version=2009-11-30&Action=DescribeSnapshots");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeSnapshotsResponseHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testDescribeSnapshotsArgs() throws SecurityException, NoSuchMethodException,
IOException {
Method method = ElasticBlockStoreAsyncClient.class.getMethod("describeSnapshotsInRegion",
Region.class, Array.newInstance(DescribeSnapshotsOptions.class, 0).getClass());
GeneratedHttpRequest<ElasticBlockStoreAsyncClient> httpMethod = processor.createRequest(
method, Region.DEFAULT, ownedBy("o1", "o2").restorableBy("r1", "r2").snapshotIds(
"s1", "s2"));
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 133\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertPayloadEquals(
httpMethod,
"Version=2009-11-30&Action=DescribeSnapshots&Owner.1=o1&Owner.2=o2&RestorableBy.1=r1&RestorableBy.2=r2&SnapshotId.1=s1&SnapshotId.2=s2");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeSnapshotsResponseHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testGetCreateVolumePermissionForSnapshot() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ElasticBlockStoreAsyncClient.class.getMethod(
"getCreateVolumePermissionForSnapshotInRegion", Region.class, String.class);
GeneratedHttpRequest<ElasticBlockStoreAsyncClient> httpMethod = processor.createRequest(
method, Region.DEFAULT, "snapshotId");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 106\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertPayloadEquals(
httpMethod,
"Version=2009-11-30&Action=DescribeSnapshotAttribute&Attribute=createVolumePermission&SnapshotId=snapshotId");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, PermissionHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testAddCreateVolumePermissionsToSnapshot() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ElasticBlockStoreAsyncClient.class.getMethod(
"addCreateVolumePermissionsToSnapshotInRegion", Region.class, Iterable.class,
Iterable.class, String.class);
GeneratedHttpRequest<ElasticBlockStoreAsyncClient> httpMethod = processor.createRequest(
method, Region.DEFAULT, ImmutableList.of("bob", "sue"), ImmutableList.of("all"),
"snapshotId");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 122\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertPayloadEquals(
httpMethod,
"Version=2009-11-30&Action=ModifySnapshotAttribute&OperationType=add&Attribute=createVolumePermission&SnapshotId=snapshotId&UserGroup.1=all&UserId.1=bob&UserId.2=sue");
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testRemoveCreateVolumePermissionsFromSnapshot() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ElasticBlockStoreAsyncClient.class.getMethod(
"removeCreateVolumePermissionsFromSnapshotInRegion", Region.class, Iterable.class,
Iterable.class, String.class);
GeneratedHttpRequest<ElasticBlockStoreAsyncClient> httpMethod = processor.createRequest(
method, Region.DEFAULT, ImmutableList.of("bob", "sue"), ImmutableList.of("all"),
"snapshotId");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 125\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertPayloadEquals(
httpMethod,
"Version=2009-11-30&Action=ModifySnapshotAttribute&OperationType=remove&Attribute=createVolumePermission&SnapshotId=snapshotId&UserGroup.1=all&UserId.1=bob&UserId.2=sue");
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testResetCreateVolumePermissionsOnSnapshot() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ElasticBlockStoreAsyncClient.class.getMethod(
"resetCreateVolumePermissionsOnSnapshotInRegion", Region.class, String.class);
GeneratedHttpRequest<ElasticBlockStoreAsyncClient> httpMethod = processor.createRequest(
method, Region.DEFAULT, "snapshotId");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 103\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertPayloadEquals(
httpMethod,
"Version=2009-11-30&Action=ResetSnapshotAttribute&Attribute=createVolumePermission&SnapshotId=snapshotId");
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
@Override
protected void checkFilters(GeneratedHttpRequest<ElasticBlockStoreAsyncClient> httpMethod) {
assertEquals(httpMethod.getFilters().size(), 1);
@ -264,10 +439,16 @@ public class ElasticBlockStoreAsyncClientTest extends RestClientTest<ElasticBloc
@Singleton
@Provides
Map<Region, URI> provideMap() {
return ImmutableMap.<Region, URI> of(Region.DEFAULT, URI.create("https://booya"),
Region.EU_WEST_1, URI.create("https://ec2.eu-west-1.amazonaws.com"),
Region.US_EAST_1, URI.create("https://ec2.us-east-1.amazonaws.com"),
Region.US_WEST_1, URI.create("https://ec2.us-west-1.amazonaws.com"));
return ImmutableMap.<Region, URI> of(Region.DEFAULT, URI
.create("https://ec2.amazonaws.com"));
}
@SuppressWarnings("unused")
@Singleton
@Provides
Map<AvailabilityZone, Region> provideAvailabilityZoneRegionMap() {
return ImmutableMap.<AvailabilityZone, Region> of(AvailabilityZone.US_EAST_1A,
Region.DEFAULT);
}
};
}

View File

@ -24,24 +24,37 @@
package org.jclouds.aws.ec2.services;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.aws.ec2.options.DescribeSnapshotsOptions.Builder.snapshotIds;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.net.URI;
import java.util.Map;
import java.util.SortedSet;
import java.util.concurrent.TimeUnit;
import org.jclouds.aws.AWSResponseException;
import org.jclouds.aws.ec2.EC2AsyncClient;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.EC2ContextFactory;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.AvailabilityZoneInfo;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Snapshot;
import org.jclouds.aws.ec2.domain.Volume;
import org.jclouds.aws.ec2.predicates.SnapshotCompleted;
import org.jclouds.aws.ec2.predicates.VolumeAvailable;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
/**
@ -51,10 +64,11 @@ import com.google.common.collect.Sets;
*/
@Test(groups = "live", sequential = true, testName = "ec2.ElasticBlockStoreClientLiveTest")
public class ElasticBlockStoreClientLiveTest {
private AvailabilityZoneAndRegionClient aclient;
private ElasticBlockStoreClient client;
private RestContext<EC2AsyncClient, EC2Client> context;
private String volumeId;
private Snapshot snapshot;
@BeforeGroups(groups = { "live" })
public void setupClient() {
@ -63,6 +77,7 @@ public class ElasticBlockStoreClientLiveTest {
context = EC2ContextFactory.createContext(user, password, new Log4JLoggingModule());
client = context.getApi().getElasticBlockStoreServices();
aclient = context.getApi().getAvailabilityZoneAndRegionServices();
}
@Test
@ -99,28 +114,55 @@ public class ElasticBlockStoreClientLiveTest {
assertEquals(volume.getId(), expected.getId());
}
@Test(dependsOnMethods = "testCreateVolumeInAvailabilityZone")
void testDeleteInRegion() {
client.deleteVolumeInRegion(Region.DEFAULT, volumeId);
SortedSet<Volume> result = Sets.newTreeSet(client.describeVolumesInRegion(Region.DEFAULT,
volumeId));
assertEquals(result.size(), 1);
Volume volume = result.iterator().next();
assertEquals(volume.getStatus(), Volume.Status.DELETING);
Map<Region, URI> provideRegions(AvailabilityZoneAndRegionClient client) {
return client.describeRegions();
}
@Test
Map<AvailabilityZone, Region> provideAvailabilityZoneToRegions(
AvailabilityZoneAndRegionClient client, Map<Region, URI> regions) {
Map<AvailabilityZone, Region> map = Maps.newHashMap();
for (Region region : regions.keySet()) {
for (AvailabilityZoneInfo zoneInfo : client.describeAvailabilityZonesInRegion(region)) {
map.put(zoneInfo.getZone(), region);
}
}
return map;
}
@Test(dependsOnMethods = "testCreateVolumeInAvailabilityZone")
void testCreateSnapshotInRegion() {
Snapshot snapshot = client.createSnapshotInRegion(Region.DEFAULT, volumeId);
Predicate<Snapshot> snapshotted = new RetryablePredicate<Snapshot>(new SnapshotCompleted(
client, provideAvailabilityZoneToRegions(aclient, aclient.describeRegions())), 600,
10, TimeUnit.SECONDS);
assert snapshotted.apply(snapshot);
Snapshot result = Iterables.getOnlyElement(client.describeSnapshotsInRegion(snapshot
.getRegion(), snapshotIds(snapshot.getId())));
assertEquals(result.getProgress(), 100);
this.snapshot = result;
}
@Test(dependsOnMethods = "testCreateSnapshotInRegion")
void testCreateVolumeFromSnapshotInAvailabilityZone() {
// Volume result =
// client.createVolumeFromSnapshotInAvailabilityZone(AvailabilityZone.US_EAST_1A, snapshotId);
// assertNotNull(result);
//
// SortedSet<Volume> result = Sets.newTreeSet(client.describeVolumesInRegion(
// Region.DEFAULT, result.getId()));
// assertNotNull(result);
// assertEquals(result.size(), 1);
// Volume volume = result.iterator().next();
// assertEquals(volume, result);
Volume volume = client.createVolumeFromSnapshotInAvailabilityZone(
AvailabilityZone.US_EAST_1A, snapshot.getId());
assertNotNull(volume);
Predicate<Volume> availabile = new RetryablePredicate<Volume>(new VolumeAvailable(client,
provideAvailabilityZoneToRegions(aclient, aclient.describeRegions())), 600, 10,
TimeUnit.SECONDS);
assert availabile.apply(volume);
Volume result = Iterables.getOnlyElement(client.describeVolumesInRegion(snapshot.getRegion(),
volume.getId()));
assertEquals(volume.getId(), result.getId());
assertEquals(volume.getSnapshotId(), snapshot.getId());
assertEquals(volume.getAvailabilityZone(), AvailabilityZone.US_EAST_1A);
assertEquals(result.getStatus(), Volume.Status.AVAILABLE);
client.deleteVolumeInRegion(snapshot.getRegion(), volume.getId());
}
@Test
@ -133,6 +175,68 @@ public class ElasticBlockStoreClientLiveTest {
// TODO: need an instance
}
@Test
void testDescribeSnapshots() {
for (Region region : ImmutableSet.of(Region.DEFAULT, Region.EU_WEST_1, Region.US_EAST_1,
Region.US_WEST_1)) {
SortedSet<Snapshot> allResults = Sets.newTreeSet(client.describeSnapshotsInRegion(region));
assertNotNull(allResults);
if (allResults.size() >= 1) {
Snapshot snapshot = allResults.last();
Snapshot result = Iterables.getOnlyElement(client.describeSnapshotsInRegion(region,
snapshotIds(snapshot.getId())));
assertNotNull(result);
assertEquals(result, snapshot);
}
}
}
@Test(enabled = false)
public void testAddCreateVolumePermissionsToSnapshot() {
// TODO client.addCreateVolumePermissionsToSnapshotInRegion(Region.DEFAULT, userIds,
// userGroups,
// snapshotId);
}
@Test(enabled = false)
public void testRemoveCreateVolumePermissionsFromSnapshot() {
// TODO client.removeCreateVolumePermissionsFromSnapshotInRegion(Region.DEFAULT, userIds,
// userGroups,
// snapshotId);
}
@Test(enabled = false)
public void testResetCreateVolumePermissionsOnSnapshot() {
// TODO client.resetCreateVolumePermissionsOnSnapshotInRegion(Region.DEFAULT, snapshotId);
}
@Test(dependsOnMethods = "testCreateSnapshotInRegion")
public void testGetCreateVolumePermissionForSnapshot() {
System.out.println(client.getCreateVolumePermissionForSnapshotInRegion(snapshot.getRegion(),
snapshot.getId()));
}
@Test(dependsOnMethods = "testCreateSnapshotInRegion")
void testDeleteVolumeInRegion() {
client.deleteVolumeInRegion(Region.DEFAULT, volumeId);
SortedSet<Volume> result = Sets.newTreeSet(client.describeVolumesInRegion(Region.DEFAULT,
volumeId));
assertEquals(result.size(), 1);
Volume volume = result.iterator().next();
assertEquals(volume.getStatus(), Volume.Status.DELETING);
}
@Test(dependsOnMethods = "testGetCreateVolumePermissionForSnapshot")
void testDeleteSnapshotInRegion() {
client.deleteSnapshotInRegion(snapshot.getRegion(), snapshot.getId());
try {
client.describeSnapshotsInRegion(snapshot.getRegion(), snapshotIds(snapshot.getId()));
assert false : "shoud have exception";
} catch (AWSResponseException e) {
assertEquals(e.getError().getCode(), "InvalidSnapshot.NotFound");
}
}
@AfterTest
public void shutdown() {
context.close();

View File

@ -38,6 +38,7 @@ import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
/**
* Tests behavior of {@code EC2Client}
@ -64,19 +65,25 @@ public class InstanceClientLiveTest {
void testDescribeInstances() {
for (Region region : ImmutableSet.of(Region.DEFAULT, Region.EU_WEST_1, Region.US_EAST_1,
Region.US_WEST_1)) {
SortedSet<Reservation> allResults = client.describeInstancesInRegion(region);
SortedSet<Reservation> allResults = Sets.newTreeSet(client
.describeInstancesInRegion(region));
assertNotNull(allResults);
assert allResults.size() >= 0 : allResults.size();
if (allResults.size() >= 2) {
Iterator<Reservation> iterator = allResults.iterator();
String id1 = iterator.next().getRunningInstances().first().getInstanceId();
String id2 = iterator.next().getRunningInstances().first().getInstanceId();
SortedSet<Reservation> twoResults = client.describeInstancesInRegion(region, id1, id2);
String id1 = Sets.newTreeSet(iterator.next().getRunningInstances()).first()
.getInstanceId();
String id2 = Sets.newTreeSet(iterator.next().getRunningInstances()).first()
.getInstanceId();
SortedSet<Reservation> twoResults = Sets.newTreeSet(client.describeInstancesInRegion(
region, id1, id2));
assertNotNull(twoResults);
assertEquals(twoResults.size(), 2);
iterator = allResults.iterator();
assertEquals(iterator.next().getRunningInstances().first().getInstanceId(), id1);
assertEquals(iterator.next().getRunningInstances().first().getInstanceId(), id2);
assertEquals(Sets.newTreeSet(iterator.next().getRunningInstances()).first()
.getInstanceId(), id1);
assertEquals(Sets.newTreeSet(iterator.next().getRunningInstances()).first()
.getInstanceId(), id2);
}
}
}

View File

@ -23,13 +23,17 @@
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.classextension.EasyMock.*;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.aws.ec2.domain.Attachment;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
/**
@ -43,11 +47,21 @@ public class AttachmentHandlerTest extends BaseHandlerTest {
DateService dateService = injector.getInstance(DateService.class);
InputStream is = getClass().getResourceAsStream("/ec2/attach.xml");
Attachment expected = new Attachment("vol-4d826724", "i-6058a509", "/dev/sdh",
Attachment.Status.ATTACHING, dateService
Attachment expected = new Attachment(Region.DEFAULT, "vol-4d826724", "i-6058a509",
"/dev/sdh", Attachment.Status.ATTACHING, dateService
.iso8601DateParse("2008-05-07T11:51:50.000Z"));
Attachment result = factory.create(injector.getInstance(AttachmentHandler.class)).parse(is);
AttachmentHandler handler = injector.getInstance(AttachmentHandler.class);
addDefaultRegionToHandler(handler);
Attachment result = factory.create(handler).parse(is);
assertEquals(result, expected);
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { Region.DEFAULT });
replay(request);
handler.setContext(request);
}
}

View File

@ -23,18 +23,33 @@
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.util.Map;
import javax.inject.Singleton;
import org.jclouds.aws.ec2.domain.Attachment;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Volume;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.config.ParserModule;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Provides;
/**
* Tests behavior of {@code CreateVolumeResponseHandler}
@ -43,16 +58,49 @@ import com.google.common.collect.Sets;
*/
@Test(groups = "unit", testName = "ec2.CreateVolumeResponseHandlerTest")
public class CreateVolumeResponseHandlerTest extends BaseHandlerTest {
@BeforeTest
@Override
protected void setUpInjector() {
injector = Guice.createInjector(new ParserModule(), new AbstractModule() {
@Override
protected void configure() {
}
@SuppressWarnings("unused")
@Singleton
@Provides
Map<AvailabilityZone, Region> provideAvailabilityZoneRegionMap() {
return ImmutableMap.<AvailabilityZone, Region> of(AvailabilityZone.US_EAST_1A,
Region.DEFAULT);
}
});
factory = injector.getInstance(ParseSax.Factory.class);
assert factory != null;
}
public void testApplyInputStream() {
DateService dateService = injector.getInstance(DateService.class);
InputStream is = getClass().getResourceAsStream("/ec2/created_volume.xml");
Volume expected = new Volume("vol-2a21e543", 1, null, AvailabilityZone.US_EAST_1A,
Volume.Status.CREATING, dateService.iso8601DateParse("2009-12-28T05:42:53.000Z"),
Sets.<Attachment>newLinkedHashSet());
Volume result = factory.create(injector.getInstance(CreateVolumeResponseHandler.class))
.parse(is);
Volume expected = new Volume(Region.DEFAULT, "vol-2a21e543", 1, null,
AvailabilityZone.US_EAST_1A, Volume.Status.CREATING, dateService
.iso8601DateParse("2009-12-28T05:42:53.000Z"), Sets
.<Attachment> newLinkedHashSet());
CreateVolumeResponseHandler handler = injector.getInstance(CreateVolumeResponseHandler.class);
addDefaultRegionToHandler(handler);
Volume result = factory.create(handler).parse(is);
assertEquals(result, expected);
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { Region.DEFAULT });
replay(request);
handler.setContext(request);
}
}

View File

@ -23,6 +23,9 @@
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
@ -31,7 +34,10 @@ import java.net.UnknownHostException;
import java.util.Set;
import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
@ -47,11 +53,21 @@ public class DescribeAddressesResponseHandlerTest extends BaseHandlerTest {
InputStream is = getClass().getResourceAsStream("/ec2/describe_addresses.xml");
Set<PublicIpInstanceIdPair> result = factory.create(
injector.getInstance(DescribeAddressesResponseHandler.class)).parse(is);
DescribeAddressesResponseHandler handler = injector
.getInstance(DescribeAddressesResponseHandler.class);
addDefaultRegionToHandler(handler);
assertEquals(result, ImmutableList.of(new PublicIpInstanceIdPair(InetAddress
.getByName("67.202.55.255"), "i-f15ebb98"), new PublicIpInstanceIdPair(InetAddress
.getByName("67.202.55.233"), null)));
Set<PublicIpInstanceIdPair> result = factory.create(handler).parse(is);
assertEquals(result, ImmutableList.of(new PublicIpInstanceIdPair(Region.DEFAULT, InetAddress
.getByName("67.202.55.255"), "i-f15ebb98"), new PublicIpInstanceIdPair(
Region.DEFAULT, InetAddress.getByName("67.202.55.233"), null)));
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { Region.DEFAULT }).atLeastOnce();
replay(request);
handler.setContext(request);
}
}

View File

@ -23,6 +23,9 @@
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
@ -30,11 +33,14 @@ import java.util.Set;
import java.util.SortedSet;
import org.jclouds.aws.ec2.domain.Image;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Image.Architecture;
import org.jclouds.aws.ec2.domain.Image.EbsBlockDevice;
import org.jclouds.aws.ec2.domain.Image.ImageState;
import org.jclouds.aws.ec2.domain.Image.ImageType;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
@ -52,15 +58,14 @@ public class DescribeImagesResponseHandlerTest extends BaseHandlerTest {
InputStream is = getClass().getResourceAsStream("/ec2/describe_images.xml");
SortedSet<Image> contents = Sets.newTreeSet();
contents.add(new Image(Architecture.I386, null, null, "ami-be3adfd7",
contents.add(new Image(Region.DEFAULT, Architecture.I386, null, null, "ami-be3adfd7",
"ec2-public-images/fedora-8-i386-base-v1.04.manifest.xml", "206029621532",
ImageState.AVAILABLE, ImageType.MACHINE, false,
Sets.<String> newHashSet("9961934F"), "aki-4438dd2d", null, "ari-4538dd2c",
Image.RootDeviceType.INSTANCE_STORE, null, ImmutableMap
.<String, EbsBlockDevice> of()));
Set<Image> result = factory.create(injector.getInstance(DescribeImagesResponseHandler.class))
.parse(is);
Set<Image> result = parseImages(is);
assertEquals(result, contents);
}
@ -69,15 +74,14 @@ public class DescribeImagesResponseHandlerTest extends BaseHandlerTest {
InputStream is = getClass().getResourceAsStream("/ec2/describe_images_windows.xml");
SortedSet<Image> contents = Sets.newTreeSet();
contents.add(new Image(Architecture.X86_64, null, null, "ami-02eb086b",
contents.add(new Image(Region.DEFAULT, Architecture.X86_64, null, null, "ami-02eb086b",
"aws-solutions-amis/SqlSvrStd2003r2-x86_64-Win_SFWBasic5.1-v1.0.manifest.xml",
"771350841976", ImageState.AVAILABLE, ImageType.MACHINE, true, Sets
.<String> newHashSet("5771E9A6"), null, "windows", null,
Image.RootDeviceType.INSTANCE_STORE, null, ImmutableMap
.<String, EbsBlockDevice> of()));
Set<Image> result = factory.create(injector.getInstance(DescribeImagesResponseHandler.class))
.parse(is);
Set<Image> result = parseImages(is);
assertEquals(result, contents);
}
@ -86,17 +90,31 @@ public class DescribeImagesResponseHandlerTest extends BaseHandlerTest {
InputStream is = getClass().getResourceAsStream("/ec2/describe_images_ebs.xml");
SortedSet<Image> contents = Sets.newTreeSet();
contents.add(new Image(Architecture.I386, "websrv_2009-12-10", "Web Server AMI",
"ami-246f8d4d", "706093390852/websrv_2009-12-10", "706093390852",
contents.add(new Image(Region.DEFAULT, Architecture.I386, "websrv_2009-12-10",
"Web Server AMI", "ami-246f8d4d", "706093390852/websrv_2009-12-10", "706093390852",
ImageState.AVAILABLE, ImageType.MACHINE, true, Sets.<String> newHashSet(), null,
"windows", null, Image.RootDeviceType.EBS, "/dev/sda1", ImmutableMap
.<String, EbsBlockDevice> of("/dev/sda1", new EbsBlockDevice(
"snap-d01272b9", 30, true), "xvdf", new EbsBlockDevice(
"snap-d31272ba", 250, false))));
Set<Image> result = factory.create(injector.getInstance(DescribeImagesResponseHandler.class))
.parse(is);
Set<Image> result = parseImages(is);
assertEquals(result, contents);
}
private Set<Image> parseImages(InputStream is) {
DescribeImagesResponseHandler handler = injector
.getInstance(DescribeImagesResponseHandler.class);
addDefaultRegionToHandler(handler);
Set<Image> result = factory.create(handler).parse(is);
return result;
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { Region.DEFAULT });
replay(request);
handler.setContext(request);
}
}

View File

@ -23,24 +23,30 @@
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.SortedSet;
import java.util.Set;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Sets;
/**
@ -64,48 +70,60 @@ public class DescribeInstancesResponseHandlerTest extends BaseHandlerTest {
public void testWhenRunning() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/ec2/describe_instances_running.xml");
SortedSet<Reservation> contents = Sets.newTreeSet();
Set<Reservation> contents = Sets.newTreeSet();
contents.add(new Reservation(ImmutableSortedSet.of("adriancole.ec2ingress"),
ImmutableSortedSet.of(new RunningInstance("0",
contents.add(new Reservation(Region.DEFAULT, ImmutableSet.of("adriancole.ec2ingress"),
ImmutableSet.of(new RunningInstance("0",
"ec2-174-129-81-68.compute-1.amazonaws.com", "ami-1fd73376", "i-0799056f",
InstanceState.RUNNING, InstanceType.M1_SMALL, InetAddress
.getByName("174.129.81.68"), "aki-a71cf9ce", "adriancole.ec21",
dateService.iso8601DateParse("2009-11-09T03:00:34.000Z"), false,
"us-east-1c", null, "ip-10-243-42-70.ec2.internal", InetAddress
.getByName("10.243.42.70"), ImmutableSet.<String> of(),
AvailabilityZone.US_EAST_1C, null, "ip-10-243-42-70.ec2.internal",
InetAddress.getByName("10.243.42.70"), ImmutableSet.<String> of(),
"ari-a51cf9cc", null, null, null)), "993194456877", null, "r-a3c508cb"));
SortedSet<Reservation> result = factory.create(
injector.getInstance(DescribeInstancesResponseHandler.class)).parse(is);
Set<Reservation> result = getReservations(is);
assertEquals(result, contents);
}
public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream("/ec2/describe_instances.xml");
SortedSet<Reservation> contents = Sets.newTreeSet();
Set<Reservation> contents = Sets.newTreeSet();
contents.add(new Reservation(ImmutableSortedSet.of("default"), ImmutableSortedSet.of(
contents.add(new Reservation(Region.DEFAULT, ImmutableSet.of("default"), ImmutableSet.of(
new RunningInstance("23", "ec2-72-44-33-4.compute-1.amazonaws.com", "ami-6ea54007",
"i-28a64341", InstanceState.RUNNING, InstanceType.M1_LARGE,
(InetAddress) null, "aki-ba3adfd3", "example-key-name", dateService
.iso8601DateParse("2007-08-07T11:54:42.000Z"), false,
"us-east-1b", null, "10-251-50-132.ec2.internal", null, ImmutableSet
.of("774F4FF8"), "ari-badbad00", null, null, null),
AvailabilityZone.US_EAST_1B, null, "10-251-50-132.ec2.internal", null,
ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null),
new RunningInstance("23", "ec2-72-44-33-6.compute-1.amazonaws.com", "ami-6ea54007",
"i-28a64435", InstanceState.RUNNING, InstanceType.M1_LARGE,
(InetAddress) null, "aki-ba3adfd3", "example-key-name", dateService
.iso8601DateParse("2007-08-07T11:54:42.000Z"), false,
"us-east-1b", null, "10-251-50-134.ec2.internal", null, ImmutableSet
.of("774F4FF8"), "ari-badbad00", null, null, null)),
AvailabilityZone.US_EAST_1B, null, "10-251-50-134.ec2.internal", null,
ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null)),
"UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null, "r-44a5402d"));
SortedSet<Reservation> result = factory.create(
injector.getInstance(DescribeInstancesResponseHandler.class)).parse(is);
Set<Reservation> result = getReservations(is);
assertEquals(result, contents);
}
private Set<Reservation> getReservations(InputStream is) {
DescribeInstancesResponseHandler handler = injector
.getInstance(DescribeInstancesResponseHandler.class);
addDefaultRegionToHandler(handler);
Set<Reservation> result = factory.create(handler).parse(is);
return result;
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { Region.DEFAULT });
replay(request);
handler.setContext(request);
}
}

View File

@ -23,13 +23,19 @@
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.util.Set;
import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
@ -45,12 +51,20 @@ public class DescribeKeyPairsResponseHandlerTest extends BaseHandlerTest {
InputStream is = getClass().getResourceAsStream("/ec2/describe_keypairs.xml");
Set<KeyPair> expected = ImmutableSet.of(new KeyPair("gsg-keypair",
Set<KeyPair> expected = ImmutableSet.of(new KeyPair(Region.DEFAULT, "gsg-keypair",
"1f:51:ae:28:bf:89:e9:d8:1f:25:5d:37:2d:7d:b8:ca:9f:f5:f1:6f", null));
Set<KeyPair> result = factory.create(
injector.getInstance(DescribeKeyPairsResponseHandler.class)).parse(is);
DescribeKeyPairsResponseHandler handler = injector
.getInstance(DescribeKeyPairsResponseHandler.class);
addDefaultRegionToHandler(handler);
Set<KeyPair> result = factory.create(handler).parse(is);
assertEquals(result, expected);
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { Region.DEFAULT });
replay(request);
handler.setContext(request);
}
}

View File

@ -23,16 +23,23 @@
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.util.Set;
import java.util.SortedSet;
import org.jclouds.aws.ec2.domain.IpPermission;
import org.jclouds.aws.ec2.domain.IpProtocol;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.SecurityGroup;
import org.jclouds.aws.ec2.domain.UserIdGroupPair;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSortedSet;
@ -48,18 +55,28 @@ public class DescribeSecurityGroupsResponseHandlerTest extends BaseHandlerTest {
InputStream is = getClass().getResourceAsStream("/ec2/describe_securitygroups.xml");
SortedSet<SecurityGroup> expected = ImmutableSortedSet.of(new SecurityGroup("WebServers",
"UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Web Servers", ImmutableSortedSet
SortedSet<SecurityGroup> expected = ImmutableSortedSet.of(new SecurityGroup(Region.DEFAULT,
"WebServers", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Web Servers", ImmutableSortedSet
.of(new IpPermission(80, 80, ImmutableSortedSet.<UserIdGroupPair> of(),
IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0")))),
new SecurityGroup("RangedPortsBySource", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM",
"Group A", ImmutableSortedSet.of(new IpPermission(6000, 7000,
ImmutableSortedSet.<UserIdGroupPair> of(), IpProtocol.TCP,
new SecurityGroup(Region.DEFAULT, "RangedPortsBySource",
"UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Group A", ImmutableSortedSet
.of(new IpPermission(6000, 7000, ImmutableSortedSet
.<UserIdGroupPair> of(), IpProtocol.TCP,
ImmutableSortedSet.<String> of()))));
SortedSet<SecurityGroup> result = factory.create(
injector.getInstance(DescribeSecurityGroupsResponseHandler.class)).parse(is);
DescribeSecurityGroupsResponseHandler handler = injector
.getInstance(DescribeSecurityGroupsResponseHandler.class);
addDefaultRegionToHandler(handler);
Set<SecurityGroup> result = factory.create(handler).parse(is);
assertEquals(result, expected);
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { Region.DEFAULT }).atLeastOnce();
replay(request);
handler.setContext(request);
}
}

View File

@ -0,0 +1,74 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.util.Set;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Snapshot;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
import com.google.common.collect.Sets;
/**
* Tests behavior of {@code DescribeSnapshotsResponseHandler}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ec2.DescribeSnapshotsResponseHandlerTest")
public class DescribeSnapshotsResponseHandlerTest extends BaseHandlerTest {
public void testApplyInputStream() {
DateService dateService = injector.getInstance(DateService.class);
InputStream is = getClass().getResourceAsStream("/ec2/describe_snapshots.xml");
Set<Snapshot> expected = Sets.newLinkedHashSet();
expected.add(new Snapshot(Region.DEFAULT, "snap-78a54011", "vol-4d826724", 10,
Snapshot.Status.PENDING, dateService.iso8601DateParse("2008-05-07T12:51:50.000Z"),
80, "218213537122", "Daily Backup", null));
DescribeSnapshotsResponseHandler handler = injector
.getInstance(DescribeSnapshotsResponseHandler.class);
addDefaultRegionToHandler(handler);
Set<Snapshot> result = factory.create(handler).parse(is);
assertEquals(result, expected);
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { Region.DEFAULT });
replay(request);
handler.setContext(request);
}
}

View File

@ -23,19 +23,34 @@
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.util.Map;
import java.util.Set;
import javax.inject.Singleton;
import org.jclouds.aws.ec2.domain.Attachment;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Volume;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.config.ParserModule;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Provides;
/**
* Tests behavior of {@code DescribeVolumesResponseHandler}
@ -44,22 +59,56 @@ import com.google.common.collect.Sets;
*/
@Test(groups = "unit", testName = "ec2.DescribeVolumesResponseHandlerTest")
public class DescribeVolumesResponseHandlerTest extends BaseHandlerTest {
@BeforeTest
@Override
protected void setUpInjector() {
injector = Guice.createInjector(new ParserModule(), new AbstractModule(){
@Override
protected void configure() {
}
@SuppressWarnings("unused")
@Singleton
@Provides
Map<AvailabilityZone, Region> provideAvailabilityZoneRegionMap() {
return ImmutableMap.<AvailabilityZone, Region> of(AvailabilityZone.US_EAST_1A,
Region.DEFAULT);
}
});
factory = injector.getInstance(ParseSax.Factory.class);
assert factory != null;
}
public void testApplyInputStream() {
DateService dateService = injector.getInstance(DateService.class);
InputStream is = getClass().getResourceAsStream("/ec2/describe_volumes.xml");
Set<Volume> expected = Sets.newLinkedHashSet();
expected.add(new Volume("vol-2a21e543", 1, null, AvailabilityZone.US_EAST_1A,
expected.add(new Volume(Region.DEFAULT, "vol-2a21e543", 1, null, AvailabilityZone.US_EAST_1A,
Volume.Status.AVAILABLE, dateService.iso8601DateParse("2009-12-28T05:42:53.000Z"),
Sets.<Attachment> newLinkedHashSet()));
expected.add(new Volume("vol-4282672b", 800, null, AvailabilityZone.US_EAST_1A,
Volume.Status.IN_USE, dateService.iso8601DateParse("2008-05-07T11:51:50.000Z"), Sets
.<Attachment> newHashSet(new Attachment("vol-4282672b", "i-6058a509",
"/dev/sdh", Attachment.Status.ATTACHED, dateService
expected.add(new Volume(Region.DEFAULT, "vol-4282672b", 800, "snap-536d1b3a",
AvailabilityZone.US_EAST_1A, Volume.Status.IN_USE, dateService
.iso8601DateParse("2008-05-07T11:51:50.000Z"), Sets
.<Attachment> newHashSet(new Attachment(Region.DEFAULT, "vol-4282672b",
"i-6058a509", "/dev/sdh", Attachment.Status.ATTACHED, dateService
.iso8601DateParse("2008-05-07T12:51:50.000Z")))));
Set<Volume> result = factory.create(
injector.getInstance(DescribeVolumesResponseHandler.class)).parse(is);
DescribeVolumesResponseHandler handler = injector
.getInstance(DescribeVolumesResponseHandler.class);
addDefaultRegionToHandler(handler);
Set<Volume> result = factory.create(handler).parse(is);
assertEquals(result, expected);
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { Region.DEFAULT }).atLeastOnce();
replay(request);
handler.setContext(request);
}
}

View File

@ -23,12 +23,18 @@
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
/**
@ -43,6 +49,7 @@ public class KeyPairResponseHandlerTest extends BaseHandlerTest {
InputStream is = getClass().getResourceAsStream("/ec2/create_keypair.xml");
KeyPair expected = new KeyPair(
Region.DEFAULT,
"gsg-keypair",
"1f:51:ae:28:bf:89:e9:d8:1f:25:5d:37:2d:7d:b8:ca:9f:f5:f1:6f",
"-----BEGIN RSA PRIVATE KEY-----\n"
@ -69,8 +76,17 @@ public class KeyPairResponseHandlerTest extends BaseHandlerTest {
+ "2ERKKdwz0ZL9SWq6VTdhr/5G994CK72fy5WhyERbDjUIdHaK3M849JJuf8cSrvSb4g==\n"
+ "-----END RSA PRIVATE KEY-----");
KeyPair result = factory.create(injector.getInstance(KeyPairResponseHandler.class)).parse(is);
KeyPairResponseHandler handler = injector.getInstance(KeyPairResponseHandler.class);
addDefaultRegionToHandler(handler);
KeyPair result = factory.create(handler).parse(is);
assertEquals(result, expected);
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { Region.DEFAULT }).atLeastOnce();
replay(request);
handler.setContext(request);
}
}

View File

@ -27,29 +27,27 @@ import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.aws.ec2.domain.LaunchPermission;
import org.jclouds.aws.ec2.domain.Permission;
import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test;
import com.google.common.collect.Sets;
/**
* Tests behavior of {@code LaunchPermissionHandler}
* Tests behavior of {@code PermissionHandler}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ec2.LaunchPermissionHandlerTest")
public class LaunchPermissionHandlerTest extends BaseHandlerTest {
@Test(groups = "unit", testName = "ec2.PermissionHandlerTest")
public class PermissionHandlerTest extends BaseHandlerTest {
public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream(
"/ec2/describe_image_attribute_launchPermission.xml");
LaunchPermission expected = new LaunchPermission(Sets.newHashSet("495219933132"), Sets
.newHashSet("all"));
Permission expected = new Permission(Sets.newHashSet("495219933132"), Sets.newHashSet("all"));
LaunchPermission result = factory.create(injector.getInstance(LaunchPermissionHandler.class))
.parse(is);
Permission result = factory.create(injector.getInstance(PermissionHandler.class)).parse(is);
assertEquals(result, expected);
}

View File

@ -23,17 +23,24 @@
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.InetAddress;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
@ -62,30 +69,38 @@ public class RunInstancesResponseHandlerTest extends BaseHandlerTest {
InputStream is = getClass().getResourceAsStream("/ec2/run_instances.xml");
Reservation expected = new Reservation(ImmutableSortedSet.of("default"), ImmutableSortedSet
.of(
new RunningInstance("0", null, "ami-60a54009", "i-2ba64342",
Reservation expected = new Reservation(Region.DEFAULT, ImmutableSortedSet.of("default"),
ImmutableSortedSet.of(new RunningInstance("0", null, "ami-60a54009", "i-2ba64342",
InstanceState.PENDING, InstanceType.M1_SMALL, (InetAddress) null, null,
"example-key-name", dateService
.iso8601DateParse("2007-08-07T11:51:50.000Z"), true, "us-east-1b",
null, null, (InetAddress) null, Sets.<String> newTreeSet(), null, null,
null, null), new RunningInstance("0", null, "ami-60a54009",
"i-2bc64242", InstanceState.PENDING, InstanceType.M1_SMALL,
(InetAddress) null, null, "example-key-name", dateService
.iso8601DateParse("2007-08-07T11:51:50.000Z"), true, "us-east-1b",
null, null, (InetAddress) null, Sets.<String> newTreeSet(), null, null,
null, null), new RunningInstance("0", null, "ami-60a54009",
"i-2be64332", InstanceState.PENDING, InstanceType.M1_SMALL,
(InetAddress) null, null, "example-key-name", dateService
.iso8601DateParse("2007-08-07T11:51:50.000Z"), true, "us-east-1b",
null, null, (InetAddress) null, Sets.<String> newTreeSet(), null, null,
null, null)
.iso8601DateParse("2007-08-07T11:51:50.000Z"), true,
AvailabilityZone.US_EAST_1B, null, null, (InetAddress) null, Sets
.<String> newTreeSet(), null, null, null, null),
new RunningInstance("0", null, "ami-60a54009", "i-2bc64242",
InstanceState.PENDING, InstanceType.M1_SMALL, (InetAddress) null,
null, "example-key-name", dateService
.iso8601DateParse("2007-08-07T11:51:50.000Z"), true,
AvailabilityZone.US_EAST_1B, null, null, (InetAddress) null, Sets
.<String> newTreeSet(), null, null, null, null),
new RunningInstance("0", null, "ami-60a54009", "i-2be64332",
InstanceState.PENDING, InstanceType.M1_SMALL, (InetAddress) null,
null, "example-key-name", dateService
.iso8601DateParse("2007-08-07T11:51:50.000Z"), true,
AvailabilityZone.US_EAST_1B, null, null, (InetAddress) null, Sets
.<String> newTreeSet(), null, null, null, null)
), "AIDADH4IGTRXXKCD", null, "r-47a5402e");
Reservation result = factory.create(
injector.getInstance(RunInstancesResponseHandler.class)).parse(is);
RunInstancesResponseHandler handler = injector.getInstance(RunInstancesResponseHandler.class);
addDefaultRegionToHandler(handler);
Reservation result = factory.create(handler).parse(is);
assertEquals(result, expected);
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { Region.DEFAULT }).atLeastOnce();
replay(request);
handler.setContext(request);
}
}

View File

@ -0,0 +1,68 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.Snapshot;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code SnapshotHandler}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ec2.SnapshotHandlerTest")
public class SnapshotHandlerTest extends BaseHandlerTest {
public void testApplyInputStream() {
DateService dateService = injector.getInstance(DateService.class);
InputStream is = getClass().getResourceAsStream("/ec2/created_snapshot.xml");
Snapshot expected = new Snapshot(Region.DEFAULT, "snap-78a54011", "vol-4d826724", 10, Snapshot.Status.PENDING,
dateService.iso8601DateParse("2008-05-07T12:51:50.000Z"), 60, "213457642086",
"Daily Backup", null);
SnapshotHandler handler = injector.getInstance(SnapshotHandler.class);
addDefaultRegionToHandler(handler);
Snapshot result = factory.create(handler).parse(is);
assertEquals(result, expected);
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { Region.DEFAULT }).atLeastOnce();
replay(request);
handler.setContext(request);
}
}

View File

@ -23,19 +23,25 @@
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.util.SortedSet;
import java.util.Set;
import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.Region;
import org.jclouds.aws.ec2.domain.TerminatedInstance;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.ImmutableSet;
/**
* Tests behavior of {@code TerminateInstancesResponseHandler}
@ -59,12 +65,20 @@ public class TerminateInstancesResponseHandlerTest extends BaseHandlerTest {
InputStream is = getClass().getResourceAsStream("/ec2/terminate_instances.xml");
SortedSet<TerminatedInstance> expected = ImmutableSortedSet.of(new TerminatedInstance(
Set<TerminatedInstance> expected = ImmutableSet.of(new TerminatedInstance(Region.DEFAULT,
"i-3ea74257", InstanceState.SHUTTING_DOWN, InstanceState.RUNNING));
SortedSet<TerminatedInstance> result = factory.create(
injector.getInstance(TerminateInstancesResponseHandler.class)).parse(is);
TerminateInstancesResponseHandler handler = injector
.getInstance(TerminateInstancesResponseHandler.class);
addDefaultRegionToHandler(handler);
Set<TerminatedInstance> result = factory.create(handler).parse(is);
assertEquals(result, expected);
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { Region.DEFAULT }).atLeastOnce();
replay(request);
handler.setContext(request);
}
}

View File

@ -0,0 +1,10 @@
<CreateSnapshotResponse xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
<snapshotId>snap-78a54011</snapshotId>
<volumeId>vol-4d826724</volumeId>
<volumeSize>10</volumeSize>
<status>pending</status>
<startTime>2008-05-07T12:51:50.000Z</startTime>
<progress>60%</progress>
<ownerId>213457642086</ownerId>
<description>Daily Backup</description>
</CreateSnapshotResponse>

View File

@ -0,0 +1,14 @@
<DescribeSnapshotsResponse xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
<snapshotSet>
<item>
<snapshotId>snap-78a54011</snapshotId>
<volumeId>vol-4d826724</volumeId>
<status>pending</status>
<startTime>2008-05-07T12:51:50.000Z</startTime>
<progress>80%</progress>
<ownerId>218213537122</ownerId>
<volumeSize>10</volumeSize>
<description>Daily Backup</description>
</item>
</snapshotSet>
</DescribeSnapshotsResponse>

View File

@ -14,7 +14,7 @@
<item>
<volumeId>vol-4282672b</volumeId>
<size>800</size>
<snapshotId />
<snapshotId>snap-536d1b3a</snapshotId>
<availabilityZone>us-east-1a</availabilityZone>
<status>in-use</status>
<createTime>2008-05-07T11:51:50.000Z</createTime>

View File

@ -33,6 +33,8 @@ import javax.inject.Inject;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpResponse;
import org.jclouds.logging.Logger;
import org.jclouds.rest.InvocationContext;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.util.Utils;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
@ -48,7 +50,7 @@ import com.google.common.io.Closeables;
*
* @author Adrian Cole
*/
public class ParseSax<T> implements Function<HttpResponse, T> {
public class ParseSax<T> implements Function<HttpResponse, T>, InvocationContext {
private final XMLReader parser;
private final HandlerWithResult<T> handler;
@ -112,7 +114,20 @@ public class ParseSax<T> implements Function<HttpResponse, T> {
*
* @author Adrian Cole
*/
public abstract static class HandlerWithResult<T> extends DefaultHandler {
public abstract static class HandlerWithResult<T> extends DefaultHandler implements
InvocationContext {
protected GeneratedHttpRequest<?> request;
public abstract T getResult();
@Override
public void setContext(GeneratedHttpRequest<?> request) {
this.request = request;
}
}
@Override
public void setContext(GeneratedHttpRequest<?> request) {
handler.setContext(request);
}
}