mirror of
https://github.com/apache/jclouds.git
synced 2025-02-16 06:56:45 +00:00
Issue 29: supports basic operations
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2236 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
870becd3f1
commit
78d72fae49
@ -21,22 +21,24 @@
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.config;
|
||||
|
||||
import static java.lang.annotation.ElementType.TYPE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
package org.jclouds.aws.ec2;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
/**
|
||||
* designates the the module configures a {@link org.jclouds.aws.ec2.EC2Connection}
|
||||
* Related to a EC2 resource.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Retention(RUNTIME)
|
||||
@Target(TYPE)
|
||||
public @interface EC2ConnectionModule {
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||
@Qualifier
|
||||
public @interface EC2 {
|
||||
|
||||
}
|
||||
}
|
461
aws/core/src/main/java/org/jclouds/aws/ec2/EC2Client.java
Normal file
461
aws/core/src/main/java/org/jclouds/aws/ec2/EC2Client.java
Normal file
@ -0,0 +1,461 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2;
|
||||
|
||||
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.binders.BindGroupNameToIndexedFormParams;
|
||||
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.IpProtocol;
|
||||
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||
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.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.RequestFilters;
|
||||
import org.jclouds.rest.annotations.VirtualHost;
|
||||
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||
|
||||
/**
|
||||
* Provides access to EC2 via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Endpoint(EC2.class)
|
||||
@RequestFilters(FormSigner.class)
|
||||
@FormParams(keys = VERSION, values = "2009-08-15")
|
||||
@VirtualHost
|
||||
public interface EC2Client {
|
||||
|
||||
/**
|
||||
* 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 <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeImages.html"
|
||||
* />
|
||||
* @see DescribeImagesOptions
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "DescribeImages")
|
||||
@XMLResponseParser(DescribeImagesResponseHandler.class)
|
||||
Future<? extends SortedSet<Image>> describeImages(DescribeImagesOptions... options);
|
||||
|
||||
/**
|
||||
* Returns information about instances that you own.
|
||||
* <p/>
|
||||
*
|
||||
* 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.
|
||||
* <p/>
|
||||
* Recently terminated instances might appear in the returned results.This interval is usually
|
||||
* less than one hour.
|
||||
*
|
||||
* @see #runInstances
|
||||
* @see #terminateInstances
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html"
|
||||
* />
|
||||
* @see DescribeInstancesOptions
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "DescribeInstances")
|
||||
@XMLResponseParser(DescribeInstancesResponseHandler.class)
|
||||
Future<? extends SortedSet<Reservation>> describeInstances(
|
||||
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
|
||||
|
||||
/**
|
||||
* Launches a specified number of instances of an AMI for which you have permissions.
|
||||
* <p/>
|
||||
*
|
||||
* 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.
|
||||
* <p/>
|
||||
* <h4>Security Groups</h4>
|
||||
* <b>Note:</b> Every instance is launched in a security group (created using the
|
||||
* CreateSecurityGroup operation.
|
||||
* <h4>Key Pair</h4>
|
||||
* 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.
|
||||
* <p/>
|
||||
* <b>Note:</b> Launching public images without a key pair ID will leave them inaccessible.
|
||||
* <p/>
|
||||
* 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.
|
||||
* <h4>User Data</h4>
|
||||
* 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.
|
||||
* <h4>Product Codes</h4>
|
||||
*
|
||||
* <b>Note:</b> If any of the AMIs have a product code attached for which the user has not
|
||||
* subscribed, the RunInstances call will fail.
|
||||
* <h4>Kernel</h4>
|
||||
*
|
||||
* <b>Important:</b> 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 <a href=
|
||||
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RunInstances.html"
|
||||
* />
|
||||
* @see RunInstancesOptions
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "RunInstances")
|
||||
@XMLResponseParser(RunInstancesResponseHandler.class)
|
||||
Future<Reservation> runInstances(@FormParam("ImageId") String imageId,
|
||||
@FormParam("MinCount") int minCount, @FormParam("MaxCount") 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.
|
||||
* <p/>
|
||||
* Terminated instances will remain visible after termination (approximately one hour).
|
||||
*
|
||||
* @param instanceIds
|
||||
* Instance ID to terminate.
|
||||
* @see #describeInstances
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-TerminateInstances.html"
|
||||
* />
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "TerminateInstances")
|
||||
@XMLResponseParser(TerminateInstancesResponseHandler.class)
|
||||
Future<? extends SortedSet<TerminatedInstance>> terminateInstances(
|
||||
@FormParam("InstanceId.0") String instanceId,
|
||||
@BinderParam(BindInstanceIdsToIndexedFormParams.class) 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 <a href=
|
||||
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateKeyPair.html"
|
||||
* />
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "CreateKeyPair")
|
||||
@XMLResponseParser(KeyPairResponseHandler.class)
|
||||
Future<KeyPair> createKeyPair(@FormParam("KeyName") 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 <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeKeyPairs.html"
|
||||
* />
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "DescribeKeyPairs")
|
||||
@XMLResponseParser(DescribeKeyPairsResponseHandler.class)
|
||||
Future<? extends SortedSet<KeyPair>> describeKeyPairs(
|
||||
@BinderParam(BindKeyNameToIndexedFormParams.class) 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 <a href=
|
||||
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteKeyPair.html"
|
||||
* />
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "DeleteKeyPair")
|
||||
Future<Void> deleteKeyPair(@FormParam("KeyName") 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 <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateSecurityGroup.html"
|
||||
* />
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "CreateSecurityGroup")
|
||||
Future<Void> createSecurityGroup(@FormParam("GroupName") String name,
|
||||
@FormParam("GroupDescription") 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 <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteSecurityGroup.html"
|
||||
* />
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "DeleteSecurityGroup")
|
||||
@ExceptionParser(ReturnVoidOnGroupNotFound.class)
|
||||
Future<Void> deleteSecurityGroup(@FormParam("GroupName") 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 <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSecurityGroups.html"
|
||||
* />
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "DescribeSecurityGroups")
|
||||
@XMLResponseParser(DescribeSecurityGroupsResponseHandler.class)
|
||||
Future<? extends SortedSet<SecurityGroup>> describeSecurityGroups(
|
||||
@BinderParam(BindGroupNameToIndexedFormParams.class) 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 <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-AuthorizeSecurityGroupIngress.html"
|
||||
*
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress")
|
||||
Future<Void> authorizeSecurityGroupIngress(
|
||||
@FormParam("GroupName") String groupName,
|
||||
@BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup);
|
||||
|
||||
/**
|
||||
*
|
||||
* Adds permissions to a security group.
|
||||
* <p/>
|
||||
* 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 <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-AuthorizeSecurityGroupIngress.html"
|
||||
*
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress")
|
||||
Future<Void> authorizeSecurityGroupIngress(@FormParam("GroupName") String groupName,
|
||||
@FormParam("IpProtocol") IpProtocol ipProtocol, @FormParam("FromPort") int fromPort,
|
||||
@FormParam("ToPort") int toPort, @FormParam("CidrIp") String cidrIp);
|
||||
|
||||
/**
|
||||
*
|
||||
* Revokes permissions from a security group. The permissions used to revoke must be specified
|
||||
* using the same values used to grant the permissions.
|
||||
*
|
||||
* @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 #authorizeSecurityGroupIngress
|
||||
* @see #deleteSecurityGroup
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RevokeSecurityGroupIngress.html"
|
||||
*
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress")
|
||||
Future<Void> revokeSecurityGroupIngress(
|
||||
@FormParam("GroupName") String groupName,
|
||||
@BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup);
|
||||
|
||||
/**
|
||||
*
|
||||
* Revokes permissions from a security group. The permissions used to revoke must be specified
|
||||
* using the same values used to grant the permissions.
|
||||
* <p/>
|
||||
* 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 <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RevokeSecurityGroupIngress.html"
|
||||
*
|
||||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress")
|
||||
Future<Void> revokeSecurityGroupIngress(@FormParam("GroupName") String groupName,
|
||||
@FormParam("IpProtocol") IpProtocol ipProtocol, @FormParam("FromPort") int fromPort,
|
||||
@FormParam("ToPort") int toPort, @FormParam("CidrIp") String cidrIp);
|
||||
}
|
62
aws/core/src/main/java/org/jclouds/aws/ec2/EC2ContextBuilder.java
Executable file
62
aws/core/src/main/java/org/jclouds/aws/ec2/EC2ContextBuilder.java
Executable file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.aws.ec2.config.EC2ContextModule;
|
||||
import org.jclouds.aws.ec2.config.EC2RestClientModule;
|
||||
import org.jclouds.rest.RestContextBuilder;
|
||||
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class EC2ContextBuilder extends RestContextBuilder<EC2Client> {
|
||||
|
||||
public EC2ContextBuilder(Properties props) {
|
||||
super(new TypeLiteral<EC2Client>() {
|
||||
}, props);
|
||||
checkNotNull(properties.getProperty(PROPERTY_AWS_ACCESSKEYID));
|
||||
checkNotNull(properties.getProperty(PROPERTY_AWS_SECRETACCESSKEY));
|
||||
}
|
||||
|
||||
protected void addClientModule(List<Module> modules) {
|
||||
modules.add(new EC2RestClientModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new EC2ContextModule());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import org.jclouds.rest.RestContext;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Creates {@link RestContext} instances bound with generic type {@link EC2Client} based on the most
|
||||
* commonly requested arguments.
|
||||
* <p/>
|
||||
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see RestContext
|
||||
*/
|
||||
public class EC2ContextFactory {
|
||||
public static RestContext<EC2Client> createContext(Properties properties, Module... modules) {
|
||||
return new EC2ContextBuilder(new EC2PropertiesBuilder(properties).build()).withModules(
|
||||
modules).buildContext();
|
||||
}
|
||||
|
||||
public static RestContext<EC2Client> createContext(String awsAccessKeyId,
|
||||
String awsSecretAccessKey, Module... modules) {
|
||||
return new EC2ContextBuilder(new EC2PropertiesBuilder(awsAccessKeyId, awsSecretAccessKey)
|
||||
.build()).withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
public static RestContext<EC2Client> createContext(URI endpoint, String awsAccessKeyId,
|
||||
String awsSecretAccessKey, Module... modules) {
|
||||
return new EC2ContextBuilder(new EC2PropertiesBuilder(awsAccessKeyId, awsSecretAccessKey)
|
||||
.withEndpoint(endpoint).build()).withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_ENDPOINT;
|
||||
import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_EXPIREINTERVAL;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.http.HttpPropertiesBuilder;
|
||||
|
||||
/**
|
||||
* Builds properties used in EC2 Clients
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class EC2PropertiesBuilder extends HttpPropertiesBuilder {
|
||||
@Override
|
||||
protected Properties defaultProperties() {
|
||||
Properties properties = super.defaultProperties();
|
||||
properties.setProperty(PROPERTY_EC2_ENDPOINT, "http://ec2.amazonaws.com");
|
||||
properties.setProperty(PROPERTY_EC2_EXPIREINTERVAL, "60");
|
||||
return properties;
|
||||
}
|
||||
|
||||
public EC2PropertiesBuilder(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
public EC2PropertiesBuilder(String id, String secret) {
|
||||
super();
|
||||
withCredentials(id, secret);
|
||||
}
|
||||
|
||||
public EC2PropertiesBuilder withCredentials(String id, String secret) {
|
||||
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, checkNotNull(id, "awsAccessKeyId"));
|
||||
properties.setProperty(PROPERTY_AWS_SECRETACCESSKEY, checkNotNull(secret,
|
||||
"awsSecretAccessKey"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public EC2PropertiesBuilder withEndpoint(URI endpoint) {
|
||||
properties.setProperty(PROPERTY_EC2_ENDPOINT, checkNotNull(endpoint, "endpoint").toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
public EC2PropertiesBuilder withRequestExpiration(long seconds) {
|
||||
properties.setProperty(PROPERTY_EC2_EXPIREINTERVAL, seconds + "");
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.jclouds.aws.ec2.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.aws.ec2.util.EC2Utils;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.Binder;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
||||
/**
|
||||
* Binds the String [] to query parameters named with GroupName.index
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @since 4.0
|
||||
*/
|
||||
public class BindGroupNameToIndexedFormParams implements Binder {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void bindToRequest(HttpRequest request, Object input) {
|
||||
checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest,
|
||||
"this binder is only valid for GeneratedHttpRequests!");
|
||||
EC2Utils.indexFormValuesWithPrefix((GeneratedHttpRequest<?>) request, "GroupName", input);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.jclouds.aws.ec2.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.aws.ec2.util.EC2Utils;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.Binder;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
||||
/**
|
||||
* Binds the String [] to form parameters named with InstanceId.index
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @since 4.0
|
||||
*/
|
||||
public class BindInstanceIdsToIndexedFormParams implements Binder {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void bindToRequest(HttpRequest request, Object input) {
|
||||
checkArgument(checkNotNull(request, "input") instanceof GeneratedHttpRequest,
|
||||
"this binder is only valid for GeneratedHttpRequests!");
|
||||
EC2Utils.indexFormValuesWithPrefix((GeneratedHttpRequest<?>) request, "InstanceId", input);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.jclouds.aws.ec2.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.aws.ec2.util.EC2Utils;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.Binder;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
||||
/**
|
||||
* Binds the String [] to query parameters named with KeyName.index
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @since 4.0
|
||||
*/
|
||||
public class BindKeyNameToIndexedFormParams implements Binder {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void bindToRequest(HttpRequest request, Object input) {
|
||||
checkArgument(checkNotNull(request, "input") instanceof GeneratedHttpRequest,
|
||||
"this binder is only valid for GeneratedHttpRequests!");
|
||||
EC2Utils.indexFormValuesWithPrefix((GeneratedHttpRequest<?>) request, "KeyName", input);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package org.jclouds.aws.ec2.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.Binder;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
||||
/**
|
||||
* Binds the String [] to query parameters named with GroupName.index
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @since 4.0
|
||||
*/
|
||||
public class BindUserIdGroupPairToSourceSecurityGroupFormParams implements Binder {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void bindToRequest(HttpRequest request, Object input) {
|
||||
checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest,
|
||||
"this binder is only valid for GeneratedHttpRequests!");
|
||||
checkArgument(checkNotNull(input, "input") instanceof UserIdGroupPair,
|
||||
"this binder is only valid for UserIdGroupPair!");
|
||||
UserIdGroupPair pair = (UserIdGroupPair) input;
|
||||
GeneratedHttpRequest generatedRequest = (GeneratedHttpRequest) request;
|
||||
generatedRequest.addFormParam("SourceSecurityGroupOwnerId", pair.getUserId());
|
||||
generatedRequest.addFormParam("SourceSecurityGroupName", pair.getGroupName());
|
||||
}
|
||||
}
|
@ -21,57 +21,41 @@
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.internal;
|
||||
package org.jclouds.aws.ec2.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.ec2.EC2Connection;
|
||||
import org.jclouds.aws.ec2.EC2Context;
|
||||
import org.jclouds.aws.ec2.EC2;
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
import org.jclouds.aws.reference.AWSConstants;
|
||||
import org.jclouds.http.functions.config.ParserModule.CDateTimeAdapter;
|
||||
import org.jclouds.http.functions.config.ParserModule.DateTimeAdapter;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.internal.RestContextImpl;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
* Uses a Guice Injector to configure the objects served by EC2Context methods.
|
||||
* Configures the EC2 connection, including logging and http transport.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see Injector
|
||||
*/
|
||||
public class GuiceEC2Context implements EC2Context {
|
||||
|
||||
@Resource
|
||||
private Logger logger = Logger.NULL;
|
||||
private final Injector injector;
|
||||
private final Closer closer;
|
||||
|
||||
@Inject
|
||||
private GuiceEC2Context(Injector injector, Closer closer) {
|
||||
this.injector = injector;
|
||||
this.closer = closer;
|
||||
public class EC2ContextModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(DateTimeAdapter.class).to(CDateTimeAdapter.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public EC2Connection getConnection() {
|
||||
return injector.getInstance(EC2Connection.class);
|
||||
@Provides
|
||||
@Singleton
|
||||
RestContext<EC2Client> provideContext(Closer closer, EC2Client defaultApi, @EC2 URI endPoint,
|
||||
@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String account) {
|
||||
return new RestContextImpl<EC2Client>(closer, defaultApi, endPoint, account);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see Closer
|
||||
*/
|
||||
public void close() {
|
||||
try {
|
||||
closer.close();
|
||||
} catch (IOException e) {
|
||||
logger.error(e, "error closing content");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
110
aws/core/src/main/java/org/jclouds/aws/ec2/config/EC2RestClientModule.java
Executable file
110
aws/core/src/main/java/org/jclouds/aws/ec2/config/EC2RestClientModule.java
Executable file
@ -0,0 +1,110 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.config;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.ec2.EC2;
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
import org.jclouds.aws.ec2.filters.FormSigner;
|
||||
import org.jclouds.aws.ec2.reference.EC2Constants;
|
||||
import org.jclouds.aws.handlers.AWSClientErrorRetryHandler;
|
||||
import org.jclouds.aws.handlers.AWSRedirectionRetryHandler;
|
||||
import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent;
|
||||
import org.jclouds.aws.util.RequestSigner;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.HttpRetryHandler;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.RestClientFactory;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.jclouds.util.TimeStamp;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
* Configures the EC2 connection.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@RequiresHttp
|
||||
@ConfiguresRestClient
|
||||
public class EC2RestClientModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindErrorHandlers();
|
||||
bindRetryHandlers();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@TimeStamp
|
||||
protected String provideTimeStamp(final DateService dateService,
|
||||
@Named(EC2Constants.PROPERTY_EC2_EXPIREINTERVAL) final int expiration) {
|
||||
return dateService.iso8601DateFormat(new DateTime().plusSeconds(expiration));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
RequestSigner provideRequestSigner(FormSigner in) {
|
||||
return in;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected EC2Client provideClient(RestClientFactory factory) {
|
||||
return factory.create(EC2Client.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@EC2
|
||||
protected URI provideURI(@Named(EC2Constants.PROPERTY_EC2_ENDPOINT) String endpoint) {
|
||||
return URI.create(endpoint);
|
||||
}
|
||||
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
|
||||
ParseAWSErrorFromXmlContent.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(
|
||||
ParseAWSErrorFromXmlContent.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(
|
||||
ParseAWSErrorFromXmlContent.class);
|
||||
}
|
||||
|
||||
protected void bindRetryHandlers() {
|
||||
bind(HttpRetryHandler.class).annotatedWith(Redirection.class).to(
|
||||
AWSRedirectionRetryHandler.class);
|
||||
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(
|
||||
AWSClientErrorRetryHandler.class);
|
||||
}
|
||||
}
|
262
aws/core/src/main/java/org/jclouds/aws/ec2/domain/Image.java
Normal file
262
aws/core/src/main/java/org/jclouds/aws/ec2/domain/Image.java
Normal file
@ -0,0 +1,262 @@
|
||||
package org.jclouds.aws.ec2.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-DescribeImagesResponseItemType.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class Image implements Comparable<Image> {
|
||||
|
||||
public Image(Architecture architecture, String imageId, String imageLocation,
|
||||
String imageOwnerId, ImageState imageState, ImageType imageType, boolean isPublic,
|
||||
@Nullable String kernelId, @Nullable String platform, Set<String> productCodes,
|
||||
@Nullable String ramdiskId) {
|
||||
this.architecture = checkNotNull(architecture, "architecture");
|
||||
this.imageId = checkNotNull(imageId, "imageId");
|
||||
this.imageLocation = checkNotNull(imageLocation, "imageLocation");
|
||||
this.imageOwnerId = checkNotNull(imageOwnerId, "imageOwnerId");
|
||||
this.imageState = checkNotNull(imageState, "imageState");
|
||||
this.imageType = checkNotNull(imageType, "imageType");
|
||||
this.isPublic = isPublic;
|
||||
this.kernelId = kernelId;
|
||||
this.platform = platform;
|
||||
this.productCodes = checkNotNull(productCodes, "productCodes");
|
||||
this.ramdiskId = ramdiskId;
|
||||
}
|
||||
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -6965068835316857535L;
|
||||
|
||||
public enum ImageState {
|
||||
/**
|
||||
* the image is successfully registered and available for launching
|
||||
*/
|
||||
AVAILABLE,
|
||||
/**
|
||||
* the image is deregistered and no longer available for launching
|
||||
*/
|
||||
DEREGISTERED;
|
||||
public String value() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
|
||||
public static ImageState fromValue(String v) {
|
||||
return valueOf(v.toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
public enum Architecture {
|
||||
I386, X86_64;
|
||||
public String value() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
|
||||
public static Architecture fromValue(String v) {
|
||||
return valueOf(v.toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
public enum ImageType {
|
||||
|
||||
MACHINE, KERNEL, RAMDISK;
|
||||
public String value() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
|
||||
public static ImageType fromValue(String v) {
|
||||
return valueOf(v.toUpperCase());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final Architecture architecture;
|
||||
private final String imageId;
|
||||
private final String imageLocation;
|
||||
private final String imageOwnerId;
|
||||
private final ImageState imageState;
|
||||
private final ImageType imageType;
|
||||
private final boolean isPublic;
|
||||
private final @Nullable
|
||||
String kernelId;
|
||||
private final @Nullable String platform;
|
||||
private final Set<String> productCodes;
|
||||
private final @Nullable
|
||||
String ramdiskId;
|
||||
|
||||
/**
|
||||
* The architecture of the image (i386 or x86_64).
|
||||
*/
|
||||
public Architecture getArchitecture() {
|
||||
return architecture;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ID of the AMI.
|
||||
*/
|
||||
public String getImageId() {
|
||||
return imageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The location of the AMI.
|
||||
*/
|
||||
public String getImageLocation() {
|
||||
return imageLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* AWS Access Key ID of the image owner.
|
||||
*/
|
||||
public String getImageOwnerId() {
|
||||
return imageOwnerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Current state of the AMI. If the operation returns available, the image is successfully
|
||||
* registered and avail able for launching. If the operation returns deregistered, the image is
|
||||
* deregistered and no longer available for launching.
|
||||
*/
|
||||
public ImageState getImageState() {
|
||||
return imageState;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of image (machine, kernel, or ramdisk).
|
||||
*/
|
||||
public ImageType getImageType() {
|
||||
return imageType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this image has public launch permissions. Returns false if it only has
|
||||
* implicit and explicit launch permissions.
|
||||
*/
|
||||
public boolean isPublic() {
|
||||
return isPublic;
|
||||
}
|
||||
|
||||
/**
|
||||
* The kernel associated with the image, if any. Only applicable for machine images.
|
||||
*/
|
||||
public String getKernelId() {
|
||||
return kernelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The operating platform of the instance.
|
||||
*/
|
||||
public String getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Product codes of the AMI.
|
||||
*/
|
||||
public Set<String> getProductCodes() {
|
||||
return productCodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* The RAM disk associated with the image, if any. Only applicable for machine images.
|
||||
*/
|
||||
public String getRamdiskId() {
|
||||
return ramdiskId;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public int compareTo(Image o) {
|
||||
return (this == o) ? 0 : getImageId().compareTo(o.getImageId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((architecture == null) ? 0 : architecture.hashCode());
|
||||
result = prime * result + ((imageId == null) ? 0 : imageId.hashCode());
|
||||
result = prime * result + ((imageLocation == null) ? 0 : imageLocation.hashCode());
|
||||
result = prime * result + ((imageOwnerId == null) ? 0 : imageOwnerId.hashCode());
|
||||
result = prime * result + ((imageState == null) ? 0 : imageState.hashCode());
|
||||
result = prime * result + ((imageType == null) ? 0 : imageType.hashCode());
|
||||
result = prime * result + (isPublic ? 1231 : 1237);
|
||||
result = prime * result + ((kernelId == null) ? 0 : kernelId.hashCode());
|
||||
result = prime * result + ((platform == null) ? 0 : platform.hashCode());
|
||||
result = prime * result + ((productCodes == null) ? 0 : productCodes.hashCode());
|
||||
result = prime * result + ((ramdiskId == null) ? 0 : ramdiskId.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Image other = (Image) obj;
|
||||
if (architecture == null) {
|
||||
if (other.architecture != null)
|
||||
return false;
|
||||
} else if (!architecture.equals(other.architecture))
|
||||
return false;
|
||||
if (imageId == null) {
|
||||
if (other.imageId != null)
|
||||
return false;
|
||||
} else if (!imageId.equals(other.imageId))
|
||||
return false;
|
||||
if (imageLocation == null) {
|
||||
if (other.imageLocation != null)
|
||||
return false;
|
||||
} else if (!imageLocation.equals(other.imageLocation))
|
||||
return false;
|
||||
if (imageOwnerId == null) {
|
||||
if (other.imageOwnerId != null)
|
||||
return false;
|
||||
} else if (!imageOwnerId.equals(other.imageOwnerId))
|
||||
return false;
|
||||
if (imageState == null) {
|
||||
if (other.imageState != null)
|
||||
return false;
|
||||
} else if (!imageState.equals(other.imageState))
|
||||
return false;
|
||||
if (imageType == null) {
|
||||
if (other.imageType != null)
|
||||
return false;
|
||||
} else if (!imageType.equals(other.imageType))
|
||||
return false;
|
||||
if (isPublic != other.isPublic)
|
||||
return false;
|
||||
if (kernelId == null) {
|
||||
if (other.kernelId != null)
|
||||
return false;
|
||||
} else if (!kernelId.equals(other.kernelId))
|
||||
return false;
|
||||
if (platform == null) {
|
||||
if (other.platform != null)
|
||||
return false;
|
||||
} else if (!platform.equals(other.platform))
|
||||
return false;
|
||||
if (productCodes == null) {
|
||||
if (other.productCodes != null)
|
||||
return false;
|
||||
} else if (!productCodes.equals(other.productCodes))
|
||||
return false;
|
||||
if (ramdiskId == null) {
|
||||
if (other.ramdiskId != null)
|
||||
return false;
|
||||
} else if (!ramdiskId.equals(other.ramdiskId))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package org.jclouds.aws.ec2.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
|
||||
/**
|
||||
*
|
||||
* The current state of the instance..
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see EC2Client#describeInstances
|
||||
* @see EC2Client#runInstances
|
||||
* @see EC2Client#terminateInstances
|
||||
*
|
||||
*/
|
||||
public enum InstanceState {
|
||||
|
||||
/**
|
||||
* the instance is in the process of being launched
|
||||
*/
|
||||
PENDING,
|
||||
|
||||
/**
|
||||
* the instance launched (although the boot process might not be completed)
|
||||
*/
|
||||
RUNNING,
|
||||
|
||||
/**
|
||||
* the instance started shutting down
|
||||
*/
|
||||
SHUTTING_DOWN,
|
||||
/**
|
||||
* the instance terminated
|
||||
*/
|
||||
TERMINATED;
|
||||
|
||||
public String value() {
|
||||
return name().toLowerCase().replaceAll("_", "-");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
|
||||
public static InstanceState fromValue(String state) {
|
||||
return valueOf(checkNotNull(state, "state").replaceAll("-", "_").toUpperCase());
|
||||
}
|
||||
|
||||
public static InstanceState fromValue(int v) {
|
||||
switch (v) {
|
||||
case 0:
|
||||
return PENDING;
|
||||
case 16:
|
||||
return RUNNING;
|
||||
case 32:
|
||||
return SHUTTING_DOWN;
|
||||
case 48:
|
||||
return TERMINATED;
|
||||
default:
|
||||
throw new IllegalArgumentException("invalid state:" + v);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package org.jclouds.aws.ec2.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
|
||||
/**
|
||||
*
|
||||
* The type of the instance. Description accurate as of 8-15-2009 release.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see EC2Client#describeInstances
|
||||
* @see EC2Client#runInstances
|
||||
* @see EC2Client#terminateInstances
|
||||
*
|
||||
*/
|
||||
public enum InstanceType {
|
||||
/**
|
||||
* Small Instance
|
||||
* <ul>
|
||||
* <li>1.7 GB memory</li>
|
||||
* <li>1 EC2 Compute Unit (1 virtual core with 1 EC2 Compute Unit)</li>
|
||||
* <li>160 GB instance storage (150 GB plus 10 GB root partition)</li>
|
||||
* <li>32-bit platform</li>
|
||||
* <li>I/O Performance: Moderate</li>
|
||||
* </ul>
|
||||
*/
|
||||
M1_SMALL,
|
||||
/**
|
||||
* Large Instance
|
||||
* <ul>
|
||||
* <li>7.5 GB memory</li>
|
||||
* <li>4 EC2 Compute Units (2 virtual cores with 2 EC2 Compute Units each)</li>
|
||||
* <li>850 GB instance storage (2x420 GB plus 10 GB root partition)</li>
|
||||
* <li>64-bit platform</li>
|
||||
* <li>I/O Performance: High</li>
|
||||
* </ul>
|
||||
*/
|
||||
M1_LARGE,
|
||||
/**
|
||||
* Extra Large Instance
|
||||
* <ul>
|
||||
* <li>15 GB memory</li>
|
||||
* <li>8 EC2 Compute Units (4 virtual cores with 2 EC2 Compute Units each)</li>
|
||||
* <li>1690 GB instance storage (4x420 GB plus 10 GB root partition)</li>
|
||||
* <li>64-bit platform</li>
|
||||
* <li>I/O Performance: High</li>
|
||||
* </ul>
|
||||
*/
|
||||
M1_XLARGE,
|
||||
/**
|
||||
* High-Memory Double Extra Large Instance
|
||||
* <ul>
|
||||
* <li>34.2 GB of memory</li>
|
||||
* <li>13 EC2 Compute Units (4 virtual cores with 3.25 EC2 Compute Units each)</li>
|
||||
* <li>850 GB of instance storage</li>
|
||||
* <li>64-bit platform</li>
|
||||
* <li>I/O Performance: High</li>
|
||||
* </ul>
|
||||
*/
|
||||
M2_2XLARGE,
|
||||
/**
|
||||
* High-Memory Quadruple Extra Large Instance
|
||||
* <ul>
|
||||
* <li>68.4 GB of memory</li>
|
||||
* <li>26 EC2 Compute Units (8 virtual cores with 3.25 EC2 Compute Units each)</li>
|
||||
* <li>1690 GB of instance storage</li>
|
||||
* <li>64-bit platform</li>
|
||||
* <li>I/O Performance: High</li>
|
||||
* </ul>
|
||||
*/
|
||||
M2_4XLARGE,
|
||||
/**
|
||||
* High-CPU Medium Instance
|
||||
* <ul>
|
||||
* <li>1.7 GB of memory</li>
|
||||
* <li>5 EC2 Compute Units (2 virtual cores with 2.5 EC2 Compute Units each)</li>
|
||||
* <li>350 GB of instance storage</li>
|
||||
* <li>32-bit platform</li>
|
||||
* <li>I/O Performance: Moderate</li>
|
||||
* </ul>
|
||||
*/
|
||||
C1_MEDIUM,
|
||||
/**
|
||||
* High-CPU Extra Large Instance
|
||||
* <ul>
|
||||
* <li>7 GB of memory</li>
|
||||
* <li>20 EC2 Compute Units (8 virtual cores with 2.5 EC2 Compute Units each)</li>
|
||||
* <li>1690 GB of instance storage</li>
|
||||
* <li>64-bit platform</li>
|
||||
* <li>I/O Performance: High</li>
|
||||
* </ul>
|
||||
*/
|
||||
C1_XLARGE;
|
||||
public String value() {
|
||||
return name().toLowerCase().replaceAll("_", ".");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
|
||||
public static InstanceType fromValue(String type) {
|
||||
return valueOf(checkNotNull(type, "type").replaceAll("\\.", "_").toUpperCase());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
package org.jclouds.aws.ec2.domain;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-IpPermissionType.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class IpPermission implements Comparable<IpPermission> {
|
||||
private final int fromPort;
|
||||
private final int toPort;
|
||||
private final SortedSet<UserIdGroupPair> groups;
|
||||
private final IpProtocol ipProtocol;
|
||||
private final SortedSet<String> ipRanges;
|
||||
|
||||
public IpPermission(int fromPort, int toPort, SortedSet<UserIdGroupPair> groups,
|
||||
IpProtocol ipProtocol, SortedSet<String> ipRanges) {
|
||||
this.fromPort = fromPort;
|
||||
this.toPort = toPort;
|
||||
this.groups = groups;
|
||||
this.ipProtocol = ipProtocol;
|
||||
this.ipRanges = ipRanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public int compareTo(IpPermission o) {
|
||||
return (this == o) ? 0 : getIpProtocol().compareTo(o.getIpProtocol());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
public int getFromPort() {
|
||||
return fromPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
public int getToPort() {
|
||||
return toPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of security group and user ID pairs.
|
||||
*/
|
||||
public SortedSet<UserIdGroupPair> getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* IP protocol
|
||||
*/
|
||||
public IpProtocol getIpProtocol() {
|
||||
return ipProtocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* IP ranges.
|
||||
*/
|
||||
public SortedSet<String> getIpRanges() {
|
||||
return ipRanges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + fromPort;
|
||||
result = prime * result + ((groups == null) ? 0 : groups.hashCode());
|
||||
result = prime * result + ((ipProtocol == null) ? 0 : ipProtocol.hashCode());
|
||||
result = prime * result + ((ipRanges == null) ? 0 : ipRanges.hashCode());
|
||||
result = prime * result + toPort;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
IpPermission other = (IpPermission) obj;
|
||||
if (fromPort != other.fromPort)
|
||||
return false;
|
||||
if (groups == null) {
|
||||
if (other.groups != null)
|
||||
return false;
|
||||
} else if (!groups.equals(other.groups))
|
||||
return false;
|
||||
if (ipProtocol == null) {
|
||||
if (other.ipProtocol != null)
|
||||
return false;
|
||||
} else if (!ipProtocol.equals(other.ipProtocol))
|
||||
return false;
|
||||
if (ipRanges == null) {
|
||||
if (other.ipRanges != null)
|
||||
return false;
|
||||
} else if (!ipRanges.equals(other.ipRanges))
|
||||
return false;
|
||||
if (toPort != other.toPort)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.jclouds.aws.ec2.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public enum IpProtocol {
|
||||
|
||||
TCP, UDP, ICMP;
|
||||
|
||||
public String value() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
|
||||
public static IpProtocol fromValue(String protocol) {
|
||||
return valueOf(checkNotNull(protocol, "protocol").toUpperCase());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package org.jclouds.aws.ec2.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateKeyPair.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class KeyPair implements Comparable<KeyPair> {
|
||||
private final String keyName;
|
||||
private final String keyFingerprint;
|
||||
@Nullable
|
||||
private final String keyMaterial;
|
||||
|
||||
public KeyPair(String keyName, String keyFingerprint, @Nullable String keyMaterial) {
|
||||
this.keyName = checkNotNull(keyName, "keyName");
|
||||
this.keyFingerprint = checkNotNull(keyFingerprint, "keyFingerprint");
|
||||
this.keyMaterial = keyMaterial;// nullable on list
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public int compareTo(KeyPair o) {
|
||||
return (this == o) ? 0 : getKeyName().compareTo(o.getKeyName());
|
||||
}
|
||||
|
||||
/**
|
||||
* A SHA-1 digest of the DER encoded private key.
|
||||
*/
|
||||
public String getKeyFingerprint() {
|
||||
return keyFingerprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* An unencrypted PEM encoded RSA private key.
|
||||
*/
|
||||
public String getKeyMaterial() {
|
||||
return keyMaterial;
|
||||
}
|
||||
|
||||
/**
|
||||
* The key pair name provided in the original request.
|
||||
*/
|
||||
public String getKeyName() {
|
||||
return keyName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((keyFingerprint == null) ? 0 : keyFingerprint.hashCode());
|
||||
result = prime * result + ((keyMaterial == null) ? 0 : keyMaterial.hashCode());
|
||||
result = prime * result + ((keyName == null) ? 0 : keyName.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
KeyPair other = (KeyPair) obj;
|
||||
if (keyFingerprint == null) {
|
||||
if (other.keyFingerprint != null)
|
||||
return false;
|
||||
} else if (!keyFingerprint.equals(other.keyFingerprint))
|
||||
return false;
|
||||
if (keyMaterial == null) {
|
||||
if (other.keyMaterial != null)
|
||||
return false;
|
||||
} else if (!keyMaterial.equals(other.keyMaterial))
|
||||
return false;
|
||||
if (keyName == null) {
|
||||
if (other.keyName != null)
|
||||
return false;
|
||||
} else if (!keyName.equals(other.keyName))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
package org.jclouds.aws.ec2.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-ReservationInfoType.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class Reservation implements Comparable<Reservation> {
|
||||
public Reservation(SortedSet<String> groupIds, SortedSet<RunningInstance> instances,
|
||||
@Nullable String ownerId, @Nullable String requesterId, @Nullable String reservationId) {
|
||||
this.groupIds = checkNotNull(groupIds, "groupIds");
|
||||
this.instances = checkNotNull(instances, "instances");
|
||||
this.ownerId = ownerId;
|
||||
this.requesterId = requesterId;
|
||||
this.reservationId = reservationId;
|
||||
}
|
||||
|
||||
private final SortedSet<String> groupIds;
|
||||
private final SortedSet<RunningInstance> instances;
|
||||
private final @Nullable
|
||||
String ownerId;
|
||||
private final @Nullable
|
||||
String requesterId;
|
||||
private final @Nullable
|
||||
String reservationId;
|
||||
|
||||
public int compareTo(Reservation o) {
|
||||
return (this == o) ? 0 : getReservationId().compareTo(o.getReservationId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Names of the security groups.
|
||||
*/
|
||||
public SortedSet<String> getGroupIds() {
|
||||
return groupIds;
|
||||
}
|
||||
|
||||
public SortedSet<RunningInstance> getRunningInstances() {
|
||||
return instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* AWS Access Key ID of the user who owns the reservation.
|
||||
*/
|
||||
public String getOwnerId() {
|
||||
return ownerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* ID of the requester.
|
||||
*/
|
||||
public String getRequesterId() {
|
||||
return requesterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique ID of the reservation.
|
||||
*/
|
||||
public String getReservationId() {
|
||||
return reservationId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode());
|
||||
result = prime * result + ((instances == null) ? 0 : instances.hashCode());
|
||||
result = prime * result + ((ownerId == null) ? 0 : ownerId.hashCode());
|
||||
result = prime * result + ((requesterId == null) ? 0 : requesterId.hashCode());
|
||||
result = prime * result + ((reservationId == null) ? 0 : reservationId.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Reservation other = (Reservation) obj;
|
||||
if (groupIds == null) {
|
||||
if (other.groupIds != null)
|
||||
return false;
|
||||
} else if (!groupIds.equals(other.groupIds))
|
||||
return false;
|
||||
if (instances == null) {
|
||||
if (other.instances != null)
|
||||
return false;
|
||||
} else if (!instances.equals(other.instances))
|
||||
return false;
|
||||
if (ownerId == null) {
|
||||
if (other.ownerId != null)
|
||||
return false;
|
||||
} else if (!ownerId.equals(other.ownerId))
|
||||
return false;
|
||||
if (requesterId == null) {
|
||||
if (other.requesterId != null)
|
||||
return false;
|
||||
} else if (!requesterId.equals(other.requesterId))
|
||||
return false;
|
||||
if (reservationId == null) {
|
||||
if (other.reservationId != null)
|
||||
return false;
|
||||
} else if (!reservationId.equals(other.reservationId))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,367 @@
|
||||
package org.jclouds.aws.ec2.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-RunningInstancesItemType.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class RunningInstance implements Comparable<RunningInstance> {
|
||||
private final String amiLaunchIndex;
|
||||
private final @Nullable
|
||||
String dnsName;
|
||||
private final String imageId;
|
||||
private final String instanceId;
|
||||
private final InstanceState instanceState;
|
||||
private final InstanceType instanceType;
|
||||
private final @Nullable
|
||||
InetAddress ipAddress;
|
||||
private final @Nullable
|
||||
String kernelId;
|
||||
private final @Nullable
|
||||
String keyName;
|
||||
private final DateTime launchTime;
|
||||
private final boolean monitoring;
|
||||
private final String availabilityZone;
|
||||
private final @Nullable
|
||||
String platform;
|
||||
private final @Nullable
|
||||
String privateDnsName;
|
||||
private final @Nullable
|
||||
InetAddress privateIpAddress;
|
||||
private final Set<String> productCodes;
|
||||
private final @Nullable
|
||||
String ramdiskId;
|
||||
private final @Nullable
|
||||
String reason;
|
||||
private final @Nullable
|
||||
String subnetId;
|
||||
private final @Nullable
|
||||
String vpcId;
|
||||
|
||||
public int compareTo(RunningInstance o) {
|
||||
return (this == o) ? 0 : getInstanceId().compareTo(o.getInstanceId());
|
||||
}
|
||||
|
||||
public RunningInstance(String amiLaunchIndex, @Nullable String dnsName, String imageId,
|
||||
String instanceId, InstanceState instanceState, InstanceType instanceType,
|
||||
@Nullable InetAddress ipAddress, @Nullable String kernelId, @Nullable String keyName,
|
||||
DateTime launchTime, boolean monitoring, String availabilityZone,
|
||||
@Nullable String platform, @Nullable String privateDnsName,
|
||||
@Nullable InetAddress privateIpAddress, Set<String> productCodes,
|
||||
@Nullable String ramdiskId, @Nullable String reason, @Nullable String subnetId,
|
||||
@Nullable String vpcId) {
|
||||
this.amiLaunchIndex = checkNotNull(amiLaunchIndex, "amiLaunchIndex");
|
||||
this.dnsName = dnsName; // nullable on runinstances.
|
||||
this.imageId = checkNotNull(imageId, "imageId");
|
||||
this.instanceId = checkNotNull(instanceId, "instanceId");
|
||||
this.instanceState = checkNotNull(instanceState, "instanceState");
|
||||
this.instanceType = checkNotNull(instanceType, "instanceType");
|
||||
this.ipAddress = ipAddress;
|
||||
this.kernelId = kernelId;
|
||||
this.keyName = keyName;
|
||||
this.launchTime = checkNotNull(launchTime, "launchTime");
|
||||
this.monitoring = checkNotNull(monitoring, "monitoring");
|
||||
this.availabilityZone = checkNotNull(availabilityZone, "availabilityZone");
|
||||
this.platform = platform;
|
||||
this.privateDnsName = privateDnsName; // nullable on runinstances.
|
||||
this.privateIpAddress = privateIpAddress;
|
||||
this.productCodes = checkNotNull(productCodes, "productCodes");
|
||||
this.ramdiskId = ramdiskId;
|
||||
this.reason = reason;
|
||||
this.subnetId = subnetId;
|
||||
this.vpcId = vpcId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The AMI launch index, which can be used to find this instance within the launch group. For
|
||||
* more information, go to the Metadata section of the Amazon Elastic Compute Cloud Developer
|
||||
* Guide.
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/2009-08-15/DeveloperGuide/" />
|
||||
*/
|
||||
public String getAmiLaunchIndex() {
|
||||
return amiLaunchIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* The public DNS name assigned to the instance. This DNS name is contactable from outside the
|
||||
* Amazon EC2 network. This element remains empty until the instance enters a running state.
|
||||
*/
|
||||
public String getDnsName() {
|
||||
return dnsName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image ID of the AMI used to launch the instance.
|
||||
*/
|
||||
public String getImageId() {
|
||||
return imageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique ID of the instance launched.
|
||||
*/
|
||||
public String getInstanceId() {
|
||||
return instanceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The current state of the instance.
|
||||
*/
|
||||
public InstanceState getInstanceState() {
|
||||
return instanceState;
|
||||
}
|
||||
|
||||
/**
|
||||
* The instance type.
|
||||
*/
|
||||
public InstanceType getInstanceType() {
|
||||
return instanceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the IP address of the instance.
|
||||
*/
|
||||
public InetAddress getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional. Kernel associated with this instance.
|
||||
*/
|
||||
public String getKernelId() {
|
||||
return kernelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this instance was launched with an associated key pair, this displays the key pair name.
|
||||
*/
|
||||
public String getKeyName() {
|
||||
return keyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* The time the instance launched.
|
||||
*/
|
||||
public DateTime getLaunchTime() {
|
||||
return launchTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether monitoring is enabled for the instance.
|
||||
*/
|
||||
public boolean isMonitoring() {
|
||||
return monitoring;
|
||||
}
|
||||
|
||||
/**
|
||||
* The location where the instance launched.
|
||||
*/
|
||||
public String getAvailabilityZone() {
|
||||
return availabilityZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Platform of the instance (e.g., Windows).
|
||||
*/
|
||||
public String getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* The private DNS name assigned to the instance. This DNS name can only be used inside the
|
||||
* Amazon EC2 network. This element remains empty until the instance enters a running state.
|
||||
*/
|
||||
public String getPrivateDnsName() {
|
||||
return privateDnsName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the private IP address that is assigned to the instance (Amazon VPC).
|
||||
*/
|
||||
public InetAddress getPrivateIpAddress() {
|
||||
return privateIpAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Product codes attached to this instance.
|
||||
*/
|
||||
public Set<String> getProductCodes() {
|
||||
return productCodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional. RAM disk associated with this instance.
|
||||
*/
|
||||
public String getRamdiskId() {
|
||||
return ramdiskId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reason for the most recent state transition. This might be an empty string.
|
||||
*/
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the subnet ID in which the instance is running (Amazon Virtual Private Cloud).
|
||||
*/
|
||||
public String getSubnetId() {
|
||||
return subnetId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the VPC in which the instance is running (Amazon Virtual Private Cloud).
|
||||
*/
|
||||
public String getVpcId() {
|
||||
return vpcId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((amiLaunchIndex == null) ? 0 : amiLaunchIndex.hashCode());
|
||||
result = prime * result + ((availabilityZone == null) ? 0 : availabilityZone.hashCode());
|
||||
result = prime * result + ((dnsName == null) ? 0 : dnsName.hashCode());
|
||||
result = prime * result + ((imageId == null) ? 0 : imageId.hashCode());
|
||||
result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
|
||||
result = prime * result + ((instanceState == null) ? 0 : instanceState.hashCode());
|
||||
result = prime * result + ((instanceType == null) ? 0 : instanceType.hashCode());
|
||||
result = prime * result + ((ipAddress == null) ? 0 : ipAddress.hashCode());
|
||||
result = prime * result + ((kernelId == null) ? 0 : kernelId.hashCode());
|
||||
result = prime * result + ((keyName == null) ? 0 : keyName.hashCode());
|
||||
result = prime * result + ((launchTime == null) ? 0 : launchTime.hashCode());
|
||||
result = prime * result + (monitoring ? 1231 : 1237);
|
||||
result = prime * result + ((platform == null) ? 0 : platform.hashCode());
|
||||
result = prime * result + ((privateDnsName == null) ? 0 : privateDnsName.hashCode());
|
||||
result = prime * result + ((privateIpAddress == null) ? 0 : privateIpAddress.hashCode());
|
||||
result = prime * result + ((productCodes == null) ? 0 : productCodes.hashCode());
|
||||
result = prime * result + ((ramdiskId == null) ? 0 : ramdiskId.hashCode());
|
||||
result = prime * result + ((reason == null) ? 0 : reason.hashCode());
|
||||
result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode());
|
||||
result = prime * result + ((vpcId == null) ? 0 : vpcId.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
RunningInstance other = (RunningInstance) obj;
|
||||
if (amiLaunchIndex == null) {
|
||||
if (other.amiLaunchIndex != null)
|
||||
return false;
|
||||
} else if (!amiLaunchIndex.equals(other.amiLaunchIndex))
|
||||
return false;
|
||||
if (availabilityZone == null) {
|
||||
if (other.availabilityZone != null)
|
||||
return false;
|
||||
} else if (!availabilityZone.equals(other.availabilityZone))
|
||||
return false;
|
||||
if (dnsName == null) {
|
||||
if (other.dnsName != null)
|
||||
return false;
|
||||
} else if (!dnsName.equals(other.dnsName))
|
||||
return false;
|
||||
if (imageId == null) {
|
||||
if (other.imageId != null)
|
||||
return false;
|
||||
} else if (!imageId.equals(other.imageId))
|
||||
return false;
|
||||
if (instanceId == null) {
|
||||
if (other.instanceId != null)
|
||||
return false;
|
||||
} else if (!instanceId.equals(other.instanceId))
|
||||
return false;
|
||||
if (instanceState == null) {
|
||||
if (other.instanceState != null)
|
||||
return false;
|
||||
} else if (!instanceState.equals(other.instanceState))
|
||||
return false;
|
||||
if (instanceType == null) {
|
||||
if (other.instanceType != null)
|
||||
return false;
|
||||
} else if (!instanceType.equals(other.instanceType))
|
||||
return false;
|
||||
if (ipAddress == null) {
|
||||
if (other.ipAddress != null)
|
||||
return false;
|
||||
} else if (!ipAddress.equals(other.ipAddress))
|
||||
return false;
|
||||
if (kernelId == null) {
|
||||
if (other.kernelId != null)
|
||||
return false;
|
||||
} else if (!kernelId.equals(other.kernelId))
|
||||
return false;
|
||||
if (keyName == null) {
|
||||
if (other.keyName != null)
|
||||
return false;
|
||||
} else if (!keyName.equals(other.keyName))
|
||||
return false;
|
||||
if (launchTime == null) {
|
||||
if (other.launchTime != null)
|
||||
return false;
|
||||
} else if (!launchTime.equals(other.launchTime))
|
||||
return false;
|
||||
if (monitoring != other.monitoring)
|
||||
return false;
|
||||
if (platform == null) {
|
||||
if (other.platform != null)
|
||||
return false;
|
||||
} else if (!platform.equals(other.platform))
|
||||
return false;
|
||||
if (privateDnsName == null) {
|
||||
if (other.privateDnsName != null)
|
||||
return false;
|
||||
} else if (!privateDnsName.equals(other.privateDnsName))
|
||||
return false;
|
||||
if (privateIpAddress == null) {
|
||||
if (other.privateIpAddress != null)
|
||||
return false;
|
||||
} else if (!privateIpAddress.equals(other.privateIpAddress))
|
||||
return false;
|
||||
if (productCodes == null) {
|
||||
if (other.productCodes != null)
|
||||
return false;
|
||||
} else if (!productCodes.equals(other.productCodes))
|
||||
return false;
|
||||
if (ramdiskId == null) {
|
||||
if (other.ramdiskId != null)
|
||||
return false;
|
||||
} else if (!ramdiskId.equals(other.ramdiskId))
|
||||
return false;
|
||||
if (reason == null) {
|
||||
if (other.reason != null)
|
||||
return false;
|
||||
} else if (!reason.equals(other.reason))
|
||||
return false;
|
||||
if (subnetId == null) {
|
||||
if (other.subnetId != null)
|
||||
return false;
|
||||
} else if (!subnetId.equals(other.subnetId))
|
||||
return false;
|
||||
if (vpcId == null) {
|
||||
if (other.vpcId != null)
|
||||
return false;
|
||||
} else if (!vpcId.equals(other.vpcId))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package org.jclouds.aws.ec2.domain;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-SecurityGroupItemType.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class SecurityGroup implements Comparable<SecurityGroup> {
|
||||
private final String name;
|
||||
private final String ownerId;
|
||||
private final String description;
|
||||
private final SortedSet<IpPermission> ipPermissions;
|
||||
|
||||
public SecurityGroup(String name, String ownerId, String description,
|
||||
SortedSet<IpPermission> ipPermissions) {
|
||||
this.name = name;
|
||||
this.ownerId = ownerId;
|
||||
this.description = description;
|
||||
this.ipPermissions = ipPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public int compareTo(SecurityGroup o) {
|
||||
return (this == o) ? 0 : getName().compareTo(o.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the security group.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* AWS Access Key ID of the owner of the security group.
|
||||
*/
|
||||
public String getOwnerId() {
|
||||
return ownerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of the security group.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set of IP permissions associated with the security group.
|
||||
*/
|
||||
public SortedSet<IpPermission> getIpPermissions() {
|
||||
return ipPermissions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((description == null) ? 0 : description.hashCode());
|
||||
result = prime * result + ((ipPermissions == null) ? 0 : ipPermissions.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((ownerId == null) ? 0 : ownerId.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
SecurityGroup other = (SecurityGroup) obj;
|
||||
if (description == null) {
|
||||
if (other.description != null)
|
||||
return false;
|
||||
} else if (!description.equals(other.description))
|
||||
return false;
|
||||
if (ipPermissions == null) {
|
||||
if (other.ipPermissions != null)
|
||||
return false;
|
||||
} else if (!ipPermissions.equals(other.ipPermissions))
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (ownerId == null) {
|
||||
if (other.ownerId != null)
|
||||
return false;
|
||||
} else if (!ownerId.equals(other.ownerId))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package org.jclouds.aws.ec2.domain;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-TerminateInstancesResponseInfoType.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class TerminatedInstance implements Comparable<TerminatedInstance> {
|
||||
|
||||
private final String instanceId;
|
||||
private final InstanceState shutdownState;
|
||||
private final InstanceState previousState;
|
||||
|
||||
public int compareTo(TerminatedInstance o) {
|
||||
return (this == o) ? 0 : getInstanceId().compareTo(o.getInstanceId());
|
||||
}
|
||||
|
||||
public TerminatedInstance(String instanceId, InstanceState shutdownState,
|
||||
InstanceState previousState) {
|
||||
this.instanceId = instanceId;
|
||||
this.shutdownState = shutdownState;
|
||||
this.previousState = previousState;
|
||||
}
|
||||
|
||||
public String getInstanceId() {
|
||||
return instanceId;
|
||||
}
|
||||
|
||||
public InstanceState getShutdownState() {
|
||||
return shutdownState;
|
||||
}
|
||||
|
||||
public InstanceState getPreviousState() {
|
||||
return previousState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
|
||||
result = prime * result + ((previousState == null) ? 0 : previousState.hashCode());
|
||||
result = prime * result + ((shutdownState == null) ? 0 : shutdownState.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
TerminatedInstance other = (TerminatedInstance) obj;
|
||||
if (instanceId == null) {
|
||||
if (other.instanceId != null)
|
||||
return false;
|
||||
} else if (!instanceId.equals(other.instanceId))
|
||||
return false;
|
||||
if (previousState == null) {
|
||||
if (other.previousState != null)
|
||||
return false;
|
||||
} else if (!previousState.equals(other.previousState))
|
||||
return false;
|
||||
if (shutdownState == null) {
|
||||
if (other.shutdownState != null)
|
||||
return false;
|
||||
} else if (!shutdownState.equals(other.shutdownState))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package org.jclouds.aws.ec2.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-UserIdGroupPairType.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class UserIdGroupPair implements Comparable<UserIdGroupPair> {
|
||||
private final String userId;
|
||||
private final String groupName;
|
||||
|
||||
public UserIdGroupPair(String userId, String groupName) {
|
||||
this.userId = checkNotNull(userId,"userId");
|
||||
this.groupName = checkNotNull(groupName,"groupName");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public int compareTo(UserIdGroupPair o) {
|
||||
return (this == o) ? 0 : getUserId().compareTo(o.getUserId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AWS User ID of an account. Cannot be used when specifying a CIDR IP address.
|
||||
*/
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Name of the security group. Cannot be used when specifying a CIDR IP address.
|
||||
*/
|
||||
public String getGroupName() {
|
||||
return groupName;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((groupName == null) ? 0 : groupName.hashCode());
|
||||
result = prime * result + ((userId == null) ? 0 : userId.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
UserIdGroupPair other = (UserIdGroupPair) obj;
|
||||
if (groupName == null) {
|
||||
if (other.groupName != null)
|
||||
return false;
|
||||
} else if (!groupName.equals(other.groupName))
|
||||
return false;
|
||||
if (userId == null) {
|
||||
if (other.userId != null)
|
||||
return false;
|
||||
} else if (!userId.equals(other.userId))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
213
aws/core/src/main/java/org/jclouds/aws/ec2/filters/FormSigner.java
Executable file
213
aws/core/src/main/java/org/jclouds/aws/ec2/filters/FormSigner.java
Executable file
@ -0,0 +1,213 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.filters;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static org.jclouds.aws.ec2.reference.EC2Parameters.ACTION;
|
||||
import static org.jclouds.aws.ec2.reference.EC2Parameters.AWS_ACCESS_KEY_ID;
|
||||
import static org.jclouds.aws.ec2.reference.EC2Parameters.SIGNATURE;
|
||||
import static org.jclouds.aws.ec2.reference.EC2Parameters.SIGNATURE_METHOD;
|
||||
import static org.jclouds.aws.ec2.reference.EC2Parameters.SIGNATURE_VERSION;
|
||||
import static org.jclouds.aws.ec2.reference.EC2Parameters.TIMESTAMP;
|
||||
import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jclouds.aws.reference.AWSConstants;
|
||||
import org.jclouds.aws.util.RequestSigner;
|
||||
import org.jclouds.http.HttpConstants;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.internal.SignatureWire;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||
import org.jclouds.util.TimeStamp;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/Form-Common-Parameters.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Singleton
|
||||
public class FormSigner implements HttpRequestFilter, RequestSigner {
|
||||
|
||||
public static String[] mandatoryParametersForSignature = new String[] { ACTION,
|
||||
SIGNATURE_METHOD, SIGNATURE_VERSION, VERSION };
|
||||
private final SignatureWire signatureWire;
|
||||
private final String accessKey;
|
||||
private final String secretKey;
|
||||
private final Provider<String> dateService;
|
||||
@Resource
|
||||
@Named(HttpConstants.SIGNATURE_LOGGER)
|
||||
private final Logger signatureLog = Logger.NULL;
|
||||
|
||||
@Inject
|
||||
public FormSigner(SignatureWire signatureWire,
|
||||
@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String accessKey,
|
||||
@Named(AWSConstants.PROPERTY_AWS_SECRETACCESSKEY) String secretKey,
|
||||
@TimeStamp Provider<String> dateService) {
|
||||
this.signatureWire = signatureWire;
|
||||
this.accessKey = accessKey;
|
||||
this.secretKey = secretKey;
|
||||
this.dateService = dateService;
|
||||
}
|
||||
|
||||
public void filter(HttpRequest in) throws HttpException {
|
||||
GeneratedHttpRequest<?> request = (GeneratedHttpRequest<?>) in;
|
||||
checkNotNull(request.getFirstHeaderOrNull(HttpHeaders.HOST),
|
||||
"request is not ready to sign; host not present");
|
||||
Multimap<String, String> decodedParams = RestAnnotationProcessor.parseQueryToMap(request
|
||||
.getEntity().toString());
|
||||
addSigningParams(decodedParams);
|
||||
validateParams(decodedParams);
|
||||
String stringToSign = createStringToSign(request, decodedParams);
|
||||
String signature = signString(stringToSign);
|
||||
addSignature(decodedParams, signature);
|
||||
setEntity(request, decodedParams);
|
||||
HttpUtils.logRequest(signatureLog, request, "<<");
|
||||
}
|
||||
|
||||
String[] sortForSigning(String queryLine) {
|
||||
String[] parts = queryLine.split("&");
|
||||
// 1. Sort the UTF-8 query string components by parameter name with natural byte ordering.
|
||||
Arrays.sort(parts, new Comparator<String>() {
|
||||
|
||||
public int compare(String o1, String o2) {
|
||||
if (o1.startsWith("AWSAccessKeyId"))
|
||||
return -1;
|
||||
return o1.compareTo(o2);
|
||||
}
|
||||
|
||||
});
|
||||
return parts;
|
||||
}
|
||||
|
||||
void setEntity(GeneratedHttpRequest<?> request, Multimap<String, String> decodedParams) {
|
||||
request.setEntity(RestAnnotationProcessor.makeQueryLine(decodedParams,
|
||||
new Comparator<Map.Entry<String, String>>() {
|
||||
public int compare(Entry<String, String> o1, Entry<String, String> o2) {
|
||||
if (o1.getKey().startsWith("Action")
|
||||
|| o2.getKey().startsWith("AWSAccessKeyId"))
|
||||
return -1;
|
||||
if (o1.getKey().startsWith("AWSAccessKeyId")
|
||||
|| o2.getKey().startsWith("Action"))
|
||||
return 1;
|
||||
return o1.getKey().compareTo(o2.getKey());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void validateParams(Multimap<String, String> params) {
|
||||
for (String parameter : mandatoryParametersForSignature) {
|
||||
checkState(params.containsKey(parameter), "parameter " + parameter
|
||||
+ " is required for signature");
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void addSignature(Multimap<String, String> params, String signature) {
|
||||
params.replaceValues(SIGNATURE, ImmutableList.of(signature));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public String signString(String stringToSign) {
|
||||
String signature;
|
||||
try {
|
||||
signature = HttpUtils.hmacSha256Base64(stringToSign, secretKey.getBytes());
|
||||
if (signatureWire.enabled())
|
||||
signatureWire.input(IOUtils.toInputStream(signature));
|
||||
} catch (Exception e) {
|
||||
throw new HttpException("error signing request", e);
|
||||
}
|
||||
return signature;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public String createStringToSign(HttpRequest request, Multimap<String, String> decodedParams) {
|
||||
HttpUtils.logRequest(signatureLog, request, ">>");
|
||||
StringBuilder stringToSign = new StringBuilder();
|
||||
// StringToSign = HTTPVerb + "\n" +
|
||||
stringToSign.append(request.getMethod()).append("\n");
|
||||
// ValueOfHostHeaderInLowercase + "\n" +
|
||||
stringToSign.append(request.getFirstHeaderOrNull(HttpHeaders.HOST).toLowerCase())
|
||||
.append("\n");
|
||||
// HTTPRequestURI + "\n" +
|
||||
stringToSign.append(request.getEndpoint().getPath()).append("\n");
|
||||
// CanonicalizedFormString <from the preceding step>
|
||||
stringToSign.append(buildCanonicalizedString(decodedParams));
|
||||
if (signatureWire.enabled())
|
||||
signatureWire.output(stringToSign.toString());
|
||||
return stringToSign.toString();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String buildCanonicalizedString(Multimap<String, String> decodedParams) {
|
||||
return RestAnnotationProcessor.makeQueryLine(decodedParams,
|
||||
new Comparator<Map.Entry<String, String>>() {
|
||||
public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
|
||||
if (o1.getKey().startsWith("AWSAccessKeyId"))
|
||||
return -1;
|
||||
return o1.getKey().compareTo(o2.getKey());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void addSigningParams(Multimap<String, String> params) {
|
||||
params.replaceValues(SIGNATURE_METHOD, ImmutableList.of("HmacSHA256"));
|
||||
params.replaceValues(SIGNATURE_VERSION, ImmutableList.of("2"));
|
||||
params.replaceValues(TIMESTAMP, ImmutableList.of(dateService.get()));
|
||||
params.replaceValues(AWS_ACCESS_KEY_ID, ImmutableList.of(accessKey));
|
||||
params.removeAll(SIGNATURE);
|
||||
}
|
||||
|
||||
public String createStringToSign(HttpRequest input) {
|
||||
return createStringToSign(input, RestAnnotationProcessor.parseQueryToMap(input.getEntity()
|
||||
.toString()));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package org.jclouds.aws.ec2.functions;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.AWSResponseException;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
@Singleton
|
||||
public class ReturnVoidOnGroupNotFound implements Function<Exception, Void> {
|
||||
|
||||
static final Void v;
|
||||
static {
|
||||
Constructor<Void> cv;
|
||||
try {
|
||||
cv = Void.class.getDeclaredConstructor();
|
||||
cv.setAccessible(true);
|
||||
v = cv.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new Error("Error setting up class", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Void apply(Exception from) {
|
||||
if (from instanceof AWSResponseException) {
|
||||
if (((AWSResponseException) from).getError().getCode().equals("InvalidGroup.NotFound"))
|
||||
return v;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
package org.jclouds.aws.ec2.options;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.aws.ec2.options.internal.BaseEC2RequestOptions;
|
||||
|
||||
/**
|
||||
* Contains options supported in the Form API for the DescribeImages operation. <h2>
|
||||
* Usage</h2> The recommended way to instantiate a DescribeImagesOptions object is to statically
|
||||
* import DescribeImagesOptions.Builder.* and invoke a static creation method followed by an
|
||||
* instance mutator (if needed):
|
||||
* <p/>
|
||||
* <code>
|
||||
* import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.*
|
||||
* <p/>
|
||||
* EC2Client connection = // get connection
|
||||
* Future<SortedSet<ImageMetadata>> images = connection.describeImages(executableBy("123125").imageIds(1000, 1004));
|
||||
* <code>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a
|
||||
* href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-form-DescribeImages.html"
|
||||
* />
|
||||
*/
|
||||
public class DescribeImagesOptions extends BaseEC2RequestOptions {
|
||||
public static final DescribeImagesOptions NONE = new DescribeImagesOptions();
|
||||
|
||||
/**
|
||||
* AMIs for which the specified user has explicit launch permissions.
|
||||
*
|
||||
*/
|
||||
public DescribeImagesOptions executableBy(String accountId) {
|
||||
formParameters.put("ExecutableBy", checkNotNull(accountId, "accountId"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getExecutableBy() {
|
||||
return getFirstFormOrNull("ExecutableBy");
|
||||
}
|
||||
|
||||
/**
|
||||
* AMI IDs to describe.
|
||||
*/
|
||||
public DescribeImagesOptions imageIds(String... imageIds) {
|
||||
indexFormValuesWithPrefix("ImageId", imageIds);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Set<String> getImageIds() {
|
||||
return getFormValuesWithKeysPrefixedBy("ImageId.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns AMIs owned by the specified owner. Multiple owners can be specified.
|
||||
*/
|
||||
public DescribeImagesOptions ownedBy(String... owners) {
|
||||
indexFormValuesWithPrefix("Owner", owners);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Set<String> getOwners() {
|
||||
return getFormValuesWithKeysPrefixedBy("Owner.");
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
* @see DescribeImagesOptions#executableBy(String )
|
||||
*/
|
||||
public static DescribeImagesOptions executableBy(String accountId) {
|
||||
DescribeImagesOptions options = new DescribeImagesOptions();
|
||||
return options.executableBy(accountId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DescribeImagesOptions#imageIds(String[] )
|
||||
*/
|
||||
public static DescribeImagesOptions imageIds(String... imageIds) {
|
||||
DescribeImagesOptions options = new DescribeImagesOptions();
|
||||
return options.imageIds(imageIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DescribeImagesOptions#ownedBy(String[] )
|
||||
*/
|
||||
public static DescribeImagesOptions ownedBy(String... owners) {
|
||||
DescribeImagesOptions options = new DescribeImagesOptions();
|
||||
return options.ownedBy(owners);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,277 @@
|
||||
package org.jclouds.aws.ec2.options;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||
import org.jclouds.aws.ec2.options.internal.BaseEC2RequestOptions;
|
||||
|
||||
/**
|
||||
* Contains options supported in the Form API for the RunInstances operation. <h2>
|
||||
* Usage</h2> The recommended way to instantiate a RunInstancesOptions object is to statically
|
||||
* import RunInstancesOptions.Builder.* and invoke a static creation method followed by an instance
|
||||
* mutator (if needed):
|
||||
* <p/>
|
||||
* <code>
|
||||
* import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.*
|
||||
* <p/>
|
||||
* EC2Client connection = // get connection
|
||||
* Future<ReservationInfo> instances = connection.runInstances(executableBy("123125").imageIds(1000, 1004));
|
||||
* <code>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a
|
||||
* href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-form-RunInstances.html"
|
||||
* />
|
||||
*/
|
||||
public class RunInstancesOptions extends BaseEC2RequestOptions {
|
||||
public static final RunInstancesOptions NONE = new RunInstancesOptions();
|
||||
|
||||
/**
|
||||
* The name of the key pair.
|
||||
*/
|
||||
public RunInstancesOptions withKeyName(String keyName) {
|
||||
formParameters.put("KeyName", checkNotNull(keyName, "keyName"));
|
||||
return this;
|
||||
}
|
||||
|
||||
String getKeyName() {
|
||||
return getFirstFormOrNull("KeyName");
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the security group.
|
||||
*/
|
||||
public RunInstancesOptions withSecurityGroup(String securityGroup) {
|
||||
formParameters.put("SecurityGroup", checkNotNull(securityGroup, "securityGroup"));
|
||||
return this;
|
||||
}
|
||||
|
||||
String getSecurityGroup() {
|
||||
return getFirstFormOrNull("SecurityGroup");
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies additional information to make available to the instance(s).
|
||||
*/
|
||||
public RunInstancesOptions withAdditionalInfo(String info) {
|
||||
formParameters.put("AdditionalInfo", checkNotNull(info, "info"));
|
||||
return this;
|
||||
}
|
||||
|
||||
String getAdditionalInfo() {
|
||||
return getFirstFormOrNull("AdditionalInfo");
|
||||
}
|
||||
|
||||
/**
|
||||
* MIME, Base64-encoded user data.
|
||||
*/
|
||||
public RunInstancesOptions withUserData(String info) {
|
||||
formParameters.put("UserData", checkNotNull(info, "info"));
|
||||
return this;
|
||||
}
|
||||
|
||||
String getUserData() {
|
||||
return getFirstFormOrNull("UserData");
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the instance type. default small;
|
||||
*/
|
||||
public RunInstancesOptions asType(InstanceType type) {
|
||||
formParameters.put("InstanceType", checkNotNull(type, "type").toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
String getType() {
|
||||
return getFirstFormOrNull("InstanceType");
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the placement constraints (Availability Zones) for launching the instances.
|
||||
*/
|
||||
public RunInstancesOptions inAvailabilityZone(String availabilityZone) {
|
||||
formParameters.put("Placement.AvailabilityZone", checkNotNull(availabilityZone,
|
||||
"availabilityZone"));
|
||||
return this;
|
||||
}
|
||||
|
||||
String getAvailabilityZone() {
|
||||
return getFirstFormOrNull("Placement.AvailabilityZone");
|
||||
}
|
||||
|
||||
/**
|
||||
* The ID of the kernel with which to launch the instance.
|
||||
*/
|
||||
public RunInstancesOptions withKernelId(String kernelId) {
|
||||
formParameters.put("KernelId", checkNotNull(kernelId, "kernelId"));
|
||||
return this;
|
||||
}
|
||||
|
||||
String getKernelId() {
|
||||
return getFirstFormOrNull("KernelId");
|
||||
}
|
||||
|
||||
/**
|
||||
* The ID of the RAM disk with which to launch the instance. Some kernels require additional
|
||||
* drivers at l aunch. Check the kernel requirements for information on whether you need to
|
||||
* specify a RAM disk. To find kernel requirements, go to th e Resource Center and search for the
|
||||
* kernel ID.
|
||||
*/
|
||||
public RunInstancesOptions withRamdisk(String ramDiskId) {
|
||||
formParameters.put("RamdiskId", checkNotNull(ramDiskId, "ramDiskId"));
|
||||
return this;
|
||||
}
|
||||
|
||||
String getRamdiskId() {
|
||||
return getFirstFormOrNull("RamdiskId");
|
||||
}
|
||||
|
||||
/**
|
||||
* The virtual name.
|
||||
*/
|
||||
public RunInstancesOptions withVirtualName(String virtualName) {
|
||||
formParameters
|
||||
.put("BlockDeviceMapping.VirtualName", checkNotNull(virtualName, "virtualName"));
|
||||
return this;
|
||||
}
|
||||
|
||||
String getVirtualName() {
|
||||
return getFirstFormOrNull("BlockDeviceMapping.VirtualName");
|
||||
}
|
||||
|
||||
/**
|
||||
* The device name (e.g., /dev/sdh).
|
||||
*/
|
||||
public RunInstancesOptions withDeviceName(String deviceName) {
|
||||
formParameters.put("BlockDeviceMapping.DeviceName", checkNotNull(deviceName, "deviceName"));
|
||||
return this;
|
||||
}
|
||||
|
||||
String getDeviceName() {
|
||||
return getFirstFormOrNull("BlockDeviceMapping.DeviceName");
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables monitoring for the instance.
|
||||
*/
|
||||
public RunInstancesOptions enableMonitoring() {
|
||||
formParameters.put("Monitoring.Enabled", "true");
|
||||
return this;
|
||||
}
|
||||
|
||||
String getMonitoringEnabled() {
|
||||
return getFirstFormOrNull("Monitoring.Enabled");
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the subnet ID within which to launch the instance(s) for Amazon Virtual Private
|
||||
* Cloud.
|
||||
*/
|
||||
public RunInstancesOptions withSubnetId(String subnetId) {
|
||||
formParameters.put("SubnetId", checkNotNull(subnetId, "subnetId"));
|
||||
return this;
|
||||
}
|
||||
|
||||
String getSubnetId() {
|
||||
return getFirstFormOrNull("SubnetId");
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
/**
|
||||
* @see RunInstancesOptions#withKeyName(String)
|
||||
*/
|
||||
public static RunInstancesOptions withKeyName(String keyName) {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
return options.withKeyName(keyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RunInstancesOptions#withSecurityGroup(String)
|
||||
*/
|
||||
public static RunInstancesOptions withSecurityGroup(String securityGroup) {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
return options.withSecurityGroup(securityGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RunInstancesOptions#withAdditionalInfo(String)
|
||||
*/
|
||||
public static RunInstancesOptions withAdditionalInfo(String additionalInfo) {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
return options.withAdditionalInfo(additionalInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RunInstancesOptions#withUserData(String)
|
||||
*/
|
||||
public static RunInstancesOptions withUserData(String userData) {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
return options.withUserData(userData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RunInstancesOptions#asType(InstanceType)
|
||||
*/
|
||||
public static RunInstancesOptions asType(InstanceType instanceType) {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
return options.asType(instanceType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RunInstancesOptions#inAvailabilityZone(String)
|
||||
*/
|
||||
public static RunInstancesOptions inAvailabilityZone(String availabilityZone) {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
return options.inAvailabilityZone(availabilityZone);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RunInstancesOptions#withKernelId(String)
|
||||
*/
|
||||
public static RunInstancesOptions withKernelId(String kernelId) {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
return options.withKernelId(kernelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RunInstancesOptions#withDeviceName(String)
|
||||
*/
|
||||
public static RunInstancesOptions withDeviceName(String deviceName) {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
return options.withDeviceName(deviceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RunInstancesOptions#enableMonitoring()
|
||||
*/
|
||||
public static RunInstancesOptions enableMonitoring() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
return options.enableMonitoring();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RunInstancesOptions#withSubnetId(String)
|
||||
*/
|
||||
public static RunInstancesOptions withSubnetId(String subnetId) {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
return options.withSubnetId(subnetId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RunInstancesOptions#withRamdisk(String)
|
||||
*/
|
||||
public static RunInstancesOptions withRamdisk(String ramdiskId) {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
return options.withRamdisk(ramdiskId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RunInstancesOptions#withVirtualName(String)
|
||||
*/
|
||||
public static RunInstancesOptions withVirtualName(String virtualName) {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
return options.withVirtualName(virtualName);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.options.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BaseEC2RequestOptions extends BaseHttpRequestOptions {
|
||||
|
||||
protected void indexFormValuesWithPrefix(String prefix, String... values) {
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
formParameters.put(prefix + "." + (i + 1), checkNotNull(values[i], prefix.toLowerCase()
|
||||
+ "s[" + i + "]"));
|
||||
}
|
||||
}
|
||||
|
||||
protected Set<String> getFormValuesWithKeysPrefixedBy(final String prefix) {
|
||||
Set<String> values = Sets.newLinkedHashSet();
|
||||
for (String key : Iterables.filter(formParameters.keySet(), new Predicate<String>() {
|
||||
|
||||
public boolean apply(String input) {
|
||||
return input.startsWith(prefix);
|
||||
}
|
||||
|
||||
})) {
|
||||
values.add(formParameters.get(key).iterator().next());
|
||||
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
}
|
@ -31,4 +31,10 @@ import org.jclouds.aws.reference.AWSConstants;
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface EC2Constants extends AWSConstants {
|
||||
public static final String PROPERTY_EC2_ENDPOINT = "jclouds.ec2.endpoint";
|
||||
|
||||
/**
|
||||
* how long do we wait before expiring requests.
|
||||
*/
|
||||
public static final String PROPERTY_EC2_EXPIREINTERVAL = "jclouds.ec2.expireinterval";
|
||||
}
|
@ -29,7 +29,7 @@ package org.jclouds.aws.ec2.reference;
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/Query-Common-Parameters.html"/>
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface CommonEC2Parameters {
|
||||
public interface EC2Parameters {
|
||||
|
||||
/**
|
||||
* Indicates the action to perform. Example: RunInstances
|
@ -0,0 +1,24 @@
|
||||
package org.jclouds.aws.ec2.util;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class EC2Utils {
|
||||
public static void indexFormValuesWithPrefix(GeneratedHttpRequest<?> request, String prefix,
|
||||
Object input) {
|
||||
checkArgument(checkNotNull(input, "input") instanceof String[],
|
||||
"this binder is only valid for String[] : " + input.getClass());
|
||||
String[] values = (String[]) input;
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
request.addFormParam(prefix + "." + (i + 1), checkNotNull(values[i], prefix
|
||||
.toLowerCase()
|
||||
+ "s[" + i + "]"));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,218 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.InstanceState;
|
||||
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||
import org.jclouds.aws.ec2.domain.Reservation;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.joda.time.DateTime;
|
||||
import org.xml.sax.Attributes;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
public abstract class BaseReservationHandler<T> extends HandlerWithResult<T> {
|
||||
|
||||
protected final DateService dateService;
|
||||
|
||||
public BaseReservationHandler(DateService dateService) {
|
||||
this.dateService = dateService;
|
||||
}
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
private StringBuilder currentText = new StringBuilder();
|
||||
private SortedSet<String> groupIds = Sets.newTreeSet();
|
||||
private SortedSet<RunningInstance> instances = Sets.newTreeSet();
|
||||
private String ownerId;
|
||||
private String requesterId;
|
||||
private String reservationId;
|
||||
private String amiLaunchIndex;
|
||||
private String dnsName;
|
||||
private String imageId;
|
||||
private String instanceId;
|
||||
private InstanceState instanceState;
|
||||
private InstanceType instanceType;
|
||||
private InetAddress ipAddress;
|
||||
private String kernelId;
|
||||
private String keyName;
|
||||
private DateTime launchTime;
|
||||
private boolean monitoring;
|
||||
private String availabilityZone;
|
||||
private String platform;
|
||||
private String privateDnsName;
|
||||
private InetAddress privateIpAddress;
|
||||
private Set<String> productCodes = Sets.newHashSet();
|
||||
private String ramdiskId;
|
||||
private String reason;
|
||||
private String subnetId;
|
||||
private String vpcId;
|
||||
protected boolean inInstances;
|
||||
protected boolean inProductCodes;
|
||||
protected boolean inGroups;
|
||||
|
||||
public void startElement(String uri, String name, String qName, Attributes attrs) {
|
||||
if (qName.equals("instancesSet")) {
|
||||
inInstances = true;
|
||||
} else if (qName.equals("productCodesSet")) {
|
||||
inProductCodes = true;
|
||||
} else if (qName.equals("groupSet")) {
|
||||
inGroups = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected String currentOrNull() {
|
||||
String returnVal = currentText.toString().trim();
|
||||
return returnVal.equals("") ? null : returnVal;
|
||||
}
|
||||
|
||||
public void endElement(String uri, String name, String qName) {
|
||||
if (qName.equals("groupId")) {
|
||||
groupIds.add(currentOrNull());
|
||||
} else if (qName.equals("ownerId")) {
|
||||
ownerId = currentOrNull();
|
||||
} else if (qName.equals("requesterId")) {
|
||||
requesterId = currentOrNull();
|
||||
} else if (qName.equals("reservationId")) {
|
||||
reservationId = currentOrNull();
|
||||
} else if (qName.equals("amiLaunchIndex")) {
|
||||
amiLaunchIndex = currentOrNull();
|
||||
} else if (qName.equals("dnsName")) {
|
||||
dnsName = currentOrNull();
|
||||
} else if (qName.equals("imageId")) {
|
||||
imageId = currentOrNull();
|
||||
} else if (qName.equals("instanceId")) {
|
||||
instanceId = currentOrNull();
|
||||
} else if (qName.equals("name")) {
|
||||
instanceState = InstanceState.fromValue(currentOrNull());
|
||||
} else if (qName.equals("instanceType")) {
|
||||
instanceType = InstanceType.fromValue(currentOrNull());
|
||||
} else if (qName.equals("ipAddress")) {
|
||||
ipAddress = parseInetAddress(currentOrNull());
|
||||
} else if (qName.equals("kernelId")) {
|
||||
kernelId = currentOrNull();
|
||||
} else if (qName.equals("keyName")) {
|
||||
keyName = currentOrNull();
|
||||
} else if (qName.equals("launchTime")) {
|
||||
launchTime = dateService.iso8601DateParse(currentOrNull());
|
||||
} else if (qName.equals("enabled")) {
|
||||
monitoring = Boolean.parseBoolean(currentOrNull());
|
||||
} else if (qName.equals("availabilityZone")) {
|
||||
availabilityZone = currentOrNull();
|
||||
} else if (qName.equals("platform")) {
|
||||
platform = currentOrNull();
|
||||
} else if (qName.equals("privateDnsName")) {
|
||||
privateDnsName = currentOrNull();
|
||||
} else if (qName.equals("privateIpAddress")) {
|
||||
privateIpAddress = parseInetAddress(currentOrNull());
|
||||
} else if (qName.equals("ramdiskId")) {
|
||||
ramdiskId = currentOrNull();
|
||||
} else if (qName.equals("reason")) {
|
||||
reason = currentOrNull();
|
||||
} else if (qName.equals("subnetId")) {
|
||||
subnetId = currentOrNull();
|
||||
} else if (qName.equals("vpcId")) {
|
||||
vpcId = currentOrNull();
|
||||
} else if (qName.equals("productCode")) {
|
||||
productCodes.add(currentOrNull());
|
||||
} else if (qName.equals("productCodesSet")) {
|
||||
inProductCodes = false;
|
||||
} else if (qName.equals("instancesSet")) {
|
||||
inInstances = false;
|
||||
} else if (qName.equals("groupSet")) {
|
||||
inGroups = false;
|
||||
} else if (qName.equals("item")) {
|
||||
inItem();
|
||||
}
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
||||
protected void inItem() {
|
||||
if (inInstances && !inProductCodes) {
|
||||
instances.add(new RunningInstance(amiLaunchIndex, dnsName, imageId, instanceId,
|
||||
instanceState, instanceType, ipAddress, kernelId, keyName, launchTime,
|
||||
monitoring, availabilityZone, platform, privateDnsName, privateIpAddress,
|
||||
productCodes, ramdiskId, reason, subnetId, vpcId));
|
||||
this.amiLaunchIndex = null;
|
||||
this.dnsName = null;
|
||||
this.imageId = null;
|
||||
this.instanceId = null;
|
||||
this.instanceState = null;
|
||||
this.instanceType = null;
|
||||
this.ipAddress = null;
|
||||
this.kernelId = null;
|
||||
this.keyName = null;
|
||||
this.launchTime = null;
|
||||
this.monitoring = false;
|
||||
this.availabilityZone = null;
|
||||
this.platform = null;
|
||||
this.privateDnsName = null;
|
||||
this.privateIpAddress = null;
|
||||
this.productCodes = Sets.newHashSet();
|
||||
this.ramdiskId = null;
|
||||
this.reason = null;
|
||||
this.subnetId = null;
|
||||
this.vpcId = null;
|
||||
}
|
||||
}
|
||||
|
||||
private InetAddress parseInetAddress(String string) {
|
||||
String[] byteStrings = string.split("\\.");
|
||||
byte[] bytes = new byte[4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
bytes[i] = (byte) Integer.parseInt(byteStrings[i]);
|
||||
}
|
||||
try {
|
||||
return InetAddress.getByAddress(bytes);
|
||||
} catch (UnknownHostException e) {
|
||||
logger.warn(e, "error parsing ipAddress", currentText);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void characters(char ch[], int start, int length) {
|
||||
currentText.append(ch, start, length);
|
||||
}
|
||||
|
||||
protected Reservation newReservation() {
|
||||
Reservation info = new Reservation(groupIds, instances, ownerId, requesterId, reservationId);
|
||||
this.groupIds = Sets.newTreeSet();
|
||||
this.instances = Sets.newTreeSet();
|
||||
this.ownerId = null;
|
||||
this.requesterId = null;
|
||||
this.reservationId = null;
|
||||
return info;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,137 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.Image;
|
||||
import org.jclouds.aws.ec2.domain.Image.Architecture;
|
||||
import org.jclouds.aws.ec2.domain.Image.ImageState;
|
||||
import org.jclouds.aws.ec2.domain.Image.ImageType;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.xml.sax.Attributes;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
* Parses the following XML document:
|
||||
* <p/>
|
||||
* DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/2009-08-15/"
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeImages.html"
|
||||
* />
|
||||
*/
|
||||
public class DescribeImagesResponseHandler extends ParseSax.HandlerWithResult<SortedSet<Image>> {
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private SortedSet<Image> contents = Sets.newTreeSet();
|
||||
private StringBuilder currentText = new StringBuilder();
|
||||
|
||||
private Architecture architecture;
|
||||
private String imageId;
|
||||
private String imageLocation;
|
||||
private String imageOwnerId;
|
||||
private ImageState imageState;
|
||||
private ImageType imageType;
|
||||
private boolean isPublic;
|
||||
private @Nullable
|
||||
String kernelId;
|
||||
private String platform;
|
||||
private Set<String> productCodes = Sets.newHashSet();
|
||||
private @Nullable
|
||||
String ramdiskId;
|
||||
private boolean inProductCodes;
|
||||
|
||||
public SortedSet<Image> getResult() {
|
||||
return contents;
|
||||
}
|
||||
|
||||
public void startElement(String uri, String name, String qName, Attributes attrs) {
|
||||
if (qName.equals("productCodesSet")) {
|
||||
inProductCodes = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void endElement(String uri, String name, String qName) {
|
||||
if (qName.equals("architecture")) {
|
||||
architecture = Architecture.fromValue(currentText.toString().trim());
|
||||
} else if (qName.equals("imageId")) {
|
||||
imageId = currentText.toString().trim();
|
||||
} else if (qName.equals("imageLocation")) {
|
||||
imageLocation = currentText.toString().trim();
|
||||
} else if (qName.equals("imageOwnerId")) {
|
||||
imageOwnerId = currentText.toString().trim();
|
||||
} else if (qName.equals("imageState")) {
|
||||
imageState = ImageState.fromValue(currentText.toString().trim());
|
||||
} else if (qName.equals("imageType")) {
|
||||
imageType = ImageType.fromValue(currentText.toString().trim());
|
||||
} else if (qName.equals("isPublic")) {
|
||||
isPublic = Boolean.parseBoolean(currentText.toString().trim());
|
||||
} else if (qName.equals("kernelId")) {
|
||||
kernelId = currentText.toString().trim();
|
||||
} else if (qName.equals("platform")) {
|
||||
platform = currentText.toString().trim();
|
||||
} else if (qName.equals("productCode")) {
|
||||
productCodes.add(currentText.toString().trim());
|
||||
} else if (qName.equals("productCodesSet")) {
|
||||
inProductCodes = false;
|
||||
} else if (qName.equals("ramdiskId")) {
|
||||
ramdiskId = currentText.toString().trim();
|
||||
} else if (qName.equals("item")) {
|
||||
if (!inProductCodes) {
|
||||
try {
|
||||
contents.add(new Image(architecture, imageId, imageLocation, imageOwnerId,
|
||||
imageState, imageType, isPublic, kernelId, platform, productCodes,
|
||||
ramdiskId));
|
||||
} catch (NullPointerException e) {
|
||||
logger.warn(e, "malformed image: %s", imageId);
|
||||
}
|
||||
this.architecture = null;
|
||||
this.imageId = null;
|
||||
this.imageLocation = null;
|
||||
this.imageOwnerId = null;
|
||||
this.imageState = null;
|
||||
this.imageType = null;
|
||||
this.isPublic = false;
|
||||
this.kernelId = null;
|
||||
this.platform = null;
|
||||
this.productCodes = Sets.newHashSet();
|
||||
this.ramdiskId = null;
|
||||
}
|
||||
|
||||
}
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
||||
public void characters(char ch[], int start, int length) {
|
||||
currentText.append(ch, start, length);
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http:
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.Reservation;
|
||||
import org.jclouds.util.DateService;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Parses the following XML document:
|
||||
* <p/>
|
||||
* DescribeImagesResponse xmlns="http:
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href="http: />
|
||||
*/
|
||||
public class DescribeInstancesResponseHandler extends
|
||||
BaseReservationHandler<SortedSet<Reservation>> {
|
||||
private SortedSet<Reservation> reservations = Sets.newTreeSet();
|
||||
|
||||
@Inject
|
||||
DescribeInstancesResponseHandler(DateService dateService) {
|
||||
super(dateService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<Reservation> getResult() {
|
||||
return reservations;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void inItem() {
|
||||
if (!inInstances && !inProductCodes && !inGroups) {
|
||||
reservations.add(super.newReservation());
|
||||
} else {
|
||||
super.inItem();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Parses: DescribeKeyPairsResponse xmlns="http://ec2.amazonaws.com/doc/2009-08-15/"
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeKeyPairs.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class DescribeKeyPairsResponseHandler extends ParseSax.HandlerWithResult<SortedSet<KeyPair>> {
|
||||
|
||||
private StringBuilder currentText = new StringBuilder();
|
||||
private SortedSet<KeyPair> keyPairs = Sets.newTreeSet();
|
||||
private String keyFingerprint;
|
||||
private String keyName;
|
||||
|
||||
public SortedSet<KeyPair> getResult() {
|
||||
return keyPairs;
|
||||
}
|
||||
|
||||
public void endElement(String uri, String name, String qName) {
|
||||
|
||||
if (qName.equals("keyFingerprint")) {
|
||||
this.keyFingerprint = currentText.toString().trim();
|
||||
} else if (qName.equals("item")) {
|
||||
keyPairs.add(new KeyPair(keyName, keyFingerprint, null));
|
||||
} else if (qName.equals("keyName")) {
|
||||
this.keyName = currentText.toString().trim();
|
||||
}
|
||||
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
||||
public void characters(char ch[], int start, int length) {
|
||||
currentText.append(ch, start, length);
|
||||
}
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.IpPermission;
|
||||
import org.jclouds.aws.ec2.domain.IpProtocol;
|
||||
import org.jclouds.aws.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.aws.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.xml.sax.Attributes;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Parses: DescribeSecurityGroupsResponse xmlns="http://ec2.amazonaws.com/doc/2009-08-15/"
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeSecurityGroups.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class DescribeSecurityGroupsResponseHandler extends
|
||||
ParseSax.HandlerWithResult<SortedSet<SecurityGroup>> {
|
||||
|
||||
private StringBuilder currentText = new StringBuilder();
|
||||
private SortedSet<SecurityGroup> securtyGroups = Sets.newTreeSet();
|
||||
private String groupName;
|
||||
private String ownerId;
|
||||
private String groupDescription;
|
||||
private SortedSet<IpPermission> ipPermissions = Sets.newTreeSet();
|
||||
private int fromPort;
|
||||
private int toPort;
|
||||
private SortedSet<UserIdGroupPair> groups = Sets.newTreeSet();
|
||||
private String userId;
|
||||
private String userIdGroupName;
|
||||
private IpProtocol ipProtocol;
|
||||
private SortedSet<String> ipRanges = Sets.newTreeSet();
|
||||
|
||||
private boolean inIpPermissions;
|
||||
private boolean inIpRanges;
|
||||
private boolean inGroups;
|
||||
|
||||
public SortedSet<SecurityGroup> getResult() {
|
||||
return securtyGroups;
|
||||
}
|
||||
|
||||
public void startElement(String uri, String name, String qName, Attributes attrs) {
|
||||
if (qName.equals("ipPermissions")) {
|
||||
inIpPermissions = true;
|
||||
} else if (qName.equals("ipRanges")) {
|
||||
inIpRanges = true;
|
||||
} else if (qName.equals("groups")) {
|
||||
inGroups = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void endElement(String uri, String name, String qName) {
|
||||
if (qName.equals("groupName")) {
|
||||
if (!inGroups)
|
||||
this.groupName = currentText.toString().trim();
|
||||
else
|
||||
this.userIdGroupName = currentText.toString().trim();
|
||||
} else if (qName.equals("ownerId")) {
|
||||
this.ownerId = currentText.toString().trim();
|
||||
} else if (qName.equals("userId")) {
|
||||
this.userId = currentText.toString().trim();
|
||||
} else if (qName.equals("groupDescription")) {
|
||||
this.groupDescription = currentText.toString().trim();
|
||||
} else if (qName.equals("ipProtocol")) {
|
||||
this.ipProtocol = IpProtocol.fromValue(currentText.toString().trim());
|
||||
} else if (qName.equals("fromPort")) {
|
||||
this.fromPort = Integer.parseInt(currentText.toString().trim());
|
||||
} else if (qName.equals("toPort")) {
|
||||
this.toPort = Integer.parseInt(currentText.toString().trim());
|
||||
} else if (qName.equals("cidrIp")) {
|
||||
this.ipRanges.add(currentText.toString().trim());
|
||||
} else if (qName.equals("ipPermissions")) {
|
||||
inIpPermissions = false;
|
||||
} else if (qName.equals("ipRanges")) {
|
||||
inIpRanges = false;
|
||||
} else if (qName.equals("groups")) {
|
||||
inGroups = false;
|
||||
} else if (qName.equals("item")) {
|
||||
if (inIpPermissions && !inIpRanges && !inGroups) {
|
||||
ipPermissions.add(new IpPermission(fromPort, toPort, groups, ipProtocol, ipRanges));
|
||||
this.fromPort = -1;
|
||||
this.toPort = -1;
|
||||
this.groups = Sets.newTreeSet();
|
||||
this.ipProtocol = null;
|
||||
this.ipRanges = Sets.newTreeSet();
|
||||
} else if (inIpPermissions && !inIpRanges && inGroups) {
|
||||
this.groups.add(new UserIdGroupPair(userId, userIdGroupName));
|
||||
this.userId = null;
|
||||
this.userIdGroupName = null;
|
||||
} else if (!inIpPermissions && !inIpRanges && !inGroups) {
|
||||
securtyGroups
|
||||
.add(new SecurityGroup(groupName, ownerId, groupDescription, ipPermissions));
|
||||
this.groupName = null;
|
||||
this.ownerId = null;
|
||||
this.groupDescription = null;
|
||||
this.ipPermissions = Sets.newTreeSet();
|
||||
}
|
||||
}
|
||||
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
||||
public void characters(char ch[], int start, int length) {
|
||||
currentText.append(ch, start, length);
|
||||
}
|
||||
}
|
63
aws/core/src/main/java/org/jclouds/aws/ec2/xml/KeyPairResponseHandler.java
Executable file
63
aws/core/src/main/java/org/jclouds/aws/ec2/xml/KeyPairResponseHandler.java
Executable file
@ -0,0 +1,63 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateKeyPair.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class KeyPairResponseHandler extends ParseSax.HandlerWithResult<KeyPair> {
|
||||
|
||||
private StringBuilder currentText = new StringBuilder();
|
||||
private String keyFingerprint;
|
||||
private String keyMaterial;
|
||||
private String keyName;
|
||||
|
||||
public KeyPair getResult() {
|
||||
return new KeyPair(keyName, keyFingerprint, keyMaterial);
|
||||
}
|
||||
|
||||
public void endElement(String uri, String name, String qName) {
|
||||
|
||||
if (qName.equals("keyFingerprint")) {
|
||||
this.keyFingerprint = currentText.toString().trim();
|
||||
} else if (qName.equals("keyMaterial")) {
|
||||
this.keyMaterial = currentText.toString().trim();
|
||||
} else if (qName.equals("keyName")) {
|
||||
this.keyName = currentText.toString().trim();
|
||||
}
|
||||
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
||||
public void characters(char ch[], int start, int length) {
|
||||
currentText.append(ch, start, length);
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
* "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
|
||||
* http:
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
@ -21,31 +21,31 @@
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2;
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.Reservation;
|
||||
import org.jclouds.util.DateService;
|
||||
|
||||
/**
|
||||
* Represents an authenticated context to EC2.
|
||||
* Parses the following XML document:
|
||||
* <p/>
|
||||
* RunInstancesResponse xmlns="http:
|
||||
*
|
||||
* <h2>Note</h2> Please issue {@link #close()} when you are finished with this
|
||||
* context in order to release resources.
|
||||
*
|
||||
*
|
||||
* @see EC2Connection
|
||||
* @author Adrian Cole
|
||||
*
|
||||
* @see <a href="http: />
|
||||
*/
|
||||
public interface EC2Context {
|
||||
public class RunInstancesResponseHandler extends BaseReservationHandler<Reservation> {
|
||||
|
||||
/**
|
||||
* low-level api to EC2. Threadsafe implementations will return a singleton.
|
||||
*
|
||||
* @return a connection to EC2
|
||||
*/
|
||||
EC2Connection getConnection();
|
||||
@Inject
|
||||
RunInstancesResponseHandler(DateService dateService) {
|
||||
super(dateService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes all connections to EC2.
|
||||
*/
|
||||
void close();
|
||||
@Override
|
||||
public Reservation getResult() {
|
||||
return newReservation();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http:
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.InstanceState;
|
||||
import org.jclouds.aws.ec2.domain.TerminatedInstance;
|
||||
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
|
||||
import org.xml.sax.Attributes;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Parses the following XML document:
|
||||
* <p/>
|
||||
* TerminateInstancesResponse xmlns="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-TerminateInstancesResponseInfoType.html"
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-TerminateInstancesResponseInfoType.html"
|
||||
* />
|
||||
*/
|
||||
public class TerminateInstancesResponseHandler extends
|
||||
HandlerWithResult<SortedSet<TerminatedInstance>> {
|
||||
private StringBuilder currentText = new StringBuilder();
|
||||
|
||||
SortedSet<TerminatedInstance> instances = Sets.newTreeSet();
|
||||
private InstanceState shutdownState;
|
||||
private InstanceState previousState;
|
||||
private String instanceId;
|
||||
|
||||
private boolean inShutdownState;
|
||||
|
||||
private boolean inPreviousState;
|
||||
|
||||
@Override
|
||||
public SortedSet<TerminatedInstance> getResult() {
|
||||
return instances;
|
||||
}
|
||||
|
||||
public void startElement(String uri, String name, String qName, Attributes attrs) {
|
||||
if (qName.equals("shutdownState")) {
|
||||
inShutdownState = true;
|
||||
} else if (qName.equals("previousState")) {
|
||||
inPreviousState = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void endElement(String uri, String name, String qName) {
|
||||
|
||||
if (qName.equals("instanceId")) {
|
||||
this.instanceId = currentOrNull();
|
||||
} else if (qName.equals("shutdownState")) {
|
||||
inShutdownState = false;
|
||||
} else if (qName.equals("previousState")) {
|
||||
inPreviousState = false;
|
||||
} else if (qName.equals("name")) {
|
||||
if (inShutdownState) {
|
||||
shutdownState = InstanceState.fromValue(currentOrNull());
|
||||
} else if (inPreviousState) {
|
||||
previousState = InstanceState.fromValue(currentOrNull());
|
||||
}
|
||||
} else if (qName.equals("item")) {
|
||||
instances.add(new TerminatedInstance(instanceId, shutdownState, previousState));
|
||||
this.instanceId = null;
|
||||
this.shutdownState = null;
|
||||
this.previousState = null;
|
||||
}
|
||||
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
||||
public void characters(char ch[], int start, int length) {
|
||||
currentText.append(ch, start, length);
|
||||
}
|
||||
|
||||
protected String currentOrNull() {
|
||||
String returnVal = currentText.toString().trim();
|
||||
return returnVal.equals("") ? null : returnVal;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.handlers;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.aws.domain.AWSError;
|
||||
import org.jclouds.aws.util.AWSUtils;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpConstants;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpRetryHandler;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
/**
|
||||
* Handles Retryable responses with error codes in the 3xx range
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class AWSClientErrorRetryHandler implements HttpRetryHandler {
|
||||
|
||||
@Inject(optional = true)
|
||||
@Named(HttpConstants.PROPERTY_HTTP_MAX_RETRIES)
|
||||
private int retryCountLimit = 5;
|
||||
|
||||
private final AWSUtils utils;
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
@Inject
|
||||
public AWSClientErrorRetryHandler(AWSUtils utils) {
|
||||
this.utils = utils;
|
||||
}
|
||||
|
||||
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
|
||||
if (command.getFailureCount() > retryCountLimit)
|
||||
return false;
|
||||
if (response.getStatusCode() == 400 || response.getStatusCode() == 403
|
||||
|| response.getStatusCode() == 409) {
|
||||
byte[] content = Utils.closeClientButKeepContentStream(response);
|
||||
command.incrementFailureCount();
|
||||
try {
|
||||
AWSError error = utils.parseAWSErrorFromContent(command, response, new String(content));
|
||||
if ("RequestTimeout".equals(error.getCode())
|
||||
|| "OperationAborted".equals(error.getCode())
|
||||
|| "SignatureDoesNotMatch".equals(error.getCode())) {
|
||||
return true;
|
||||
}
|
||||
} catch (HttpException e) {
|
||||
logger.warn(e, "error parsing response: %s", new String(content));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.handlers;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.aws.domain.AWSError;
|
||||
import org.jclouds.aws.reference.AWSConstants;
|
||||
import org.jclouds.aws.util.AWSUtils;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
||||
import org.jclouds.http.handlers.RedirectionRetryHandler;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
/**
|
||||
* Handles Retryable responses with error codes in the 3xx range
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class AWSRedirectionRetryHandler extends RedirectionRetryHandler {
|
||||
private final AWSUtils utils;
|
||||
|
||||
@Inject
|
||||
public AWSRedirectionRetryHandler(BackoffLimitedRetryHandler backoffHandler, AWSUtils utils) {
|
||||
super(backoffHandler);
|
||||
this.utils = utils;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
|
||||
if (response.getFirstHeaderOrNull(HttpHeaders.LOCATION) == null
|
||||
&& (response.getStatusCode() == 301 || response.getStatusCode() == 307)) {
|
||||
byte[] content = Utils.closeClientButKeepContentStream(response);
|
||||
if (command.getRequest().getMethod() == HttpMethod.HEAD) {
|
||||
command.setMethod(HttpMethod.GET);
|
||||
return true;
|
||||
} else {
|
||||
command.incrementRedirectCount();
|
||||
try {
|
||||
AWSError error = utils.parseAWSErrorFromContent(command, response, new String(
|
||||
content));
|
||||
String host = error.getDetails().get(AWSConstants.ENDPOINT);
|
||||
if (host != null) {
|
||||
if (host.equals(command.getRequest().getEndpoint().getHost())) {
|
||||
// must be an amazon error related to
|
||||
// http://developer.amazonwebservices.com/connect/thread.jspa?messageID=72287𑩟
|
||||
return backoffHandler.shouldRetryRequest(command, response);
|
||||
} else {
|
||||
command.setHostAndPort(host, command.getRequest().getEndpoint().getPort());
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (HttpException e) {
|
||||
logger.error(e, "error on redirect for command %s; response %s; retrying...",
|
||||
command, response);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return super.shouldRetryRequest(command, response);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.handlers;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.aws.AWSResponseException;
|
||||
import org.jclouds.aws.domain.AWSError;
|
||||
import org.jclouds.aws.util.AWSUtils;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
/**
|
||||
* This will parse and set an appropriate exception on the command object.
|
||||
*
|
||||
* @see AWSError
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public class ParseAWSErrorFromXmlContent implements HttpErrorHandler {
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final AWSUtils utils;
|
||||
|
||||
@Inject
|
||||
public ParseAWSErrorFromXmlContent(AWSUtils utils) {
|
||||
this.utils = utils;
|
||||
}
|
||||
|
||||
public void handleError(HttpCommand command, HttpResponse response) {
|
||||
String content;
|
||||
try {
|
||||
content = response.getContent() != null ? Utils.toStringAndClose(response.getContent())
|
||||
: null;
|
||||
if (content != null) {
|
||||
try {
|
||||
if (content.indexOf('<') >= 0) {
|
||||
AWSError error = utils.parseAWSErrorFromContent(command, response, content);
|
||||
command.setException(new AWSResponseException(command, response, error));
|
||||
} else {
|
||||
command.setException(new HttpResponseException(command, response, content));
|
||||
}
|
||||
} catch (Exception he) {
|
||||
command.setException(new HttpResponseException(command, response, content));
|
||||
Utils.rethrowIfRuntime(he);
|
||||
}
|
||||
} else {
|
||||
command.setException(new HttpResponseException(command, response));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
command.setException(new HttpResponseException(command, response));
|
||||
Utils.rethrowIfRuntime(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -21,8 +21,9 @@
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2;
|
||||
|
||||
public class EC2Connection {
|
||||
|
||||
}
|
||||
/**
|
||||
* This package contains HttpResponseHandlers needed to operate the REST api.
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/RESTAuthentication.html" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
package org.jclouds.aws.handlers;
|
@ -0,0 +1,357 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.imageIds;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.Image;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||
import org.jclouds.aws.ec2.domain.IpPermission;
|
||||
import org.jclouds.aws.ec2.domain.IpProtocol;
|
||||
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||
import org.jclouds.aws.ec2.domain.Reservation;
|
||||
import org.jclouds.aws.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.aws.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code EC2Client}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", sequential = true, testName = "ec2.EC2ClientLiveTest")
|
||||
public class EC2ClientLiveTest {
|
||||
|
||||
private EC2Client client;
|
||||
private String user;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
|
||||
client = EC2ContextFactory.createContext(user, password, new Log4JLoggingModule()).getApi();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDescribeImages() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
SortedSet<Image> allResults = client.describeImages().get(30, TimeUnit.SECONDS);
|
||||
assertNotNull(allResults);
|
||||
assert allResults.size() >= 2 : allResults.size();
|
||||
Iterator<Image> iterator = allResults.iterator();
|
||||
String id1 = iterator.next().getImageId();
|
||||
String id2 = iterator.next().getImageId();
|
||||
SortedSet<Image> twoResults = client.describeImages(imageIds(id1, id2)).get(30,
|
||||
TimeUnit.SECONDS);
|
||||
assertNotNull(twoResults);
|
||||
assertEquals(twoResults.size(), 2);
|
||||
iterator = twoResults.iterator();
|
||||
assertEquals(iterator.next().getImageId(), id1);
|
||||
assertEquals(iterator.next().getImageId(), id2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDescribeInstances() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
SortedSet<Reservation> allResults = client.describeInstances().get(30, TimeUnit.SECONDS);
|
||||
assertNotNull(allResults);
|
||||
assert allResults.size() >= 0 : allResults.size();
|
||||
if (allResults.size() >= 2) {
|
||||
Iterator<RunningInstance> iterator = allResults.iterator().next().getRunningInstances()
|
||||
.iterator();
|
||||
String id1 = iterator.next().getInstanceId();
|
||||
String id2 = iterator.next().getInstanceId();
|
||||
SortedSet<Reservation> twoResults = client.describeInstances(id1, id2).get(30,
|
||||
TimeUnit.SECONDS);
|
||||
assertNotNull(twoResults);
|
||||
assertEquals(twoResults.size(), 2);
|
||||
iterator = twoResults.iterator().next().getRunningInstances().iterator();
|
||||
assertEquals(iterator.next().getInstanceId(), id1);
|
||||
assertEquals(iterator.next().getInstanceId(), id2);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDescribeKeyPairs() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
SortedSet<KeyPair> allResults = client.describeKeyPairs().get(30, TimeUnit.SECONDS);
|
||||
assertNotNull(allResults);
|
||||
assert allResults.size() >= 0 : allResults.size();
|
||||
if (allResults.size() >= 2) {
|
||||
Iterator<KeyPair> iterator = allResults.iterator();
|
||||
String id1 = iterator.next().getKeyName();
|
||||
String id2 = iterator.next().getKeyName();
|
||||
SortedSet<KeyPair> twoResults = client.describeKeyPairs(id1, id2)
|
||||
.get(30, TimeUnit.SECONDS);
|
||||
assertNotNull(twoResults);
|
||||
assertEquals(twoResults.size(), 2);
|
||||
iterator = twoResults.iterator();
|
||||
assertEquals(iterator.next().getKeyName(), id1);
|
||||
assertEquals(iterator.next().getKeyName(), id2);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDescribeSecurityGroups() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
SortedSet<SecurityGroup> allResults = client.describeSecurityGroups().get(30,
|
||||
TimeUnit.SECONDS);
|
||||
assertNotNull(allResults);
|
||||
assert allResults.size() >= 0 : allResults.size();
|
||||
if (allResults.size() >= 2) {
|
||||
Iterator<SecurityGroup> iterator = allResults.iterator();
|
||||
String id1 = iterator.next().getName();
|
||||
String id2 = iterator.next().getName();
|
||||
SortedSet<SecurityGroup> twoResults = client.describeSecurityGroups(id1, id2).get(30,
|
||||
TimeUnit.SECONDS);
|
||||
assertNotNull(twoResults);
|
||||
assertEquals(twoResults.size(), 2);
|
||||
iterator = twoResults.iterator();
|
||||
assertEquals(iterator.next().getName(), id1);
|
||||
assertEquals(iterator.next().getName(), id2);
|
||||
}
|
||||
}
|
||||
|
||||
public static final String PREFIX = System.getProperty("user.name") + "-ec2";
|
||||
|
||||
@Test
|
||||
void testCreateKeyPair() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
String keyName = PREFIX + "1";
|
||||
try {
|
||||
client.deleteKeyPair(keyName).get(30, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
client.deleteKeyPair(keyName).get(30, TimeUnit.SECONDS);
|
||||
|
||||
KeyPair result = client.createKeyPair(keyName).get(30, TimeUnit.SECONDS);
|
||||
assertNotNull(result);
|
||||
assertNotNull(result.getKeyMaterial());
|
||||
assertNotNull(result.getKeyFingerprint());
|
||||
assertEquals(result.getKeyName(), keyName);
|
||||
|
||||
SortedSet<KeyPair> twoResults = client.describeKeyPairs(keyName).get(30, TimeUnit.SECONDS);
|
||||
assertNotNull(twoResults);
|
||||
assertEquals(twoResults.size(), 1);
|
||||
KeyPair listPair = twoResults.iterator().next();
|
||||
assertEquals(listPair.getKeyName(), result.getKeyName());
|
||||
assertEquals(listPair.getKeyFingerprint(), result.getKeyFingerprint());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateSecurityGroup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
String groupName = PREFIX + "1";
|
||||
String groupDescription = PREFIX + "1 description";
|
||||
try {
|
||||
client.deleteSecurityGroup(groupName).get(30, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
client.deleteSecurityGroup(groupName).get(30, TimeUnit.SECONDS);
|
||||
|
||||
client.createSecurityGroup(groupName, groupDescription).get(30, TimeUnit.SECONDS);
|
||||
|
||||
verifySecurityGroup(groupName, groupDescription);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuthorizeSecurityGroupIngressCidr() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
String groupName = PREFIX + "ingress";
|
||||
|
||||
try {
|
||||
client.deleteSecurityGroup(groupName).get(30, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
client.createSecurityGroup(groupName, groupName).get(30, TimeUnit.SECONDS);
|
||||
client.authorizeSecurityGroupIngress(groupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0").get(30,
|
||||
TimeUnit.SECONDS);
|
||||
assertEventually(new GroupHasPermission(client, groupName, new IpPermission(80, 80, Sets
|
||||
.<UserIdGroupPair> newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0"))));
|
||||
|
||||
client.revokeSecurityGroupIngress(groupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0").get(30,
|
||||
TimeUnit.SECONDS);
|
||||
assertEventually(new GroupHasNoPermissions(client, groupName));
|
||||
|
||||
}
|
||||
|
||||
private void verifySecurityGroup(String groupName, String description)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
SortedSet<SecurityGroup> oneResult = client.describeSecurityGroups(groupName).get(30,
|
||||
TimeUnit.SECONDS);
|
||||
assertNotNull(oneResult);
|
||||
assertEquals(oneResult.size(), 1);
|
||||
SecurityGroup listPair = oneResult.iterator().next();
|
||||
assertEquals(listPair.getName(), groupName);
|
||||
assertEquals(listPair.getDescription(), description);
|
||||
}
|
||||
|
||||
@Test(enabled = false)
|
||||
// TODO
|
||||
void testAuthorizeSecurityGroupIngressSourceGroup() throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
String group1Name = PREFIX + "ingress1";
|
||||
String group2Name = PREFIX + "ingress2";
|
||||
|
||||
try {
|
||||
client.deleteSecurityGroup(group1Name).get(30, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
try {
|
||||
client.deleteSecurityGroup(group2Name).get(30, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
client.createSecurityGroup(group1Name, group1Name).get(30, TimeUnit.SECONDS);
|
||||
client.createSecurityGroup(group2Name, group2Name).get(30, TimeUnit.SECONDS);
|
||||
ensureGroupsExist(group1Name, group2Name);
|
||||
client.authorizeSecurityGroupIngress(group1Name, IpProtocol.TCP, 80, 80, "0.0.0.0/0").get(30,
|
||||
TimeUnit.SECONDS);
|
||||
assertEventually(new GroupHasPermission(client, group2Name, new IpPermission(80, 80, Sets
|
||||
.<UserIdGroupPair> newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0"))));
|
||||
|
||||
SortedSet<SecurityGroup> oneResult = client.describeSecurityGroups(group1Name).get(30,
|
||||
TimeUnit.SECONDS);
|
||||
assertNotNull(oneResult);
|
||||
assertEquals(oneResult.size(), 1);
|
||||
SecurityGroup group = oneResult.iterator().next();
|
||||
assertEquals(group.getName(), group1Name);
|
||||
|
||||
client.authorizeSecurityGroupIngress(group2Name,
|
||||
new UserIdGroupPair(group.getOwnerId(), group1Name)).get(30, TimeUnit.SECONDS);
|
||||
assertEventually(new GroupHasPermission(client, group2Name, new IpPermission(80, 80, Sets
|
||||
.<UserIdGroupPair> newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0"))));
|
||||
|
||||
client.revokeSecurityGroupIngress(group2Name,
|
||||
new UserIdGroupPair(group.getOwnerId(), group1Name)).get(30, TimeUnit.SECONDS);
|
||||
assertEventually(new GroupHasNoPermissions(client, group2Name));
|
||||
}
|
||||
|
||||
private static final class GroupHasPermission implements Runnable {
|
||||
private final EC2Client client;
|
||||
private final String group;
|
||||
private final IpPermission permission;
|
||||
|
||||
private GroupHasPermission(EC2Client client, String group, IpPermission permission) {
|
||||
this.client = client;
|
||||
this.group = group;
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
SortedSet<SecurityGroup> oneResult = client.describeSecurityGroups(group).get(30,
|
||||
TimeUnit.SECONDS);
|
||||
assertNotNull(oneResult);
|
||||
assertEquals(oneResult.size(), 1);
|
||||
SecurityGroup listPair = oneResult.iterator().next();
|
||||
assert listPair.getIpPermissions().contains(permission);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class GroupHasNoPermissions implements Runnable {
|
||||
private final EC2Client client;
|
||||
private final String group;
|
||||
|
||||
private GroupHasNoPermissions(EC2Client client, String group) {
|
||||
this.client = client;
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
SortedSet<SecurityGroup> oneResult = client.describeSecurityGroups(group).get(30,
|
||||
TimeUnit.SECONDS);
|
||||
assertNotNull(oneResult);
|
||||
assertEquals(oneResult.size(), 1);
|
||||
SecurityGroup listPair = oneResult.iterator().next();
|
||||
assertEquals(listPair.getIpPermissions().size(), 0);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureGroupsExist(String group1Name, String group2Name)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
SortedSet<SecurityGroup> twoResults = client.describeSecurityGroups(group1Name, group2Name)
|
||||
.get(30, TimeUnit.SECONDS);
|
||||
assertNotNull(twoResults);
|
||||
assertEquals(twoResults.size(), 2);
|
||||
Iterator<SecurityGroup> iterator = twoResults.iterator();
|
||||
SecurityGroup listPair1 = iterator.next();
|
||||
assertEquals(listPair1.getName(), group1Name);
|
||||
assertEquals(listPair1.getDescription(), group1Name);
|
||||
|
||||
SecurityGroup listPair2 = iterator.next();
|
||||
assertEquals(listPair2.getName(), group2Name);
|
||||
assertEquals(listPair2.getDescription(), group2Name);
|
||||
}
|
||||
|
||||
private static final int INCONSISTENCY_WINDOW = 5000;
|
||||
|
||||
/**
|
||||
* Due to eventual consistency, container commands may not return correctly immediately. Hence,
|
||||
* we will try up to the inconsistency window to see if the assertion completes.
|
||||
*/
|
||||
protected static void assertEventually(Runnable assertion) throws InterruptedException {
|
||||
long start = System.currentTimeMillis();
|
||||
AssertionError error = null;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
try {
|
||||
assertion.run();
|
||||
if (i > 0)
|
||||
System.err.printf("%d attempts and %dms asserting %s%n", i + 1, System
|
||||
.currentTimeMillis()
|
||||
- start, assertion.getClass().getSimpleName());
|
||||
return;
|
||||
} catch (AssertionError e) {
|
||||
error = e;
|
||||
}
|
||||
Thread.sleep(INCONSISTENCY_WINDOW / 30);
|
||||
}
|
||||
if (error != null)
|
||||
throw error;
|
||||
|
||||
}
|
||||
|
||||
}
|
481
aws/core/src/test/java/org/jclouds/aws/ec2/EC2ClientTest.java
Normal file
481
aws/core/src/test/java/org/jclouds/aws/ec2/EC2ClientTest.java
Normal file
@ -0,0 +1,481 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2;
|
||||
|
||||
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.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.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.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.jclouds.util.TimeStamp;
|
||||
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<EC2Client> {
|
||||
|
||||
public void testDescribeImages() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = EC2Client.class.getMethod("describeImages", Array.newInstance(
|
||||
DescribeImagesOptions.class, 0).getClass());
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(httpMethod, "Version=2009-08-15&Action=DescribeImages");
|
||||
filter.filter(httpMethod);
|
||||
assertEntityEquals(
|
||||
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 = EC2Client.class.getMethod("describeImages", Array.newInstance(
|
||||
DescribeImagesOptions.class, 0).getClass());
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(
|
||||
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 testDescribeInstances() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = EC2Client.class.getMethod("describeInstances", Array.newInstance(
|
||||
String.class, 0).getClass());
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(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 = EC2Client.class.getMethod("describeInstances", Array.newInstance(
|
||||
String.class, 0).getClass());
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(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 = EC2Client.class.getMethod("terminateInstances", String.class, Array
|
||||
.newInstance(String.class, 0).getClass());
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(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 = EC2Client.class.getMethod("runInstances", String.class, int.class, int.class,
|
||||
Array.newInstance(RunInstancesOptions.class, 0).getClass());
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(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 = EC2Client.class.getMethod("runInstances", String.class, int.class, int.class,
|
||||
Array.newInstance(RunInstancesOptions.class, 0).getClass());
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(
|
||||
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 = EC2Client.class.getMethod("createKeyPair", String.class);
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(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 testDeleteKeyPair() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = EC2Client.class.getMethod("deleteKeyPair", String.class);
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(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 = EC2Client.class.getMethod("describeKeyPairs", Array.newInstance(String.class,
|
||||
0).getClass());
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(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 = EC2Client.class.getMethod("describeKeyPairs", Array.newInstance(String.class,
|
||||
0).getClass());
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(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 = EC2Client.class.getMethod("deleteSecurityGroup", String.class);
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(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 = EC2Client.class.getMethod("createSecurityGroup", String.class, String.class);
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(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 = EC2Client.class.getMethod("describeSecurityGroups", Array.newInstance(
|
||||
String.class, 0).getClass());
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(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 = EC2Client.class.getMethod("describeSecurityGroups", Array.newInstance(
|
||||
String.class, 0).getClass());
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(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 = EC2Client.class.getMethod("authorizeSecurityGroupIngress", String.class,
|
||||
UserIdGroupPair.class);
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(
|
||||
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 = EC2Client.class.getMethod("authorizeSecurityGroupIngress", String.class,
|
||||
IpProtocol.class, int.class, int.class, String.class);
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(
|
||||
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 = EC2Client.class.getMethod("revokeSecurityGroupIngress", String.class,
|
||||
UserIdGroupPair.class);
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(
|
||||
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 = EC2Client.class.getMethod("revokeSecurityGroupIngress", String.class,
|
||||
IpProtocol.class, int.class, int.class, String.class);
|
||||
GeneratedHttpRequest<EC2Client> 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");
|
||||
assertEntityEquals(
|
||||
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<EC2Client> httpMethod) {
|
||||
assertEquals(httpMethod.getFilters().size(), 1);
|
||||
assertEquals(httpMethod.getFilters().get(0).getClass(), FormSigner.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TypeLiteral<RestAnnotationProcessor<EC2Client>> createTypeLiteral() {
|
||||
return new TypeLiteral<RestAnnotationProcessor<EC2Client>>() {
|
||||
};
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2;
|
||||
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.aws.ec2.config.EC2RestClientModule;
|
||||
import org.jclouds.aws.ec2.filters.FormSigner;
|
||||
import org.jclouds.aws.ec2.reference.EC2Constants;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.internal.RestContextImpl;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Tests behavior of modules configured in EC2ContextBuilderT
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ec2.EC2ContextBuilderTest")
|
||||
public class EC2ContextBuilderTest {
|
||||
|
||||
public void testNewBuilder() {
|
||||
EC2ContextBuilder builder = newBuilder();
|
||||
assertEquals(builder.getProperties().getProperty(EC2Constants.PROPERTY_EC2_ENDPOINT),
|
||||
"http://ec2.amazonaws.com");
|
||||
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_ACCESSKEYID), "id");
|
||||
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_SECRETACCESSKEY), "secret");
|
||||
}
|
||||
|
||||
public void testBuildContext() {
|
||||
RestContext<EC2Client> context = newBuilder().buildContext();
|
||||
assertEquals(context.getClass(), RestContextImpl.class);
|
||||
assertEquals(context.getAccount(), "id");
|
||||
assertEquals(context.getEndPoint(), URI.create("http://ec2.amazonaws.com"));
|
||||
}
|
||||
|
||||
public void testBuildInjector() {
|
||||
Injector i = newBuilder().buildInjector();
|
||||
assert i.getInstance(Key.get(new TypeLiteral<RestContext<EC2Client>>() {
|
||||
})) != null; // TODO: test all things taken from context
|
||||
assert i.getInstance(FormSigner.class) != null;
|
||||
}
|
||||
|
||||
protected void testAddContextModule() {
|
||||
List<Module> modules = new ArrayList<Module>();
|
||||
EC2ContextBuilder builder = newBuilder();
|
||||
builder.addContextModule(modules);
|
||||
assertEquals(modules.size(), 1);
|
||||
assertEquals(modules.get(0).getClass(), EC2RestClientModule.class);
|
||||
}
|
||||
|
||||
private EC2ContextBuilder newBuilder() {
|
||||
EC2ContextBuilder builder = new EC2ContextBuilder(new EC2PropertiesBuilder("id", "secret")
|
||||
.build());
|
||||
return builder;
|
||||
}
|
||||
|
||||
protected void addClientModule() {
|
||||
List<Module> modules = new ArrayList<Module>();
|
||||
EC2ContextBuilder builder = newBuilder();
|
||||
builder.addClientModule(modules);
|
||||
assertEquals(modules.size(), 1);
|
||||
assertEquals(modules.get(0).getClass(), EC2RestClientModule.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,211 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKeyName;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.InstanceState;
|
||||
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||
import org.jclouds.aws.ec2.domain.IpProtocol;
|
||||
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||
import org.jclouds.concurrent.WithinThreadExecutorService;
|
||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.SshException;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.jclouds.util.Utils;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* Follows the book Cloud Application Architectures ISBN: 978-0-596-15636-7
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", sequential = true, testName = "ec2.ExpensiveEC2ClientLiveTest")
|
||||
public class ExpensiveEC2ClientLiveTest {
|
||||
|
||||
private EC2Client client;
|
||||
protected SshClient.Factory sshFactory;
|
||||
private String serverPrefix = System.getProperty("user.name") + ".ec2";
|
||||
private KeyPair keyPair;
|
||||
private String securityGroupName;
|
||||
private String serverId;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
|
||||
client = new EC2ContextBuilder(new EC2PropertiesBuilder(user, password).build()).withModules(
|
||||
new Log4JLoggingModule()).buildContext().getApi();
|
||||
|
||||
Injector injector = Guice.createInjector(new Log4JLoggingModule(), new JschSshClientModule(),
|
||||
new ExecutorServiceModule(new WithinThreadExecutorService()));
|
||||
client = EC2ContextFactory.createContext(user, password, new Log4JLoggingModule()).getApi();
|
||||
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateSecurityGroupIngressCidr() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
securityGroupName = serverPrefix + "ingress";
|
||||
|
||||
try {
|
||||
client.deleteSecurityGroup(securityGroupName).get(30, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
client.createSecurityGroup(securityGroupName, securityGroupName).get(30, TimeUnit.SECONDS);
|
||||
client.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0")
|
||||
.get(30, TimeUnit.SECONDS);
|
||||
client
|
||||
.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 443, 443,
|
||||
"0.0.0.0/0").get(30, TimeUnit.SECONDS);
|
||||
client.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 22, 22, "0.0.0.0/0")
|
||||
.get(30, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateKeyPair() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
String keyName = serverPrefix + "1";
|
||||
try {
|
||||
client.deleteKeyPair(keyName).get(30, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
client.deleteKeyPair(keyName).get(30, TimeUnit.SECONDS);
|
||||
|
||||
keyPair = client.createKeyPair(keyName).get(30, TimeUnit.SECONDS);
|
||||
assertNotNull(keyPair);
|
||||
assertNotNull(keyPair.getKeyMaterial());
|
||||
assertNotNull(keyPair.getKeyFingerprint());
|
||||
assertEquals(keyPair.getKeyName(), keyName);
|
||||
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = { "testCreateKeyPair", "testCreateSecurityGroupIngressCidr" })
|
||||
public void testCreateRunningInstance() throws Exception {
|
||||
String imageId = "ami-1fd73376";
|
||||
RunningInstance server = null;
|
||||
while (server == null) {
|
||||
try {
|
||||
server = client.runInstances(
|
||||
imageId,
|
||||
1,
|
||||
1,
|
||||
withKeyName(keyPair.getKeyName()).asType(InstanceType.M1_SMALL)
|
||||
.withSecurityGroup(securityGroupName)).get(30, TimeUnit.SECONDS)
|
||||
.getRunningInstances().iterator().next();
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
HttpResponseException htpe = (HttpResponseException) e.getCause().getCause();
|
||||
if (htpe.getResponse().getStatusCode() == 400)
|
||||
continue;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
assertNotNull(server.getInstanceId());
|
||||
serverId = server.getInstanceId();
|
||||
assertEquals(server.getInstanceState(), InstanceState.PENDING);
|
||||
server = blockUntilRunningInstanceActive(serverId);
|
||||
|
||||
sshPing(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* this tests "personality" as the file looked up was sent during server creation
|
||||
*/
|
||||
private void sshPing(RunningInstance newDetails) throws IOException {
|
||||
try {
|
||||
doCheckKey(newDetails);
|
||||
} catch (SshException e) {// try twice in case there is a network timeout
|
||||
try {
|
||||
Thread.sleep(10 * 1000);
|
||||
} catch (InterruptedException e1) {
|
||||
}
|
||||
doCheckKey(newDetails);
|
||||
}
|
||||
}
|
||||
|
||||
private void doCheckKey(RunningInstance newDetails) throws IOException {
|
||||
SshClient connection = sshFactory.create(new InetSocketAddress(newDetails.getDnsName(), 22),
|
||||
"root", keyPair.getKeyMaterial().getBytes());
|
||||
try {
|
||||
connection.connect();
|
||||
InputStream etcPasswd = connection.get("/etc/passwd");
|
||||
Utils.toStringAndClose(etcPasswd);
|
||||
} finally {
|
||||
if (connection != null)
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private RunningInstance blockUntilRunningInstanceActive(String serverId)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
RunningInstance currentDetails = null;
|
||||
for (currentDetails = getRunningInstance(serverId); currentDetails.getInstanceState() != InstanceState.RUNNING; currentDetails = getRunningInstance(serverId)) {
|
||||
System.out.printf("%s blocking on status active: currently: %s%n", currentDetails
|
||||
.getInstanceId(), currentDetails.getInstanceState());
|
||||
Thread.sleep(5 * 1000);
|
||||
}
|
||||
System.out.printf("%s awaiting daemons to start%n", currentDetails.getInstanceId());
|
||||
Thread.sleep(10 * 1000);
|
||||
return currentDetails;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
void cleanup() {
|
||||
if (serverId != null)
|
||||
client.terminateInstances(serverId);
|
||||
if (keyPair != null)
|
||||
client.deleteKeyPair(keyPair.getKeyName());
|
||||
if (securityGroupName != null)
|
||||
client.deleteSecurityGroup(securityGroupName);
|
||||
}
|
||||
|
||||
private RunningInstance getRunningInstance(String serverId) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
return client.describeInstances(serverId).get(15, TimeUnit.SECONDS).first()
|
||||
.getRunningInstances().first();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.config;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
import org.jclouds.aws.ec2.reference.EC2Constants;
|
||||
import org.jclouds.concurrent.WithinThreadExecutorService;
|
||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.config.RestModule;
|
||||
import org.jclouds.rest.internal.RestContextImpl;
|
||||
import org.jclouds.util.Jsr330;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ec2.EC2ContextModuleTest")
|
||||
public class EC2ContextModuleTest {
|
||||
|
||||
Injector createInjector() {
|
||||
return Guice.createInjector(new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||
new EC2RestClientModule(), new RestModule(),
|
||||
new JavaUrlHttpCommandExecutorServiceModule(), new JDKLoggingModule(),
|
||||
new EC2ContextModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(EC2Constants.PROPERTY_AWS_ACCESSKEYID)).to("user");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(EC2Constants.PROPERTY_AWS_SECRETACCESSKEY)).to("key");
|
||||
bindConstant().annotatedWith(Jsr330.named(EC2Constants.PROPERTY_EC2_ENDPOINT))
|
||||
.to("http://localhost");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(EC2Constants.PROPERTY_EC2_EXPIREINTERVAL)).to(30);
|
||||
super.configure();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testContextImpl() {
|
||||
RestContext<EC2Client> handler = createInjector().getInstance(
|
||||
Key.get(new TypeLiteral<RestContext<EC2Client>>() {
|
||||
}));
|
||||
assertEquals(handler.getClass(), RestContextImpl.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package org.jclouds.aws.ec2.config;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.aws.ec2.reference.EC2Constants;
|
||||
import org.jclouds.aws.handlers.AWSClientErrorRetryHandler;
|
||||
import org.jclouds.aws.handlers.AWSRedirectionRetryHandler;
|
||||
import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent;
|
||||
import org.jclouds.concurrent.WithinThreadExecutorService;
|
||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.http.functions.config.ParserModule;
|
||||
import org.jclouds.http.handlers.DelegatingErrorHandler;
|
||||
import org.jclouds.http.handlers.DelegatingRetryHandler;
|
||||
import org.jclouds.util.Jsr330;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ec2.EC2RestClientModuleTest")
|
||||
public class EC2RestClientModuleTest {
|
||||
|
||||
Injector createInjector() {
|
||||
return Guice.createInjector(new EC2RestClientModule(), new ExecutorServiceModule(
|
||||
new WithinThreadExecutorService()), new ParserModule(), new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(Jsr330.named(EC2Constants.PROPERTY_AWS_ACCESSKEYID)).to(
|
||||
"user");
|
||||
bindConstant().annotatedWith(Jsr330.named(EC2Constants.PROPERTY_AWS_SECRETACCESSKEY))
|
||||
.to("key");
|
||||
bindConstant().annotatedWith(Jsr330.named(EC2Constants.PROPERTY_EC2_ENDPOINT)).to(
|
||||
"http://localhost");
|
||||
bindConstant().annotatedWith(Jsr330.named(EC2Constants.PROPERTY_EC2_EXPIREINTERVAL))
|
||||
.to(30);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testServerErrorHandler() {
|
||||
DelegatingErrorHandler handler = createInjector().getInstance(DelegatingErrorHandler.class);
|
||||
assertEquals(handler.getServerErrorHandler().getClass(), ParseAWSErrorFromXmlContent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testClientErrorHandler() {
|
||||
DelegatingErrorHandler handler = createInjector().getInstance(DelegatingErrorHandler.class);
|
||||
assertEquals(handler.getClientErrorHandler().getClass(), ParseAWSErrorFromXmlContent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testClientRetryHandler() {
|
||||
DelegatingRetryHandler handler = createInjector().getInstance(DelegatingRetryHandler.class);
|
||||
assertEquals(handler.getClientErrorRetryHandler().getClass(),
|
||||
AWSClientErrorRetryHandler.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRedirectionRetryHandler() {
|
||||
DelegatingRetryHandler handler = createInjector().getInstance(DelegatingRetryHandler.class);
|
||||
assertEquals(handler.getRedirectionRetryHandler().getClass(),
|
||||
AWSRedirectionRetryHandler.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package org.jclouds.aws.ec2.filters;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.aws.ec2.config.EC2RestClientModule;
|
||||
import org.jclouds.aws.ec2.reference.EC2Constants;
|
||||
import org.jclouds.concurrent.WithinThreadExecutorService;
|
||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.http.functions.config.ParserModule;
|
||||
import org.jclouds.util.Jsr330;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
@Test(groups = "unit", testName = "ec2.FormSignerTest")
|
||||
public class FormSignerTest {
|
||||
|
||||
private Injector injector;
|
||||
private FormSigner filter;
|
||||
|
||||
@Test
|
||||
void testBuildCanonicalizedString() {
|
||||
assertEquals(
|
||||
filter.buildCanonicalizedString(new ImmutableMultimap.Builder<String, String>().put(
|
||||
"AWSAccessKeyId", "foo").put( "Action","DescribeImages").put(
|
||||
"Expires","2008-02-10T12:00:00Z").put("ImageId.1", "ami-2bb65342").put(
|
||||
"SignatureMethod", "HmacSHA256").put("SignatureVersion", "2").put("Version",
|
||||
"2009-08-15").build()),
|
||||
"AWSAccessKeyId=foo&Action=DescribeImages&Expires=2008-02-10T12%3A00%3A00Z&ImageId.1=ami-2bb65342&SignatureMethod=HmacSHA256&SignatureVersion=2&Version=2009-08-15");
|
||||
}
|
||||
|
||||
/**
|
||||
* before class, as we need to ensure that the filter is threadsafe.
|
||||
*
|
||||
*/
|
||||
@BeforeClass
|
||||
protected void createFilter() {
|
||||
injector = Guice.createInjector(new EC2RestClientModule(), new ExecutorServiceModule(
|
||||
new WithinThreadExecutorService()), new ParserModule(), new AbstractModule() {
|
||||
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(Jsr330.named(EC2Constants.PROPERTY_AWS_ACCESSKEYID)).to(
|
||||
"foo");
|
||||
bindConstant().annotatedWith(Jsr330.named(EC2Constants.PROPERTY_AWS_SECRETACCESSKEY))
|
||||
.to("bar");
|
||||
bindConstant().annotatedWith(Jsr330.named(EC2Constants.PROPERTY_EC2_ENDPOINT)).to(
|
||||
"https://ec2.amazonaws.com");
|
||||
bindConstant().annotatedWith(Jsr330.named(EC2Constants.PROPERTY_EC2_EXPIREINTERVAL))
|
||||
.to(30);
|
||||
}
|
||||
});
|
||||
filter = injector.getInstance(FormSigner.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
package org.jclouds.aws.ec2.options;
|
||||
|
||||
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.executableBy;
|
||||
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.imageIds;
|
||||
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.ownedBy;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.jclouds.http.options.HttpRequestOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests possible uses of DescribeImagesOptions and DescribeImagesOptions.Builder.*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class DescribeImagesOptionsTest {
|
||||
|
||||
@Test
|
||||
public void testAssignability() {
|
||||
assert HttpRequestOptions.class.isAssignableFrom(DescribeImagesOptions.class);
|
||||
assert !String.class.isAssignableFrom(DescribeImagesOptions.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecutableBy() {
|
||||
DescribeImagesOptions options = new DescribeImagesOptions();
|
||||
options.executableBy("test");
|
||||
assertEquals(options.buildFormParameters().get("ExecutableBy"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullExecutableBy() {
|
||||
DescribeImagesOptions options = new DescribeImagesOptions();
|
||||
assertEquals(options.buildFormParameters().get("ExecutableBy"), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecutableByStatic() {
|
||||
DescribeImagesOptions options = executableBy("test");
|
||||
assertEquals(options.buildFormParameters().get("ExecutableBy"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testExecutableByNPE() {
|
||||
executableBy(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOwners() {
|
||||
DescribeImagesOptions options = new DescribeImagesOptions();
|
||||
options.ownedBy("test");
|
||||
assertEquals(options.buildFormParameters().get("Owner.1"), Collections.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleOwners() {
|
||||
DescribeImagesOptions options = new DescribeImagesOptions();
|
||||
options.ownedBy("test", "trouble");
|
||||
assertEquals(options.buildFormParameters().get("Owner.1"), Collections.singletonList("test"));
|
||||
assertEquals(options.buildFormParameters().get("Owner.2"), Collections
|
||||
.singletonList("trouble"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullOwners() {
|
||||
DescribeImagesOptions options = new DescribeImagesOptions();
|
||||
assertEquals(options.buildFormParameters().get("Owner.1"), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOwnersStatic() {
|
||||
DescribeImagesOptions options = ownedBy("test");
|
||||
assertEquals(options.buildFormParameters().get("Owner.1"), Collections.singletonList("test"));
|
||||
}
|
||||
|
||||
public void testNoOwners() {
|
||||
ownedBy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageIds() {
|
||||
DescribeImagesOptions options = new DescribeImagesOptions();
|
||||
options.imageIds("test");
|
||||
assertEquals(options.buildFormParameters().get("ImageId.1"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleImageIds() {
|
||||
DescribeImagesOptions options = new DescribeImagesOptions();
|
||||
options.imageIds("test", "trouble");
|
||||
assertEquals(options.buildFormParameters().get("ImageId.1"), Collections
|
||||
.singletonList("test"));
|
||||
assertEquals(options.buildFormParameters().get("ImageId.2"), Collections
|
||||
.singletonList("trouble"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullImageIds() {
|
||||
DescribeImagesOptions options = new DescribeImagesOptions();
|
||||
assertEquals(options.buildFormParameters().get("ImageId.1"), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageIdsStatic() {
|
||||
DescribeImagesOptions options = imageIds("test");
|
||||
assertEquals(options.buildFormParameters().get("ImageId.1"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
public void testNoImageIds() {
|
||||
imageIds();
|
||||
}
|
||||
}
|
@ -0,0 +1,344 @@
|
||||
package org.jclouds.aws.ec2.options;
|
||||
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.asType;
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.enableMonitoring;
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.inAvailabilityZone;
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withAdditionalInfo;
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withDeviceName;
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKernelId;
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKeyName;
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withRamdisk;
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withSecurityGroup;
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withSubnetId;
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withUserData;
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withVirtualName;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||
import org.jclouds.http.options.HttpRequestOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests possible uses of RunInstancesOptions and RunInstancesOptions.Builder.*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class RunInstancesOptionsTest {
|
||||
|
||||
@Test
|
||||
public void testAssignability() {
|
||||
assert HttpRequestOptions.class.isAssignableFrom(RunInstancesOptions.class);
|
||||
assert !String.class.isAssignableFrom(RunInstancesOptions.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithKeyName() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
options.withKeyName("test");
|
||||
assertEquals(options.buildFormParameters().get("KeyName"), Collections.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullWithKeyName() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
assertEquals(options.buildFormParameters().get("KeyName"), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithKeyNameStatic() {
|
||||
RunInstancesOptions options = withKeyName("test");
|
||||
assertEquals(options.buildFormParameters().get("KeyName"), Collections.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testWithKeyNameNPE() {
|
||||
withKeyName(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithSecurityGroup() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
options.withSecurityGroup("test");
|
||||
assertEquals(options.buildFormParameters().get("SecurityGroup"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullWithSecurityGroup() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
assertEquals(options.buildFormParameters().get("SecurityGroup"), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithSecurityGroupStatic() {
|
||||
RunInstancesOptions options = withSecurityGroup("test");
|
||||
assertEquals(options.buildFormParameters().get("SecurityGroup"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testWithSecurityGroupNPE() {
|
||||
withSecurityGroup(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithAdditionalInfo() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
options.withAdditionalInfo("test");
|
||||
assertEquals(options.buildFormParameters().get("AdditionalInfo"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullWithAdditionalInfo() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
assertEquals(options.buildFormParameters().get("AdditionalInfo"), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithAdditionalInfoStatic() {
|
||||
RunInstancesOptions options = withAdditionalInfo("test");
|
||||
assertEquals(options.buildFormParameters().get("AdditionalInfo"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testWithAdditionalInfoNPE() {
|
||||
withAdditionalInfo(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithUserData() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
options.withUserData("test");
|
||||
assertEquals(options.buildFormParameters().get("UserData"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullWithUserData() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
assertEquals(options.buildFormParameters().get("UserData"), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithUserDataStatic() {
|
||||
RunInstancesOptions options = withUserData("test");
|
||||
assertEquals(options.buildFormParameters().get("UserData"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testWithUserDataNPE() {
|
||||
withUserData(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithInstanceType() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
options.asType(InstanceType.C1_XLARGE);
|
||||
assertEquals(options.buildFormParameters().get("InstanceType"), Collections
|
||||
.singletonList("c1.xlarge"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullWithInstanceType() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
assertEquals(options.buildFormParameters().get("InstanceType"), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithInstanceTypeStatic() {
|
||||
RunInstancesOptions options = asType(InstanceType.C1_XLARGE);
|
||||
assertEquals(options.buildFormParameters().get("InstanceType"), Collections
|
||||
.singletonList("c1.xlarge"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testWithInstanceTypeNPE() {
|
||||
asType(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInAvailabilityZone() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
options.inAvailabilityZone("test");
|
||||
assertEquals(options.buildFormParameters().get("Placement.AvailabilityZone"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullAvailabilityZone() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
assertEquals(options.buildFormParameters().get("Placement.AvailabilityZone"),
|
||||
Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInAvailabilityZoneStatic() {
|
||||
RunInstancesOptions options = inAvailabilityZone("test");
|
||||
assertEquals(options.buildFormParameters().get("Placement.AvailabilityZone"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testInAvailabilityZoneNPE() {
|
||||
inAvailabilityZone(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithKernelId() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
options.withKernelId("test");
|
||||
assertEquals(options.buildFormParameters().get("KernelId"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullWithKernelId() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
assertEquals(options.buildFormParameters().get("KernelId"), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithKernelIdStatic() {
|
||||
RunInstancesOptions options = withKernelId("test");
|
||||
assertEquals(options.buildFormParameters().get("KernelId"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testWithKernelIdNPE() {
|
||||
withKernelId(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithDeviceName() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
options.withDeviceName("test");
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.DeviceName"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullWithDeviceName() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.DeviceName"),
|
||||
Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithDeviceNameStatic() {
|
||||
RunInstancesOptions options = withDeviceName("test");
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.DeviceName"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testWithDeviceNameNPE() {
|
||||
withDeviceName(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithMonitoringEnabled() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
options.enableMonitoring();
|
||||
assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections
|
||||
.singletonList("true"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullWithMonitoringEnabled() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithMonitoringEnabledStatic() {
|
||||
RunInstancesOptions options = enableMonitoring();
|
||||
assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections
|
||||
.singletonList("true"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithSubnetId() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
options.withSubnetId("test");
|
||||
assertEquals(options.buildFormParameters().get("SubnetId"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullWithSubnetId() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
assertEquals(options.buildFormParameters().get("SubnetId"), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithSubnetIdStatic() {
|
||||
RunInstancesOptions options = withSubnetId("test");
|
||||
assertEquals(options.buildFormParameters().get("SubnetId"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testWithSubnetIdNPE() {
|
||||
withSubnetId(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithRamdisk() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
options.withRamdisk("test");
|
||||
assertEquals(options.buildFormParameters().get("RamdiskId"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullWithRamdisk() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
assertEquals(options.buildFormParameters().get("RamdiskId"), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithRamdiskStatic() {
|
||||
RunInstancesOptions options = withRamdisk("test");
|
||||
assertEquals(options.buildFormParameters().get("RamdiskId"), Collections
|
||||
.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testWithRamdiskNPE() {
|
||||
withRamdisk(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithVirtualName() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
options.withVirtualName("test");
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"),
|
||||
Collections.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullWithVirtualName() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"),
|
||||
Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithVirtualNameStatic() {
|
||||
RunInstancesOptions options = withVirtualName("test");
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"),
|
||||
Collections.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testWithVirtualNameNPE() {
|
||||
withVirtualName(null);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.Image;
|
||||
import org.jclouds.aws.ec2.domain.Image.Architecture;
|
||||
import org.jclouds.aws.ec2.domain.Image.ImageState;
|
||||
import org.jclouds.aws.ec2.domain.Image.ImageType;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code DescribeImagesResponseHandler}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ec2.DescribeImagesResponseHandlerTest")
|
||||
public class DescribeImagesResponseHandlerTest extends BaseHandlerTest {
|
||||
|
||||
public void testApplyInputStream() {
|
||||
InputStream is = getClass().getResourceAsStream("/ec2/describe_images.xml");
|
||||
SortedSet<Image> contents = Sets.newTreeSet();
|
||||
|
||||
contents.add(new Image(Architecture.I386, "ami-be3adfd7",
|
||||
"ec2-public-images/fedora-8-i386-base-v1.04.manifest.xml", "206029621532",
|
||||
ImageState.AVAILABLE, ImageType.MACHINE, false, "aki-4438dd2d", null, Sets
|
||||
.<String> newHashSet(), "ari-4538dd2c"));
|
||||
|
||||
SortedSet<Image> result = (SortedSet<Image>) factory.create(
|
||||
injector.getInstance(DescribeImagesResponseHandler.class)).parse(is);
|
||||
|
||||
assertEquals(result, contents);
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.InstanceState;
|
||||
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||
import org.jclouds.aws.ec2.domain.Reservation;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code DescribeInstancesResponseHandler}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ec2.DescribeInstancesResponseHandlerTest")
|
||||
public class DescribeInstancesResponseHandlerTest extends BaseHandlerTest {
|
||||
|
||||
private DateService dateService;
|
||||
|
||||
@BeforeTest
|
||||
@Override
|
||||
protected void setUpInjector() {
|
||||
super.setUpInjector();
|
||||
dateService = injector.getInstance(DateService.class);
|
||||
assert dateService != null;
|
||||
}
|
||||
|
||||
public void testWhenRunning() throws UnknownHostException {
|
||||
|
||||
InputStream is = getClass().getResourceAsStream("/ec2/describe_instances_running.xml");
|
||||
SortedSet<Reservation> contents = Sets.newTreeSet();
|
||||
|
||||
contents.add(new Reservation(ImmutableSortedSet.of("adriancole.ec2ingress"),
|
||||
ImmutableSortedSet.of(new RunningInstance("0",
|
||||
"ec2-174-129-81-68.compute-1.amazonaws.com", "ami-1fd73376", "i-0799056f",
|
||||
InstanceState.RUNNING, InstanceType.M1_SMALL, InetAddress
|
||||
.getByName("174.129.81.68"), "aki-a71cf9ce", "adriancole.ec21",
|
||||
dateService.iso8601DateParse("2009-11-09T03:00:34.000Z"), false,
|
||||
"us-east-1c", null, "ip-10-243-42-70.ec2.internal", InetAddress
|
||||
.getByName("10.243.42.70"), ImmutableSet.<String> of(),
|
||||
"ari-a51cf9cc", null, null, null)), "993194456877", null, "r-a3c508cb"));
|
||||
|
||||
SortedSet<Reservation> result = factory.create(
|
||||
injector.getInstance(DescribeInstancesResponseHandler.class)).parse(is);
|
||||
|
||||
assertEquals(result, contents);
|
||||
|
||||
}
|
||||
|
||||
public void testApplyInputStream() {
|
||||
|
||||
InputStream is = getClass().getResourceAsStream("/ec2/describe_instances.xml");
|
||||
SortedSet<Reservation> contents = Sets.newTreeSet();
|
||||
|
||||
contents.add(new Reservation(ImmutableSortedSet.of("default"), ImmutableSortedSet.of(
|
||||
new RunningInstance("23", "ec2-72-44-33-4.compute-1.amazonaws.com", "ami-6ea54007",
|
||||
"i-28a64341", InstanceState.RUNNING, InstanceType.M1_LARGE,
|
||||
(InetAddress) null, "aki-ba3adfd3", "example-key-name", dateService
|
||||
.iso8601DateParse("2007-08-07T11:54:42.000Z"), false,
|
||||
"us-east-1b", null, "10-251-50-132.ec2.internal", null, ImmutableSet
|
||||
.of("774F4FF8"), "ari-badbad00", null, null, null),
|
||||
new RunningInstance("23", "ec2-72-44-33-6.compute-1.amazonaws.com", "ami-6ea54007",
|
||||
"i-28a64435", InstanceState.RUNNING, InstanceType.M1_LARGE,
|
||||
(InetAddress) null, "aki-ba3adfd3", "example-key-name", dateService
|
||||
.iso8601DateParse("2007-08-07T11:54:42.000Z"), false,
|
||||
"us-east-1b", null, "10-251-50-134.ec2.internal", null, ImmutableSet
|
||||
.of("774F4FF8"), "ari-badbad00", null, null, null)),
|
||||
"UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null, "r-44a5402d"));
|
||||
|
||||
SortedSet<Reservation> result = factory.create(
|
||||
injector.getInstance(DescribeInstancesResponseHandler.class)).parse(is);
|
||||
|
||||
assertEquals(result, contents);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code DescribeKeyPairsHandler}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ec2.DescribeKeyPairsHandlerTest")
|
||||
public class DescribeKeyPairsResponseHandlerTest extends BaseHandlerTest {
|
||||
public void testApplyInputStream() {
|
||||
|
||||
InputStream is = getClass().getResourceAsStream("/ec2/describe_keypairs.xml");
|
||||
|
||||
SortedSet<KeyPair> expected = ImmutableSortedSet.of(new KeyPair("gsg-keypair",
|
||||
"1f:51:ae:28:bf:89:e9:d8:1f:25:5d:37:2d:7d:b8:ca:9f:f5:f1:6f", null));
|
||||
|
||||
SortedSet<KeyPair> result = factory.create(
|
||||
injector.getInstance(DescribeKeyPairsResponseHandler.class)).parse(is);
|
||||
|
||||
assertEquals(result, expected);
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.IpPermission;
|
||||
import org.jclouds.aws.ec2.domain.IpProtocol;
|
||||
import org.jclouds.aws.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.aws.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code DescribeSecurityGroupsHandler}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ec2.DescribeSecurityGroupsHandlerTest")
|
||||
public class DescribeSecurityGroupsResponseHandlerTest extends BaseHandlerTest {
|
||||
public void testApplyInputStream() {
|
||||
|
||||
InputStream is = getClass().getResourceAsStream("/ec2/describe_securitygroups.xml");
|
||||
|
||||
SortedSet<SecurityGroup> expected = ImmutableSortedSet.of(new SecurityGroup("WebServers",
|
||||
"UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Web Servers", ImmutableSortedSet
|
||||
.of(new IpPermission(80, 80, ImmutableSortedSet.<UserIdGroupPair> of(),
|
||||
IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0")))),
|
||||
new SecurityGroup("RangedPortsBySource", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM",
|
||||
"Group A", ImmutableSortedSet.of(new IpPermission(6000, 7000,
|
||||
ImmutableSortedSet.<UserIdGroupPair> of(), IpProtocol.TCP,
|
||||
ImmutableSortedSet.<String> of()))));
|
||||
|
||||
SortedSet<SecurityGroup> result = factory.create(
|
||||
injector.getInstance(DescribeSecurityGroupsResponseHandler.class)).parse(is);
|
||||
|
||||
assertEquals(result, expected);
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code KeyPairResponseHandler}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ec2.KeyPairResponseHandlerTest")
|
||||
public class KeyPairResponseHandlerTest extends BaseHandlerTest {
|
||||
public void testApplyInputStream() {
|
||||
|
||||
InputStream is = getClass().getResourceAsStream("/ec2/create_keypair.xml");
|
||||
|
||||
KeyPair expected = new KeyPair(
|
||||
"gsg-keypair",
|
||||
"1f:51:ae:28:bf:89:e9:d8:1f:25:5d:37:2d:7d:b8:ca:9f:f5:f1:6f",
|
||||
"-----BEGIN RSA PRIVATE KEY-----\n"
|
||||
+ "MIIEoQIBAAKCAQBuLFg5ujHrtm1jnutSuoO8Xe56LlT+HM8v/xkaa39EstM3/aFxTHgElQiJLChp\n"
|
||||
+ "HungXQ29VTc8rc1bW0lkdi23OH5eqkMHGhvEwqa0HWASUMll4o3o/IX+0f2UcPoKCOVUR+jx71Sg\n"
|
||||
+ "5AU52EQfanIn3ZQ8lFW7Edp5a3q4DhjGlUKToHVbicL5E+g45zfB95wIyywWZfeW/UUF3LpGZyq/\n"
|
||||
+ "ebIUlq1qTbHkLbCC2r7RTn8vpQWp47BGVYGtGSBMpTRP5hnbzzuqj3itkiLHjU39S2sJCJ0TrJx5\n"
|
||||
+ "i8BygR4s3mHKBj8l+ePQxG1kGbF6R4yg6sECmXn17MRQVXODNHZbAgMBAAECggEAY1tsiUsIwDl5\n"
|
||||
+ "91CXirkYGuVfLyLflXenxfI50mDFms/mumTqloHO7tr0oriHDR5K7wMcY/YY5YkcXNo7mvUVD1pM\n"
|
||||
+ "ZNUJs7rw9gZRTrf7LylaJ58kOcyajw8TsC4e4LPbFaHwS1d6K8rXh64o6WgW4SrsB6ICmr1kGQI7\n"
|
||||
+ "3wcfgt5ecIu4TZf0OE9IHjn+2eRlsrjBdeORi7KiUNC/pAG23I6MdDOFEQRcCSigCj+4/mciFUSA\n"
|
||||
+ "SWS4dMbrpb9FNSIcf9dcLxVM7/6KxgJNfZc9XWzUw77Jg8x92Zd0fVhHOux5IZC+UvSKWB4dyfcI\n"
|
||||
+ "tE8C3p9bbU9VGyY5vLCAiIb4qQKBgQDLiO24GXrIkswF32YtBBMuVgLGCwU9h9HlO9mKAc2m8Cm1\n"
|
||||
+ "jUE5IpzRjTedc9I2qiIMUTwtgnw42auSCzbUeYMURPtDqyQ7p6AjMujp9EPemcSVOK9vXYL0Ptco\n"
|
||||
+ "xW9MC0dtV6iPkCN7gOqiZXPRKaFbWADp16p8UAIvS/a5XXk5jwKBgQCKkpHi2EISh1uRkhxljyWC\n"
|
||||
+ "iDCiK6JBRsMvpLbc0v5dKwP5alo1fmdR5PJaV2qvZSj5CYNpMAy1/EDNTY5OSIJU+0KFmQbyhsbm\n"
|
||||
+ "rdLNLDL4+TcnT7c62/aH01ohYaf/VCbRhtLlBfqGoQc7+sAc8vmKkesnF7CqCEKDyF/dhrxYdQKB\n"
|
||||
+ "gC0iZzzNAapayz1+JcVTwwEid6j9JqNXbBc+Z2YwMi+T0Fv/P/hwkX/ypeOXnIUcw0Ih/YtGBVAC\n"
|
||||
+ "DQbsz7LcY1HqXiHKYNWNvXgwwO+oiChjxvEkSdsTTIfnK4VSCvU9BxDbQHjdiNDJbL6oar92UN7V\n"
|
||||
+ "rBYvChJZF7LvUH4YmVpHAoGAbZ2X7XvoeEO+uZ58/BGKOIGHByHBDiXtzMhdJr15HTYjxK7OgTZm\n"
|
||||
+ "gK+8zp4L9IbvLGDMJO8vft32XPEWuvI8twCzFH+CsWLQADZMZKSsBasOZ/h1FwhdMgCMcY+Qlzd4\n"
|
||||
+ "JZKjTSu3i7vhvx6RzdSedXEMNTZWN4qlIx3kR5aHcukCgYA9T+Zrvm1F0seQPbLknn7EqhXIjBaT\n"
|
||||
+ "P8TTvW/6bdPi23ExzxZn7KOdrfclYRph1LHMpAONv/x2xALIf91UB+v5ohy1oDoasL0gij1houRe\n"
|
||||
+ "2ERKKdwz0ZL9SWq6VTdhr/5G994CK72fy5WhyERbDjUIdHaK3M849JJuf8cSrvSb4g==\n"
|
||||
+ "-----END RSA PRIVATE KEY-----");
|
||||
|
||||
KeyPair result = factory.create(injector.getInstance(KeyPairResponseHandler.class)).parse(is);
|
||||
|
||||
assertEquals(result, expected);
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.InstanceState;
|
||||
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||
import org.jclouds.aws.ec2.domain.Reservation;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code RunInstancesResponseHandler}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ec2.RunInstancesResponseHandlerTest")
|
||||
public class RunInstancesResponseHandlerTest extends BaseHandlerTest {
|
||||
|
||||
private DateService dateService;
|
||||
|
||||
@BeforeTest
|
||||
@Override
|
||||
protected void setUpInjector() {
|
||||
super.setUpInjector();
|
||||
dateService = injector.getInstance(DateService.class);
|
||||
assert dateService != null;
|
||||
}
|
||||
|
||||
public void testApplyInputStream() {
|
||||
|
||||
InputStream is = getClass().getResourceAsStream("/ec2/run_instances.xml");
|
||||
|
||||
Reservation expected = new Reservation(ImmutableSortedSet.of("default"), ImmutableSortedSet
|
||||
.of(
|
||||
new RunningInstance("0", null, "ami-60a54009", "i-2ba64342",
|
||||
InstanceState.PENDING, InstanceType.M1_SMALL, (InetAddress) null, null,
|
||||
"example-key-name", dateService
|
||||
.iso8601DateParse("2007-08-07T11:51:50.000Z"), true, "us-east-1b",
|
||||
null, null, (InetAddress) null, Sets.<String> newTreeSet(), null, null,
|
||||
null, null), new RunningInstance("0", null, "ami-60a54009",
|
||||
"i-2bc64242", InstanceState.PENDING, InstanceType.M1_SMALL,
|
||||
(InetAddress) null, null, "example-key-name", dateService
|
||||
.iso8601DateParse("2007-08-07T11:51:50.000Z"), true, "us-east-1b",
|
||||
null, null, (InetAddress) null, Sets.<String> newTreeSet(), null, null,
|
||||
null, null), new RunningInstance("0", null, "ami-60a54009",
|
||||
"i-2be64332", InstanceState.PENDING, InstanceType.M1_SMALL,
|
||||
(InetAddress) null, null, "example-key-name", dateService
|
||||
.iso8601DateParse("2007-08-07T11:51:50.000Z"), true, "us-east-1b",
|
||||
null, null, (InetAddress) null, Sets.<String> newTreeSet(), null, null,
|
||||
null, null)
|
||||
|
||||
), "AIDADH4IGTRXXKCD", null, "r-47a5402e");
|
||||
|
||||
Reservation result = factory.create(
|
||||
injector.getInstance(RunInstancesResponseHandler.class)).parse(is);
|
||||
|
||||
assertEquals(result, expected);
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.InstanceState;
|
||||
import org.jclouds.aws.ec2.domain.TerminatedInstance;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code TerminateInstancesResponseHandler}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ec2.TerminateInstancesResponseHandlerTest")
|
||||
public class TerminateInstancesResponseHandlerTest extends BaseHandlerTest {
|
||||
|
||||
private DateService dateService;
|
||||
|
||||
@BeforeTest
|
||||
@Override
|
||||
protected void setUpInjector() {
|
||||
super.setUpInjector();
|
||||
dateService = injector.getInstance(DateService.class);
|
||||
assert dateService != null;
|
||||
}
|
||||
|
||||
public void testApplyInputStream() {
|
||||
|
||||
InputStream is = getClass().getResourceAsStream("/ec2/terminate_instances.xml");
|
||||
|
||||
SortedSet<TerminatedInstance> expected = ImmutableSortedSet.of(new TerminatedInstance(
|
||||
"i-3ea74257", InstanceState.SHUTTING_DOWN, InstanceState.RUNNING));
|
||||
|
||||
SortedSet<TerminatedInstance> result = factory.create(
|
||||
injector.getInstance(TerminateInstancesResponseHandler.class)).parse(is);
|
||||
|
||||
assertEquals(result, expected);
|
||||
}
|
||||
}
|
27
aws/core/src/test/resources/ec2/create_keypair.xml
Normal file
27
aws/core/src/test/resources/ec2/create_keypair.xml
Normal file
@ -0,0 +1,27 @@
|
||||
<CreateKeyPairResponse xmlns="http://ec2.amazonaws.com/doc/2009-08-15/">
|
||||
<keyName>gsg-keypair</keyName>
|
||||
<keyFingerprint>1f:51:ae:28:bf:89:e9:d8:1f:25:5d:37:2d:7d:b8:ca:9f:f5:f1:6f</keyFingerprint>
|
||||
<keyMaterial>-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEoQIBAAKCAQBuLFg5ujHrtm1jnutSuoO8Xe56LlT+HM8v/xkaa39EstM3/aFxTHgElQiJLChp
|
||||
HungXQ29VTc8rc1bW0lkdi23OH5eqkMHGhvEwqa0HWASUMll4o3o/IX+0f2UcPoKCOVUR+jx71Sg
|
||||
5AU52EQfanIn3ZQ8lFW7Edp5a3q4DhjGlUKToHVbicL5E+g45zfB95wIyywWZfeW/UUF3LpGZyq/
|
||||
ebIUlq1qTbHkLbCC2r7RTn8vpQWp47BGVYGtGSBMpTRP5hnbzzuqj3itkiLHjU39S2sJCJ0TrJx5
|
||||
i8BygR4s3mHKBj8l+ePQxG1kGbF6R4yg6sECmXn17MRQVXODNHZbAgMBAAECggEAY1tsiUsIwDl5
|
||||
91CXirkYGuVfLyLflXenxfI50mDFms/mumTqloHO7tr0oriHDR5K7wMcY/YY5YkcXNo7mvUVD1pM
|
||||
ZNUJs7rw9gZRTrf7LylaJ58kOcyajw8TsC4e4LPbFaHwS1d6K8rXh64o6WgW4SrsB6ICmr1kGQI7
|
||||
3wcfgt5ecIu4TZf0OE9IHjn+2eRlsrjBdeORi7KiUNC/pAG23I6MdDOFEQRcCSigCj+4/mciFUSA
|
||||
SWS4dMbrpb9FNSIcf9dcLxVM7/6KxgJNfZc9XWzUw77Jg8x92Zd0fVhHOux5IZC+UvSKWB4dyfcI
|
||||
tE8C3p9bbU9VGyY5vLCAiIb4qQKBgQDLiO24GXrIkswF32YtBBMuVgLGCwU9h9HlO9mKAc2m8Cm1
|
||||
jUE5IpzRjTedc9I2qiIMUTwtgnw42auSCzbUeYMURPtDqyQ7p6AjMujp9EPemcSVOK9vXYL0Ptco
|
||||
xW9MC0dtV6iPkCN7gOqiZXPRKaFbWADp16p8UAIvS/a5XXk5jwKBgQCKkpHi2EISh1uRkhxljyWC
|
||||
iDCiK6JBRsMvpLbc0v5dKwP5alo1fmdR5PJaV2qvZSj5CYNpMAy1/EDNTY5OSIJU+0KFmQbyhsbm
|
||||
rdLNLDL4+TcnT7c62/aH01ohYaf/VCbRhtLlBfqGoQc7+sAc8vmKkesnF7CqCEKDyF/dhrxYdQKB
|
||||
gC0iZzzNAapayz1+JcVTwwEid6j9JqNXbBc+Z2YwMi+T0Fv/P/hwkX/ypeOXnIUcw0Ih/YtGBVAC
|
||||
DQbsz7LcY1HqXiHKYNWNvXgwwO+oiChjxvEkSdsTTIfnK4VSCvU9BxDbQHjdiNDJbL6oar92UN7V
|
||||
rBYvChJZF7LvUH4YmVpHAoGAbZ2X7XvoeEO+uZ58/BGKOIGHByHBDiXtzMhdJr15HTYjxK7OgTZm
|
||||
gK+8zp4L9IbvLGDMJO8vft32XPEWuvI8twCzFH+CsWLQADZMZKSsBasOZ/h1FwhdMgCMcY+Qlzd4
|
||||
JZKjTSu3i7vhvx6RzdSedXEMNTZWN4qlIx3kR5aHcukCgYA9T+Zrvm1F0seQPbLknn7EqhXIjBaT
|
||||
P8TTvW/6bdPi23ExzxZn7KOdrfclYRph1LHMpAONv/x2xALIf91UB+v5ohy1oDoasL0gij1houRe
|
||||
2ERKKdwz0ZL9SWq6VTdhr/5G994CK72fy5WhyERbDjUIdHaK3M849JJuf8cSrvSb4g==
|
||||
-----END RSA PRIVATE KEY-----</keyMaterial>
|
||||
</CreateKeyPairResponse>
|
16
aws/core/src/test/resources/ec2/describe_images.xml
Normal file
16
aws/core/src/test/resources/ec2/describe_images.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/2009-08-15/">
|
||||
<imagesSet>
|
||||
<item>
|
||||
<imageId>ami-be3adfd7</imageId>
|
||||
<imageLocation>ec2-public-images/fedora-8-i386-base-v1.04.manifest.xml
|
||||
</imageLocation>
|
||||
<imageState>available</imageState>
|
||||
<imageOwnerId>206029621532</imageOwnerId>
|
||||
<isPublic>false</isPublic>
|
||||
<architecture>i386</architecture>
|
||||
<imageType>machine</imageType>
|
||||
<kernelId>aki-4438dd2d</kernelId>
|
||||
<ramdiskId>ari-4538dd2c</ramdiskId>
|
||||
</item>
|
||||
</imagesSet>
|
||||
</DescribeImagesResponse>
|
59
aws/core/src/test/resources/ec2/describe_instances.xml
Normal file
59
aws/core/src/test/resources/ec2/describe_instances.xml
Normal file
@ -0,0 +1,59 @@
|
||||
<DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2009-08-15/">
|
||||
<reservationSet>
|
||||
<item>
|
||||
<reservationId>r-44a5402d</reservationId>
|
||||
<ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId>
|
||||
<groupSet>
|
||||
<item>
|
||||
<groupId>default</groupId>
|
||||
</item>
|
||||
</groupSet>
|
||||
<instancesSet>
|
||||
<item>
|
||||
<instanceId>i-28a64341</instanceId>
|
||||
<imageId>ami-6ea54007</imageId>
|
||||
<instanceState>
|
||||
<code>0</code>
|
||||
<name>running</name>
|
||||
</instanceState>
|
||||
<privateDnsName>10-251-50-132.ec2.internal</privateDnsName>
|
||||
<dnsName>ec2-72-44-33-4.compute-1.amazonaws.com</dnsName>
|
||||
<keyName>example-key-name</keyName>
|
||||
<amiLaunchIndex>23</amiLaunchIndex>
|
||||
<productCodesSet>
|
||||
<item><productCode>774F4FF8</productCode></item>
|
||||
</productCodesSet>
|
||||
<instanceType>m1.large</instanceType>
|
||||
<launchTime>2007-08-07T11:54:42.000Z</launchTime>
|
||||
<placement>
|
||||
<availabilityZone>us-east-1b</availabilityZone>
|
||||
</placement>
|
||||
<kernelId>aki-ba3adfd3</kernelId>
|
||||
<ramdiskId>ari-badbad00</ramdiskId>
|
||||
</item>
|
||||
<item>
|
||||
<instanceId>i-28a64435</instanceId>
|
||||
<imageId>ami-6ea54007</imageId>
|
||||
<instanceState>
|
||||
<code>0</code>
|
||||
<name>running</name>
|
||||
</instanceState>
|
||||
<privateDnsName>10-251-50-134.ec2.internal</privateDnsName>
|
||||
<dnsName>ec2-72-44-33-6.compute-1.amazonaws.com</dnsName>
|
||||
<keyName>example-key-name</keyName>
|
||||
<amiLaunchIndex>23</amiLaunchIndex>
|
||||
<productCodesSet>
|
||||
<item><productCode>774F4FF8</productCode></item>
|
||||
</productCodesSet>
|
||||
<instanceType>m1.large</instanceType>
|
||||
<launchTime>2007-08-07T11:54:42.000Z</launchTime>
|
||||
<placement>
|
||||
<availabilityZone>us-east-1b</availabilityZone>
|
||||
</placement>
|
||||
<kernelId>aki-ba3adfd3</kernelId>
|
||||
<ramdiskId>ari-badbad00</ramdiskId>
|
||||
</item>
|
||||
</instancesSet>
|
||||
</item>
|
||||
</reservationSet>
|
||||
</DescribeInstancesResponse>
|
@ -0,0 +1,44 @@
|
||||
<DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2009-08-15/">
|
||||
<requestId>ae75a8cc-b707-4a20-b130-61ad6f20de61</requestId>
|
||||
<reservationSet>
|
||||
<item>
|
||||
<reservationId>r-a3c508cb</reservationId>
|
||||
<ownerId>993194456877</ownerId>
|
||||
<groupSet>
|
||||
<item>
|
||||
<groupId>adriancole.ec2ingress</groupId>
|
||||
</item>
|
||||
</groupSet>
|
||||
<instancesSet>
|
||||
<item>
|
||||
<instanceId>i-0799056f</instanceId>
|
||||
<imageId>ami-1fd73376</imageId>
|
||||
<instanceState>
|
||||
<code>16</code>
|
||||
<name>running</name>
|
||||
</instanceState>
|
||||
<privateDnsName>ip-10-243-42-70.ec2.internal
|
||||
</privateDnsName>
|
||||
<dnsName>ec2-174-129-81-68.compute-1.amazonaws.com
|
||||
</dnsName>
|
||||
<reason />
|
||||
<keyName>adriancole.ec21</keyName>
|
||||
<amiLaunchIndex>0</amiLaunchIndex>
|
||||
<productCodes />
|
||||
<instanceType>m1.small</instanceType>
|
||||
<launchTime>2009-11-09T03:00:34.000Z</launchTime>
|
||||
<placement>
|
||||
<availabilityZone>us-east-1c</availabilityZone>
|
||||
</placement>
|
||||
<kernelId>aki-a71cf9ce</kernelId>
|
||||
<ramdiskId>ari-a51cf9cc</ramdiskId>
|
||||
<monitoring>
|
||||
<state>disabled</state>
|
||||
</monitoring>
|
||||
<privateIpAddress>10.243.42.70</privateIpAddress>
|
||||
<ipAddress>174.129.81.68</ipAddress>
|
||||
</item>
|
||||
</instancesSet>
|
||||
</item>
|
||||
</reservationSet>
|
||||
</DescribeInstancesResponse>
|
8
aws/core/src/test/resources/ec2/describe_keypairs.xml
Normal file
8
aws/core/src/test/resources/ec2/describe_keypairs.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<DescribeKeyPairsResponse xmlns="http://ec2.amazonaws.com/doc/2009-08-15/">
|
||||
<keySet>
|
||||
<item>
|
||||
<keyName>gsg-keypair</keyName>
|
||||
<keyFingerprint>1f:51:ae:28:bf:89:e9:d8:1f:25:5d:37:2d:7d:b8:ca:9f:f5:f1:6f</keyFingerprint>
|
||||
</item>
|
||||
</keySet>
|
||||
</DescribeKeyPairsResponse>
|
36
aws/core/src/test/resources/ec2/describe_securitygroups.xml
Normal file
36
aws/core/src/test/resources/ec2/describe_securitygroups.xml
Normal file
@ -0,0 +1,36 @@
|
||||
<DescribeSecurityGroupsResponse xmlns="http://ec2.amazonaws.com/doc/2009-08-15/">
|
||||
<securityGroupInfo>
|
||||
<item>
|
||||
<ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId>
|
||||
<groupName>WebServers</groupName>
|
||||
<groupDescription>Web Servers</groupDescription>
|
||||
<ipPermissions>
|
||||
<item>
|
||||
<ipProtocol>tcp</ipProtocol>
|
||||
<fromPort>80</fromPort>
|
||||
<toPort>80</toPort>
|
||||
<groups/>
|
||||
<ipRanges>
|
||||
<item>
|
||||
<cidrIp>0.0.0.0/0</cidrIp>
|
||||
</item>
|
||||
</ipRanges>
|
||||
</item>
|
||||
</ipPermissions>
|
||||
</item>
|
||||
<item>
|
||||
<ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId>
|
||||
<groupName>RangedPortsBySource</groupName>
|
||||
<groupDescription>Group A</groupDescription>
|
||||
<ipPermissions>
|
||||
<item>
|
||||
<ipProtocol>tcp</ipProtocol>
|
||||
<fromPort>6000</fromPort>
|
||||
<toPort>7000</toPort>
|
||||
<groups/>
|
||||
<ipRanges/>
|
||||
</item>
|
||||
</ipPermissions>
|
||||
</item>
|
||||
</securityGroupInfo>
|
||||
</DescribeSecurityGroupsResponse>
|
114
aws/core/src/test/resources/ec2/log4j.xml
Executable file
114
aws/core/src/test/resources/ec2/log4j.xml
Executable file
@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
====================================================================
|
||||
|
||||
-->
|
||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||
|
||||
<!--
|
||||
For more configuration infromation and examples see the Apache Log4j
|
||||
website: http://logging.apache.org/log4j/
|
||||
-->
|
||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
|
||||
debug="false">
|
||||
|
||||
<!-- A time/date based rolling appender -->
|
||||
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||
<param name="File" value="target/test-data/jclouds-wire.log" />
|
||||
<param name="Append" value="true" />
|
||||
|
||||
<!-- Rollover at midnight each day -->
|
||||
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||
|
||||
<param name="Threshold" value="TRACE" />
|
||||
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||
|
||||
<!--
|
||||
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
|
||||
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
|
||||
%m%n"/>
|
||||
-->
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- A time/date based rolling appender -->
|
||||
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||
<param name="File" value="target/test-data/jclouds.log" />
|
||||
<param name="Append" value="true" />
|
||||
|
||||
<!-- Rollover at midnight each day -->
|
||||
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||
|
||||
<param name="Threshold" value="TRACE" />
|
||||
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||
|
||||
<!--
|
||||
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
|
||||
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
|
||||
%m%n"/>
|
||||
-->
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
|
||||
<appender-ref ref="FILE" />
|
||||
</appender>
|
||||
|
||||
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
|
||||
<appender-ref ref="WIREFILE" />
|
||||
</appender>
|
||||
|
||||
<!-- ================ -->
|
||||
<!-- Limit categories -->
|
||||
<!-- ================ -->
|
||||
|
||||
<category name="org.jclouds">
|
||||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNC" />
|
||||
</category>
|
||||
|
||||
<category name="jclouds.http.headers">
|
||||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNCWIRE" />
|
||||
</category>
|
||||
<category name="jclouds.http.wire">
|
||||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNCWIRE" />
|
||||
</category>
|
||||
|
||||
<!-- ======================= -->
|
||||
<!-- Setup the Root category -->
|
||||
<!-- ======================= -->
|
||||
|
||||
<root>
|
||||
<priority value="WARN" />
|
||||
</root>
|
||||
|
||||
</log4j:configuration>
|
71
aws/core/src/test/resources/ec2/run_instances.xml
Normal file
71
aws/core/src/test/resources/ec2/run_instances.xml
Normal file
@ -0,0 +1,71 @@
|
||||
<RunInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2009-08-15/">
|
||||
<reservationId>r-47a5402e</reservationId>
|
||||
<ownerId>AIDADH4IGTRXXKCD</ownerId>
|
||||
<groupSet>
|
||||
<item>
|
||||
<groupId>default</groupId>
|
||||
</item>
|
||||
</groupSet>
|
||||
<instancesSet>
|
||||
<item>
|
||||
<instanceId>i-2ba64342</instanceId>
|
||||
<imageId>ami-60a54009</imageId>
|
||||
<instanceState>
|
||||
<code>0</code>
|
||||
<name>pending</name>
|
||||
</instanceState>
|
||||
<privateDnsName></privateDnsName>
|
||||
<dnsName></dnsName>
|
||||
<keyName>example-key-name</keyName>
|
||||
<amiLaunchIndex>0</amiLaunchIndex>
|
||||
<instanceType>m1.small</instanceType>
|
||||
<launchTime>2007-08-07T11:51:50.000Z</launchTime>
|
||||
<placement>
|
||||
<availabilityZone>us-east-1b</availabilityZone>
|
||||
</placement>
|
||||
<monitoring>
|
||||
<enabled>true</enabled>
|
||||
</monitoring>
|
||||
</item>
|
||||
<item>
|
||||
<instanceId>i-2bc64242</instanceId>
|
||||
<imageId>ami-60a54009</imageId>
|
||||
<instanceState>
|
||||
<code>0</code>
|
||||
<name>pending</name>
|
||||
</instanceState>
|
||||
<privateDnsName></privateDnsName>
|
||||
<dnsName></dnsName>
|
||||
<keyName>example-key-name</keyName>
|
||||
<amiLaunchIndex>1</amiLaunchIndex>
|
||||
<instanceType>m1.small</instanceType>
|
||||
<launchTime>2007-08-07T11:51:50.000Z</launchTime>
|
||||
<placement>
|
||||
<availabilityZone>us-east-1b</availabilityZone>
|
||||
</placement>
|
||||
<monitoring>
|
||||
<enabled>true</enabled>
|
||||
</monitoring>
|
||||
</item>
|
||||
<item>
|
||||
<instanceId>i-2be64332</instanceId>
|
||||
<imageId>ami-60a54009</imageId>
|
||||
<instanceState>
|
||||
<code>0</code>
|
||||
<name>pending</name>
|
||||
</instanceState>
|
||||
<privateDnsName></privateDnsName>
|
||||
<dnsName></dnsName>
|
||||
<keyName>example-key-name</keyName>
|
||||
<amiLaunchIndex>2</amiLaunchIndex>
|
||||
<instanceType>m1.small</instanceType>
|
||||
<launchTime>2007-08-07T11:51:50.000Z</launchTime>
|
||||
<placement>
|
||||
<availabilityZone>us-east-1b</availabilityZone>
|
||||
</placement>
|
||||
<monitoring>
|
||||
<enabled>true</enabled>
|
||||
</monitoring>
|
||||
</item>
|
||||
</instancesSet>
|
||||
</RunInstancesResponse>
|
15
aws/core/src/test/resources/ec2/terminate_instances.xml
Normal file
15
aws/core/src/test/resources/ec2/terminate_instances.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<TerminateInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2009-08-15/">
|
||||
<instancesSet>
|
||||
<item>
|
||||
<instanceId>i-3ea74257</instanceId>
|
||||
<shutdownState>
|
||||
<code>32</code>
|
||||
<name>shutting-down</name>
|
||||
</shutdownState>
|
||||
<previousState>
|
||||
<code>16</code>
|
||||
<name>running</name>
|
||||
</previousState>
|
||||
</item>
|
||||
</instancesSet>
|
||||
</TerminateInstancesResponse>
|
@ -1,48 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
$HeadURL$
|
||||
$Revision$
|
||||
$Date$
|
||||
|
||||
Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
|
||||
|
||||
====================================================================
|
||||
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.html
|
||||
|
||||
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.
|
||||
====================================================================
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-ec2-project</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-ec2-core</artifactId>
|
||||
<name>jclouds Amazon EC2 Components Core</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>jclouds Core components to access Amazon EC2</description>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/aws/ec2/core</connection>
|
||||
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk/aws/ec2/core</developerConnection>
|
||||
<url>http://jclouds.googlecode.com/svn/trunk/aws/ec2/core</url>
|
||||
</scm>
|
||||
</project>
|
@ -1,271 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.commands.options;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.ACTION;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.AWS_ACCESS_KEY_ID;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.EXPIRES;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.SIGNATURE;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.SIGNATURE_METHOD;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.SIGNATURE_VERSION;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.TIMESTAMP;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.VERSION;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import org.jclouds.aws.ec2.reference.CommonEC2Parameters;
|
||||
import org.jclouds.aws.util.AWSUtils;
|
||||
import org.jclouds.aws.util.DateService;
|
||||
import org.jclouds.http.HttpHeaders;
|
||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* Contains the base options needed for all EC2 QUERY API operations.<h2>
|
||||
* Extend this class in the following way to avoid massive boilerplate code: Usage:
|
||||
* <p/>
|
||||
*
|
||||
* <pre>
|
||||
* public static class MyRequestOptions extends BaseEC2RequestOptions<MyRequestOptions> {
|
||||
* static {
|
||||
* realClass = MyRequestOptions.class;
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public String getAction() {
|
||||
* return "MyRequest";
|
||||
* }
|
||||
*
|
||||
* public String getId() {
|
||||
* return parameters.get("id");
|
||||
* }
|
||||
*
|
||||
* public MyRequestOptions withId(String id) {
|
||||
* encodeAndReplaceParameter("id", id);
|
||||
* return this;
|
||||
* }
|
||||
*
|
||||
* public static class Builder extends BaseEC2RequestOptions.Builder {
|
||||
* public static MyRequestOptions withId(String id) {
|
||||
* MyRequestOptions options = new MyRequestOptions();
|
||||
* return options.withId(id);
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/Query-Common-Parameters.html"
|
||||
* />
|
||||
* @see CommonEC2Parameters
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public abstract class BaseEC2RequestOptions<T extends EC2RequestOptions> extends
|
||||
BaseHttpRequestOptions implements EC2RequestOptions {
|
||||
|
||||
public static String[] mandatoryParametersForSignature = new String[] { ACTION,
|
||||
SIGNATURE_METHOD, SIGNATURE_VERSION, VERSION };
|
||||
|
||||
static final DateService dateService = new DateService();
|
||||
|
||||
private String awsSecretAccessKey;
|
||||
|
||||
private String awsAccessKeyId;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see CommonEC2Parameters#ACTION
|
||||
*/
|
||||
public abstract String getAction();
|
||||
|
||||
protected static Class<? extends EC2RequestOptions> realClass = BaseEC2RequestOptions.class;
|
||||
|
||||
/**
|
||||
* Sets the request property <code>Action</code> to the appropriate name
|
||||
*
|
||||
*/
|
||||
public BaseEC2RequestOptions() {
|
||||
try {
|
||||
parameters.put(ACTION, URLEncoder.encode(getAction(), "UTF-8"));
|
||||
parameters.put(SIGNATURE_METHOD, URLEncoder.encode("HmacSHA256", "UTF-8"));
|
||||
parameters.put(SIGNATURE_VERSION, URLEncoder.encode("2", "UTF-8"));
|
||||
parameters.put(VERSION, URLEncoder.encode("2009-04-04", "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
assert false : e.toString();
|
||||
// job of unit test to ensure this never happens
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see CommonEC2Parameters#TIMESTAMP
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T timeStamp() {
|
||||
encodeAndReplaceParameter(TIMESTAMP, dateService.iso8601DateFormat());
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see CommonEC2Parameters#EXPIRES
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T expireAt(DateTime time) {
|
||||
try {
|
||||
parameters.put(EXPIRES, URLEncoder.encode(dateService.iso8601DateFormat(checkNotNull(time,
|
||||
"time")), "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new IllegalArgumentException("bad encoding on datetime: " + time, e);
|
||||
}
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildQueryString() {
|
||||
checkState(awsSecretAccessKey != null,
|
||||
"request is not ready to sign; awsSecretAccessKey not present");
|
||||
checkState(awsAccessKeyId != null, "request is not ready to sign; awsAccessKeyId not present");
|
||||
String host = getFirstHeaderOrNull(HttpHeaders.HOST);
|
||||
checkState(host != null, "request is not ready to sign; host not present");
|
||||
// timestamp is incompatible with expires
|
||||
if (parameters.get(EXPIRES) == null) {
|
||||
timeStamp();
|
||||
}
|
||||
for (String parameter : mandatoryParametersForSignature) {
|
||||
checkState(parameters.get(parameter) != null, "parameter " + parameter
|
||||
+ " is required for signature");
|
||||
}
|
||||
parameters.remove(SIGNATURE);
|
||||
encodeAndReplaceParameter(AWS_ACCESS_KEY_ID, awsAccessKeyId);
|
||||
|
||||
// 1. Sort the UTF-8 query string components by parameter name with natural byte ordering.
|
||||
// -- as parameters are a SortedSet, they are already sorted.
|
||||
// 2. URL encode the parameter name and values according to the following rules...
|
||||
// -- all parameters are URL encoded on the way in
|
||||
// 3. Separate the encoded parameter names from their encoded values with the equals sign,
|
||||
// even if the parameter value is empty.
|
||||
// -- we do not allow null values.
|
||||
// 4. Separate the name-value pairs with an ampersand.
|
||||
// -- buildQueryString() does this.
|
||||
StringBuilder toSign = new StringBuilder();
|
||||
toSign.append(HttpMethod.GET).append("\n").append(host.toLowerCase()).append("\n").append("/").append(
|
||||
"\n");
|
||||
String canonicalizedQueryString = super.buildQueryString().replaceFirst("\\?", "");
|
||||
toSign.append(canonicalizedQueryString);
|
||||
String signature;
|
||||
try {
|
||||
signature = AWSUtils.hmacSha256Base64(toSign.toString(), awsSecretAccessKey.getBytes());
|
||||
encodeAndReplaceParameter(SIGNATURE, signature);
|
||||
return super.buildQueryString();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("error signing request [" + toSign.toString() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see CommonEC2Parameters#AWS_ACCESS_KEY_ID
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T signWith(String awsAccessKeyId, String awsSecretAccessKey) {
|
||||
this.awsAccessKeyId = checkNotNull(awsAccessKeyId, "awsAccessKeyId");
|
||||
this.awsSecretAccessKey = checkNotNull(awsSecretAccessKey, "awsSecretAccessKey");
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see HttpHeaders#HOST
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T usingHost(String hostname) {
|
||||
this.replaceHeader(HttpHeaders.HOST, hostname);
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The types here are parameterized in effort to return the proper type of the subclass
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public static abstract class Builder {
|
||||
|
||||
/**
|
||||
* @see BaseEC2RequestOptions#expireAt(DateTime)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends EC2RequestOptions> T expireAt(DateTime time) {
|
||||
T options;
|
||||
try {
|
||||
options = (T) realClass.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new Error("incorrect configuration, class: " + realClass
|
||||
+ " should extend BaseEC2RequestOptions", e);
|
||||
}
|
||||
return (T) options.expireAt(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see BaseEC2RequestOptions#usingHost(String)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends EC2RequestOptions> T usingHost(String hostname) {
|
||||
T options;
|
||||
try {
|
||||
options = (T) realClass.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new Error("incorrect configuration, class: " + realClass
|
||||
+ " should extend BaseEC2RequestOptions", e);
|
||||
}
|
||||
return (T) options.usingHost(hostname);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see BaseEC2RequestOptions#signWith(String,String)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends EC2RequestOptions> T signWith(String awsAccessKeyId,
|
||||
String awsSecretAccessKey) {
|
||||
T options;
|
||||
try {
|
||||
options = (T) realClass.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new Error("incorrect configuration, class: " + realClass
|
||||
+ " should extend BaseEC2RequestOptions", e);
|
||||
}
|
||||
return (T) options.signWith(awsAccessKeyId, awsSecretAccessKey);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,176 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.commands.options;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.ACTION;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.AWS_ACCESS_KEY_ID;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.EXPIRES;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.SIGNATURE;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.SIGNATURE_METHOD;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.SIGNATURE_VERSION;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.TIMESTAMP;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.VERSION;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
import org.jclouds.aws.ec2.reference.CommonEC2Parameters;
|
||||
import org.jclouds.aws.reference.AWSConstants;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.util.DateService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* Contains the base options needed for all EC2 QUERY API operations.<h2>
|
||||
* Extend this class in the following way to avoid massive boilerplate code: Usage:
|
||||
* <p/>
|
||||
*
|
||||
* <pre>
|
||||
* public static class MyRequestOptions extends BaseEC2RequestOptions<MyRequestOptions> {
|
||||
* static {
|
||||
* realClass = MyRequestOptions.class;
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public String getAction() {
|
||||
* return "MyRequest";
|
||||
* }
|
||||
*
|
||||
* public String getId() {
|
||||
* return queryParameters.get("id");
|
||||
* }
|
||||
*
|
||||
* public MyRequestOptions withId(String id) {
|
||||
* encodeAndReplaceParameter("id", id);
|
||||
* return this;
|
||||
* }
|
||||
*
|
||||
* public static class Builder extends BaseEC2RequestOptions.Builder {
|
||||
* public static MyRequestOptions withId(String id) {
|
||||
* MyRequestOptions options = new MyRequestOptions();
|
||||
* return options.withId(id);
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/Query-Common-Parameters.html"
|
||||
* />
|
||||
* @see CommonEC2Parameters
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public class EC2QuerySigner implements HttpRequestFilter {
|
||||
|
||||
public static String[] mandatoryParametersForSignature = new String[] { ACTION,
|
||||
SIGNATURE_METHOD, SIGNATURE_VERSION, VERSION };
|
||||
private final String accessKey;
|
||||
private final String secretKey;
|
||||
private final DateService dateService;
|
||||
|
||||
@Inject
|
||||
public EC2QuerySigner(@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String accessKey,
|
||||
@Named(AWSConstants.PROPERTY_AWS_SECRETACCESSKEY) String secretKey,
|
||||
DateService dateService) {
|
||||
this.accessKey = accessKey;
|
||||
this.secretKey = secretKey;
|
||||
this.dateService = dateService;
|
||||
}
|
||||
|
||||
public HttpRequest filter(HttpRequest request) throws HttpException {
|
||||
validateRequest(request);
|
||||
request = addSigningParamsToRequest(request);
|
||||
String stringToSign = buildStringToSign(request);
|
||||
String signature = sign(stringToSign);
|
||||
return addSignatureToRequest(request, signature);
|
||||
}
|
||||
|
||||
private void validateRequest(HttpRequest request) {
|
||||
for (String parameter : mandatoryParametersForSignature) {
|
||||
checkState(request.getEndpoint().getQuery().contains(parameter), "parameter " + parameter
|
||||
+ " is required for signature");
|
||||
}
|
||||
checkState(request.getHeaders().get(HttpHeaders.HOST) != null,
|
||||
"request is not ready to sign; host not present");
|
||||
}
|
||||
|
||||
private HttpRequest addSignatureToRequest(HttpRequest request, String signature) {
|
||||
UriBuilder builder = UriBuilder.fromUri(request.getEndpoint());
|
||||
builder.queryParam(SIGNATURE, signature);
|
||||
return new HttpRequest(request.getMethod(), builder.build(), request.getHeaders(), request
|
||||
.getEntity());
|
||||
}
|
||||
|
||||
private String sign(String stringToSign) {
|
||||
String signature;
|
||||
try {
|
||||
signature = HttpUtils.hmacSha256Base64(stringToSign, secretKey.getBytes());
|
||||
} catch (Exception e) {
|
||||
throw new HttpException("error signing request", e);
|
||||
}
|
||||
return signature;
|
||||
}
|
||||
|
||||
private String buildStringToSign(HttpRequest request) {
|
||||
// 1. Sort the UTF-8 query string components by parameter name with natural byte ordering.
|
||||
// -- as queryParameters are a SortedSet, they are already sorted.
|
||||
// 2. URL encode the parameter name and values according to the following rules...
|
||||
// -- all queryParameters are URL encoded on the way in
|
||||
// 3. Separate the encoded parameter names from their encoded values with the equals sign,
|
||||
// even if the parameter value is empty.
|
||||
// -- we do not allow null values.
|
||||
// 4. Separate the name-value pairs with an ampersand.
|
||||
// -- buildQueryString() does this.
|
||||
StringBuilder toSign = new StringBuilder();
|
||||
toSign.append(request.getMethod()).append("\n").append(
|
||||
request.getEndpoint().getHost().toLowerCase()).append("\n").append("/").append("\n");
|
||||
toSign.append(request.getEndpoint().getQuery());
|
||||
String stringToSign = toSign.toString();
|
||||
return stringToSign;
|
||||
}
|
||||
|
||||
private HttpRequest addSigningParamsToRequest(HttpRequest request) {
|
||||
UriBuilder builder = UriBuilder.fromUri(request.getEndpoint());
|
||||
builder.queryParam(SIGNATURE_METHOD, "HmacSHA256");
|
||||
builder.queryParam(SIGNATURE_VERSION, "2");
|
||||
builder.queryParam(VERSION, "2009-04-04");
|
||||
|
||||
// timestamp is incompatible with expires
|
||||
if (request.getEndpoint().getQuery().contains(EXPIRES)) {
|
||||
// TODO tune this if necessary
|
||||
builder.queryParam(TIMESTAMP, dateService.iso8601DateFormat());
|
||||
}
|
||||
builder.queryParam(AWS_ACCESS_KEY_ID, accessKey);
|
||||
return new HttpRequest(request.getMethod(), builder.build(), request.getHeaders(), request
|
||||
.getEntity());
|
||||
}
|
||||
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.commands.options;
|
||||
|
||||
import org.jclouds.aws.ec2.reference.EC2Constants;
|
||||
import org.jclouds.http.options.HttpRequestOptions;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
*
|
||||
* defines the interface needed to properly sign EC2 QUERY requests.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface EC2RequestOptions extends HttpRequestOptions {
|
||||
|
||||
/**
|
||||
* @see org.jclouds.aws.ec2.reference.CommonEC2Parameters#ACTION
|
||||
*/
|
||||
String getAction();
|
||||
|
||||
/**
|
||||
* @see org.jclouds.aws.ec2.reference.CommonEC2Parameters#AWS_ACCESS_KEY_ID
|
||||
* @see org.jclouds.aws.ec2.reference.CommonEC2Parameters#SIGNATURE
|
||||
*/
|
||||
EC2RequestOptions signWith(@Named(EC2Constants.PROPERTY_AWS_ACCESSKEYID) String accessKey,
|
||||
@Named(EC2Constants.PROPERTY_AWS_SECRETACCESSKEY) String secretKey);
|
||||
|
||||
/**
|
||||
* @see org.jclouds.aws.ec2.reference.CommonEC2Parameters#EXPIRES
|
||||
*/
|
||||
EC2RequestOptions expireAt(DateTime time);
|
||||
|
||||
/**
|
||||
* @see org.jclouds.aws.ec2.reference.CommonEC2Parameters#TIMESTAMP
|
||||
*/
|
||||
EC2RequestOptions timeStamp();
|
||||
|
||||
/**
|
||||
* @see org.jclouds.http.HttpHeaders#HOST
|
||||
*/
|
||||
EC2RequestOptions usingHost(String hostname);
|
||||
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.commands.options;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import org.jclouds.util.DateService;
|
||||
import org.joda.time.DateTime;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests possible uses of BaseEC2RequestOptions and BaseEC2RequestOptions.Builder.*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ec2.BaseEC2RequestOptionsTest")
|
||||
public class BaseEC2RequestOptionsTest {
|
||||
|
||||
@Test
|
||||
public void testGetAction() {
|
||||
EC2RequestOptions options = new MyRequestOptions();
|
||||
assertEquals(options.getAction(), "MyRequest");
|
||||
}
|
||||
|
||||
public static class MyRequestOptions extends BaseEC2RequestOptions<MyRequestOptions> {
|
||||
static {
|
||||
realClass = MyRequestOptions.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAction() {
|
||||
return "MyRequest";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see MyRequestOptions#withId(String)
|
||||
*/
|
||||
public String getId() {
|
||||
return queryParameters.get("id");
|
||||
}
|
||||
|
||||
/**
|
||||
* add the 'id' parameter to the query string
|
||||
*/
|
||||
public MyRequestOptions withId(String id) {
|
||||
encodeAndReplaceParameter("id", id);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class Builder extends BaseEC2RequestOptions.Builder {
|
||||
/**
|
||||
* @see MyRequestOptions#withId(String)
|
||||
*/
|
||||
public static MyRequestOptions withId(String id) {
|
||||
MyRequestOptions options = new MyRequestOptions();
|
||||
return options.withId(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpireAt() throws UnsupportedEncodingException {
|
||||
DateTime date = new DateTime();
|
||||
BaseEC2RequestOptions<EC2RequestOptions> options = MyRequestOptions.Builder.expireAt(date);
|
||||
String dateString = URLEncoder.encode(new DateService().iso8601DateFormat(date), "UTF-8");
|
||||
makeReady(options);
|
||||
assert options.buildQueryString().contains("Expires=" + dateString) : String.format(
|
||||
"%1s$ should have contained %2s$", options.buildQueryString(), dateString);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalStateException.class)
|
||||
public void testBuildQueryWithNotEnoughArguments() {
|
||||
EC2RequestOptions options = new MyRequestOptions();
|
||||
options.buildQueryString();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildQueryWithEnoughArguments() {
|
||||
EC2RequestOptions options = new MyRequestOptions();
|
||||
makeReady(options);
|
||||
options.buildQueryString();
|
||||
}
|
||||
|
||||
private void makeReady(EC2RequestOptions options) {
|
||||
options.signWith("meow", "bark");
|
||||
options.usingHost("localhost");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpireAtStatic() throws UnsupportedEncodingException {
|
||||
DateTime date = new DateTime();
|
||||
BaseEC2RequestOptions<EC2RequestOptions> options = MyRequestOptions.Builder.expireAt(date);
|
||||
String dateString = URLEncoder.encode(new DateService().iso8601DateFormat(date), "UTF-8");
|
||||
makeReady(options);
|
||||
assert options.buildQueryString().contains("Expires=" + dateString) : String.format(
|
||||
"%1s$ should have contained %2s$", options.buildQueryString(), dateString);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.commands.options;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.ACTION;
|
||||
import static org.jclouds.aws.ec2.reference.CommonEC2Parameters.EXPIRES;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
import org.jclouds.aws.reference.AWSConstants;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import org.jclouds.util.Jsr330;
|
||||
|
||||
@Test(groups = "unit", testName = "s3.EC2QuerySignerTest")
|
||||
public class EC2QuerySignerTest {
|
||||
|
||||
@Test
|
||||
void testExpires() {
|
||||
UriBuilder builder = UriBuilder.fromUri(URI.create("https://ec2.amazonaws.com/"));
|
||||
builder.queryParam(ACTION,"DescribeImages");
|
||||
builder.queryParam(EXPIRES,"2008-02-10T12%3A00%3A00Z");
|
||||
builder.queryParam("ImageId.1","ami-2bb65342");
|
||||
HttpRequest request = new HttpRequest(HttpMethod.GET,builder.build());
|
||||
createFilter();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAclQueryString() {
|
||||
URI host = URI.create("http://s3.amazonaws.com:80/?acl");
|
||||
HttpRequest request = new HttpRequest(HttpMethod.GET, host);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
createFilter().appendUriPath(request, builder);
|
||||
assertEquals(builder.toString(), "/?acl");
|
||||
}
|
||||
|
||||
// "?acl", "?location", "?logging", or "?torrent"
|
||||
|
||||
@Test
|
||||
void testAppendBucketNameHostHeaderService() {
|
||||
URI host = URI.create("http://s3.amazonaws.com:80");
|
||||
HttpRequest request = new HttpRequest(HttpMethod.GET, host);
|
||||
request.getHeaders().put(HttpHeaders.HOST, "s3.amazonaws.com");
|
||||
StringBuilder builder = new StringBuilder();
|
||||
createFilter().appendBucketName(request, builder);
|
||||
assertEquals(builder.toString(), "");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAppendBucketNameURIHost() {
|
||||
URI host = URI.create("http://adriancole.s3int5.s3-external-3.amazonaws.com:80");
|
||||
HttpRequest request = new HttpRequest(HttpMethod.GET, host);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
createFilter().appendBucketName(request, builder);
|
||||
assertEquals(builder.toString(), "/adriancole.s3int5");
|
||||
}
|
||||
|
||||
|
||||
|
||||
private EC2QuerySigner createFilter() {
|
||||
return Guice.createInjector(new AbstractModule() {
|
||||
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(Jsr330.named(AWSConstants.PROPERTY_AWS_ACCESSKEYID)).to(
|
||||
"foo");
|
||||
bindConstant().annotatedWith(Jsr330.named(AWSConstants.PROPERTY_AWS_SECRETACCESSKEY)).to(
|
||||
"bar");
|
||||
bind(DateService.class);
|
||||
|
||||
}
|
||||
}).getInstance(EC2QuerySigner.class);
|
||||
}
|
||||
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
$HeadURL$
|
||||
$Revision$
|
||||
$Date$
|
||||
|
||||
Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
|
||||
====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
d istributed 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.html
|
||||
|
||||
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.
|
||||
====================================================================
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>jclouds-aws-project</artifactId>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jclouds-ec2-project</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>jclouds ec2 aggregator</name>
|
||||
<modules>
|
||||
<module>core</module>
|
||||
</modules>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-aws-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-aws-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
Loading…
x
Reference in New Issue
Block a user