diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/EC2AsyncClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/EC2AsyncClient.java index 106abede9b..f87a7e8c32 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/EC2AsyncClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/EC2AsyncClient.java @@ -23,273 +23,45 @@ */ package org.jclouds.aws.ec2; -import static org.jclouds.aws.ec2.reference.EC2Parameters.ACTION; -import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION; +import org.jclouds.aws.ec2.internal.EC2AsyncClientImpl; +import org.jclouds.aws.ec2.services.AMIAsyncClient; +import org.jclouds.aws.ec2.services.ElasticIPAddressAsyncClient; +import org.jclouds.aws.ec2.services.InstanceAsyncClient; +import org.jclouds.aws.ec2.services.KeyPairAsyncClient; +import org.jclouds.aws.ec2.services.SecurityGroupAsyncClient; -import java.net.InetAddress; -import java.util.SortedSet; -import java.util.concurrent.Future; - -import javax.ws.rs.FormParam; -import javax.ws.rs.POST; -import javax.ws.rs.Path; - -import org.jclouds.aws.ec2.binders.BindGroupNameToIndexedFormParams; -import org.jclouds.aws.ec2.binders.BindInetAddressesToIndexedFormParams; -import org.jclouds.aws.ec2.binders.BindInstanceIdsToIndexedFormParams; -import org.jclouds.aws.ec2.binders.BindKeyNameToIndexedFormParams; -import org.jclouds.aws.ec2.binders.BindUserIdGroupPairToSourceSecurityGroupFormParams; -import org.jclouds.aws.ec2.domain.Image; -import org.jclouds.aws.ec2.domain.ImageAttribute; -import org.jclouds.aws.ec2.domain.IpProtocol; -import org.jclouds.aws.ec2.domain.KeyPair; -import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair; -import org.jclouds.aws.ec2.domain.Reservation; -import org.jclouds.aws.ec2.domain.SecurityGroup; -import org.jclouds.aws.ec2.domain.TerminatedInstance; -import org.jclouds.aws.ec2.domain.UserIdGroupPair; -import org.jclouds.aws.ec2.filters.FormSigner; -import org.jclouds.aws.ec2.functions.ReturnVoidOnGroupNotFound; -import org.jclouds.aws.ec2.options.DescribeImagesOptions; -import org.jclouds.aws.ec2.options.RunInstancesOptions; -import org.jclouds.aws.ec2.xml.AllocateAddressResponseHandler; -import org.jclouds.aws.ec2.xml.DescribeAddressesResponseHandler; -import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandler; -import org.jclouds.aws.ec2.xml.DescribeInstancesResponseHandler; -import org.jclouds.aws.ec2.xml.DescribeKeyPairsResponseHandler; -import org.jclouds.aws.ec2.xml.DescribeSecurityGroupsResponseHandler; -import org.jclouds.aws.ec2.xml.KeyPairResponseHandler; -import org.jclouds.aws.ec2.xml.RunInstancesResponseHandler; -import org.jclouds.aws.ec2.xml.TerminateInstancesResponseHandler; -import org.jclouds.rest.annotations.BinderParam; -import org.jclouds.rest.annotations.Endpoint; -import org.jclouds.rest.annotations.ExceptionParser; -import org.jclouds.rest.annotations.FormParams; -import org.jclouds.rest.annotations.ParamParser; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.VirtualHost; -import org.jclouds.rest.annotations.XMLResponseParser; -import org.jclouds.rest.functions.InetAddressToHostAddress; +import com.google.inject.ImplementedBy; /** - * Provides access to EC2 via their REST API. - *

+ * Provides asynchronous access to EC2 services. * * @author Adrian Cole */ -@Endpoint(EC2.class) -@RequestFilters(FormSigner.class) -@FormParams(keys = VERSION, values = "2009-08-15") -@VirtualHost +@ImplementedBy(EC2AsyncClientImpl.class) public interface EC2AsyncClient { + /** + * Provides asynchronous access to AMI services. + */ + AMIAsyncClient getAMIServices(); /** - * @see EC2Client#describeImages + * Provides asynchronous access to Elastic IP Address services. */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "DescribeImages") - @XMLResponseParser(DescribeImagesResponseHandler.class) - Future> describeImages(DescribeImagesOptions... options); + ElasticIPAddressAsyncClient getElasticIPAddressServices(); /** - * Returns information about an attribute of an AMI. Only one attribute can be specified per - * call. - * - * @param imageId - * The ID of the AMI for which an attribute will be described - * @param attribute - * the attribute to describe - * @see #describeImages - * @see #modifyImageAttribute - * @see #resetImageAttribute - * @see - * @see DescribeImagesOptions + * Provides asynchronous access to Instance services. */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "DescribeImageAttribute") - Future describeImageAttribute(@FormParam("ImageId") String imageId, - @FormParam("Attribute") ImageAttribute attribute); + InstanceAsyncClient getInstanceServices(); /** - * Acquires an elastic IP address for use with your account. - * - * @see #describeAddresses - * @see #releaseAddress - * @see #associateAddress - * @see #disassociateAddress - * @see allocateAddress(); + KeyPairAsyncClient getKeyPairServices(); /** - * @see EC2Client#associateAddress + * Provides asynchronous access to SecurityGroup services. */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "AssociateAddress") - Future associateAddress( - @FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp, - @FormParam("InstanceId") String instanceId); + SecurityGroupAsyncClient getSecurityGroupServices(); - /** - * @see EC2Client#disassociateAddress - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "DisassociateAddress") - Future disassociateAddress( - @FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp); - - /** - * @see EC2Client#releaseAddress - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "ReleaseAddress") - Future releaseAddress( - @FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp); - - /** - * @see EC2Client#describeAddresses - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "DescribeAddresses") - @XMLResponseParser(DescribeAddressesResponseHandler.class) - Future> describeAddresses( - @BinderParam(BindInetAddressesToIndexedFormParams.class) InetAddress... publicIps); - - /** - * @see EC2Client#describeInstances - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "DescribeInstances") - @XMLResponseParser(DescribeInstancesResponseHandler.class) - Future> describeInstances( - @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds); - - /** - * @see EC2Client#runInstances - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "RunInstances") - @XMLResponseParser(RunInstancesResponseHandler.class) - Future runInstances(@FormParam("ImageId") String imageId, - @FormParam("MinCount") int minCount, @FormParam("MaxCount") int maxCount, - RunInstancesOptions... options); - - /** - * @see EC2Client#terminateInstances - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "TerminateInstances") - @XMLResponseParser(TerminateInstancesResponseHandler.class) - Future> terminateInstances( - @FormParam("InstanceId.0") String instanceId, - @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds); - - /** - * @see EC2Client#createKeyPair - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "CreateKeyPair") - @XMLResponseParser(KeyPairResponseHandler.class) - Future createKeyPair(@FormParam("KeyName") String keyName); - - /** - * @see EC2Client#describeKeyPairs - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "DescribeKeyPairs") - @XMLResponseParser(DescribeKeyPairsResponseHandler.class) - Future> describeKeyPairs( - @BinderParam(BindKeyNameToIndexedFormParams.class) String... keyPairNames); - - /** - * @see EC2Client#deleteKeyPair - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "DeleteKeyPair") - Future deleteKeyPair(@FormParam("KeyName") String keyName); - - /** - * @see EC2Client#createSecurityGroup - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "CreateSecurityGroup") - Future createSecurityGroup(@FormParam("GroupName") String name, - @FormParam("GroupDescription") String description); - - /** - * @see EC2Client#deleteSecurityGroup - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "DeleteSecurityGroup") - @ExceptionParser(ReturnVoidOnGroupNotFound.class) - Future deleteSecurityGroup(@FormParam("GroupName") String name); - - /** - * @see EC2Client#describeSecurityGroups - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "DescribeSecurityGroups") - @XMLResponseParser(DescribeSecurityGroupsResponseHandler.class) - Future> describeSecurityGroups( - @BinderParam(BindGroupNameToIndexedFormParams.class) String... securityGroupNames); - - /** - * @see EC2Client#authorizeSecurityGroupIngress(String,UserIdGroupPair) - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress") - Future authorizeSecurityGroupIngress( - @FormParam("GroupName") String groupName, - @BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup); - - /** - * @see EC2Client#authorizeSecurityGroupIngress(String,IpProtocol,int,int,String) - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress") - Future authorizeSecurityGroupIngress(@FormParam("GroupName") String groupName, - @FormParam("IpProtocol") IpProtocol ipProtocol, @FormParam("FromPort") int fromPort, - @FormParam("ToPort") int toPort, @FormParam("CidrIp") String cidrIp); - - /** - * @see EC2Client#revokeSecurityGroupIngress(String,UserIdGroupPair) - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress") - Future revokeSecurityGroupIngress( - @FormParam("GroupName") String groupName, - @BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup); - - /** - * @see EC2Client#revokeSecurityGroupIngress(String,IpProtocol,int,int,String) - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress") - Future revokeSecurityGroupIngress(@FormParam("GroupName") String groupName, - @FormParam("IpProtocol") IpProtocol ipProtocol, @FormParam("FromPort") int fromPort, - @FormParam("ToPort") int toPort, @FormParam("CidrIp") String cidrIp); } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/EC2Client.java b/aws/core/src/main/java/org/jclouds/aws/ec2/EC2Client.java index 9894efe82d..65b49c4b67 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/EC2Client.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/EC2Client.java @@ -23,441 +23,45 @@ */ package org.jclouds.aws.ec2; -import java.net.InetAddress; -import java.util.SortedSet; -import java.util.concurrent.TimeUnit; +import org.jclouds.aws.ec2.internal.EC2ClientImpl; +import org.jclouds.aws.ec2.services.AMIClient; +import org.jclouds.aws.ec2.services.ElasticIPAddressClient; +import org.jclouds.aws.ec2.services.InstanceClient; +import org.jclouds.aws.ec2.services.KeyPairClient; +import org.jclouds.aws.ec2.services.SecurityGroupClient; -import org.jclouds.aws.AWSResponseException; -import org.jclouds.aws.ec2.domain.Image; -import org.jclouds.aws.ec2.domain.ImageAttribute; -import org.jclouds.aws.ec2.domain.IpProtocol; -import org.jclouds.aws.ec2.domain.KeyPair; -import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair; -import org.jclouds.aws.ec2.domain.Reservation; -import org.jclouds.aws.ec2.domain.SecurityGroup; -import org.jclouds.aws.ec2.domain.TerminatedInstance; -import org.jclouds.aws.ec2.domain.UserIdGroupPair; -import org.jclouds.aws.ec2.options.DescribeImagesOptions; -import org.jclouds.aws.ec2.options.RunInstancesOptions; -import org.jclouds.concurrent.Timeout; +import com.google.inject.ImplementedBy; /** - * Provides access to EC2 via their REST API. - *

+ * Provides synchronous access to EC2 services. * * @author Adrian Cole */ -@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) +@ImplementedBy(EC2ClientImpl.class) public interface EC2Client { + /** + * Provides synchronous access to AMI services. + */ + AMIClient getAMIServices(); /** - * Returns information about AMIs, AKIs, and ARIs. This includes image type, product codes, - * architecture, and kernel and RAM disk IDs. Images available to you include p ublic images, - * private images that you own, and private images owned by other users for which you have - * explicit launch permissions. - * - * @see #describeInstances - * @see #describeImageAttribute - * @see - * @see DescribeImagesOptions + * Provides synchronous access to Elastic IP Address services. */ - SortedSet describeImages(DescribeImagesOptions... options); + ElasticIPAddressClient getElasticIPAddressServices(); /** - * Returns information about an attribute of an AMI. Only one attribute can be specified per - * call. - * - * @param imageId - * The ID of the AMI for which an attribute will be described - * @param attribute - * the attribute to describe - * @see #describeImages - * @see #modifyImageAttribute - * @see #resetImageAttribute - * @see - * @see DescribeImagesOptions + * Provides synchronous access to Instance services. */ - String describeImageAttribute(String imageId, ImageAttribute attribute); + InstanceClient getInstanceServices(); /** - * Acquires an elastic IP address for use with your account. - * - * @see #describeAddresses - * @see #releaseAddress - * @see #associateAddress - * @see #disassociateAddress - * @see - */ - SortedSet describeAddresses(InetAddress... publicIps); - - /** - * Returns information about instances that you own. - *

- * - * If you specify one or more instance IDs, Amazon EC2 returns information for those instances. - * If you do not specify instance IDs, Amazon EC2 returns information for all relevant instances. - * If you specify an invalid instance ID, a fault is returned. If you specify an instance that - * you do not own, it will not be included in the returned results. - *

- * Recently terminated instances might appear in the returned results.This interval is usually - * less than one hour. - * - * @see #runInstances - * @see #terminateInstances - * @see - */ - SortedSet describeInstances(String... instanceIds); - - /** - * Launches a specified number of instances of an AMI for which you have permissions. - *

- * - * If Amazon EC2 cannot launch the minimum number AMIs you request, no instances will be - * launched. If there is insufficient capacity to launch the maximum number of AMIs you request, - * Amazon EC2 launches the minimum number specified for each AMI and allocate the remaining - * available instances using round robin. - *

- *

Security Groups

- * Note: Every instance is launched in a security group (created using the - * CreateSecurityGroup operation. - *

Key Pair

- * You can provide an optional key pair ID for each image in the launch request (created using - * the CreateKeyPair operation). All instances that are created from images that use this key - * pair will have access to the associated public key at boot. You can use this key to provide - * secure access to an instance of an image on a per-instance basis. Amazon EC2 public images use - * this feature to provide secure access without passwords. - *

- * Note: Launching public images without a key pair ID will leave them inaccessible. - *

- * The public key material is made available to the instance at boot time by placing it in the - * openssh_id.pub file on a logical device that is exposed to the instance as /dev/sda2 (the - * instance store). The format of this file is suitable for use as an entry within - * ~/.ssh/authorized_keys (the OpenSSH format). This can be done at boot (e.g., as part of - * rc.local) allowing for secure access without passwords. - *

User Data

- * Optional user data can be provided in the launch request. All instances that collectively - * comprise the launch request have access to this data. For more information, go the Amazon - * Elastic Compute Cloud Developer Guide. - *

Product Codes

- * - * Note: If any of the AMIs have a product code attached for which the user has not - * subscribed, the RunInstances call will fail. - *

Kernel

- * - * Important: We strongly recommend using the 2.6.18 Xen stock kernel with High-CPU and - * High-Memory instances. Although the default Amazon EC2 kernels will work, the new kernels - * provide greater stability and performance for these instance types. For more information about - * kernels, go the Amazon Elastic Compute Cloud Developer Guide. - * - * @param imageId - * Unique ID of a machine image, returned by a call to - * @param minCount - * Minimum number of instances to launch. If the value is more than Amazon EC2 can - * launch, no instances a re launched at all. Constraints: Between 1 and the maximum - * number allowed for your account (default: 20). - * @param maxCount - * Maximum number of instances to launch. If the value is more than Amazon EC2 can - * launch, the largest possible number above minCount will be launched instead. - * Constraints: Between 1 and the maximum number allowed for your account (default: - * 20). - * @see #describeInstances - * @see #terminateInstances - * @see #authorizeSecurityGroupIngress - * @see #revokeSecurityGroupIngress - * @see #describeSecurityGroups - * @see #createSecurityGroup - * @see #createKeyPair - * @see
- * @see RunInstancesOptions - */ - Reservation runInstances(String imageId, int minCount, int maxCount, - RunInstancesOptions... options); - - /** - * Shuts down one or more instances. This operation is idempotent; if you terminate an instance - * more than once, each call will succeed. - *

- * Terminated instances will remain visible after termination (approximately one hour). - * - * @param instanceIds - * Instance ID to terminate. - * @see #describeInstances - * @see - */ - SortedSet terminateInstances(String instanceId, String... instanceIds); - - /** - * Creates a new 2048-bit RSA key pair with the specified name. The public key is stored by - * Amazon EC2 and the private key is displayed on the console. The private key is returned as an - * unencrypted PEM encoded PKCS#8 private key. If a key with the specified name already exists, - * Amazon EC2 returns an error. - * - * @see #runInstances - * @see #describeKeyPairs - * @see #deleteKeyPair - * - * @see - */ - KeyPair createKeyPair(String keyName); - - /** - * Returns information about key pairs available to you. If you specify key pairs, information - * about those key pairs is returned. Otherwise, information for all registered key pairs is - * returned. - * - * @param keyPairNames - * Key pairs to describe. - * @see #runInstances - * @see #describeAvailabilityZones - * @see - */ - SortedSet describeKeyPairs(String... keyPairNames); - - /** - * Deletes the specified key pair, by removing the public key from Amazon EC2. You must own the - * key pair - * - * @see #describeKeyPairs - * @see #createKeyPair - * - * @see - */ - - void deleteKeyPair(String keyName); - - /** - * Creates a new security group. Group names must be unique per account. - * - * @param name - * Name of the security group. Accepts alphanumeric characters, spaces, dashes, and - * underscores. - * @param description - * Description of the group. This is informational only. If the description contains - * spaces, you must enc lose it in single quotes (') or URL-encode it. Accepts - * alphanumeric characters, spaces, dashes, and underscores. - * @see #runInstances - * @see #describeSecurityGroups - * @see #authorizeSecurityGroupIngress - * @see #revokeSecurityGroupIngress - * @see #deleteSecurityGroup - * - * @see - */ - void createSecurityGroup(String name, String description); - - /** - * Deletes a security group that you own. - * - * @param name - * Name of the security group to delete. - * - * @see #describeSecurityGroups - * @see #authorizeSecurityGroupIngress - * @see #revokeSecurityGroupIngress - * @see #createSecurityGroup - * - * @see - */ - void deleteSecurityGroup(String name); - - /** - * Returns information about security groups that you own. - * - * @param securityGroupNames - * Name of the security groups - * - * @see #createSecurityGroup - * @see #authorizeSecurityGroupIngress - * @see #revokeSecurityGroupIngress - * @see #deleteSecurityGroup - * - * @see - */ - SortedSet describeSecurityGroups(String... securityGroupNames); - - /** - * - * Adds permissions to a security group based on another group. - * - * @param groupName - * Name of the group to modify. The name must be valid and belong to the account - * @param sourceSecurityGroup - * group to associate with this group. - * - * @see #createSecurityGroup - * @see #describeSecurityGroups - * @see #revokeSecurityGroupIngress - * @see #deleteSecurityGroup - * - * @see - * Permissions are specified by the IP protocol (TCP, UDP or ICMP), the source of the request (by - * IP range or an Amazon EC2 user-group pair), the source and destination port ranges (for TCP - * and UDP), and the ICMP codes and types (for ICMP). When authorizing ICMP, -1 can be used as a - * wildcard in the type and code fields. Permission changes are propagated to instances within - * the security group as quickly as possible. However, depending on the number of instances, a - * small delay might occur. - * - * @param groupName - * Name of the group to modify. The name must be valid and belong to the account - * @param ipProtocol - * IP protocol. - * @param fromPort - * Start of port range for the TCP and UDP protocols, or an ICMP type number. An ICMP - * type number of -1 indicates a wildcard (i.e., any ICMP type number). - * @param toPort - * End of port range for the TCP and UDP protocols, or an ICMP code. An ICMP code of -1 - * indicates a wildcard (i.e., any ICMP code). - * @param cidrIp - * CIDR range. - * - * @see #createSecurityGroup - * @see #describeSecurityGroups - * @see #revokeSecurityGroupIngress - * @see #deleteSecurityGroup - * - * @see - * Permissions are specified by IP protocol (TCP, UDP, or ICMP), the source of the request (by IP - * range or an Amazon EC2 user-group pair), the source and destination port ranges (for TCP and - * UDP), and the ICMP codes and types (for ICMP). - * - * Permission changes are quickly propagated to instances within the security group. However, - * depending on the number of instances in the group, a small delay is might occur. - * - * @param groupName - * Name of the group to modify. The name must be valid and belong to the account - * @param ipProtocol - * IP protocol. - * @param fromPort - * Start of port range for the TCP and UDP protocols, or an ICMP type number. An ICMP - * type number of -1 indicates a wildcard (i.e., any ICMP type number). - * @param toPort - * End of port range for the TCP and UDP protocols, or an ICMP code. An ICMP code of -1 - * indicates a wildcard (i.e., any ICMP code). - * @param cidrIp - * CIDR range. - * - * @see #createSecurityGroup - * @see #describeSecurityGroups - * @see #authorizeSecurityGroupIngress - * @see #deleteSecurityGroup - * - * @see > running instance ami(%s) type(%s) keyPair(%s) securityGroup(%s)", ami, type, keyPair.getKeyName(), securityGroupName); - RunningInstance runningInstance = Iterables.getLast(ec2Client.runInstances( - ami, - 1, - 1, - withKeyName(keyPair.getKeyName()).asType(type).withSecurityGroup(securityGroupName) - .withAdditionalInfo(name)).getRunningInstances()); + RunningInstance runningInstance = Iterables + .getLast(ec2Client.getInstanceServices().runInstances( + ami, + 1, + 1, + withKeyName(keyPair.getKeyName()).asType(type).withSecurityGroup( + securityGroupName).withAdditionalInfo(name)).getRunningInstances()); logger.debug("<< started instance(%s)", runningInstance.getInstanceId()); instanceStateRunning.apply(runningInstance); logger.debug("<< running instance(%s)", runningInstance.getInstanceId()); @@ -138,12 +139,12 @@ public class EC2ComputeService implements ComputeService { logger.debug(">> creating keyPair name(%s)", name); KeyPair keyPair; try { - keyPair = ec2Client.createKeyPair(name); + keyPair = ec2Client.getKeyPairServices().createKeyPair(name); logger.debug("<< created keyPair(%s)", keyPair.getKeyName()); } catch (AWSResponseException e) { if (e.getError().getCode().equals("InvalidKeyPair.Duplicate")) { - keyPair = ec2Client.describeKeyPairs(name).last(); + keyPair = ec2Client.getKeyPairServices().describeKeyPairs(name).last(); logger.debug("<< reused keyPair(%s)", keyPair.getKeyName()); } else { @@ -157,12 +158,13 @@ public class EC2ComputeService implements ComputeService { logger.debug(">> creating securityGroup name(%s)", name); try { - ec2Client.createSecurityGroup(name, name); + ec2Client.getSecurityGroupServices().createSecurityGroup(name, name); logger.debug("<< created securityGroup(%s)", name); logger.debug(">> authorizing securityGroup name(%s) ports(%s)", name, ImmutableSet .of(ports)); for (int port : ports) { - ec2Client.authorizeSecurityGroupIngress(name, IpProtocol.TCP, port, port, "0.0.0.0/0"); + ec2Client.getSecurityGroupServices().authorizeSecurityGroupIngress(name, + IpProtocol.TCP, port, port, "0.0.0.0/0"); } logger.debug("<< authorized securityGroup(%s)", name); } catch (AWSResponseException e) { @@ -203,7 +205,7 @@ public class EC2ComputeService implements ComputeService { private RunningInstance getRunningInstance(String id) { RunningInstance runningInstance = Iterables.getLast(Iterables.getLast( - ec2Client.describeInstances(id)).getRunningInstances()); + ec2Client.getInstanceServices().describeInstances(id)).getRunningInstances()); return runningInstance; } @@ -225,7 +227,7 @@ public class EC2ComputeService implements ComputeService { public SortedSet listServers() { logger.debug(">> listing servers"); SortedSet servers = Sets.newTreeSet(); - for (Reservation reservation : ec2Client.describeInstances()) { + for (Reservation reservation : ec2Client.getInstanceServices().describeInstances()) { Iterables.addAll(servers, Iterables.transform(reservation.getRunningInstances(), new Function() { @Override @@ -244,13 +246,13 @@ public class EC2ComputeService implements ComputeService { // grab the old keyname String name = runningInstance.getKeyName(); logger.debug(">> terminating instance(%s)", runningInstance.getInstanceId()); - ec2Client.terminateInstances(id); + ec2Client.getInstanceServices().terminateInstances(id); logger.debug("<< terminated instance(%s)", runningInstance.getInstanceId()); logger.debug(">> deleting keyPair(%s)", name); - ec2Client.deleteKeyPair(name); + ec2Client.getKeyPairServices().deleteKeyPair(name); logger.debug("<< deleted keyPair(%s)", name); logger.debug(">> deleting securityGroup(%s)", name); - ec2Client.deleteSecurityGroup(name); + ec2Client.getSecurityGroupServices().deleteSecurityGroup(name); logger.debug("<< deleted securityGroup(%s)", name); } } \ No newline at end of file diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/config/EC2RestClientModule.java b/aws/core/src/main/java/org/jclouds/aws/ec2/config/EC2RestClientModule.java index bb06cca8ba..cee788de44 100755 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/config/EC2RestClientModule.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/config/EC2RestClientModule.java @@ -31,12 +31,20 @@ import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.aws.ec2.EC2; -import org.jclouds.aws.ec2.EC2AsyncClient; -import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.aws.ec2.filters.FormSigner; import org.jclouds.aws.ec2.predicates.InstanceStateRunning; import org.jclouds.aws.ec2.reference.EC2Constants; +import org.jclouds.aws.ec2.services.AMIAsyncClient; +import org.jclouds.aws.ec2.services.AMIClient; +import org.jclouds.aws.ec2.services.ElasticIPAddressAsyncClient; +import org.jclouds.aws.ec2.services.ElasticIPAddressClient; +import org.jclouds.aws.ec2.services.InstanceAsyncClient; +import org.jclouds.aws.ec2.services.InstanceClient; +import org.jclouds.aws.ec2.services.KeyPairAsyncClient; +import org.jclouds.aws.ec2.services.KeyPairClient; +import org.jclouds.aws.ec2.services.SecurityGroupAsyncClient; +import org.jclouds.aws.ec2.services.SecurityGroupClient; import org.jclouds.aws.handlers.AWSClientErrorRetryHandler; import org.jclouds.aws.handlers.AWSRedirectionRetryHandler; import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent; @@ -94,17 +102,67 @@ public class EC2RestClientModule extends AbstractModule { @Provides @Singleton - protected EC2AsyncClient provideAsyncClient(RestClientFactory factory) { - return factory.create(EC2AsyncClient.class); + protected AMIAsyncClient provideAMIAsyncClient(RestClientFactory factory) { + return factory.create(AMIAsyncClient.class); } @Provides @Singleton - public EC2Client provideClient(EC2AsyncClient client) throws IllegalArgumentException, + public AMIClient provideAMIClient(AMIAsyncClient client) throws IllegalArgumentException, SecurityException, NoSuchMethodException { - return SyncProxy.create(EC2Client.class, client); + return SyncProxy.create(AMIClient.class, client); } + + @Provides + @Singleton + protected ElasticIPAddressAsyncClient provideElasticIPAddressAsyncClient(RestClientFactory factory) { + return factory.create( ElasticIPAddressAsyncClient.class); + } + + @Provides + @Singleton + public ElasticIPAddressClient provideElasticIPAddressClient( ElasticIPAddressAsyncClient client) throws IllegalArgumentException, + SecurityException, NoSuchMethodException { + return SyncProxy.create( ElasticIPAddressClient.class, client); + } + + @Provides + @Singleton + protected InstanceAsyncClient provideInstanceAsyncClient(RestClientFactory factory) { + return factory.create(InstanceAsyncClient.class); + } + + @Provides + @Singleton + public InstanceClient provideInstanceClient(InstanceAsyncClient client) throws IllegalArgumentException, + SecurityException, NoSuchMethodException { + return SyncProxy.create(InstanceClient.class, client); + } + @Provides + @Singleton + protected KeyPairAsyncClient provideKeyPairAsyncClient(RestClientFactory factory) { + return factory.create(KeyPairAsyncClient.class); + } + + @Provides + @Singleton + public KeyPairClient provideKeyPairClient(KeyPairAsyncClient client) throws IllegalArgumentException, + SecurityException, NoSuchMethodException { + return SyncProxy.create(KeyPairClient.class, client); + } + @Provides + @Singleton + protected SecurityGroupAsyncClient provideSecurityGroupAsyncClient(RestClientFactory factory) { + return factory.create(SecurityGroupAsyncClient.class); + } + + @Provides + @Singleton + public SecurityGroupClient provideSecurityGroupClient(SecurityGroupAsyncClient client) throws IllegalArgumentException, + SecurityException, NoSuchMethodException { + return SyncProxy.create(SecurityGroupClient.class, client); + } @Provides @Singleton @EC2 diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/internal/EC2AsyncClientImpl.java b/aws/core/src/main/java/org/jclouds/aws/ec2/internal/EC2AsyncClientImpl.java new file mode 100644 index 0000000000..4a790062fa --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/internal/EC2AsyncClientImpl.java @@ -0,0 +1,99 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.internal; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.aws.ec2.EC2AsyncClient; +import org.jclouds.aws.ec2.services.AMIAsyncClient; +import org.jclouds.aws.ec2.services.ElasticIPAddressAsyncClient; +import org.jclouds.aws.ec2.services.InstanceAsyncClient; +import org.jclouds.aws.ec2.services.KeyPairAsyncClient; +import org.jclouds.aws.ec2.services.SecurityGroupAsyncClient; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class EC2AsyncClientImpl implements EC2AsyncClient { + + private final AMIAsyncClient AMIServices; + private final ElasticIPAddressAsyncClient elasticIPAddressServices; + private final InstanceAsyncClient instanceServices; + private final KeyPairAsyncClient keyPairServices; + private final SecurityGroupAsyncClient securityGroupServices; + + @Inject + public EC2AsyncClientImpl(AMIAsyncClient AMIServices, + ElasticIPAddressAsyncClient elasticIPAddressServices, + InstanceAsyncClient instanceServices, KeyPairAsyncClient keyPairServices, + SecurityGroupAsyncClient securityGroupServices) { + this.AMIServices = checkNotNull(AMIServices, "AMIServices"); + this.elasticIPAddressServices = checkNotNull(elasticIPAddressServices, + "elasticIPAddressServices"); + this.instanceServices = checkNotNull(instanceServices, "instanceServices"); + this.keyPairServices = checkNotNull(keyPairServices, "keyPairServices"); + this.securityGroupServices = checkNotNull(securityGroupServices, "securityGroupServices"); + } + + /** + * {@inheritDoc} + */ + public AMIAsyncClient getAMIServices() { + return AMIServices; + } + + /** + * {@inheritDoc} + */ + public ElasticIPAddressAsyncClient getElasticIPAddressServices() { + return elasticIPAddressServices; + } + + /** + * {@inheritDoc} + */ + public InstanceAsyncClient getInstanceServices() { + return instanceServices; + } + + /** + * {@inheritDoc} + */ + public KeyPairAsyncClient getKeyPairServices() { + return keyPairServices; + } + + /** + * {@inheritDoc} + */ + public SecurityGroupAsyncClient getSecurityGroupServices() { + return securityGroupServices; + } + +} diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/internal/EC2ClientImpl.java b/aws/core/src/main/java/org/jclouds/aws/ec2/internal/EC2ClientImpl.java new file mode 100644 index 0000000000..afbd392d2b --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/internal/EC2ClientImpl.java @@ -0,0 +1,98 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.internal; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.aws.ec2.EC2Client; +import org.jclouds.aws.ec2.services.AMIClient; +import org.jclouds.aws.ec2.services.ElasticIPAddressClient; +import org.jclouds.aws.ec2.services.InstanceClient; +import org.jclouds.aws.ec2.services.KeyPairClient; +import org.jclouds.aws.ec2.services.SecurityGroupClient; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class EC2ClientImpl implements EC2Client { + + private final AMIClient AMIServices; + private final ElasticIPAddressClient elasticIPAddressServices; + private final InstanceClient instanceServices; + private final KeyPairClient keyPairServices; + private final SecurityGroupClient securityGroupServices; + + @Inject + public EC2ClientImpl(AMIClient AMIServices, ElasticIPAddressClient elasticIPAddressServices, + InstanceClient instanceServices, KeyPairClient keyPairServices, + SecurityGroupClient securityGroupServices) { + this.AMIServices = checkNotNull(AMIServices, "AMIServices"); + this.elasticIPAddressServices = checkNotNull(elasticIPAddressServices, + "elasticIPAddressServices"); + this.instanceServices = checkNotNull(instanceServices, "instanceServices"); + this.keyPairServices = checkNotNull(keyPairServices, "keyPairServices"); + this.securityGroupServices = checkNotNull(securityGroupServices, "securityGroupServices"); + } + + /** + * {@inheritDoc} + */ + public AMIClient getAMIServices() { + return AMIServices; + } + + /** + * {@inheritDoc} + */ + public ElasticIPAddressClient getElasticIPAddressServices() { + return elasticIPAddressServices; + } + + /** + * {@inheritDoc} + */ + public InstanceClient getInstanceServices() { + return instanceServices; + } + + /** + * {@inheritDoc} + */ + public KeyPairClient getKeyPairServices() { + return keyPairServices; + } + + /** + * {@inheritDoc} + */ + public SecurityGroupClient getSecurityGroupServices() { + return securityGroupServices; + } + +} diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/predicates/InstanceStateRunning.java b/aws/core/src/main/java/org/jclouds/aws/ec2/predicates/InstanceStateRunning.java index e3a2469657..317052e769 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/predicates/InstanceStateRunning.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/predicates/InstanceStateRunning.java @@ -3,9 +3,9 @@ package org.jclouds.aws.ec2.predicates; import javax.annotation.Resource; import javax.inject.Singleton; -import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.domain.InstanceState; import org.jclouds.aws.ec2.domain.RunningInstance; +import org.jclouds.aws.ec2.services.InstanceClient; import org.jclouds.logging.Logger; import com.google.common.base.Predicate; @@ -21,13 +21,13 @@ import com.google.inject.Inject; @Singleton public class InstanceStateRunning implements Predicate { - private final EC2Client client; + private final InstanceClient client; @Resource protected Logger logger = Logger.NULL; @Inject - public InstanceStateRunning(EC2Client client) { + public InstanceStateRunning(InstanceClient client) { this.client = client; } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIAsyncClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIAsyncClient.java new file mode 100644 index 0000000000..33eac07db9 --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIAsyncClient.java @@ -0,0 +1,77 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.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.concurrent.Future; + +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.domain.Image; +import org.jclouds.aws.ec2.domain.ImageAttribute; +import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.options.DescribeImagesOptions; +import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandler; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.FormParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; + +/** + * Provides access to EC2 via their REST API. + *

+ * + * @author Adrian Cole + */ +@Endpoint(EC2.class) +@RequestFilters(FormSigner.class) +@FormParams(keys = VERSION, values = "2009-11-30") +@VirtualHost +public interface AMIAsyncClient { + + /** + * @see BaseEC2Client#describeImages + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DescribeImages") + @XMLResponseParser(DescribeImagesResponseHandler.class) + Future> describeImages(DescribeImagesOptions... options); + + /** + * @see BaseEC2Client#describeImages + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DescribeImageAttribute") + Future describeImageAttribute(@FormParam("ImageId") String imageId, + @FormParam("Attribute") ImageAttribute attribute); +} diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIClient.java new file mode 100644 index 0000000000..c020e41ccd --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIClient.java @@ -0,0 +1,75 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.services; + +import java.util.SortedSet; +import java.util.concurrent.TimeUnit; + +import org.jclouds.aws.ec2.domain.Image; +import org.jclouds.aws.ec2.domain.ImageAttribute; +import org.jclouds.aws.ec2.options.DescribeImagesOptions; +import org.jclouds.concurrent.Timeout; + +/** + * Provides access to EC2 via their REST API. + *

+ * + * @author Adrian Cole + */ +@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) +public interface AMIClient { + + /** + * Returns information about AMIs, AKIs, and ARIs. This includes image type, product codes, + * architecture, and kernel and RAM disk IDs. Images available to you include p ublic images, + * private images that you own, and private images owned by other users for which you have + * explicit launch permissions. + * + * @see #describeInstances + * @see #describeImageAttribute + * @see + * @see DescribeImagesOptions + */ + @Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) + SortedSet describeImages(DescribeImagesOptions... options); + + /** + * Returns information about an attribute of an AMI. Only one attribute can be specified per + * call. + * + * @param imageId + * The ID of the AMI for which an attribute will be described + * @param attribute + * the attribute to describe + * @see #describeImages + * @see #modifyImageAttribute + * @see #resetImageAttribute + * @see + * @see DescribeImagesOptions + */ + String describeImageAttribute(String imageId, ImageAttribute attribute); + +} diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/ElasticIPAddressAsyncClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/ElasticIPAddressAsyncClient.java new file mode 100644 index 0000000000..2f1c20befa --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/ElasticIPAddressAsyncClient.java @@ -0,0 +1,111 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.services; + +import static org.jclouds.aws.ec2.reference.EC2Parameters.ACTION; +import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION; + +import java.net.InetAddress; +import java.util.SortedSet; +import java.util.concurrent.Future; + +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.BindInetAddressesToIndexedFormParams; +import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair; +import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.xml.AllocateAddressResponseHandler; +import org.jclouds.aws.ec2.xml.DescribeAddressesResponseHandler; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.FormParams; +import org.jclouds.rest.annotations.ParamParser; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.rest.functions.InetAddressToHostAddress; + +/** + * Provides access to EC2 Elastic IP Addresses via REST API. + *

+ * + * @author Adrian Cole + */ +@Endpoint(EC2.class) +@RequestFilters(FormSigner.class) +@FormParams(keys = VERSION, values = "2009-11-30") +@VirtualHost +public interface ElasticIPAddressAsyncClient { + + /** + * @see BaseEC2Client#allocateAddress + */ + @POST + @Path("/") + @XMLResponseParser(AllocateAddressResponseHandler.class) + @FormParams(keys = ACTION, values = "AllocateAddress") + Future allocateAddress(); + + /** + * @see BaseEC2Client#associateAddress + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "AssociateAddress") + Future associateAddress( + @FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp, + @FormParam("InstanceId") String instanceId); + + /** + * @see BaseEC2Client#disassociateAddress + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DisassociateAddress") + Future disassociateAddress( + @FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp); + + /** + * @see BaseEC2Client#releaseAddress + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "ReleaseAddress") + Future releaseAddress( + @FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp); + + /** + * @see BaseEC2Client#describeAddresses + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DescribeAddresses") + @XMLResponseParser(DescribeAddressesResponseHandler.class) + Future> describeAddresses( + @BinderParam(BindInetAddressesToIndexedFormParams.class) InetAddress... publicIps); + +} diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/ElasticIPAddressClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/ElasticIPAddressClient.java new file mode 100644 index 0000000000..94f4afac7f --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/ElasticIPAddressClient.java @@ -0,0 +1,116 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.services; + +import java.net.InetAddress; +import java.util.SortedSet; +import java.util.concurrent.TimeUnit; + +import org.jclouds.aws.AWSResponseException; +import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair; +import org.jclouds.concurrent.Timeout; + +/** + * Provides access to EC2 via their REST API. + *

+ * + * @author Adrian Cole + */ +@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) +public interface ElasticIPAddressClient { + + /** + * Acquires an elastic IP address for use with your account. + * + * @see #describeAddresses + * @see #releaseAddress + * @see #associateAddress + * @see #disassociateAddress + * @see + */ + SortedSet describeAddresses(InetAddress... publicIps); + +} \ No newline at end of file diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceAsyncClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceAsyncClient.java new file mode 100644 index 0000000000..2d62719a41 --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceAsyncClient.java @@ -0,0 +1,96 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.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.concurrent.Future; + +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.BindInstanceIdsToIndexedFormParams; +import org.jclouds.aws.ec2.domain.Reservation; +import org.jclouds.aws.ec2.domain.TerminatedInstance; +import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.options.RunInstancesOptions; +import org.jclouds.aws.ec2.xml.DescribeInstancesResponseHandler; +import org.jclouds.aws.ec2.xml.RunInstancesResponseHandler; +import org.jclouds.aws.ec2.xml.TerminateInstancesResponseHandler; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.FormParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; + +/** + * Provides access to EC2 via their REST API. + *

+ * + * @author Adrian Cole + */ +@Endpoint(EC2.class) +@RequestFilters(FormSigner.class) +@FormParams(keys = VERSION, values = "2009-11-30") +@VirtualHost +public interface InstanceAsyncClient { + + /** + * @see BaseEC2Client#describeInstances + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DescribeInstances") + @XMLResponseParser(DescribeInstancesResponseHandler.class) + Future> describeInstances( + @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds); + + /** + * @see BaseEC2Client#runInstances + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "RunInstances") + @XMLResponseParser(RunInstancesResponseHandler.class) + Future runInstances(@FormParam("ImageId") String imageId, + @FormParam("MinCount") int minCount, @FormParam("MaxCount") int maxCount, + RunInstancesOptions... options); + + /** + * @see BaseEC2Client#terminateInstances + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "TerminateInstances") + @XMLResponseParser(TerminateInstancesResponseHandler.class) + Future> terminateInstances( + @FormParam("InstanceId.0") String instanceId, + @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds); + +} diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceClient.java new file mode 100644 index 0000000000..5d412718d5 --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceClient.java @@ -0,0 +1,143 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.services; + +import java.util.SortedSet; +import java.util.concurrent.TimeUnit; + +import org.jclouds.aws.ec2.domain.Reservation; +import org.jclouds.aws.ec2.domain.TerminatedInstance; +import org.jclouds.aws.ec2.options.RunInstancesOptions; +import org.jclouds.concurrent.Timeout; + +/** + * Provides access to EC2 via their REST API. + *

+ * + * @author Adrian Cole + */ +@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) +public interface InstanceClient { + + /** + * Returns information about instances that you own. + *

+ * + * If you specify one or more instance IDs, Amazon EC2 returns information for those instances. + * If you do not specify instance IDs, Amazon EC2 returns information for all relevant instances. + * If you specify an invalid instance ID, a fault is returned. If you specify an instance that + * you do not own, it will not be included in the returned results. + *

+ * Recently terminated instances might appear in the returned results.This interval is usually + * less than one hour. + * + * @see #runInstances + * @see #terminateInstances + * @see + */ + SortedSet describeInstances(String... instanceIds); + + /** + * Launches a specified number of instances of an AMI for which you have permissions. + *

+ * + * If Amazon EC2 cannot launch the minimum number AMIs you request, no instances will be + * launched. If there is insufficient capacity to launch the maximum number of AMIs you request, + * Amazon EC2 launches the minimum number specified for each AMI and allocate the remaining + * available instances using round robin. + *

+ *

Security Groups

+ * Note: Every instance is launched in a security group (created using the + * CreateSecurityGroup operation. + *

Key Pair

+ * You can provide an optional key pair ID for each image in the launch request (created using + * the CreateKeyPair operation). All instances that are created from images that use this key + * pair will have access to the associated public key at boot. You can use this key to provide + * secure access to an instance of an image on a per-instance basis. Amazon EC2 public images use + * this feature to provide secure access without passwords. + *

+ * Note: Launching public images without a key pair ID will leave them inaccessible. + *

+ * The public key material is made available to the instance at boot time by placing it in the + * openssh_id.pub file on a logical device that is exposed to the instance as /dev/sda2 (the + * instance store). The format of this file is suitable for use as an entry within + * ~/.ssh/authorized_keys (the OpenSSH format). This can be done at boot (e.g., as part of + * rc.local) allowing for secure access without passwords. + *

User Data

+ * Optional user data can be provided in the launch request. All instances that collectively + * comprise the launch request have access to this data. For more information, go the Amazon + * Elastic Compute Cloud Developer Guide. + *

Product Codes

+ * + * Note: If any of the AMIs have a product code attached for which the user has not + * subscribed, the RunInstances call will fail. + *

Kernel

+ * + * Important: We strongly recommend using the 2.6.18 Xen stock kernel with High-CPU and + * High-Memory instances. Although the default Amazon EC2 kernels will work, the new kernels + * provide greater stability and performance for these instance types. For more information about + * kernels, go the Amazon Elastic Compute Cloud Developer Guide. + * + * @param imageId + * Unique ID of a machine image, returned by a call to + * @param minCount + * Minimum number of instances to launch. If the value is more than Amazon EC2 can + * launch, no instances a re launched at all. Constraints: Between 1 and the maximum + * number allowed for your account (default: 20). + * @param maxCount + * Maximum number of instances to launch. If the value is more than Amazon EC2 can + * launch, the largest possible number above minCount will be launched instead. + * Constraints: Between 1 and the maximum number allowed for your account (default: + * 20). + * @see #describeInstances + * @see #terminateInstances + * @see #authorizeSecurityGroupIngress + * @see #revokeSecurityGroupIngress + * @see #describeSecurityGroups + * @see #createSecurityGroup + * @see #createKeyPair + * @see
+ * @see RunInstancesOptions + */ + Reservation runInstances(String imageId, int minCount, int maxCount, + RunInstancesOptions... options); + + /** + * Shuts down one or more instances. This operation is idempotent; if you terminate an instance + * more than once, each call will succeed. + *

+ * Terminated instances will remain visible after termination (approximately one hour). + * + * @param instanceIds + * Instance ID to terminate. + * @see #describeInstances + * @see + */ + SortedSet terminateInstances(String instanceId, String... instanceIds); + +} diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/KeyPairAsyncClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/KeyPairAsyncClient.java new file mode 100644 index 0000000000..5aec53ac40 --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/KeyPairAsyncClient.java @@ -0,0 +1,88 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.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.concurrent.Future; + +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.BindKeyNameToIndexedFormParams; +import org.jclouds.aws.ec2.domain.KeyPair; +import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.xml.DescribeKeyPairsResponseHandler; +import org.jclouds.aws.ec2.xml.KeyPairResponseHandler; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.FormParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; + +/** + * Provides access to EC2 via their REST API. + *

+ * + * @author Adrian Cole + */ +@Endpoint(EC2.class) +@RequestFilters(FormSigner.class) +@FormParams(keys = VERSION, values = "2009-11-30") +@VirtualHost +public interface KeyPairAsyncClient { + + /** + * @see BaseEC2Client#createKeyPair + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "CreateKeyPair") + @XMLResponseParser(KeyPairResponseHandler.class) + Future createKeyPair(@FormParam("KeyName") String keyName); + + /** + * @see BaseEC2Client#describeKeyPairs + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DescribeKeyPairs") + @XMLResponseParser(DescribeKeyPairsResponseHandler.class) + Future> describeKeyPairs( + @BinderParam(BindKeyNameToIndexedFormParams.class) String... keyPairNames); + + /** + * @see BaseEC2Client#deleteKeyPair + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DeleteKeyPair") + Future deleteKeyPair(@FormParam("KeyName") String keyName); + +} diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/KeyPairClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/KeyPairClient.java new file mode 100644 index 0000000000..e30f60ca6d --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/KeyPairClient.java @@ -0,0 +1,85 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.services; + +import java.util.SortedSet; +import java.util.concurrent.TimeUnit; + +import org.jclouds.aws.ec2.domain.KeyPair; +import org.jclouds.concurrent.Timeout; + +/** + * Provides access to EC2 via their REST API. + *

+ * + * @author Adrian Cole + */ +@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) +public interface KeyPairClient { + + /** + * Creates a new 2048-bit RSA key pair with the specified name. The public key is stored by + * Amazon EC2 and the private key is displayed on the console. The private key is returned as an + * unencrypted PEM encoded PKCS#8 private key. If a key with the specified name already exists, + * Amazon EC2 returns an error. + * + * @see #runInstances + * @see #describeKeyPairs + * @see #deleteKeyPair + * + * @see + */ + KeyPair createKeyPair(String keyName); + + /** + * Returns information about key pairs available to you. If you specify key pairs, information + * about those key pairs is returned. Otherwise, information for all registered key pairs is + * returned. + * + * @param keyPairNames + * Key pairs to describe. + * @see #runInstances + * @see #describeAvailabilityZones + * @see + */ + SortedSet describeKeyPairs(String... keyPairNames); + + /** + * Deletes the specified key pair, by removing the public key from Amazon EC2. You must own the + * key pair + * + * @see #describeKeyPairs + * @see #createKeyPair + * + * @see + */ + + void deleteKeyPair(String keyName); + +} diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/SecurityGroupAsyncClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/SecurityGroupAsyncClient.java new file mode 100644 index 0000000000..1c495baea1 --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/SecurityGroupAsyncClient.java @@ -0,0 +1,132 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.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.concurrent.Future; + +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.BindGroupNameToIndexedFormParams; +import org.jclouds.aws.ec2.binders.BindUserIdGroupPairToSourceSecurityGroupFormParams; +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.filters.FormSigner; +import org.jclouds.aws.ec2.functions.ReturnVoidOnGroupNotFound; +import org.jclouds.aws.ec2.xml.DescribeSecurityGroupsResponseHandler; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.FormParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; + +/** + * Provides access to EC2 via their REST API. + *

+ * + * @author Adrian Cole + */ +@Endpoint(EC2.class) +@RequestFilters(FormSigner.class) +@FormParams(keys = VERSION, values = "2009-11-30") +@VirtualHost +public interface SecurityGroupAsyncClient { + + /** + * @see BaseEC2Client#createSecurityGroup + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "CreateSecurityGroup") + Future createSecurityGroup(@FormParam("GroupName") String name, + @FormParam("GroupDescription") String description); + + /** + * @see BaseEC2Client#deleteSecurityGroup + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DeleteSecurityGroup") + @ExceptionParser(ReturnVoidOnGroupNotFound.class) + Future deleteSecurityGroup(@FormParam("GroupName") String name); + + /** + * @see BaseEC2Client#describeSecurityGroups + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DescribeSecurityGroups") + @XMLResponseParser(DescribeSecurityGroupsResponseHandler.class) + Future> describeSecurityGroups( + @BinderParam(BindGroupNameToIndexedFormParams.class) String... securityGroupNames); + + /** + * @see BaseEC2Client#authorizeSecurityGroupIngress(String,UserIdGroupPair) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress") + Future authorizeSecurityGroupIngress( + @FormParam("GroupName") String groupName, + @BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup); + + /** + * @see BaseEC2Client#authorizeSecurityGroupIngress(String,IpProtocol,int,int,String) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress") + Future authorizeSecurityGroupIngress(@FormParam("GroupName") String groupName, + @FormParam("IpProtocol") IpProtocol ipProtocol, @FormParam("FromPort") int fromPort, + @FormParam("ToPort") int toPort, @FormParam("CidrIp") String cidrIp); + + /** + * @see BaseEC2Client#revokeSecurityGroupIngress(String,UserIdGroupPair) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress") + Future revokeSecurityGroupIngress( + @FormParam("GroupName") String groupName, + @BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup); + + /** + * @see BaseEC2Client#revokeSecurityGroupIngress(String,IpProtocol,int,int,String) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress") + Future revokeSecurityGroupIngress(@FormParam("GroupName") String groupName, + @FormParam("IpProtocol") IpProtocol ipProtocol, @FormParam("FromPort") int fromPort, + @FormParam("ToPort") int toPort, @FormParam("CidrIp") String cidrIp); +} diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/SecurityGroupClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/SecurityGroupClient.java new file mode 100644 index 0000000000..47dc849bf4 --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/SecurityGroupClient.java @@ -0,0 +1,205 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.services; + +import java.util.SortedSet; +import java.util.concurrent.TimeUnit; + +import org.jclouds.aws.ec2.domain.IpProtocol; +import org.jclouds.aws.ec2.domain.SecurityGroup; +import org.jclouds.aws.ec2.domain.UserIdGroupPair; +import org.jclouds.concurrent.Timeout; + +/** + * Provides access to EC2 via their REST API. + *

+ * + * @author Adrian Cole + */ +@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) +public interface SecurityGroupClient { + + /** + * Creates a new security group. Group names must be unique per account. + * + * @param name + * Name of the security group. Accepts alphanumeric characters, spaces, dashes, and + * underscores. + * @param description + * Description of the group. This is informational only. If the description contains + * spaces, you must enc lose it in single quotes (') or URL-encode it. Accepts + * alphanumeric characters, spaces, dashes, and underscores. + * @see #runInstances + * @see #describeSecurityGroups + * @see #authorizeSecurityGroupIngress + * @see #revokeSecurityGroupIngress + * @see #deleteSecurityGroup + * + * @see + */ + void createSecurityGroup(String name, String description); + + /** + * Deletes a security group that you own. + * + * @param name + * Name of the security group to delete. + * + * @see #describeSecurityGroups + * @see #authorizeSecurityGroupIngress + * @see #revokeSecurityGroupIngress + * @see #createSecurityGroup + * + * @see + */ + void deleteSecurityGroup(String name); + + /** + * Returns information about security groups that you own. + * + * @param securityGroupNames + * Name of the security groups + * + * @see #createSecurityGroup + * @see #authorizeSecurityGroupIngress + * @see #revokeSecurityGroupIngress + * @see #deleteSecurityGroup + * + * @see + */ + SortedSet describeSecurityGroups(String... securityGroupNames); + + /** + * + * Adds permissions to a security group based on another group. + * + * @param groupName + * Name of the group to modify. The name must be valid and belong to the account + * @param sourceSecurityGroup + * group to associate with this group. + * + * @see #createSecurityGroup + * @see #describeSecurityGroups + * @see #revokeSecurityGroupIngress + * @see #deleteSecurityGroup + * + * @see + * Permissions are specified by the IP protocol (TCP, UDP or ICMP), the source of the request (by + * IP range or an Amazon EC2 user-group pair), the source and destination port ranges (for TCP + * and UDP), and the ICMP codes and types (for ICMP). When authorizing ICMP, -1 can be used as a + * wildcard in the type and code fields. Permission changes are propagated to instances within + * the security group as quickly as possible. However, depending on the number of instances, a + * small delay might occur. + * + * @param groupName + * Name of the group to modify. The name must be valid and belong to the account + * @param ipProtocol + * IP protocol. + * @param fromPort + * Start of port range for the TCP and UDP protocols, or an ICMP type number. An ICMP + * type number of -1 indicates a wildcard (i.e., any ICMP type number). + * @param toPort + * End of port range for the TCP and UDP protocols, or an ICMP code. An ICMP code of -1 + * indicates a wildcard (i.e., any ICMP code). + * @param cidrIp + * CIDR range. + * + * @see #createSecurityGroup + * @see #describeSecurityGroups + * @see #revokeSecurityGroupIngress + * @see #deleteSecurityGroup + * + * @see + * Permissions are specified by IP protocol (TCP, UDP, or ICMP), the source of the request (by IP + * range or an Amazon EC2 user-group pair), the source and destination port ranges (for TCP and + * UDP), and the ICMP codes and types (for ICMP). + * + * Permission changes are quickly propagated to instances within the security group. However, + * depending on the number of instances in the group, a small delay is might occur. + * + * @param groupName + * Name of the group to modify. The name must be valid and belong to the account + * @param ipProtocol + * IP protocol. + * @param fromPort + * Start of port range for the TCP and UDP protocols, or an ICMP type number. An ICMP + * type number of -1 indicates a wildcard (i.e., any ICMP type number). + * @param toPort + * End of port range for the TCP and UDP protocols, or an ICMP code. An ICMP code of -1 + * indicates a wildcard (i.e., any ICMP code). + * @param cidrIp + * CIDR range. + * + * @see #createSecurityGroup + * @see #describeSecurityGroups + * @see #authorizeSecurityGroupIngress + * @see #deleteSecurityGroup + * + * @see allResults = client.describeImages(); + SortedSet allResults = client.getAMIServices().describeImages(); assertNotNull(allResults); assert allResults.size() >= 2 : allResults.size(); Iterator iterator = allResults.iterator(); String id1 = iterator.next().getImageId(); String id2 = iterator.next().getImageId(); - SortedSet twoResults = client.describeImages(imageIds(id1, id2)); + SortedSet twoResults = client.getAMIServices().describeImages(imageIds(id1, id2)); assertNotNull(twoResults); assertEquals(twoResults.size(), 2); iterator = twoResults.iterator(); @@ -87,11 +87,13 @@ public class EC2ClientLiveTest { @Test void testDescribeAddresses() { - SortedSet allResults = client.describeAddresses(); + SortedSet allResults = client.getElasticIPAddressServices() + .describeAddresses(); assertNotNull(allResults); if (allResults.size() >= 1) { PublicIpInstanceIdPair pair = allResults.last(); - SortedSet result = client.describeAddresses(pair.getPublicIp()); + SortedSet result = client.getElasticIPAddressServices() + .describeAddresses(pair.getPublicIp()); assertNotNull(result); PublicIpInstanceIdPair compare = result.last(); assertEquals(compare, pair); @@ -101,31 +103,38 @@ public class EC2ClientLiveTest { @Test(dependsOnMethods = "testDescribeImages", enabled = false) void testDescribeImageAttribute() throws InterruptedException, ExecutionException, TimeoutException { - SortedSet oneResult = client.describeImages(imageIds(imageId)); + SortedSet oneResult = client.getAMIServices().describeImages(imageIds(imageId)); @SuppressWarnings("unused") Image expects = oneResult.last(); - System.out.println(client.describeImageAttribute(imageId, ImageAttribute.PRODUCT_CODES)); + System.out.println(client.getAMIServices().describeImageAttribute(imageId, + ImageAttribute.PRODUCT_CODES)); - System.out.println(client.describeImageAttribute(imageId, ImageAttribute.PRODUCT_CODES)); - System.out.println(client.describeImageAttribute(imageId, ImageAttribute.RAMDISK)); - System.out.println(client.describeImageAttribute(imageId, ImageAttribute.KERNEL)); - System.out.println(client.describeImageAttribute(imageId, ImageAttribute.PLATFORM)); - System.out.println(client.describeImageAttribute(imageId, ImageAttribute.LAUNCH_PERMISSION)); - System.out.println(client - .describeImageAttribute(imageId, ImageAttribute.BLOCK_DEVICE_MAPPING)); + System.out.println(client.getAMIServices().describeImageAttribute(imageId, + ImageAttribute.PRODUCT_CODES)); + System.out.println(client.getAMIServices().describeImageAttribute(imageId, + ImageAttribute.RAMDISK)); + System.out.println(client.getAMIServices().describeImageAttribute(imageId, + ImageAttribute.KERNEL)); + System.out.println(client.getAMIServices().describeImageAttribute(imageId, + ImageAttribute.PLATFORM)); + System.out.println(client.getAMIServices().describeImageAttribute(imageId, + ImageAttribute.LAUNCH_PERMISSION)); + System.out.println(client.getAMIServices().describeImageAttribute(imageId, + ImageAttribute.BLOCK_DEVICE_MAPPING)); } @Test void testDescribeInstances() { - SortedSet allResults = client.describeInstances(); + SortedSet allResults = client.getInstanceServices().describeInstances(); assertNotNull(allResults); assert allResults.size() >= 0 : allResults.size(); if (allResults.size() >= 2) { Iterator iterator = allResults.iterator(); String id1 = iterator.next().getRunningInstances().first().getInstanceId(); String id2 = iterator.next().getRunningInstances().first().getInstanceId(); - SortedSet twoResults = client.describeInstances(id1, id2); + SortedSet twoResults = client.getInstanceServices().describeInstances(id1, + id2); assertNotNull(twoResults); assertEquals(twoResults.size(), 2); iterator = allResults.iterator(); @@ -136,14 +145,14 @@ public class EC2ClientLiveTest { @Test void testDescribeKeyPairs() { - SortedSet allResults = client.describeKeyPairs(); + SortedSet allResults = client.getKeyPairServices().describeKeyPairs(); assertNotNull(allResults); assert allResults.size() >= 0 : allResults.size(); if (allResults.size() >= 2) { Iterator iterator = allResults.iterator(); String id1 = iterator.next().getKeyName(); String id2 = iterator.next().getKeyName(); - SortedSet twoResults = client.describeKeyPairs(id1, id2); + SortedSet twoResults = client.getKeyPairServices().describeKeyPairs(id1, id2); assertNotNull(twoResults); assertEquals(twoResults.size(), 2); iterator = twoResults.iterator(); @@ -155,14 +164,16 @@ public class EC2ClientLiveTest { @Test void testDescribeSecurityGroups() throws InterruptedException, ExecutionException, TimeoutException { - SortedSet allResults = client.describeSecurityGroups(); + SortedSet allResults = client.getSecurityGroupServices() + .describeSecurityGroups(); assertNotNull(allResults); assert allResults.size() >= 0 : allResults.size(); if (allResults.size() >= 2) { Iterator iterator = allResults.iterator(); String id1 = iterator.next().getName(); String id2 = iterator.next().getName(); - SortedSet twoResults = client.describeSecurityGroups(id1, id2); + SortedSet twoResults = client.getSecurityGroupServices() + .describeSecurityGroups(id1, id2); assertNotNull(twoResults); assertEquals(twoResults.size(), 2); iterator = twoResults.iterator(); @@ -177,19 +188,19 @@ public class EC2ClientLiveTest { void testCreateKeyPair() { String keyName = PREFIX + "1"; try { - client.deleteKeyPair(keyName); + client.getKeyPairServices().deleteKeyPair(keyName); } catch (Exception e) { } - client.deleteKeyPair(keyName); + client.getKeyPairServices().deleteKeyPair(keyName); - KeyPair result = client.createKeyPair(keyName); + KeyPair result = client.getKeyPairServices().createKeyPair(keyName); assertNotNull(result); assertNotNull(result.getKeyMaterial()); assertNotNull(result.getKeyFingerprint()); assertEquals(result.getKeyName(), keyName); - SortedSet twoResults = client.describeKeyPairs(keyName); + SortedSet twoResults = client.getKeyPairServices().describeKeyPairs(keyName); assertNotNull(twoResults); assertEquals(twoResults.size(), 1); KeyPair listPair = twoResults.iterator().next(); @@ -202,13 +213,13 @@ public class EC2ClientLiveTest { String groupName = PREFIX + "1"; String groupDescription = PREFIX + "1 description"; try { - client.deleteSecurityGroup(groupName); + client.getSecurityGroupServices().deleteSecurityGroup(groupName); } catch (Exception e) { } - client.deleteSecurityGroup(groupName); + client.getSecurityGroupServices().deleteSecurityGroup(groupName); - client.createSecurityGroup(groupName, groupDescription); + client.getSecurityGroupServices().createSecurityGroup(groupName, groupDescription); verifySecurityGroup(groupName, groupDescription); } @@ -219,22 +230,25 @@ public class EC2ClientLiveTest { String groupName = PREFIX + "ingress"; try { - client.deleteSecurityGroup(groupName); + client.getSecurityGroupServices().deleteSecurityGroup(groupName); } catch (Exception e) { } - client.createSecurityGroup(groupName, groupName); - client.authorizeSecurityGroupIngress(groupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0"); + client.getSecurityGroupServices().createSecurityGroup(groupName, groupName); + client.getSecurityGroupServices().authorizeSecurityGroupIngress(groupName, IpProtocol.TCP, + 80, 80, "0.0.0.0/0"); assertEventually(new GroupHasPermission(client, groupName, new IpPermission(80, 80, Sets . newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0")))); - client.revokeSecurityGroupIngress(groupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0"); + client.getSecurityGroupServices().revokeSecurityGroupIngress(groupName, IpProtocol.TCP, 80, + 80, "0.0.0.0/0"); assertEventually(new GroupHasNoPermissions(client, groupName)); } private void verifySecurityGroup(String groupName, String description) { - SortedSet oneResult = client.describeSecurityGroups(groupName); + SortedSet oneResult = client.getSecurityGroupServices() + .describeSecurityGroups(groupName); assertNotNull(oneResult); assertEquals(oneResult.size(), 1); SecurityGroup listPair = oneResult.iterator().next(); @@ -249,36 +263,38 @@ public class EC2ClientLiveTest { String group2Name = PREFIX + "ingress2"; try { - client.deleteSecurityGroup(group1Name); + client.getSecurityGroupServices().deleteSecurityGroup(group1Name); } catch (Exception e) { } try { - client.deleteSecurityGroup(group2Name); + client.getSecurityGroupServices().deleteSecurityGroup(group2Name); } catch (Exception e) { } - client.createSecurityGroup(group1Name, group1Name); - client.createSecurityGroup(group2Name, group2Name); + client.getSecurityGroupServices().createSecurityGroup(group1Name, group1Name); + client.getSecurityGroupServices().createSecurityGroup(group2Name, group2Name); ensureGroupsExist(group1Name, group2Name); - client.authorizeSecurityGroupIngress(group1Name, IpProtocol.TCP, 80, 80, "0.0.0.0/0"); + client.getSecurityGroupServices().authorizeSecurityGroupIngress(group1Name, IpProtocol.TCP, + 80, 80, "0.0.0.0/0"); assertEventually(new GroupHasPermission(client, group2Name, new IpPermission(80, 80, Sets . newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0")))); - SortedSet oneResult = client.describeSecurityGroups(group1Name); + SortedSet oneResult = client.getSecurityGroupServices() + .describeSecurityGroups(group1Name); assertNotNull(oneResult); assertEquals(oneResult.size(), 1); SecurityGroup group = oneResult.iterator().next(); assertEquals(group.getName(), group1Name); - client.authorizeSecurityGroupIngress(group2Name, new UserIdGroupPair(group.getOwnerId(), - group1Name)); + client.getSecurityGroupServices().authorizeSecurityGroupIngress(group2Name, + new UserIdGroupPair(group.getOwnerId(), group1Name)); assertEventually(new GroupHasPermission(client, group2Name, new IpPermission(80, 80, Sets . newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0")))); - client.revokeSecurityGroupIngress(group2Name, new UserIdGroupPair(group.getOwnerId(), - group1Name)); + client.getSecurityGroupServices().revokeSecurityGroupIngress(group2Name, + new UserIdGroupPair(group.getOwnerId(), group1Name)); assertEventually(new GroupHasNoPermissions(client, group2Name)); } @@ -295,7 +311,8 @@ public class EC2ClientLiveTest { public void run() { try { - SortedSet oneResult = client.describeSecurityGroups(group); + SortedSet oneResult = client.getSecurityGroupServices() + .describeSecurityGroups(group); assertNotNull(oneResult); assertEquals(oneResult.size(), 1); SecurityGroup listPair = oneResult.iterator().next(); @@ -317,7 +334,8 @@ public class EC2ClientLiveTest { public void run() { try { - SortedSet oneResult = client.describeSecurityGroups(group); + SortedSet oneResult = client.getSecurityGroupServices() + .describeSecurityGroups(group); assertNotNull(oneResult); assertEquals(oneResult.size(), 1); SecurityGroup listPair = oneResult.iterator().next(); @@ -329,7 +347,8 @@ public class EC2ClientLiveTest { } private void ensureGroupsExist(String group1Name, String group2Name) { - SortedSet twoResults = client.describeSecurityGroups(group1Name, group2Name); + SortedSet twoResults = client.getSecurityGroupServices() + .describeSecurityGroups(group1Name, group2Name); assertNotNull(twoResults); assertEquals(twoResults.size(), 2); Iterator iterator = twoResults.iterator(); diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/EC2ClientTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/EC2ClientTest.java deleted file mode 100644 index 670fe880e9..0000000000 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/EC2ClientTest.java +++ /dev/null @@ -1,600 +0,0 @@ -/** - * - * Copyright (C) 2009 Cloud Conscious, LLC. - * - * ==================================================================== - * 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; - -import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.executableBy; -import static org.testng.Assert.assertEquals; - -import java.io.IOException; -import java.lang.reflect.Array; -import java.lang.reflect.Method; -import java.net.InetAddress; -import java.net.URI; - -import org.jclouds.aws.ec2.domain.ImageAttribute; -import org.jclouds.aws.ec2.domain.IpProtocol; -import org.jclouds.aws.ec2.domain.UserIdGroupPair; -import org.jclouds.aws.ec2.filters.FormSigner; -import org.jclouds.aws.ec2.functions.ReturnVoidOnGroupNotFound; -import org.jclouds.aws.ec2.options.DescribeImagesOptions; -import org.jclouds.aws.ec2.options.RunInstancesOptions; -import org.jclouds.aws.ec2.xml.AllocateAddressResponseHandler; -import org.jclouds.aws.ec2.xml.DescribeAddressesResponseHandler; -import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandler; -import org.jclouds.aws.ec2.xml.DescribeInstancesResponseHandler; -import org.jclouds.aws.ec2.xml.DescribeKeyPairsResponseHandler; -import org.jclouds.aws.ec2.xml.DescribeSecurityGroupsResponseHandler; -import org.jclouds.aws.ec2.xml.KeyPairResponseHandler; -import org.jclouds.aws.ec2.xml.RunInstancesResponseHandler; -import org.jclouds.aws.ec2.xml.TerminateInstancesResponseHandler; -import org.jclouds.aws.reference.AWSConstants; -import org.jclouds.date.TimeStamp; -import org.jclouds.http.functions.ParseSax; -import org.jclouds.http.functions.ReturnStringIf200; -import org.jclouds.http.functions.ReturnVoidIf2xx; -import org.jclouds.logging.Logger; -import org.jclouds.logging.Logger.LoggerFactory; -import org.jclouds.rest.RestClientTest; -import org.jclouds.rest.internal.GeneratedHttpRequest; -import org.jclouds.rest.internal.RestAnnotationProcessor; -import org.jclouds.util.Jsr330; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; - -import com.google.inject.AbstractModule; -import com.google.inject.Module; -import com.google.inject.Provides; -import com.google.inject.TypeLiteral; - -/** - * Tests behavior of {@code EC2Client} - * - * @author Adrian Cole - */ -@Test(groups = "unit", testName = "ec2.EC2ClientTest") -public class EC2ClientTest extends RestClientTest { - - public void testDescribeImages() throws SecurityException, NoSuchMethodException, IOException { - Method method = EC2AsyncClient.class.getMethod("describeImages", Array.newInstance( - DescribeImagesOptions.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 40\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=DescribeImages"); - filter.filter(httpMethod); - assertPayloadEquals( - httpMethod, - "Action=DescribeImages&Signature=wJmKTnrx5v3PSECZJjm%2BE1s8I%2FqHkVs2K1hJ6yxbpC0%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2009-08-15&AWSAccessKeyId=user"); - - assertResponseParserClassEquals(method, httpMethod, ParseSax.class); - assertSaxResponseParserClassEquals(method, DescribeImagesResponseHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testDescribeImagesOptions() throws SecurityException, NoSuchMethodException, - IOException { - Method method = EC2AsyncClient.class.getMethod("describeImages", Array.newInstance( - DescribeImagesOptions.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, executableBy( - "me").ownedBy("fred", "nancy").imageIds("1", "2")); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 107\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals( - httpMethod, - "Version=2009-08-15&Action=DescribeImages&ExecutableBy=me&Owner.1=fred&Owner.2=nancy&ImageId.1=1&ImageId.2=2"); - - assertResponseParserClassEquals(method, httpMethod, ParseSax.class); - assertSaxResponseParserClassEquals(method, DescribeImagesResponseHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testDescribeImageAttribute() throws SecurityException, NoSuchMethodException, - IOException { - Method method = EC2AsyncClient.class.getMethod("describeImageAttribute", String.class, - ImageAttribute.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "imageId", - ImageAttribute.BLOCK_DEVICE_MAPPING); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 93\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, - "Version=2009-08-15&Action=DescribeImageAttribute&ImageId=imageId&Attribute=blockDeviceMapping"); - filter.filter(httpMethod); - assertPayloadEquals( - httpMethod, - "Action=DescribeImageAttribute&Attribute=blockDeviceMapping&ImageId=imageId&Signature=IiyxXwoOmpLiPC%2BbfBdqJwE758bvbs8kXCL71FefStY%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2009-08-15&AWSAccessKeyId=user"); - - assertResponseParserClassEquals(method, httpMethod, ReturnStringIf200.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testDescribeInstances() throws SecurityException, NoSuchMethodException, IOException { - Method method = EC2AsyncClient.class.getMethod("describeInstances", Array.newInstance( - String.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method); - - 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-08-15&Action=DescribeInstances"); - - assertResponseParserClassEquals(method, httpMethod, ParseSax.class); - assertSaxResponseParserClassEquals(method, DescribeInstancesResponseHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testDescribeInstancesArgs() throws SecurityException, NoSuchMethodException, - IOException { - Method method = EC2AsyncClient.class.getMethod("describeInstances", Array.newInstance( - String.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "1", "2"); - - 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-08-15&Action=DescribeInstances&InstanceId.1=1&InstanceId.2=2"); - - assertResponseParserClassEquals(method, httpMethod, ParseSax.class); - assertSaxResponseParserClassEquals(method, DescribeInstancesResponseHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testTerminateInstances() throws SecurityException, NoSuchMethodException, - IOException { - Method method = EC2AsyncClient.class.getMethod("terminateInstances", String.class, Array - .newInstance(String.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "1", "2"); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 59\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, - "Version=2009-08-15&Action=TerminateInstances&InstanceId.0=1&InstanceId.1=2"); - - assertResponseParserClassEquals(method, httpMethod, ParseSax.class); - assertSaxResponseParserClassEquals(method, TerminateInstancesResponseHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testRunInstances() throws SecurityException, NoSuchMethodException, IOException { - Method method = EC2AsyncClient.class.getMethod("runInstances", String.class, int.class, int.class, - Array.newInstance(RunInstancesOptions.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "ami-voo", 1, 1); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 76\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, - "Version=2009-08-15&Action=RunInstances&ImageId=ami-voo&MaxCount=1&MinCount=1"); - - assertResponseParserClassEquals(method, httpMethod, ParseSax.class); - assertSaxResponseParserClassEquals(method, RunInstancesResponseHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testRunInstancesOptions() throws SecurityException, NoSuchMethodException, - IOException { - Method method = EC2AsyncClient.class.getMethod("runInstances", String.class, int.class, int.class, - Array.newInstance(RunInstancesOptions.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "ami-voo", 1, 5, - new RunInstancesOptions().withKernelId("kernelId").enableMonitoring()); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 118\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals( - httpMethod, - "Version=2009-08-15&Action=RunInstances&ImageId=ami-voo&MaxCount=5&MinCount=1&KernelId=kernelId&Monitoring.Enabled=true"); - - assertResponseParserClassEquals(method, httpMethod, ParseSax.class); - assertSaxResponseParserClassEquals(method, RunInstancesResponseHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testCreateKeyPair() throws SecurityException, NoSuchMethodException, IOException { - Method method = EC2AsyncClient.class.getMethod("createKeyPair", String.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "mykey"); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 53\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=CreateKeyPair&KeyName=mykey"); - - assertResponseParserClassEquals(method, httpMethod, ParseSax.class); - assertSaxResponseParserClassEquals(method, KeyPairResponseHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testDisassociateAddress() throws SecurityException, NoSuchMethodException, - IOException { - Method method = EC2AsyncClient.class.getMethod("disassociateAddress", InetAddress.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, InetAddress - .getByAddress(new byte[] { 127, 0, 0, 1 })); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 64\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, - "Version=2009-08-15&Action=DisassociateAddress&PublicIp=127.0.0.1"); - - assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testAssociateAddress() throws SecurityException, NoSuchMethodException, IOException { - Method method = EC2AsyncClient.class - .getMethod("associateAddress", InetAddress.class, String.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, InetAddress - .getByAddress(new byte[] { 127, 0, 0, 1 }), "me"); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 75\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, - "Version=2009-08-15&Action=AssociateAddress&PublicIp=127.0.0.1&InstanceId=me"); - - assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testReleaseAddress() throws SecurityException, NoSuchMethodException, IOException { - Method method = EC2AsyncClient.class.getMethod("releaseAddress", InetAddress.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, InetAddress - .getByAddress(new byte[] { 127, 0, 0, 1 })); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 59\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=ReleaseAddress&PublicIp=127.0.0.1"); - - assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testDescribeAddresses() throws SecurityException, NoSuchMethodException, IOException { - Method method = EC2AsyncClient.class.getMethod("describeAddresses", Array.newInstance( - InetAddress.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, InetAddress - .getByAddress(new byte[] { 127, 0, 0, 1 })); - - 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-08-15&Action=DescribeAddresses&PublicIp.1=127.0.0.1"); - - assertResponseParserClassEquals(method, httpMethod, ParseSax.class); - assertSaxResponseParserClassEquals(method, DescribeAddressesResponseHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testAllocateAddress() throws SecurityException, NoSuchMethodException, IOException { - Method method = EC2AsyncClient.class.getMethod("allocateAddress"); - GeneratedHttpRequest httpMethod = processor.createRequest(method); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 41\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=AllocateAddress"); - - assertResponseParserClassEquals(method, httpMethod, ParseSax.class); - assertSaxResponseParserClassEquals(method, AllocateAddressResponseHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testDeleteKeyPair() throws SecurityException, NoSuchMethodException, IOException { - Method method = EC2AsyncClient.class.getMethod("deleteKeyPair", String.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "mykey"); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 53\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=DeleteKeyPair&KeyName=mykey"); - - assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testDescribeKeyPairs() throws SecurityException, NoSuchMethodException, IOException { - Method method = EC2AsyncClient.class.getMethod("describeKeyPairs", Array.newInstance(String.class, - 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 42\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=DescribeKeyPairs"); - - assertResponseParserClassEquals(method, httpMethod, ParseSax.class); - assertSaxResponseParserClassEquals(method, DescribeKeyPairsResponseHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testDescribeKeyPairsArgs() throws SecurityException, NoSuchMethodException, - IOException { - Method method = EC2AsyncClient.class.getMethod("describeKeyPairs", Array.newInstance(String.class, - 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "1", "2"); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 42\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, - "Version=2009-08-15&Action=DescribeKeyPairs&KeyName.1=1&KeyName.2=2"); - - assertResponseParserClassEquals(method, httpMethod, ParseSax.class); - assertSaxResponseParserClassEquals(method, DescribeKeyPairsResponseHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testDeleteSecurityGroup() throws SecurityException, NoSuchMethodException, - IOException { - Method method = EC2AsyncClient.class.getMethod("deleteSecurityGroup", String.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "name"); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 60\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=DeleteSecurityGroup&GroupName=name"); - - assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, ReturnVoidOnGroupNotFound.class); - - checkFilters(httpMethod); - } - - public void testCreateSecurityGroup() throws SecurityException, NoSuchMethodException, - IOException { - Method method = EC2AsyncClient.class.getMethod("createSecurityGroup", String.class, String.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "name", - "description"); - - 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-08-15&Action=CreateSecurityGroup&GroupName=name&GroupDescription=description"); - - assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testDescribeSecurityGroups() throws SecurityException, NoSuchMethodException, - IOException { - Method method = EC2AsyncClient.class.getMethod("describeSecurityGroups", Array.newInstance( - String.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 48\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, "Version=2009-08-15&Action=DescribeSecurityGroups"); - - assertResponseParserClassEquals(method, httpMethod, ParseSax.class); - assertSaxResponseParserClassEquals(method, DescribeSecurityGroupsResponseHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testDescribeSecurityGroupsArgs() throws SecurityException, NoSuchMethodException, - IOException { - Method method = EC2AsyncClient.class.getMethod("describeSecurityGroups", Array.newInstance( - String.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "1", "2"); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 48\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals(httpMethod, - "Version=2009-08-15&Action=DescribeSecurityGroups&GroupName.1=1&GroupName.2=2"); - - assertResponseParserClassEquals(method, httpMethod, ParseSax.class); - assertSaxResponseParserClassEquals(method, DescribeSecurityGroupsResponseHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testAuthorizeSecurityGroupIngressGroup() throws SecurityException, - NoSuchMethodException, IOException { - Method method = EC2AsyncClient.class.getMethod("authorizeSecurityGroupIngress", String.class, - UserIdGroupPair.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "group", - new UserIdGroupPair("sourceUser", "sourceGroup")); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 71\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals( - httpMethod, - "Version=2009-08-15&Action=AuthorizeSecurityGroupIngress&GroupName=group&SourceSecurityGroupOwnerId=sourceUser&SourceSecurityGroupName=sourceGroup"); - - assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testAuthorizeSecurityGroupIngressCidr() throws SecurityException, - NoSuchMethodException, IOException { - Method method = EC2AsyncClient.class.getMethod("authorizeSecurityGroupIngress", String.class, - IpProtocol.class, int.class, int.class, String.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "group", - IpProtocol.TCP, 6000, 7000, "0.0.0.0/0"); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 131\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals( - httpMethod, - "Version=2009-08-15&Action=AuthorizeSecurityGroupIngress&GroupName=group&FromPort=6000&IpProtocol=tcp&ToPort=7000&CidrIp=0.0.0.0%2F0"); - - assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testRevokeSecurityGroupIngressGroup() throws SecurityException, - NoSuchMethodException, IOException { - Method method = EC2AsyncClient.class.getMethod("revokeSecurityGroupIngress", String.class, - UserIdGroupPair.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "group", - new UserIdGroupPair("sourceUser", "sourceGroup")); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 68\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals( - httpMethod, - "Version=2009-08-15&Action=RevokeSecurityGroupIngress&GroupName=group&SourceSecurityGroupOwnerId=sourceUser&SourceSecurityGroupName=sourceGroup"); - - assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - public void testRevokeSecurityGroupIngressCidr() throws SecurityException, - NoSuchMethodException, IOException { - Method method = EC2AsyncClient.class.getMethod("revokeSecurityGroupIngress", String.class, - IpProtocol.class, int.class, int.class, String.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "group", - IpProtocol.TCP, 6000, 7000, "0.0.0.0/0"); - - assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); - assertHeadersEqual(httpMethod, - "Content-Length: 128\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); - assertPayloadEquals( - httpMethod, - "Version=2009-08-15&Action=RevokeSecurityGroupIngress&GroupName=group&FromPort=6000&IpProtocol=tcp&ToPort=7000&CidrIp=0.0.0.0%2F0"); - - assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, null); - - checkFilters(httpMethod); - } - - @Override - protected void checkFilters(GeneratedHttpRequest httpMethod) { - assertEquals(httpMethod.getFilters().size(), 1); - assertEquals(httpMethod.getFilters().get(0).getClass(), FormSigner.class); - } - - @Override - protected TypeLiteral> createTypeLiteral() { - return new TypeLiteral>() { - }; - } - - private FormSigner filter; - - @Override - @BeforeTest - protected void setupFactory() { - super.setupFactory(); - this.filter = injector.getInstance(FormSigner.class); - } - - @Override - protected Module createModule() { - return new AbstractModule() { - @Override - protected void configure() { - bind(URI.class).annotatedWith(EC2.class).toInstance( - URI.create("https://ec2.amazonaws.com")); - bindConstant().annotatedWith(Jsr330.named(AWSConstants.PROPERTY_AWS_ACCESSKEYID)).to( - "user"); - bindConstant().annotatedWith(Jsr330.named(AWSConstants.PROPERTY_AWS_SECRETACCESSKEY)) - .to("key"); - bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() { - public Logger getLogger(String category) { - return Logger.NULL; - } - }); - } - - @SuppressWarnings("unused") - @Provides - @TimeStamp - String provide() { - return "2009-11-08T15:54:08.897Z"; - } - }; - } -} diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/ExpensiveEC2ClientLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/ExpensiveEC2ClientLiveTest.java index ceeca19057..5b8749a316 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/ExpensiveEC2ClientLiveTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/ExpensiveEC2ClientLiveTest.java @@ -97,28 +97,30 @@ public class ExpensiveEC2ClientLiveTest { securityGroupName = serverPrefix + "ingress"; try { - client.deleteSecurityGroup(securityGroupName); + client.getSecurityGroupServices().deleteSecurityGroup(securityGroupName); } catch (Exception e) { } - client.createSecurityGroup(securityGroupName, securityGroupName); - client.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0"); - client.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 443, 443, - "0.0.0.0/0"); - client.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 22, 22, "0.0.0.0/0"); + client.getSecurityGroupServices().createSecurityGroup(securityGroupName, securityGroupName); + client.getSecurityGroupServices().authorizeSecurityGroupIngress(securityGroupName, + IpProtocol.TCP, 80, 80, "0.0.0.0/0"); + client.getSecurityGroupServices().authorizeSecurityGroupIngress(securityGroupName, + IpProtocol.TCP, 443, 443, "0.0.0.0/0"); + client.getSecurityGroupServices().authorizeSecurityGroupIngress(securityGroupName, + IpProtocol.TCP, 22, 22, "0.0.0.0/0"); } @Test(enabled = true) void testCreateKeyPair() throws InterruptedException, ExecutionException, TimeoutException { String keyName = serverPrefix + "1"; try { - client.deleteKeyPair(keyName); + client.getKeyPairServices().deleteKeyPair(keyName); } catch (Exception e) { } - client.deleteKeyPair(keyName); + client.getKeyPairServices().deleteKeyPair(keyName); - keyPair = client.createKeyPair(keyName); + keyPair = client.getKeyPairServices().createKeyPair(keyName); assertNotNull(keyPair); assertNotNull(keyPair.getKeyMaterial()); assertNotNull(keyPair.getKeyFingerprint()); @@ -133,7 +135,7 @@ public class ExpensiveEC2ClientLiveTest { while (server == null) { try { System.out.printf("%d: running instance%n", System.currentTimeMillis()); - server = client.runInstances( + server = client.getInstanceServices().runInstances( imageId, 1, 1, @@ -159,36 +161,37 @@ public class ExpensiveEC2ClientLiveTest { @Test(enabled = true, dependsOnMethods = "testCreateRunningInstance") void testElasticIpAddress() throws InterruptedException, ExecutionException, TimeoutException, IOException { - address = client.allocateAddress(); + address = client.getElasticIPAddressServices().allocateAddress(); assertNotNull(address); - PublicIpInstanceIdPair compare = client.describeAddresses(address).last(); + PublicIpInstanceIdPair compare = client.getElasticIPAddressServices().describeAddresses( + address).last(); assertEquals(compare.getPublicIp(), address); assert compare.getInstanceId() == null; - client.associateAddress(address, serverId); + client.getElasticIPAddressServices().associateAddress(address, serverId); - compare = client.describeAddresses(address).last(); + compare = client.getElasticIPAddressServices().describeAddresses(address).last(); assertEquals(compare.getPublicIp(), address); assertEquals(compare.getInstanceId(), serverId); - Reservation reservation = client.describeInstances(serverId).last(); + Reservation reservation = client.getInstanceServices().describeInstances(serverId).last(); assertNotNull(reservation.getRunningInstances().last().getIpAddress()); assertFalse(reservation.getRunningInstances().last().getIpAddress().equals(address)); doCheckKey(address); - client.disassociateAddress(address); + client.getElasticIPAddressServices().disassociateAddress(address); - compare = client.describeAddresses(address).last(); + compare = client.getElasticIPAddressServices().describeAddresses(address).last(); assertEquals(compare.getPublicIp(), address); assert compare.getInstanceId() == null; - reservation = client.describeInstances(serverId).last(); + reservation = client.getInstanceServices().describeInstances(serverId).last(); // assert reservation.getRunningInstances().last().getIpAddress() == null; TODO } @@ -244,18 +247,19 @@ public class ExpensiveEC2ClientLiveTest { @AfterTest void cleanup() throws InterruptedException, ExecutionException, TimeoutException { if (address != null) - client.releaseAddress(address); + client.getElasticIPAddressServices().releaseAddress(address); if (serverId != null) - client.terminateInstances(serverId); + client.getInstanceServices().terminateInstances(serverId); if (keyPair != null) - client.deleteKeyPair(keyPair.getKeyName()); + client.getKeyPairServices().deleteKeyPair(keyPair.getKeyName()); if (securityGroupName != null) - client.deleteSecurityGroup(securityGroupName); + client.getSecurityGroupServices().deleteSecurityGroup(securityGroupName); } private RunningInstance getRunningInstance(String serverId) throws InterruptedException, ExecutionException, TimeoutException { - return client.describeInstances(serverId).first().getRunningInstances().first(); + return client.getInstanceServices().describeInstances(serverId).first().getRunningInstances() + .first(); } } diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIAsyncClientTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIAsyncClientTest.java new file mode 100644 index 0000000000..877867a9b4 --- /dev/null +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIAsyncClientTest.java @@ -0,0 +1,178 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.services; + +import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.executableBy; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.net.URI; + +import org.jclouds.aws.ec2.EC2; +import org.jclouds.aws.ec2.domain.ImageAttribute; +import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.options.DescribeImagesOptions; +import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandler; +import org.jclouds.aws.reference.AWSConstants; +import org.jclouds.date.TimeStamp; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ReturnStringIf200; +import org.jclouds.logging.Logger; +import org.jclouds.logging.Logger.LoggerFactory; +import org.jclouds.rest.RestClientTest; +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.jclouds.util.Jsr330; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.google.inject.AbstractModule; +import com.google.inject.Module; +import com.google.inject.Provides; +import com.google.inject.TypeLiteral; + +/** + * Tests behavior of {@code AMIAsyncClient} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ec2.AMIAsyncClientTest") +public class AMIAsyncClientTest extends RestClientTest { + + public void testDescribeImages() throws SecurityException, NoSuchMethodException, IOException { + Method method = AMIAsyncClient.class.getMethod("describeImages", Array.newInstance( + DescribeImagesOptions.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 40\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals(httpMethod, "Version=2009-11-30&Action=DescribeImages"); + filter.filter(httpMethod); + assertPayloadEquals( + httpMethod, + "Action=DescribeImages&Signature=z1UAagWh%2BypA%2BR66ZAOvJJm5uQcBzGDVcbVeMilfioU%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2009-11-30&AWSAccessKeyId=user"); + + assertResponseParserClassEquals(method, httpMethod, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeImagesResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testDescribeImagesOptions() throws SecurityException, NoSuchMethodException, + IOException { + Method method = AMIAsyncClient.class.getMethod("describeImages", Array.newInstance( + DescribeImagesOptions.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + executableBy("me").ownedBy("fred", "nancy").imageIds("1", "2")); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 107\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals( + httpMethod, + "Version=2009-11-30&Action=DescribeImages&ExecutableBy=me&Owner.1=fred&Owner.2=nancy&ImageId.1=1&ImageId.2=2"); + + assertResponseParserClassEquals(method, httpMethod, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeImagesResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testDescribeImageAttribute() throws SecurityException, NoSuchMethodException, + IOException { + Method method = AMIAsyncClient.class.getMethod("describeImageAttribute", String.class, + ImageAttribute.class); + GeneratedHttpRequest httpMethod = processor.createRequest(method, "imageId", + ImageAttribute.BLOCK_DEVICE_MAPPING); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 93\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals(httpMethod, + "Version=2009-11-30&Action=DescribeImageAttribute&ImageId=imageId&Attribute=blockDeviceMapping"); + filter.filter(httpMethod); + assertPayloadEquals( + httpMethod, + "Action=DescribeImageAttribute&Attribute=blockDeviceMapping&ImageId=imageId&Signature=A1%2BcJegB6Et36%2BGC%2FEJ0puDJljBY9oeF2YYsH%2FDIxUA%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2009-11-30&AWSAccessKeyId=user"); + + assertResponseParserClassEquals(method, httpMethod, ReturnStringIf200.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + @Override + protected void checkFilters(GeneratedHttpRequest httpMethod) { + assertEquals(httpMethod.getFilters().size(), 1); + assertEquals(httpMethod.getFilters().get(0).getClass(), FormSigner.class); + } + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } + + private FormSigner filter; + + @Override + @BeforeTest + protected void setupFactory() { + super.setupFactory(); + this.filter = injector.getInstance(FormSigner.class); + } + + @Override + protected Module createModule() { + return new AbstractModule() { + @Override + protected void configure() { + bind(URI.class).annotatedWith(EC2.class).toInstance( + URI.create("https://ec2.amazonaws.com")); + bindConstant().annotatedWith(Jsr330.named(AWSConstants.PROPERTY_AWS_ACCESSKEYID)).to( + "user"); + bindConstant().annotatedWith(Jsr330.named(AWSConstants.PROPERTY_AWS_SECRETACCESSKEY)) + .to("key"); + bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() { + public Logger getLogger(String category) { + return Logger.NULL; + } + }); + } + + @SuppressWarnings("unused") + @Provides + @TimeStamp + String provide() { + return "2009-11-08T15:54:08.897Z"; + } + }; + } +} diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/ElasticIPAddressAsyncClientTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/ElasticIPAddressAsyncClientTest.java new file mode 100644 index 0000000000..b1353234c7 --- /dev/null +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/ElasticIPAddressAsyncClientTest.java @@ -0,0 +1,194 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.services; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.net.InetAddress; +import java.net.URI; + +import org.jclouds.aws.ec2.EC2; +import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.xml.AllocateAddressResponseHandler; +import org.jclouds.aws.ec2.xml.DescribeAddressesResponseHandler; +import org.jclouds.aws.reference.AWSConstants; +import org.jclouds.date.TimeStamp; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ReturnVoidIf2xx; +import org.jclouds.logging.Logger; +import org.jclouds.logging.Logger.LoggerFactory; +import org.jclouds.rest.RestClientTest; +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.jclouds.util.Jsr330; +import org.testng.annotations.Test; + +import com.google.inject.AbstractModule; +import com.google.inject.Module; +import com.google.inject.Provides; +import com.google.inject.TypeLiteral; + +/** + * Tests behavior of {@code ElasticIPAddressAsyncClient} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ec2.ElasticIPAddressAsyncClientTest") +public class ElasticIPAddressAsyncClientTest extends RestClientTest { + + public void testDisassociateAddress() throws SecurityException, NoSuchMethodException, + IOException { + Method method = ElasticIPAddressAsyncClient.class.getMethod("disassociateAddress", + InetAddress.class); + GeneratedHttpRequest httpMethod = processor.createRequest( + method, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 })); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 64\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals(httpMethod, + "Version=2009-11-30&Action=DisassociateAddress&PublicIp=127.0.0.1"); + + assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testAssociateAddress() throws SecurityException, NoSuchMethodException, IOException { + Method method = ElasticIPAddressAsyncClient.class.getMethod("associateAddress", + InetAddress.class, String.class); + GeneratedHttpRequest httpMethod = processor.createRequest( + method, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }), "me"); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 75\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals(httpMethod, + "Version=2009-11-30&Action=AssociateAddress&PublicIp=127.0.0.1&InstanceId=me"); + + assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testReleaseAddress() throws SecurityException, NoSuchMethodException, IOException { + Method method = ElasticIPAddressAsyncClient.class.getMethod("releaseAddress", + InetAddress.class); + GeneratedHttpRequest httpMethod = processor.createRequest( + method, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 })); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 59\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals(httpMethod, "Version=2009-11-30&Action=ReleaseAddress&PublicIp=127.0.0.1"); + + assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testDescribeAddresses() throws SecurityException, NoSuchMethodException, IOException { + Method method = ElasticIPAddressAsyncClient.class.getMethod("describeAddresses", Array + .newInstance(InetAddress.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest( + method, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 })); + + 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=DescribeAddresses&PublicIp.1=127.0.0.1"); + + assertResponseParserClassEquals(method, httpMethod, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeAddressesResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testAllocateAddress() throws SecurityException, NoSuchMethodException, IOException { + Method method = ElasticIPAddressAsyncClient.class.getMethod("allocateAddress"); + GeneratedHttpRequest httpMethod = processor + .createRequest(method); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 41\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals(httpMethod, "Version=2009-11-30&Action=AllocateAddress"); + + assertResponseParserClassEquals(method, httpMethod, ParseSax.class); + assertSaxResponseParserClassEquals(method, AllocateAddressResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + @Override + protected void checkFilters(GeneratedHttpRequest httpMethod) { + assertEquals(httpMethod.getFilters().size(), 1); + assertEquals(httpMethod.getFilters().get(0).getClass(), FormSigner.class); + } + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } + + @Override + protected Module createModule() { + return new AbstractModule() { + @Override + protected void configure() { + bind(URI.class).annotatedWith(EC2.class).toInstance( + URI.create("https://ec2.amazonaws.com")); + bindConstant().annotatedWith(Jsr330.named(AWSConstants.PROPERTY_AWS_ACCESSKEYID)).to( + "user"); + bindConstant().annotatedWith(Jsr330.named(AWSConstants.PROPERTY_AWS_SECRETACCESSKEY)) + .to("key"); + bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() { + public Logger getLogger(String category) { + return Logger.NULL; + } + }); + } + + @SuppressWarnings("unused") + @Provides + @TimeStamp + String provide() { + return "2009-11-08T15:54:08.897Z"; + } + }; + } +} diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/InstanceAsyncClientTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/InstanceAsyncClientTest.java new file mode 100644 index 0000000000..dbdd355e93 --- /dev/null +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/InstanceAsyncClientTest.java @@ -0,0 +1,199 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.services; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.net.URI; + +import org.jclouds.aws.ec2.EC2; +import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.options.RunInstancesOptions; +import org.jclouds.aws.ec2.xml.DescribeInstancesResponseHandler; +import org.jclouds.aws.ec2.xml.RunInstancesResponseHandler; +import org.jclouds.aws.ec2.xml.TerminateInstancesResponseHandler; +import org.jclouds.aws.reference.AWSConstants; +import org.jclouds.date.TimeStamp; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.logging.Logger; +import org.jclouds.logging.Logger.LoggerFactory; +import org.jclouds.rest.RestClientTest; +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.jclouds.util.Jsr330; +import org.testng.annotations.Test; + +import com.google.inject.AbstractModule; +import com.google.inject.Module; +import com.google.inject.Provides; +import com.google.inject.TypeLiteral; + +/** + * Tests behavior of {@code InstanceAsyncClient} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ec2.InstanceAsyncClientTest") +public class InstanceAsyncClientTest extends RestClientTest { + + public void testDescribeInstances() throws SecurityException, NoSuchMethodException, IOException { + Method method = InstanceAsyncClient.class.getMethod("describeInstances", Array.newInstance( + String.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method); + + 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=DescribeInstances"); + + assertResponseParserClassEquals(method, httpMethod, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeInstancesResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testDescribeInstancesArgs() throws SecurityException, NoSuchMethodException, + IOException { + Method method = InstanceAsyncClient.class.getMethod("describeInstances", Array.newInstance( + String.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, "1", + "2"); + + 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=DescribeInstances&InstanceId.1=1&InstanceId.2=2"); + + assertResponseParserClassEquals(method, httpMethod, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeInstancesResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testTerminateInstances() throws SecurityException, NoSuchMethodException, + IOException { + Method method = InstanceAsyncClient.class.getMethod("terminateInstances", String.class, Array + .newInstance(String.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, "1", + "2"); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 59\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals(httpMethod, + "Version=2009-11-30&Action=TerminateInstances&InstanceId.0=1&InstanceId.1=2"); + + assertResponseParserClassEquals(method, httpMethod, ParseSax.class); + assertSaxResponseParserClassEquals(method, TerminateInstancesResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testRunInstances() throws SecurityException, NoSuchMethodException, IOException { + Method method = InstanceAsyncClient.class.getMethod("runInstances", String.class, int.class, + int.class, Array.newInstance(RunInstancesOptions.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + "ami-voo", 1, 1); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 76\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals(httpMethod, + "Version=2009-11-30&Action=RunInstances&ImageId=ami-voo&MaxCount=1&MinCount=1"); + + assertResponseParserClassEquals(method, httpMethod, ParseSax.class); + assertSaxResponseParserClassEquals(method, RunInstancesResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testRunInstancesOptions() throws SecurityException, NoSuchMethodException, + IOException { + Method method = InstanceAsyncClient.class.getMethod("runInstances", String.class, int.class, + int.class, Array.newInstance(RunInstancesOptions.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + "ami-voo", 1, 5, new RunInstancesOptions().withKernelId("kernelId") + .enableMonitoring()); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 118\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals( + httpMethod, + "Version=2009-11-30&Action=RunInstances&ImageId=ami-voo&MaxCount=5&MinCount=1&KernelId=kernelId&Monitoring.Enabled=true"); + + assertResponseParserClassEquals(method, httpMethod, ParseSax.class); + assertSaxResponseParserClassEquals(method, RunInstancesResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + @Override + protected void checkFilters(GeneratedHttpRequest httpMethod) { + assertEquals(httpMethod.getFilters().size(), 1); + assertEquals(httpMethod.getFilters().get(0).getClass(), FormSigner.class); + } + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } + + @Override + protected Module createModule() { + return new AbstractModule() { + @Override + protected void configure() { + bind(URI.class).annotatedWith(EC2.class).toInstance( + URI.create("https://ec2.amazonaws.com")); + bindConstant().annotatedWith(Jsr330.named(AWSConstants.PROPERTY_AWS_ACCESSKEYID)).to( + "user"); + bindConstant().annotatedWith(Jsr330.named(AWSConstants.PROPERTY_AWS_SECRETACCESSKEY)) + .to("key"); + bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() { + public Logger getLogger(String category) { + return Logger.NULL; + } + }); + } + + @SuppressWarnings("unused") + @Provides + @TimeStamp + String provide() { + return "2009-11-08T15:54:08.897Z"; + } + }; + } +} diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/KeyPairAsyncClientTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/KeyPairAsyncClientTest.java new file mode 100644 index 0000000000..9e5eabd9cc --- /dev/null +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/KeyPairAsyncClientTest.java @@ -0,0 +1,153 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.services; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.net.URI; + +import org.jclouds.aws.ec2.EC2; +import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.xml.DescribeKeyPairsResponseHandler; +import org.jclouds.aws.reference.AWSConstants; +import org.jclouds.date.TimeStamp; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ReturnVoidIf2xx; +import org.jclouds.logging.Logger; +import org.jclouds.logging.Logger.LoggerFactory; +import org.jclouds.rest.RestClientTest; +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.jclouds.util.Jsr330; +import org.testng.annotations.Test; + +import com.google.inject.AbstractModule; +import com.google.inject.Module; +import com.google.inject.Provides; +import com.google.inject.TypeLiteral; + +/** + * Tests behavior of {@code KeyPairAsyncClient} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ec2.KeyPairAsyncClientTest") +public class KeyPairAsyncClientTest extends RestClientTest { + + public void testDeleteKeyPair() throws SecurityException, NoSuchMethodException, IOException { + Method method = KeyPairAsyncClient.class.getMethod("deleteKeyPair", String.class); + GeneratedHttpRequest httpMethod = processor + .createRequest(method, "mykey"); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 53\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals(httpMethod, "Version=2009-11-30&Action=DeleteKeyPair&KeyName=mykey"); + + assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testDescribeKeyPairs() throws SecurityException, NoSuchMethodException, IOException { + Method method = KeyPairAsyncClient.class.getMethod("describeKeyPairs", Array.newInstance( + String.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 42\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals(httpMethod, "Version=2009-11-30&Action=DescribeKeyPairs"); + + assertResponseParserClassEquals(method, httpMethod, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeKeyPairsResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testDescribeKeyPairsArgs() throws SecurityException, NoSuchMethodException, + IOException { + Method method = KeyPairAsyncClient.class.getMethod("describeKeyPairs", Array.newInstance( + String.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, "1", + "2"); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 42\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals(httpMethod, + "Version=2009-11-30&Action=DescribeKeyPairs&KeyName.1=1&KeyName.2=2"); + + assertResponseParserClassEquals(method, httpMethod, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeKeyPairsResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + @Override + protected void checkFilters(GeneratedHttpRequest httpMethod) { + assertEquals(httpMethod.getFilters().size(), 1); + assertEquals(httpMethod.getFilters().get(0).getClass(), FormSigner.class); + } + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } + + @Override + protected Module createModule() { + return new AbstractModule() { + @Override + protected void configure() { + bind(URI.class).annotatedWith(EC2.class).toInstance( + URI.create("https://ec2.amazonaws.com")); + bindConstant().annotatedWith(Jsr330.named(AWSConstants.PROPERTY_AWS_ACCESSKEYID)).to( + "user"); + bindConstant().annotatedWith(Jsr330.named(AWSConstants.PROPERTY_AWS_SECRETACCESSKEY)) + .to("key"); + bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() { + public Logger getLogger(String category) { + return Logger.NULL; + } + }); + } + + @SuppressWarnings("unused") + @Provides + @TimeStamp + String provide() { + return "2009-11-08T15:54:08.897Z"; + } + }; + } +} diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/SecurityGroupAsyncClientTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/SecurityGroupAsyncClientTest.java new file mode 100644 index 0000000000..616f2ab73b --- /dev/null +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/SecurityGroupAsyncClientTest.java @@ -0,0 +1,263 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.services; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.net.URI; + +import org.jclouds.aws.ec2.EC2; +import org.jclouds.aws.ec2.domain.IpProtocol; +import org.jclouds.aws.ec2.domain.UserIdGroupPair; +import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.functions.ReturnVoidOnGroupNotFound; +import org.jclouds.aws.ec2.xml.DescribeSecurityGroupsResponseHandler; +import org.jclouds.aws.reference.AWSConstants; +import org.jclouds.date.TimeStamp; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ReturnVoidIf2xx; +import org.jclouds.logging.Logger; +import org.jclouds.logging.Logger.LoggerFactory; +import org.jclouds.rest.RestClientTest; +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.jclouds.util.Jsr330; +import org.testng.annotations.Test; + +import com.google.inject.AbstractModule; +import com.google.inject.Module; +import com.google.inject.Provides; +import com.google.inject.TypeLiteral; + +/** + * Tests behavior of {@code SecurityGroupAsyncClient} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ec2.SecurityGroupAsyncClientTest") +public class SecurityGroupAsyncClientTest extends RestClientTest { + + public void testDeleteSecurityGroup() throws SecurityException, NoSuchMethodException, + IOException { + Method method = SecurityGroupAsyncClient.class.getMethod("deleteSecurityGroup", String.class); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + "name"); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 60\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals(httpMethod, + "Version=2009-11-30&Action=DeleteSecurityGroup&GroupName=name"); + + assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, ReturnVoidOnGroupNotFound.class); + + checkFilters(httpMethod); + } + + public void testCreateSecurityGroup() throws SecurityException, NoSuchMethodException, + IOException { + Method method = SecurityGroupAsyncClient.class.getMethod("createSecurityGroup", String.class, + String.class); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + "name", "description"); + + 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=CreateSecurityGroup&GroupName=name&GroupDescription=description"); + + assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testDescribeSecurityGroups() throws SecurityException, NoSuchMethodException, + IOException { + Method method = SecurityGroupAsyncClient.class.getMethod("describeSecurityGroups", Array + .newInstance(String.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 48\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals(httpMethod, "Version=2009-11-30&Action=DescribeSecurityGroups"); + + assertResponseParserClassEquals(method, httpMethod, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeSecurityGroupsResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testDescribeSecurityGroupsArgs() throws SecurityException, NoSuchMethodException, + IOException { + Method method = SecurityGroupAsyncClient.class.getMethod("describeSecurityGroups", Array + .newInstance(String.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + "1", "2"); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 48\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals(httpMethod, + "Version=2009-11-30&Action=DescribeSecurityGroups&GroupName.1=1&GroupName.2=2"); + + assertResponseParserClassEquals(method, httpMethod, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeSecurityGroupsResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testAuthorizeSecurityGroupIngressGroup() throws SecurityException, + NoSuchMethodException, IOException { + Method method = SecurityGroupAsyncClient.class.getMethod("authorizeSecurityGroupIngress", + String.class, UserIdGroupPair.class); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + "group", new UserIdGroupPair("sourceUser", "sourceGroup")); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 71\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals( + httpMethod, + "Version=2009-11-30&Action=AuthorizeSecurityGroupIngress&GroupName=group&SourceSecurityGroupOwnerId=sourceUser&SourceSecurityGroupName=sourceGroup"); + + assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testAuthorizeSecurityGroupIngressCidr() throws SecurityException, + NoSuchMethodException, IOException { + Method method = SecurityGroupAsyncClient.class.getMethod("authorizeSecurityGroupIngress", + String.class, IpProtocol.class, int.class, int.class, String.class); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + "group", IpProtocol.TCP, 6000, 7000, "0.0.0.0/0"); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 131\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals( + httpMethod, + "Version=2009-11-30&Action=AuthorizeSecurityGroupIngress&GroupName=group&FromPort=6000&IpProtocol=tcp&ToPort=7000&CidrIp=0.0.0.0%2F0"); + + assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testRevokeSecurityGroupIngressGroup() throws SecurityException, + NoSuchMethodException, IOException { + Method method = SecurityGroupAsyncClient.class.getMethod("revokeSecurityGroupIngress", + String.class, UserIdGroupPair.class); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + "group", new UserIdGroupPair("sourceUser", "sourceGroup")); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 68\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals( + httpMethod, + "Version=2009-11-30&Action=RevokeSecurityGroupIngress&GroupName=group&SourceSecurityGroupOwnerId=sourceUser&SourceSecurityGroupName=sourceGroup"); + + assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + public void testRevokeSecurityGroupIngressCidr() throws SecurityException, + NoSuchMethodException, IOException { + Method method = SecurityGroupAsyncClient.class.getMethod("revokeSecurityGroupIngress", + String.class, IpProtocol.class, int.class, int.class, String.class); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + "group", IpProtocol.TCP, 6000, 7000, "0.0.0.0/0"); + + assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual(httpMethod, + "Content-Length: 128\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); + assertPayloadEquals( + httpMethod, + "Version=2009-11-30&Action=RevokeSecurityGroupIngress&GroupName=group&FromPort=6000&IpProtocol=tcp&ToPort=7000&CidrIp=0.0.0.0%2F0"); + + assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + + @Override + protected void checkFilters(GeneratedHttpRequest httpMethod) { + assertEquals(httpMethod.getFilters().size(), 1); + assertEquals(httpMethod.getFilters().get(0).getClass(), FormSigner.class); + } + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } + + @Override + protected Module createModule() { + return new AbstractModule() { + @Override + protected void configure() { + bind(URI.class).annotatedWith(EC2.class).toInstance( + URI.create("https://ec2.amazonaws.com")); + bindConstant().annotatedWith(Jsr330.named(AWSConstants.PROPERTY_AWS_ACCESSKEYID)).to( + "user"); + bindConstant().annotatedWith(Jsr330.named(AWSConstants.PROPERTY_AWS_SECRETACCESSKEY)) + .to("key"); + bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() { + public Logger getLogger(String category) { + return Logger.NULL; + } + }); + } + + @SuppressWarnings("unused") + @Provides + @TimeStamp + String provide() { + return "2009-11-08T15:54:08.897Z"; + } + }; + } +}