diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/binders/IfNotNullBindAvailabilityZoneToFormParam.java b/aws/core/src/main/java/org/jclouds/aws/ec2/binders/IfNotNullBindAvailabilityZoneToFormParam.java new file mode 100644 index 0000000000..ef280071fa --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/binders/IfNotNullBindAvailabilityZoneToFormParam.java @@ -0,0 +1,53 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ +package org.jclouds.aws.ec2.binders; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import org.jclouds.aws.ec2.domain.AvailabilityZone; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; +import org.jclouds.rest.internal.GeneratedHttpRequest; + +/** + * Binds the AvailabilityZone to a form parameter if set. + * + * @author Adrian Cole + */ +public class IfNotNullBindAvailabilityZoneToFormParam implements Binder { + + @SuppressWarnings("unchecked") + public void bindToRequest(HttpRequest request, Object input) { + if (input != null) { + checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest, + "this binder is only valid for GeneratedHttpRequests!"); + checkArgument(input instanceof AvailabilityZone, + "this binder is only valid for AvailabilityZone!"); + ((GeneratedHttpRequest) request).addFormParam("Placement.AvailabilityZone", + ((AvailabilityZone) input).value()); + } + } + +} \ No newline at end of file diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2ComputeService.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2ComputeService.java index 9f85fe1e0e..f3f5563221 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2ComputeService.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2ComputeService.java @@ -41,6 +41,7 @@ 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.Region; import org.jclouds.aws.ec2.domain.Reservation; import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.compute.ComputeService; @@ -111,7 +112,9 @@ public class EC2ComputeService implements ComputeService { keyPair.getKeyName(), securityGroupName); RunningInstance runningInstance = Iterables - .getLast(ec2Client.getInstanceServices().runInstances( + .getLast(ec2Client.getInstanceServices().runInstancesInRegion( + Region.DEFAULT, + null, ami, 1, 1, @@ -139,12 +142,13 @@ public class EC2ComputeService implements ComputeService { logger.debug(">> creating keyPair name(%s)", name); KeyPair keyPair; try { - keyPair = ec2Client.getKeyPairServices().createKeyPair(name); + keyPair = ec2Client.getKeyPairServices().createKeyPairInRegion(Region.DEFAULT, name); logger.debug("<< created keyPair(%s)", keyPair.getKeyName()); } catch (AWSResponseException e) { if (e.getError().getCode().equals("InvalidKeyPair.Duplicate")) { - keyPair = ec2Client.getKeyPairServices().describeKeyPairs(name).last(); + keyPair = Iterables.getLast(ec2Client.getKeyPairServices().describeKeyPairsInRegion( + Region.DEFAULT, name)); logger.debug("<< reused keyPair(%s)", keyPair.getKeyName()); } else { @@ -158,13 +162,14 @@ public class EC2ComputeService implements ComputeService { logger.debug(">> creating securityGroup name(%s)", name); try { - ec2Client.getSecurityGroupServices().createSecurityGroup(name, name); + ec2Client.getSecurityGroupServices().createSecurityGroupInRegion(Region.DEFAULT, name, + name); logger.debug("<< created securityGroup(%s)", name); logger.debug(">> authorizing securityGroup name(%s) ports(%s)", name, ImmutableSet .of(ports)); for (int port : ports) { - ec2Client.getSecurityGroupServices().authorizeSecurityGroupIngress(name, - IpProtocol.TCP, port, port, "0.0.0.0/0"); + ec2Client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion( + Region.DEFAULT, name, IpProtocol.TCP, port, port, "0.0.0.0/0"); } logger.debug("<< authorized securityGroup(%s)", name); } catch (AWSResponseException e) { @@ -205,7 +210,8 @@ public class EC2ComputeService implements ComputeService { private RunningInstance getRunningInstance(String id) { RunningInstance runningInstance = Iterables.getLast(Iterables.getLast( - ec2Client.getInstanceServices().describeInstances(id)).getRunningInstances()); + ec2Client.getInstanceServices().describeInstancesInRegion(Region.DEFAULT, id)) + .getRunningInstances()); return runningInstance; } @@ -227,7 +233,8 @@ public class EC2ComputeService implements ComputeService { public SortedSet listServers() { logger.debug(">> listing servers"); SortedSet servers = Sets.newTreeSet(); - for (Reservation reservation : ec2Client.getInstanceServices().describeInstances()) { + for (Reservation reservation : ec2Client.getInstanceServices().describeInstancesInRegion( + Region.DEFAULT)) { Iterables.addAll(servers, Iterables.transform(reservation.getRunningInstances(), new Function() { @Override @@ -246,13 +253,13 @@ public class EC2ComputeService implements ComputeService { // grab the old keyname String name = runningInstance.getKeyName(); logger.debug(">> terminating instance(%s)", runningInstance.getInstanceId()); - ec2Client.getInstanceServices().terminateInstances(id); + ec2Client.getInstanceServices().terminateInstancesInRegion(Region.DEFAULT, id); logger.debug("<< terminated instance(%s)", runningInstance.getInstanceId()); logger.debug(">> deleting keyPair(%s)", name); - ec2Client.getKeyPairServices().deleteKeyPair(name); + ec2Client.getKeyPairServices().deleteKeyPairInRegion(Region.DEFAULT, name); logger.debug("<< deleted keyPair(%s)", name); logger.debug(">> deleting securityGroup(%s)", name); - ec2Client.getSecurityGroupServices().deleteSecurityGroup(name); + ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(Region.DEFAULT, name); logger.debug("<< deleted securityGroup(%s)", name); } } \ No newline at end of file diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/options/RunInstancesOptions.java b/aws/core/src/main/java/org/jclouds/aws/ec2/options/RunInstancesOptions.java index 19872c55ba..3452ac6407 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/options/RunInstancesOptions.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/options/RunInstancesOptions.java @@ -109,19 +109,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions { 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. */ @@ -240,14 +227,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions { 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) */ diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/predicates/InstanceStateRunning.java b/aws/core/src/main/java/org/jclouds/aws/ec2/predicates/InstanceStateRunning.java index 317052e769..ee42796fe2 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/predicates/InstanceStateRunning.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/predicates/InstanceStateRunning.java @@ -4,6 +4,7 @@ import javax.annotation.Resource; import javax.inject.Singleton; import org.jclouds.aws.ec2.domain.InstanceState; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.aws.ec2.services.InstanceClient; import org.jclouds.logging.Logger; @@ -41,7 +42,8 @@ public class InstanceStateRunning implements Predicate { } private RunningInstance refresh(String instanceId) { - return Iterables.getLast(Iterables.getLast(client.describeInstances(instanceId)) + return Iterables.getLast(Iterables.getLast(client.describeInstancesInRegion( + Region.DEFAULT,instanceId)) .getRunningInstances()); } } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIAsyncClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIAsyncClient.java index 636db94499..1a04d5e4c0 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIAsyncClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIAsyncClient.java @@ -40,8 +40,10 @@ import org.jclouds.aws.ec2.binders.BindUserGroupsToIndexedFormParams; import org.jclouds.aws.ec2.binders.BindUserIdsToIndexedFormParams; import org.jclouds.aws.ec2.domain.Image; import org.jclouds.aws.ec2.domain.LaunchPermission; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.domain.Image.EbsBlockDevice; import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.functions.RegionToEndpoint; import org.jclouds.aws.ec2.options.CreateImageOptions; import org.jclouds.aws.ec2.options.DescribeImagesOptions; import org.jclouds.aws.ec2.options.RegisterImageBackedByEbsOptions; @@ -53,6 +55,7 @@ import org.jclouds.aws.ec2.xml.LaunchPermissionHandler; import org.jclouds.aws.ec2.xml.ProductCodesHandler; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.FormParams; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.VirtualHost; @@ -71,135 +74,156 @@ import org.jclouds.rest.annotations.XMLResponseParser; public interface AMIAsyncClient { /** - * @see AMIClient#describeImages + * @see AMIClient#describeImagesInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "DescribeImages") @XMLResponseParser(DescribeImagesResponseHandler.class) - Future> describeImages(DescribeImagesOptions... options); + Future> describeImagesInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + DescribeImagesOptions... options); /** - * @see AMIClient#createImage + * @see AMIClient#createImageInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "CreateImage") @XMLResponseParser(ImageIdHandler.class) - Future createImage(@FormParam("Name") String name, - @FormParam("InstanceId") String instanceId, CreateImageOptions... options); + Future createImageInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + @FormParam("Name") String name, @FormParam("InstanceId") String instanceId, + CreateImageOptions... options); /** - * @see AMIClient#deregisterImage + * @see AMIClient#deregisterImageInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "DeregisterImage") - Future deregisterImage(@FormParam("ImageId") String imageId); + Future deregisterImageInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + @FormParam("ImageId") String imageId); /** - * @see AMIClient#registerImageFromManifest + * @see AMIClient#registerImageFromManifestInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "RegisterImage") @XMLResponseParser(ImageIdHandler.class) - Future registerImageFromManifest(@FormParam("Name") String imageName, - @FormParam("ImageLocation") String pathToManifest, RegisterImageOptions... options); + Future registerImageFromManifestInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + @FormParam("Name") String imageName, @FormParam("ImageLocation") String pathToManifest, + RegisterImageOptions... options); /** - * @see AMIClient#registerImageBackedByEbs + * @see AMIClient#registerImageBackedByEbsInRegion */ @POST @Path("/") @FormParams(keys = { ACTION, "RootDeviceName", "BlockDeviceMapping.0.DeviceName" }, values = { "RegisterImage", "/dev/sda1", "/dev/sda1" }) @XMLResponseParser(ImageIdHandler.class) - Future registerImageBackedByEbs(@FormParam("Name") String imageName, + Future registerImageBackedByEbsInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + @FormParam("Name") String imageName, @FormParam("BlockDeviceMapping.0.Ebs.SnapshotId") String ebsSnapshotId, RegisterImageBackedByEbsOptions... options); /** - * @see AMIClient#resetLaunchPermissionsOnImage + * @see AMIClient#resetLaunchPermissionsOnImageInRegion */ @POST @Path("/") @FormParams(keys = { ACTION, "Attribute" }, values = { "ResetImageAttribute", "launchPermission" }) - Future resetLaunchPermissionsOnImage(@FormParam("ImageId") String imageId); + Future resetLaunchPermissionsOnImageInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + @FormParam("ImageId") String imageId); /** - * @see AMIClient#addLaunchPermissionsToImage + * @see AMIClient#addLaunchPermissionsToImageInRegion */ @POST @Path("/") @FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = { "ModifyImageAttribute", "add", "launchPermission" }) - Future addLaunchPermissionsToImage( + Future addLaunchPermissionsToImageInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @BinderParam(BindUserIdsToIndexedFormParams.class) Iterable userIds, @BinderParam(BindUserGroupsToIndexedFormParams.class) Iterable userGroups, @FormParam("ImageId") String imageId); /** - * @see AMIClient#removeLaunchPermissionsToImage + * @see AMIClient#removeLaunchPermissionsToImageInRegion */ @POST @Path("/") @FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = { "ModifyImageAttribute", "remove", "launchPermission" }) - Future removeLaunchPermissionsFromImage( + Future removeLaunchPermissionsFromImageInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @BinderParam(BindUserIdsToIndexedFormParams.class) Iterable userIds, @BinderParam(BindUserGroupsToIndexedFormParams.class) Iterable userGroups, @FormParam("ImageId") String imageId); /** - * @see AMIClient#getLaunchPermissionForImage + * @see AMIClient#getLaunchPermissionForImageInRegion */ @POST @Path("/") @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeImageAttribute", "launchPermission" }) @XMLResponseParser(LaunchPermissionHandler.class) - Future getLaunchPermissionForImage(@FormParam("ImageId") String imageId); + Future getLaunchPermissionForImageInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + @FormParam("ImageId") String imageId); /** - * @see AMIClient#getProductCodesForImage + * @see AMIClient#getProductCodesForImageInRegion */ @POST @Path("/") @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeImageAttribute", "productCodes" }) @XMLResponseParser(ProductCodesHandler.class) - Future> getProductCodesForImage(@FormParam("ImageId") String imageId); + Future> getProductCodesForImageInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + @FormParam("ImageId") String imageId); /** - * @see AMIClient#getBlockDeviceMappingsForImage + * @see AMIClient#getBlockDeviceMappingsForImageInRegion */ @POST @Path("/") @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeImageAttribute", "blockDeviceMapping" }) @XMLResponseParser(BlockDeviceMappingHandler.class) - Future> getBlockDeviceMappingsForImage( + Future> getBlockDeviceMappingsForImageInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @FormParam("ImageId") String imageId); /** - * @see AMIClient#addProductCodesToImage + * @see AMIClient#addProductCodesToImageInRegion */ @POST @Path("/") @FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = { "ModifyImageAttribute", "add", "productCodes" }) - Future addProductCodesToImage( + Future addProductCodesToImageInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @BinderParam(BindProductCodesToIndexedFormParams.class) Iterable productCodes, @FormParam("ImageId") String imageId); /** - * @see AMIClient#removeProductCodesToImage + * @see AMIClient#removeProductCodesToImageInRegion */ @POST @Path("/") @FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = { "ModifyImageAttribute", "remove", "productCodes" }) - Future removeProductCodesFromImage( + Future removeProductCodesFromImageInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @BinderParam(BindProductCodesToIndexedFormParams.class) Iterable productCodes, @FormParam("ImageId") String imageId); } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIClient.java index 12dc71aa7b..8002b899f6 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIClient.java @@ -29,6 +29,7 @@ import java.util.concurrent.TimeUnit; import org.jclouds.aws.ec2.domain.Image; import org.jclouds.aws.ec2.domain.LaunchPermission; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.domain.Image.EbsBlockDevice; import org.jclouds.aws.ec2.options.CreateImageOptions; import org.jclouds.aws.ec2.options.DescribeImagesOptions; @@ -51,6 +52,8 @@ public interface AMIClient { * private images that you own, and private images owned by other users for which you have * explicit launch permissions. * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. * @see InstanceClient#describeInstances * @see #describeImageAttribute * @see describeImages(DescribeImagesOptions... options); + Set describeImagesInRegion(Region region, DescribeImagesOptions... options); /** * Returns the {@link LaunchPermission}s of an image. * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. * @param imageId * The ID of the AMI for which an attribute will be described * @see #describeImages @@ -72,11 +77,13 @@ public interface AMIClient { * /> * @see DescribeImagesOptions */ - LaunchPermission getLaunchPermissionForImage(String imageId); + LaunchPermission getLaunchPermissionForImageInRegion(Region region, String imageId); /** * Returns the Product Codes of an image. * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. * @param imageId * The ID of the AMI for which an attribute will be described * @see #describeImages @@ -86,11 +93,13 @@ public interface AMIClient { * /> * @see DescribeImagesOptions */ - Set getProductCodesForImage(String imageId); + Set getProductCodesForImageInRegion(Region region, String imageId); /** * Returns a map of device name to block device for the image. * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. * @param imageId * The ID of the AMI for which an attribute will be described * @see #describeImages @@ -100,11 +109,13 @@ public interface AMIClient { * /> * @see DescribeImagesOptions */ - Map getBlockDeviceMappingsForImage(String imageId); + Map getBlockDeviceMappingsForImageInRegion(Region region, String imageId); /** * Creates an AMI that uses an Amazon EBS root device from a "running" or "stopped" instance. * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. * @param name * The name of the AMI that was provided during image creation. 3-128 alphanumeric * characters, parenthesis (()), commas (,), slashes (/), dashes (-), or underscores(_) @@ -122,13 +133,16 @@ public interface AMIClient { * "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateImage.html" * /> */ - String createImage(String name, String instanceId, CreateImageOptions... options); + String createImageInRegion(Region region, String name, String instanceId, + CreateImageOptions... options); /** * * Deregisters the specified AMI. Once deregistered, the AMI cannot be used to launch new * instances. * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. * @param imageId * Unique ID of the AMI which was assigned during registration. To register an AMI, use * RegisterImage. To view the AMI IDs of AMIs that belong to your account. use @@ -139,7 +153,7 @@ public interface AMIClient { * @see */ - void deregisterImage(String imageId); + void deregisterImageInRegion(Region region, String imageId); /** * Registers an AMI with Amazon EC2. Images must be registered before they can be launched. To @@ -151,6 +165,8 @@ public interface AMIClient { *

Note

Any modifications to an AMI backed by Amazon S3 invalidates this registration. * If you make changes to an image, deregister the previous image and register the new image. * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. * @param name * The name of the AMI that was provided during image creation. 3-128 alphanumeric * characters, parenthesis (()), commas (,), slashes (/), dashes (-), or underscores(_) @@ -167,7 +183,7 @@ public interface AMIClient { * "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RegisterImage.html" * /> */ - String registerImageFromManifest(String name, String pathToManifest, + String registerImageFromManifestInRegion(Region region, String name, String pathToManifest, RegisterImageOptions... options); /** @@ -183,6 +199,8 @@ public interface AMIClient { *

* Amazon EBS snapshots are not guaranteed to be bootable. * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. * @param name * The name of the AMI that was provided during image creation. 3-128 alphanumeric * characters, parenthesis (()), commas (,), slashes (/), dashes (-), or underscores(_) @@ -200,12 +218,14 @@ public interface AMIClient { * "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RegisterImage.html" * /> */ - String registerImageBackedByEbs(String name, String ebsSnapshotId, + String registerImageBackedByEbsInRegion(Region region, String name, String ebsSnapshotId, RegisterImageBackedByEbsOptions... options); /** * Adds {@code launchPermission}s to an AMI. * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. * @param userIds * AWS Access Key ID. * @param userGroups @@ -219,12 +239,14 @@ public interface AMIClient { * @see */ - void addLaunchPermissionsToImage(Iterable userIds, Iterable userGroups, - String imageId); + void addLaunchPermissionsToImageInRegion(Region region, Iterable userIds, + Iterable userGroups, String imageId); /** * Resets the {@code launchPermission}s on an AMI. * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. * @param imageId * ID of the AMI on which the attribute will be reset. * @@ -234,11 +256,13 @@ public interface AMIClient { * @see */ - void resetLaunchPermissionsOnImage(String imageId); + void resetLaunchPermissionsOnImageInRegion(Region region, String imageId); /** * Removes {@code launchPermission}s from an AMI. * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. * @param userIds * AWS Access Key ID. * @param userGroups @@ -252,12 +276,14 @@ public interface AMIClient { * @see */ - void removeLaunchPermissionsFromImage(Iterable userIds, Iterable userGroups, - String imageId); + void removeLaunchPermissionsFromImageInRegion(Region region, Iterable userIds, + Iterable userGroups, String imageId); /** * Adds {@code productCode}s to an AMI. * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. * @param productCodes * Product Codes * @param imageId @@ -269,11 +295,13 @@ public interface AMIClient { * @see */ - void addProductCodesToImage(Iterable productCodes, String imageId); + void addProductCodesToImageInRegion(Region region, Iterable productCodes, String imageId); /** * Removes {@code productCode}s from an AMI. * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. * @param productCodes * Product Codes * @param imageId @@ -285,5 +313,6 @@ public interface AMIClient { * @see */ - void removeProductCodesFromImage(Iterable productCodes, String imageId); + void removeProductCodesFromImageInRegion(Region region, Iterable productCodes, + String imageId); } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/ElasticIPAddressAsyncClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/ElasticIPAddressAsyncClient.java index 2f1c20befa..fa48a10635 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/services/ElasticIPAddressAsyncClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/ElasticIPAddressAsyncClient.java @@ -27,7 +27,7 @@ import static org.jclouds.aws.ec2.reference.EC2Parameters.ACTION; import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION; import java.net.InetAddress; -import java.util.SortedSet; +import java.util.Set; import java.util.concurrent.Future; import javax.ws.rs.FormParam; @@ -37,11 +37,14 @@ import javax.ws.rs.Path; import org.jclouds.aws.ec2.EC2; import org.jclouds.aws.ec2.binders.BindInetAddressesToIndexedFormParams; import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.functions.RegionToEndpoint; import org.jclouds.aws.ec2.xml.AllocateAddressResponseHandler; import org.jclouds.aws.ec2.xml.DescribeAddressesResponseHandler; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.FormParams; import org.jclouds.rest.annotations.ParamParser; import org.jclouds.rest.annotations.RequestFilters; @@ -62,50 +65,55 @@ import org.jclouds.rest.functions.InetAddressToHostAddress; public interface ElasticIPAddressAsyncClient { /** - * @see BaseEC2Client#allocateAddress + * @see BaseEC2Client#allocateAddressInRegion */ @POST @Path("/") @XMLResponseParser(AllocateAddressResponseHandler.class) @FormParams(keys = ACTION, values = "AllocateAddress") - Future allocateAddress(); + Future allocateAddressInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region); /** - * @see BaseEC2Client#associateAddress + * @see BaseEC2Client#associateAddressInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "AssociateAddress") - Future associateAddress( + Future associateAddressInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp, @FormParam("InstanceId") String instanceId); /** - * @see BaseEC2Client#disassociateAddress + * @see BaseEC2Client#disassociateAddressInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "DisassociateAddress") - Future disassociateAddress( + Future disassociateAddressInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp); /** - * @see BaseEC2Client#releaseAddress + * @see BaseEC2Client#releaseAddressInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "ReleaseAddress") - Future releaseAddress( + Future releaseAddressInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp); /** - * @see BaseEC2Client#describeAddresses + * @see BaseEC2Client#describeAddressesInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "DescribeAddresses") @XMLResponseParser(DescribeAddressesResponseHandler.class) - Future> describeAddresses( + Future> describeAddressesInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @BinderParam(BindInetAddressesToIndexedFormParams.class) InetAddress... publicIps); } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/ElasticIPAddressClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/ElasticIPAddressClient.java index 94f4afac7f..61f797c61b 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/services/ElasticIPAddressClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/ElasticIPAddressClient.java @@ -24,11 +24,12 @@ package org.jclouds.aws.ec2.services; import java.net.InetAddress; -import java.util.SortedSet; +import java.util.Set; import java.util.concurrent.TimeUnit; import org.jclouds.aws.AWSResponseException; import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.concurrent.Timeout; /** @@ -43,19 +44,23 @@ public interface ElasticIPAddressClient { /** * Acquires an elastic IP address for use with your account. * + * @param region + * Elastic IP addresses are tied to a Region and cannot be mapped across Regions. * @see #describeAddresses * @see #releaseAddress * @see #associateAddress * @see #disassociateAddress * @see */ - SortedSet describeAddresses(InetAddress... publicIps); + Set describeAddressesInRegion(Region region, + InetAddress... publicIps); } \ No newline at end of file diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceAsyncClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceAsyncClient.java index 2d62719a41..b94513cbe1 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceAsyncClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceAsyncClient.java @@ -29,21 +29,27 @@ import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION; import java.util.SortedSet; import java.util.concurrent.Future; +import javax.annotation.Nullable; import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import org.jclouds.aws.ec2.EC2; import org.jclouds.aws.ec2.binders.BindInstanceIdsToIndexedFormParams; +import org.jclouds.aws.ec2.binders.IfNotNullBindAvailabilityZoneToFormParam; +import org.jclouds.aws.ec2.domain.AvailabilityZone; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.domain.Reservation; import org.jclouds.aws.ec2.domain.TerminatedInstance; import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.functions.RegionToEndpoint; import org.jclouds.aws.ec2.options.RunInstancesOptions; import org.jclouds.aws.ec2.xml.DescribeInstancesResponseHandler; import org.jclouds.aws.ec2.xml.RunInstancesResponseHandler; import org.jclouds.aws.ec2.xml.TerminateInstancesResponseHandler; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.FormParams; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.VirtualHost; @@ -62,34 +68,38 @@ import org.jclouds.rest.annotations.XMLResponseParser; public interface InstanceAsyncClient { /** - * @see BaseEC2Client#describeInstances + * @see BaseEC2Client#describeInstancesInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "DescribeInstances") @XMLResponseParser(DescribeInstancesResponseHandler.class) - Future> describeInstances( + Future> describeInstancesInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds); /** - * @see BaseEC2Client#runInstances + * @see BaseEC2Client#runInstancesInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "RunInstances") @XMLResponseParser(RunInstancesResponseHandler.class) - Future runInstances(@FormParam("ImageId") String imageId, - @FormParam("MinCount") int minCount, @FormParam("MaxCount") int maxCount, - RunInstancesOptions... options); + Future runInstancesInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + @Nullable @BinderParam(IfNotNullBindAvailabilityZoneToFormParam.class) AvailabilityZone nullableAvailabilityZone, + @FormParam("ImageId") String imageId, @FormParam("MinCount") int minCount, + @FormParam("MaxCount") int maxCount, RunInstancesOptions... options); /** - * @see BaseEC2Client#terminateInstances + * @see BaseEC2Client#terminateInstancesInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "TerminateInstances") @XMLResponseParser(TerminateInstancesResponseHandler.class) - Future> terminateInstances( + Future> terminateInstancesInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @FormParam("InstanceId.0") String instanceId, @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds); diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceClient.java index 5d412718d5..5b27669238 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceClient.java @@ -26,6 +26,10 @@ package org.jclouds.aws.ec2.services; import java.util.SortedSet; import java.util.concurrent.TimeUnit; +import javax.annotation.Nullable; + +import org.jclouds.aws.ec2.domain.AvailabilityZone; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.domain.Reservation; import org.jclouds.aws.ec2.domain.TerminatedInstance; import org.jclouds.aws.ec2.options.RunInstancesOptions; @@ -52,12 +56,16 @@ public interface InstanceClient { * Recently terminated instances might appear in the returned results.This interval is usually * less than one hour. * + * @param region + * Instances are tied to Availability Zones. However, the instance ID is tied to the + * Region. + * * @see #runInstances * @see #terminateInstances * @see */ - SortedSet describeInstances(String... instanceIds); + SortedSet describeInstancesInRegion(Region region, String... instanceIds); /** * Launches a specified number of instances of an AMI for which you have permissions. @@ -100,6 +108,13 @@ public interface InstanceClient { * provide greater stability and performance for these instance types. For more information about * kernels, go the Amazon Elastic Compute Cloud Developer Guide. * + * @param region + * Instances are tied to Availability Zones. However, the instance ID is tied to the + * Region. + * @param nullableAvailabilityZone + * Specifies the placement constraints (Availability Zones) for launching the + * instances. If null, Amazon will determine the best availability zone to place the + * instance. * @param imageId * Unique ID of a machine image, returned by a call to * @param minCount @@ -123,8 +138,9 @@ public interface InstanceClient { * /> * @see RunInstancesOptions */ - Reservation runInstances(String imageId, int minCount, int maxCount, - RunInstancesOptions... options); + Reservation runInstancesInRegion(Region region, + @Nullable AvailabilityZone nullableAvailabilityZone, String imageId, int minCount, + int maxCount, RunInstancesOptions... options); /** * Shuts down one or more instances. This operation is idempotent; if you terminate an instance @@ -132,12 +148,17 @@ public interface InstanceClient { *

* Terminated instances will remain visible after termination (approximately one hour). * + * @param region + * Instances are tied to Availability Zones. However, the instance ID is tied to the + * Region. + * * @param instanceIds * Instance ID to terminate. * @see #describeInstances * @see */ - SortedSet terminateInstances(String instanceId, String... instanceIds); + SortedSet terminateInstancesInRegion(Region region, String instanceId, + String... instanceIds); } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/KeyPairAsyncClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/KeyPairAsyncClient.java index 5aec53ac40..6d85fbd584 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/services/KeyPairAsyncClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/KeyPairAsyncClient.java @@ -26,7 +26,7 @@ package org.jclouds.aws.ec2.services; import static org.jclouds.aws.ec2.reference.EC2Parameters.ACTION; import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION; -import java.util.SortedSet; +import java.util.Set; import java.util.concurrent.Future; import javax.ws.rs.FormParam; @@ -36,11 +36,14 @@ import javax.ws.rs.Path; import org.jclouds.aws.ec2.EC2; import org.jclouds.aws.ec2.binders.BindKeyNameToIndexedFormParams; import org.jclouds.aws.ec2.domain.KeyPair; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.functions.RegionToEndpoint; import org.jclouds.aws.ec2.xml.DescribeKeyPairsResponseHandler; import org.jclouds.aws.ec2.xml.KeyPairResponseHandler; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.FormParams; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.VirtualHost; @@ -59,30 +62,35 @@ import org.jclouds.rest.annotations.XMLResponseParser; public interface KeyPairAsyncClient { /** - * @see BaseEC2Client#createKeyPair + * @see BaseEC2Client#createKeyPairInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "CreateKeyPair") @XMLResponseParser(KeyPairResponseHandler.class) - Future createKeyPair(@FormParam("KeyName") String keyName); + Future createKeyPairInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + @FormParam("KeyName") String keyName); /** - * @see BaseEC2Client#describeKeyPairs + * @see BaseEC2Client#describeKeyPairsInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "DescribeKeyPairs") @XMLResponseParser(DescribeKeyPairsResponseHandler.class) - Future> describeKeyPairs( + Future> describeKeyPairsInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @BinderParam(BindKeyNameToIndexedFormParams.class) String... keyPairNames); /** - * @see BaseEC2Client#deleteKeyPair + * @see BaseEC2Client#deleteKeyPairInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "DeleteKeyPair") - Future deleteKeyPair(@FormParam("KeyName") String keyName); + Future deleteKeyPairInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + @FormParam("KeyName") String keyName); } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/KeyPairClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/KeyPairClient.java index e30f60ca6d..0052eee6f1 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/services/KeyPairClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/KeyPairClient.java @@ -23,10 +23,11 @@ */ package org.jclouds.aws.ec2.services; -import java.util.SortedSet; +import java.util.Set; import java.util.concurrent.TimeUnit; import org.jclouds.aws.ec2.domain.KeyPair; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.concurrent.Timeout; /** @@ -44,6 +45,11 @@ public interface KeyPairClient { * unencrypted PEM encoded PKCS#8 private key. If a key with the specified name already exists, * Amazon EC2 returns an error. * + * @param region + * Key pairs (to connect to instances) are Region-specific. + * @param keyName + * A unique name for the key pair. + * * @see #runInstances * @see #describeKeyPairs * @see #deleteKeyPair @@ -52,26 +58,34 @@ public interface KeyPairClient { * "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateKeyPair.html" * /> */ - KeyPair createKeyPair(String keyName); + KeyPair createKeyPairInRegion(Region region, 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 region + * Key pairs (to connect to instances) are Region-specific. * @param keyPairNames * Key pairs to describe. + * * @see #runInstances * @see #describeAvailabilityZones * @see */ - SortedSet describeKeyPairs(String... keyPairNames); + Set describeKeyPairsInRegion(Region region, String... keyPairNames); /** * Deletes the specified key pair, by removing the public key from Amazon EC2. You must own the * key pair * + * @param region + * Key pairs (to connect to instances) are Region-specific. + * @param keyName + * Name of the key pair to delete + * * @see #describeKeyPairs * @see #createKeyPair * @@ -79,7 +93,6 @@ public interface KeyPairClient { * "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteKeyPair.html" * /> */ - - void deleteKeyPair(String keyName); + void deleteKeyPairInRegion(Region region, String keyName); } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/MonitoringAsyncClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/MonitoringAsyncClient.java index f74fb2cd0c..3078ded69f 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/services/MonitoringAsyncClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/MonitoringAsyncClient.java @@ -36,10 +36,13 @@ import javax.ws.rs.Path; import org.jclouds.aws.ec2.EC2; import org.jclouds.aws.ec2.binders.BindInstanceIdsToIndexedFormParams; import org.jclouds.aws.ec2.domain.MonitoringState; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.functions.RegionToEndpoint; import org.jclouds.aws.ec2.xml.MonitoringStateHandler; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.FormParams; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.VirtualHost; @@ -58,24 +61,26 @@ import org.jclouds.rest.annotations.XMLResponseParser; public interface MonitoringAsyncClient { /** - * @see Monitoring#monitorInstances + * @see Monitoring#monitorInstancesInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "MonitorInstances") @XMLResponseParser(MonitoringStateHandler.class) - Future> monitorInstances( + Future> monitorInstancesInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @FormParam("InstanceId.0") String instanceId, @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds); /** - * @see Monitoring#monitorInstances + * @see Monitoring#monitorInstancesInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "UnmonitorInstances") @XMLResponseParser(MonitoringStateHandler.class) - Future> unmonitorInstances( + Future> unmonitorInstancesInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @FormParam("InstanceId.0") String instanceId, @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds); } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/MonitoringClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/MonitoringClient.java index 9ab52cd78d..b7824fe014 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/services/MonitoringClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/MonitoringClient.java @@ -27,10 +27,12 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import org.jclouds.aws.ec2.domain.MonitoringState; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.concurrent.Timeout; /** - * Provides monitoring services for EC2. For more information, refer to the Amazon CloudWatch Developer Guide. + * Provides monitoring services for EC2. For more information, refer to the Amazon CloudWatch + * Developer Guide. *

* * @author Adrian Cole @@ -39,26 +41,35 @@ import org.jclouds.concurrent.Timeout; public interface MonitoringClient { /** - * Enables monitoring for a running instance. For more information, refer to the Amazon CloudWatch Developer Guide. + * Enables monitoring for a running instance. For more information, refer to the Amazon + * CloudWatch Developer Guide. * + * @param region + * Instances are tied to Availability Zones. However, the instance ID is tied to the + * Region. * @see InstanceClient#runInstances * @see #unmonitorInstances * - * @see */ - Map monitorInstances(String instanceId, String... instanceIds); + Map monitorInstancesInRegion(Region region, String instanceId, + String... instanceIds); /** - * Disables monitoring for a running instance. For more information, refer to the Amazon CloudWatch Developer Guide. + * Disables monitoring for a running instance. For more information, refer to the Amazon + * CloudWatch Developer Guide. + * + * @param region + * Instances are tied to Availability Zones. However, the instance ID is tied to the + * Region. * * @see InstanceClient#runInstances * @see #monitorInstances * - * @see */ - Map unmonitorInstances(String instanceId, String... instanceIds); + Map unmonitorInstancesInRegion(Region region, String instanceId, + String... instanceIds); } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/SecurityGroupAsyncClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/SecurityGroupAsyncClient.java index 1c495baea1..0e025f2efd 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/services/SecurityGroupAsyncClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/SecurityGroupAsyncClient.java @@ -37,13 +37,16 @@ import org.jclouds.aws.ec2.EC2; import org.jclouds.aws.ec2.binders.BindGroupNameToIndexedFormParams; import org.jclouds.aws.ec2.binders.BindUserIdGroupPairToSourceSecurityGroupFormParams; import org.jclouds.aws.ec2.domain.IpProtocol; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.domain.SecurityGroup; import org.jclouds.aws.ec2.domain.UserIdGroupPair; import org.jclouds.aws.ec2.filters.FormSigner; +import org.jclouds.aws.ec2.functions.RegionToEndpoint; import org.jclouds.aws.ec2.functions.ReturnVoidOnGroupNotFound; import org.jclouds.aws.ec2.xml.DescribeSecurityGroupsResponseHandler; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.FormParams; import org.jclouds.rest.annotations.RequestFilters; @@ -63,70 +66,82 @@ import org.jclouds.rest.annotations.XMLResponseParser; public interface SecurityGroupAsyncClient { /** - * @see BaseEC2Client#createSecurityGroup + * @see BaseEC2Client#createSecurityGroupInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "CreateSecurityGroup") - Future createSecurityGroup(@FormParam("GroupName") String name, - @FormParam("GroupDescription") String description); + Future createSecurityGroupInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + @FormParam("GroupName") String name, @FormParam("GroupDescription") String description); /** - * @see BaseEC2Client#deleteSecurityGroup + * @see BaseEC2Client#deleteSecurityGroupInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "DeleteSecurityGroup") @ExceptionParser(ReturnVoidOnGroupNotFound.class) - Future deleteSecurityGroup(@FormParam("GroupName") String name); + Future deleteSecurityGroupInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + @FormParam("GroupName") String name); /** - * @see BaseEC2Client#describeSecurityGroups + * @see BaseEC2Client#describeSecurityGroupsInRegion */ @POST @Path("/") @FormParams(keys = ACTION, values = "DescribeSecurityGroups") @XMLResponseParser(DescribeSecurityGroupsResponseHandler.class) - Future> describeSecurityGroups( + Future> describeSecurityGroupsInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @BinderParam(BindGroupNameToIndexedFormParams.class) String... securityGroupNames); /** - * @see BaseEC2Client#authorizeSecurityGroupIngress(String,UserIdGroupPair) + * @see BaseEC2Client#authorizeSecurityGroupIngressInRegion(Region, String,UserIdGroupPair) */ @POST @Path("/") @FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress") - Future authorizeSecurityGroupIngress( + Future authorizeSecurityGroupIngressInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @FormParam("GroupName") String groupName, @BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup); /** - * @see BaseEC2Client#authorizeSecurityGroupIngress(String,IpProtocol,int,int,String) + * @see BaseEC2Client#authorizeSecurityGroupIngressInRegion(Region, + * String,IpProtocol,int,int,String) */ @POST @Path("/") @FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress") - Future authorizeSecurityGroupIngress(@FormParam("GroupName") String groupName, + Future authorizeSecurityGroupIngressInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + @FormParam("GroupName") String groupName, @FormParam("IpProtocol") IpProtocol ipProtocol, @FormParam("FromPort") int fromPort, @FormParam("ToPort") int toPort, @FormParam("CidrIp") String cidrIp); /** - * @see BaseEC2Client#revokeSecurityGroupIngress(String,UserIdGroupPair) + * @see BaseEC2Client#revokeSecurityGroupIngressInRegion(Region, String,UserIdGroupPair) */ @POST @Path("/") @FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress") - Future revokeSecurityGroupIngress( + Future revokeSecurityGroupIngressInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, @FormParam("GroupName") String groupName, @BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup); /** - * @see BaseEC2Client#revokeSecurityGroupIngress(String,IpProtocol,int,int,String) + * @see BaseEC2Client#revokeSecurityGroupIngressInRegion(Region, + * String,IpProtocol,int,int,String) */ @POST @Path("/") @FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress") - Future revokeSecurityGroupIngress(@FormParam("GroupName") String groupName, + Future revokeSecurityGroupIngressInRegion( + @EndpointParam(parser = RegionToEndpoint.class) Region region, + @FormParam("GroupName") String groupName, @FormParam("IpProtocol") IpProtocol ipProtocol, @FormParam("FromPort") int fromPort, @FormParam("ToPort") int toPort, @FormParam("CidrIp") String cidrIp); } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/SecurityGroupClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/SecurityGroupClient.java index 47dc849bf4..fd8fff972a 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/services/SecurityGroupClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/SecurityGroupClient.java @@ -27,6 +27,7 @@ import java.util.SortedSet; import java.util.concurrent.TimeUnit; import org.jclouds.aws.ec2.domain.IpProtocol; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.domain.SecurityGroup; import org.jclouds.aws.ec2.domain.UserIdGroupPair; import org.jclouds.concurrent.Timeout; @@ -43,6 +44,10 @@ public interface SecurityGroupClient { /** * Creates a new security group. Group names must be unique per account. * + * @param region + * Security groups are not copied across Regions. Instances within the Region cannot + * communicate with instances outside the Region using group-based firewall rules. + * Traffic from instances in another Region is seen as WAN bandwidth. * @param name * Name of the security group. Accepts alphanumeric characters, spaces, dashes, and * underscores. @@ -59,11 +64,15 @@ public interface SecurityGroupClient { * @see */ - void createSecurityGroup(String name, String description); + void createSecurityGroupInRegion(Region region, String name, String description); /** * Deletes a security group that you own. * + * @param region + * Security groups are not copied across Regions. Instances within the Region cannot + * communicate with instances outside the Region using group-based firewall rules. + * Traffic from instances in another Region is seen as WAN bandwidth. * @param name * Name of the security group to delete. * @@ -75,11 +84,15 @@ public interface SecurityGroupClient { * @see */ - void deleteSecurityGroup(String name); + void deleteSecurityGroupInRegion(Region region, String name); /** * Returns information about security groups that you own. * + * @param region + * Security groups are not copied across Regions. Instances within the Region cannot + * communicate with instances outside the Region using group-based firewall rules. + * Traffic from instances in another Region is seen as WAN bandwidth. * @param securityGroupNames * Name of the security groups * @@ -91,12 +104,17 @@ public interface SecurityGroupClient { * @see */ - SortedSet describeSecurityGroups(String... securityGroupNames); + SortedSet describeSecurityGroupsInRegion(Region region, + String... securityGroupNames); /** * * Adds permissions to a security group based on another group. * + * @param region + * Security groups are not copied across Regions. Instances within the Region cannot + * communicate with instances outside the Region using group-based firewall rules. + * Traffic from instances in another Region is seen as WAN bandwidth. * @param groupName * Name of the group to modify. The name must be valid and belong to the account * @param sourceSecurityGroup @@ -110,7 +128,8 @@ public interface SecurityGroupClient { * @see > { + HandlerWithResult> { @Resource protected Logger logger = Logger.NULL; - private SortedSet pairs = Sets.newTreeSet(); + private Set pairs = Sets.newLinkedHashSet(); private InetAddress ipAddress; private StringBuilder currentText = new StringBuilder(); @@ -87,7 +87,7 @@ public class DescribeAddressesResponseHandler extends } @Override - public SortedSet getResult() { + public Set getResult() { return pairs; } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/xml/DescribeKeyPairsResponseHandler.java b/aws/core/src/main/java/org/jclouds/aws/ec2/xml/DescribeKeyPairsResponseHandler.java index 70bb2a4678..8ed94f6161 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/xml/DescribeKeyPairsResponseHandler.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/xml/DescribeKeyPairsResponseHandler.java @@ -23,7 +23,7 @@ */ package org.jclouds.aws.ec2.xml; -import java.util.SortedSet; +import java.util.Set; import org.jclouds.aws.ec2.domain.KeyPair; import org.jclouds.http.functions.ParseSax; @@ -37,14 +37,14 @@ import com.google.common.collect.Sets; * /> * @author Adrian Cole */ -public class DescribeKeyPairsResponseHandler extends ParseSax.HandlerWithResult> { +public class DescribeKeyPairsResponseHandler extends ParseSax.HandlerWithResult> { private StringBuilder currentText = new StringBuilder(); - private SortedSet keyPairs = Sets.newTreeSet(); + private Set keyPairs = Sets.newLinkedHashSet(); private String keyFingerprint; private String keyName; - public SortedSet getResult() { + public Set getResult() { return keyPairs; } diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/EC2ClientLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/EC2ClientLiveTest.java deleted file mode 100644 index 1da7b36abb..0000000000 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/EC2ClientLiveTest.java +++ /dev/null @@ -1,347 +0,0 @@ -/** - * - * Copyright (C) 2009 Cloud Conscious, LLC. - * - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - */ -package org.jclouds.aws.ec2; - -import static com.google.common.base.Preconditions.checkNotNull; -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.TimeoutException; - -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.PublicIpInstanceIdPair; -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() { - 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 testDescribeAddresses() { - SortedSet allResults = client.getElasticIPAddressServices() - .describeAddresses(); - assertNotNull(allResults); - if (allResults.size() >= 1) { - PublicIpInstanceIdPair pair = allResults.last(); - SortedSet result = client.getElasticIPAddressServices() - .describeAddresses(pair.getPublicIp()); - assertNotNull(result); - PublicIpInstanceIdPair compare = result.last(); - assertEquals(compare, pair); - } - } - - @Test - void testDescribeInstances() { - SortedSet allResults = client.getInstanceServices().describeInstances(); - assertNotNull(allResults); - assert allResults.size() >= 0 : allResults.size(); - if (allResults.size() >= 2) { - Iterator iterator = allResults.iterator(); - String id1 = iterator.next().getRunningInstances().first().getInstanceId(); - String id2 = iterator.next().getRunningInstances().first().getInstanceId(); - SortedSet twoResults = client.getInstanceServices().describeInstances(id1, - id2); - assertNotNull(twoResults); - assertEquals(twoResults.size(), 2); - iterator = allResults.iterator(); - assertEquals(iterator.next().getRunningInstances().first().getInstanceId(), id1); - assertEquals(iterator.next().getRunningInstances().first().getInstanceId(), id2); - } - } - - @Test - void testDescribeKeyPairs() { - SortedSet allResults = client.getKeyPairServices().describeKeyPairs(); - assertNotNull(allResults); - assert allResults.size() >= 0 : allResults.size(); - if (allResults.size() >= 2) { - Iterator iterator = allResults.iterator(); - String id1 = iterator.next().getKeyName(); - String id2 = iterator.next().getKeyName(); - SortedSet twoResults = client.getKeyPairServices().describeKeyPairs(id1, id2); - 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 allResults = client.getSecurityGroupServices() - .describeSecurityGroups(); - assertNotNull(allResults); - assert allResults.size() >= 0 : allResults.size(); - if (allResults.size() >= 2) { - Iterator iterator = allResults.iterator(); - String id1 = iterator.next().getName(); - String id2 = iterator.next().getName(); - SortedSet twoResults = client.getSecurityGroupServices() - .describeSecurityGroups(id1, id2); - 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() { - String keyName = PREFIX + "1"; - try { - client.getKeyPairServices().deleteKeyPair(keyName); - } catch (Exception e) { - - } - client.getKeyPairServices().deleteKeyPair(keyName); - - KeyPair result = client.getKeyPairServices().createKeyPair(keyName); - assertNotNull(result); - assertNotNull(result.getKeyMaterial()); - assertNotNull(result.getKeyFingerprint()); - assertEquals(result.getKeyName(), keyName); - - SortedSet twoResults = client.getKeyPairServices().describeKeyPairs(keyName); - assertNotNull(twoResults); - assertEquals(twoResults.size(), 1); - KeyPair listPair = twoResults.iterator().next(); - assertEquals(listPair.getKeyName(), result.getKeyName()); - assertEquals(listPair.getKeyFingerprint(), result.getKeyFingerprint()); - } - - @Test - void testCreateSecurityGroup() { - String groupName = PREFIX + "1"; - String groupDescription = PREFIX + "1 description"; - try { - client.getSecurityGroupServices().deleteSecurityGroup(groupName); - } catch (Exception e) { - - } - client.getSecurityGroupServices().deleteSecurityGroup(groupName); - - client.getSecurityGroupServices().createSecurityGroup(groupName, groupDescription); - - verifySecurityGroup(groupName, groupDescription); - } - - @Test - void testAuthorizeSecurityGroupIngressCidr() throws InterruptedException, ExecutionException, - TimeoutException { - String groupName = PREFIX + "ingress"; - - try { - client.getSecurityGroupServices().deleteSecurityGroup(groupName); - } catch (Exception e) { - } - - client.getSecurityGroupServices().createSecurityGroup(groupName, groupName); - client.getSecurityGroupServices().authorizeSecurityGroupIngress(groupName, IpProtocol.TCP, - 80, 80, "0.0.0.0/0"); - assertEventually(new GroupHasPermission(client, groupName, new IpPermission(80, 80, Sets - . newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0")))); - - client.getSecurityGroupServices().revokeSecurityGroupIngress(groupName, IpProtocol.TCP, 80, - 80, "0.0.0.0/0"); - assertEventually(new GroupHasNoPermissions(client, groupName)); - - } - - private void verifySecurityGroup(String groupName, String description) { - SortedSet oneResult = client.getSecurityGroupServices() - .describeSecurityGroups(groupName); - 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 { - String group1Name = PREFIX + "ingress1"; - String group2Name = PREFIX + "ingress2"; - - try { - client.getSecurityGroupServices().deleteSecurityGroup(group1Name); - } catch (Exception e) { - - } - try { - client.getSecurityGroupServices().deleteSecurityGroup(group2Name); - } catch (Exception e) { - - } - - client.getSecurityGroupServices().createSecurityGroup(group1Name, group1Name); - client.getSecurityGroupServices().createSecurityGroup(group2Name, group2Name); - ensureGroupsExist(group1Name, group2Name); - client.getSecurityGroupServices().authorizeSecurityGroupIngress(group1Name, IpProtocol.TCP, - 80, 80, "0.0.0.0/0"); - assertEventually(new GroupHasPermission(client, group2Name, new IpPermission(80, 80, Sets - . newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0")))); - - SortedSet oneResult = client.getSecurityGroupServices() - .describeSecurityGroups(group1Name); - assertNotNull(oneResult); - assertEquals(oneResult.size(), 1); - SecurityGroup group = oneResult.iterator().next(); - assertEquals(group.getName(), group1Name); - - client.getSecurityGroupServices().authorizeSecurityGroupIngress(group2Name, - new UserIdGroupPair(group.getOwnerId(), group1Name)); - assertEventually(new GroupHasPermission(client, group2Name, new IpPermission(80, 80, Sets - . newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0")))); - - client.getSecurityGroupServices().revokeSecurityGroupIngress(group2Name, - new UserIdGroupPair(group.getOwnerId(), group1Name)); - 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 oneResult = client.getSecurityGroupServices() - .describeSecurityGroups(group); - 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 oneResult = client.getSecurityGroupServices() - .describeSecurityGroups(group); - 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) { - SortedSet twoResults = client.getSecurityGroupServices() - .describeSecurityGroups(group1Name, group2Name); - assertNotNull(twoResults); - assertEquals(twoResults.size(), 2); - Iterator 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; - - } - -} diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/ExpensiveEC2ClientLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/ExpensiveEC2ClientLiveTest.java index 5b8749a316..cfd72cf9fe 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/ExpensiveEC2ClientLiveTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/ExpensiveEC2ClientLiveTest.java @@ -42,6 +42,7 @@ 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.PublicIpInstanceIdPair; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.domain.Reservation; import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.http.HttpResponseException; @@ -56,6 +57,7 @@ import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; +import com.google.common.collect.Iterables; import com.google.inject.Injector; /** @@ -97,30 +99,32 @@ public class ExpensiveEC2ClientLiveTest { securityGroupName = serverPrefix + "ingress"; try { - client.getSecurityGroupServices().deleteSecurityGroup(securityGroupName); + client.getSecurityGroupServices().deleteSecurityGroupInRegion(Region.DEFAULT, + securityGroupName); } catch (Exception e) { } - client.getSecurityGroupServices().createSecurityGroup(securityGroupName, securityGroupName); - client.getSecurityGroupServices().authorizeSecurityGroupIngress(securityGroupName, - IpProtocol.TCP, 80, 80, "0.0.0.0/0"); - client.getSecurityGroupServices().authorizeSecurityGroupIngress(securityGroupName, - IpProtocol.TCP, 443, 443, "0.0.0.0/0"); - client.getSecurityGroupServices().authorizeSecurityGroupIngress(securityGroupName, - IpProtocol.TCP, 22, 22, "0.0.0.0/0"); + client.getSecurityGroupServices().createSecurityGroupInRegion(Region.DEFAULT, + securityGroupName, securityGroupName); + client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(Region.DEFAULT, + securityGroupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0"); + client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(Region.DEFAULT, + securityGroupName, IpProtocol.TCP, 443, 443, "0.0.0.0/0"); + client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(Region.DEFAULT, + securityGroupName, IpProtocol.TCP, 22, 22, "0.0.0.0/0"); } @Test(enabled = true) void testCreateKeyPair() throws InterruptedException, ExecutionException, TimeoutException { String keyName = serverPrefix + "1"; try { - client.getKeyPairServices().deleteKeyPair(keyName); + client.getKeyPairServices().deleteKeyPairInRegion(Region.DEFAULT, keyName); } catch (Exception e) { } - client.getKeyPairServices().deleteKeyPair(keyName); + client.getKeyPairServices().deleteKeyPairInRegion(Region.DEFAULT, keyName); - keyPair = client.getKeyPairServices().createKeyPair(keyName); + keyPair = client.getKeyPairServices().createKeyPairInRegion(Region.DEFAULT, keyName); assertNotNull(keyPair); assertNotNull(keyPair.getKeyMaterial()); assertNotNull(keyPair.getKeyFingerprint()); @@ -135,7 +139,9 @@ public class ExpensiveEC2ClientLiveTest { while (server == null) { try { System.out.printf("%d: running instance%n", System.currentTimeMillis()); - server = client.getInstanceServices().runInstances( + server = client.getInstanceServices().runInstancesInRegion( + Region.DEFAULT, + null, imageId, 1, 1, @@ -161,37 +167,42 @@ public class ExpensiveEC2ClientLiveTest { @Test(enabled = true, dependsOnMethods = "testCreateRunningInstance") void testElasticIpAddress() throws InterruptedException, ExecutionException, TimeoutException, IOException { - address = client.getElasticIPAddressServices().allocateAddress(); + address = client.getElasticIPAddressServices().allocateAddressInRegion(Region.DEFAULT); assertNotNull(address); - PublicIpInstanceIdPair compare = client.getElasticIPAddressServices().describeAddresses( - address).last(); + PublicIpInstanceIdPair compare = Iterables.getLast(client.getElasticIPAddressServices() + .describeAddressesInRegion(Region.DEFAULT, address)); assertEquals(compare.getPublicIp(), address); assert compare.getInstanceId() == null; - client.getElasticIPAddressServices().associateAddress(address, serverId); + client.getElasticIPAddressServices().associateAddressInRegion(Region.DEFAULT, address, + serverId); - compare = client.getElasticIPAddressServices().describeAddresses(address).last(); + compare = Iterables.getLast(client.getElasticIPAddressServices().describeAddressesInRegion( + Region.DEFAULT, address)); assertEquals(compare.getPublicIp(), address); assertEquals(compare.getInstanceId(), serverId); - Reservation reservation = client.getInstanceServices().describeInstances(serverId).last(); + Reservation reservation = client.getInstanceServices().describeInstancesInRegion( + Region.DEFAULT, serverId).last(); assertNotNull(reservation.getRunningInstances().last().getIpAddress()); assertFalse(reservation.getRunningInstances().last().getIpAddress().equals(address)); doCheckKey(address); - client.getElasticIPAddressServices().disassociateAddress(address); + client.getElasticIPAddressServices().disassociateAddressInRegion(Region.DEFAULT, address); - compare = client.getElasticIPAddressServices().describeAddresses(address).last(); + compare = Iterables.getLast(client.getElasticIPAddressServices().describeAddressesInRegion( + Region.DEFAULT, address)); assertEquals(compare.getPublicIp(), address); assert compare.getInstanceId() == null; - reservation = client.getInstanceServices().describeInstances(serverId).last(); + reservation = client.getInstanceServices() + .describeInstancesInRegion(Region.DEFAULT, serverId).last(); // assert reservation.getRunningInstances().last().getIpAddress() == null; TODO } @@ -247,19 +258,20 @@ public class ExpensiveEC2ClientLiveTest { @AfterTest void cleanup() throws InterruptedException, ExecutionException, TimeoutException { if (address != null) - client.getElasticIPAddressServices().releaseAddress(address); + client.getElasticIPAddressServices().releaseAddressInRegion(Region.DEFAULT, address); if (serverId != null) - client.getInstanceServices().terminateInstances(serverId); + client.getInstanceServices().terminateInstancesInRegion(Region.DEFAULT, serverId); if (keyPair != null) - client.getKeyPairServices().deleteKeyPair(keyPair.getKeyName()); + client.getKeyPairServices().deleteKeyPairInRegion(Region.DEFAULT, keyPair.getKeyName()); if (securityGroupName != null) - client.getSecurityGroupServices().deleteSecurityGroup(securityGroupName); + client.getSecurityGroupServices().deleteSecurityGroupInRegion(Region.DEFAULT, + securityGroupName); } private RunningInstance getRunningInstance(String serverId) throws InterruptedException, ExecutionException, TimeoutException { - return client.getInstanceServices().describeInstances(serverId).first().getRunningInstances() - .first(); + return client.getInstanceServices().describeInstancesInRegion(Region.DEFAULT, serverId) + .first().getRunningInstances().first(); } } diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/options/RunInstancesOptionsTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/options/RunInstancesOptionsTest.java index 2be4d544e5..079e52c4d8 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/options/RunInstancesOptionsTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/options/RunInstancesOptionsTest.java @@ -25,7 +25,6 @@ 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; @@ -136,8 +135,7 @@ public class RunInstancesOptionsTest { public void testWithUserData() { RunInstancesOptions options = new RunInstancesOptions(); options.withUserData("test"); - assertEquals(options.buildFormParameters().get("UserData"), Collections - .singletonList("test")); + assertEquals(options.buildFormParameters().get("UserData"), Collections.singletonList("test")); } @Test @@ -149,8 +147,7 @@ public class RunInstancesOptionsTest { @Test public void testWithUserDataStatic() { RunInstancesOptions options = withUserData("test"); - assertEquals(options.buildFormParameters().get("UserData"), Collections - .singletonList("test")); + assertEquals(options.buildFormParameters().get("UserData"), Collections.singletonList("test")); } @Test(expectedExceptions = NullPointerException.class) @@ -184,39 +181,11 @@ public class RunInstancesOptionsTest { 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")); + assertEquals(options.buildFormParameters().get("KernelId"), Collections.singletonList("test")); } @Test @@ -228,8 +197,7 @@ public class RunInstancesOptionsTest { @Test public void testWithKernelIdStatic() { RunInstancesOptions options = withKernelId("test"); - assertEquals(options.buildFormParameters().get("KernelId"), Collections - .singletonList("test")); + assertEquals(options.buildFormParameters().get("KernelId"), Collections.singletonList("test")); } @Test(expectedExceptions = NullPointerException.class) @@ -289,8 +257,7 @@ public class RunInstancesOptionsTest { public void testWithSubnetId() { RunInstancesOptions options = new RunInstancesOptions(); options.withSubnetId("test"); - assertEquals(options.buildFormParameters().get("SubnetId"), Collections - .singletonList("test")); + assertEquals(options.buildFormParameters().get("SubnetId"), Collections.singletonList("test")); } @Test @@ -302,8 +269,7 @@ public class RunInstancesOptionsTest { @Test public void testWithSubnetIdStatic() { RunInstancesOptions options = withSubnetId("test"); - assertEquals(options.buildFormParameters().get("SubnetId"), Collections - .singletonList("test")); + assertEquals(options.buildFormParameters().get("SubnetId"), Collections.singletonList("test")); } @Test(expectedExceptions = NullPointerException.class) @@ -341,8 +307,8 @@ public class RunInstancesOptionsTest { public void testWithVirtualName() { RunInstancesOptions options = new RunInstancesOptions(); options.withVirtualName("test"); - assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"), - Collections.singletonList("test")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"), Collections + .singletonList("test")); } @Test @@ -355,8 +321,8 @@ public class RunInstancesOptionsTest { @Test public void testWithVirtualNameStatic() { RunInstancesOptions options = withVirtualName("test"); - assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"), - Collections.singletonList("test")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"), Collections + .singletonList("test")); } @Test(expectedExceptions = NullPointerException.class) diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIAsyncClientTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIAsyncClientTest.java index 59f5739830..041481d477 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIAsyncClientTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIAsyncClientTest.java @@ -30,8 +30,12 @@ import java.io.IOException; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.net.URI; +import java.util.Map; + +import javax.inject.Singleton; import org.jclouds.aws.ec2.EC2; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.filters.FormSigner; import org.jclouds.aws.ec2.options.CreateImageOptions; import org.jclouds.aws.ec2.options.DescribeImagesOptions; @@ -56,6 +60,7 @@ import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.inject.AbstractModule; import com.google.inject.Module; import com.google.inject.Provides; @@ -70,16 +75,17 @@ import com.google.inject.TypeLiteral; public class AMIAsyncClientTest extends RestClientTest { public void testCreateImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("createImage", String.class, String.class, - Array.newInstance(CreateImageOptions.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "name", - "instanceId"); + Method method = AMIAsyncClient.class.getMethod("createImageInRegion", Region.class, + String.class, String.class, Array.newInstance(CreateImageOptions.class, 0) + .getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT, "name", "instanceId"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, "Content-Length: 69\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); assertPayloadEquals(httpMethod, - "Version=2009-11-30&Action=CreateImage&Name=name&InstanceId=instanceId"); + "Version=2009-11-30&Action=CreateImage&InstanceId=instanceId&Name=name"); assertResponseParserClassEquals(method, httpMethod, ParseSax.class); assertSaxResponseParserClassEquals(method, ImageIdHandler.class); assertExceptionParserClassEquals(method, null); @@ -89,17 +95,19 @@ public class AMIAsyncClientTest extends RestClientTest { public void testCreateImageOptions() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("createImage", String.class, String.class, - Array.newInstance(CreateImageOptions.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "name", - "instanceId", new CreateImageOptions().withDescription("description").noReboot()); + Method method = AMIAsyncClient.class.getMethod("createImageInRegion", Region.class, + String.class, String.class, Array.newInstance(CreateImageOptions.class, 0) + .getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT, "name", "instanceId", new CreateImageOptions().withDescription( + "description").noReboot()); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, "Content-Length: 107\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); assertPayloadEquals( httpMethod, - "Version=2009-11-30&Action=CreateImage&Name=name&InstanceId=instanceId&Description=description&NoReboot=true"); + "Version=2009-11-30&Action=CreateImage&InstanceId=instanceId&Name=name&Description=description&NoReboot=true"); assertResponseParserClassEquals(method, httpMethod, ParseSax.class); assertSaxResponseParserClassEquals(method, ImageIdHandler.class); @@ -109,8 +117,8 @@ public class AMIAsyncClientTest extends RestClientTest { } public void testDescribeImages() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("describeImages", Array.newInstance( - DescribeImagesOptions.class, 0).getClass()); + Method method = AMIAsyncClient.class.getMethod("describeImagesInRegion", Region.class, Array + .newInstance(DescribeImagesOptions.class, 0).getClass()); GeneratedHttpRequest httpMethod = processor.createRequest(method); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); @@ -131,10 +139,10 @@ public class AMIAsyncClientTest extends RestClientTest { public void testDescribeImagesOptions() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("describeImages", Array.newInstance( - DescribeImagesOptions.class, 0).getClass()); + Method method = AMIAsyncClient.class.getMethod("describeImagesInRegion", Region.class, Array + .newInstance(DescribeImagesOptions.class, 0).getClass()); GeneratedHttpRequest httpMethod = processor.createRequest(method, - executableBy("me").ownedBy("fred", "nancy").imageIds("1", "2")); + Region.DEFAULT, executableBy("me").ownedBy("fred", "nancy").imageIds("1", "2")); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -151,8 +159,10 @@ public class AMIAsyncClientTest extends RestClientTest { } public void testDeregisterImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("deregisterImage", String.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "imageId"); + Method method = AMIAsyncClient.class.getMethod("deregisterImageInRegion", Region.class, + String.class); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT, "imageId"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -168,16 +178,17 @@ public class AMIAsyncClientTest extends RestClientTest { public void testRegisterImageFromManifest() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("registerImageFromManifest", String.class, - String.class, Array.newInstance(RegisterImageOptions.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "name", - "pathToManifest"); + Method method = AMIAsyncClient.class.getMethod("registerImageFromManifestInRegion", + Region.class, String.class, String.class, Array.newInstance( + RegisterImageOptions.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT, "name", "pathToManifest"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, "Content-Length: 78\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); assertPayloadEquals(httpMethod, - "Version=2009-11-30&Action=RegisterImage&Name=name&ImageLocation=pathToManifest"); + "Version=2009-11-30&Action=RegisterImage&ImageLocation=pathToManifest&Name=name"); assertResponseParserClassEquals(method, httpMethod, ParseSax.class); assertSaxResponseParserClassEquals(method, ImageIdHandler.class); assertExceptionParserClassEquals(method, null); @@ -187,17 +198,19 @@ public class AMIAsyncClientTest extends RestClientTest { public void testRegisterImageFromManifestOptions() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("registerImageFromManifest", String.class, - String.class, Array.newInstance(RegisterImageOptions.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "name", - "pathToManifest", new RegisterImageOptions().withDescription("description")); + Method method = AMIAsyncClient.class.getMethod("registerImageFromManifestInRegion", + Region.class, String.class, String.class, Array.newInstance( + RegisterImageOptions.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT, "name", "pathToManifest", new RegisterImageOptions() + .withDescription("description")); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, "Content-Length: 102\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); assertPayloadEquals( httpMethod, - "Version=2009-11-30&Action=RegisterImage&Name=name&ImageLocation=pathToManifest&Description=description"); + "Version=2009-11-30&Action=RegisterImage&ImageLocation=pathToManifest&Name=name&Description=description"); assertResponseParserClassEquals(method, httpMethod, ParseSax.class); assertSaxResponseParserClassEquals(method, ImageIdHandler.class); @@ -208,18 +221,18 @@ public class AMIAsyncClientTest extends RestClientTest { public void testRegisterImageBackedByEBS() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class - .getMethod("registerImageBackedByEbs", String.class, String.class, Array - .newInstance(RegisterImageBackedByEbsOptions.class, 0).getClass()); + Method method = AMIAsyncClient.class.getMethod("registerImageBackedByEbsInRegion", + Region.class, String.class, String.class, Array.newInstance( + RegisterImageBackedByEbsOptions.class, 0).getClass()); GeneratedHttpRequest httpMethod = processor.createRequest(method, - "imageName", "snapshotId"); + Region.DEFAULT, "imageName", "snapshotId"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, "Content-Length: 176\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); assertPayloadEquals( httpMethod, - "Version=2009-11-30&Action=RegisterImage&RootDeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.DeviceName=%2Fdev%2Fsda1&Name=imageName&BlockDeviceMapping.0.Ebs.SnapshotId=snapshotId"); + "Version=2009-11-30&Action=RegisterImage&RootDeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.Ebs.SnapshotId=snapshotId&Name=imageName"); assertResponseParserClassEquals(method, httpMethod, ParseSax.class); assertSaxResponseParserClassEquals(method, ImageIdHandler.class); assertExceptionParserClassEquals(method, null); @@ -229,20 +242,21 @@ public class AMIAsyncClientTest extends RestClientTest { public void testRegisterImageBackedByEBSOptions() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class - .getMethod("registerImageBackedByEbs", String.class, String.class, Array - .newInstance(RegisterImageBackedByEbsOptions.class, 0).getClass()); + Method method = AMIAsyncClient.class.getMethod("registerImageBackedByEbsInRegion", + Region.class, String.class, String.class, Array.newInstance( + RegisterImageBackedByEbsOptions.class, 0).getClass()); GeneratedHttpRequest httpMethod = processor.createRequest(method, - "imageName", "snapshotId", new RegisterImageBackedByEbsOptions().withDescription( - "description").addBlockDeviceFromSnapshot("/dev/device", null, "snapshot") - .addNewBlockDevice("/dev/newdevice", "newblock", 100)); + Region.DEFAULT, "imageName", "snapshotId", new RegisterImageBackedByEbsOptions() + .withDescription("description").addBlockDeviceFromSnapshot("/dev/device", + null, "snapshot").addNewBlockDevice("/dev/newdevice", "newblock", + 100)); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, "Content-Length: 528\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); assertPayloadEquals( httpMethod, - "Version=2009-11-30&Action=RegisterImage&RootDeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.DeviceName=%2Fdev%2Fsda1&Name=imageName&BlockDeviceMapping.0.Ebs.SnapshotId=snapshotId&Description=description&BlockDeviceMapping.1.Ebs.DeleteOnTermination=false&BlockDeviceMapping.1.DeviceName=%2Fdev%2Fdevice&BlockDeviceMapping.1.Ebs.SnapshotId=snapshot&BlockDeviceMapping.2.Ebs.DeleteOnTermination=false&BlockDeviceMapping.2.DeviceName=%2Fdev%2Fnewdevice&BlockDeviceMapping.2.VirtualName=newblock&BlockDeviceMapping.2.Ebs.VolumeSize=100"); + "Version=2009-11-30&Action=RegisterImage&RootDeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.Ebs.SnapshotId=snapshotId&Name=imageName&Description=description&BlockDeviceMapping.1.Ebs.DeleteOnTermination=false&BlockDeviceMapping.1.DeviceName=%2Fdev%2Fdevice&BlockDeviceMapping.1.Ebs.SnapshotId=snapshot&BlockDeviceMapping.2.Ebs.DeleteOnTermination=false&BlockDeviceMapping.2.DeviceName=%2Fdev%2Fnewdevice&BlockDeviceMapping.2.VirtualName=newblock&BlockDeviceMapping.2.Ebs.VolumeSize=100"); assertResponseParserClassEquals(method, httpMethod, ParseSax.class); assertSaxResponseParserClassEquals(method, ImageIdHandler.class); @@ -253,8 +267,10 @@ public class AMIAsyncClientTest extends RestClientTest { public void testGetLaunchPermissionForImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("getLaunchPermissionForImage", String.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "imageId"); + Method method = AMIAsyncClient.class.getMethod("getLaunchPermissionForImageInRegion", + Region.class, String.class); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT, "imageId"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -271,8 +287,10 @@ public class AMIAsyncClientTest extends RestClientTest { public void testGetProductCodesForImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("getProductCodesForImage", String.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "imageId"); + Method method = AMIAsyncClient.class.getMethod("getProductCodesForImageInRegion", + Region.class, String.class); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT, "imageId"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -289,9 +307,10 @@ public class AMIAsyncClientTest extends RestClientTest { public void testGetBlockDeviceMappingsForImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class - .getMethod("getBlockDeviceMappingsForImage", String.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "imageId"); + Method method = AMIAsyncClient.class.getMethod("getBlockDeviceMappingsForImageInRegion", + Region.class, String.class); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT, "imageId"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -308,17 +327,17 @@ public class AMIAsyncClientTest extends RestClientTest { public void testAddLaunchPermissionsToImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("addLaunchPermissionsToImage", Iterable.class, - Iterable.class, String.class); + Method method = AMIAsyncClient.class.getMethod("addLaunchPermissionsToImageInRegion", + Region.class, Iterable.class, Iterable.class, String.class); GeneratedHttpRequest httpMethod = processor.createRequest(method, - ImmutableList.of("bob", "sue"), ImmutableList.of("all"), "imageId"); + Region.DEFAULT, ImmutableList.of("bob", "sue"), ImmutableList.of("all"), "imageId"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, "Content-Length: 107\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); assertPayloadEquals( httpMethod, - "Version=2009-11-30&Action=ModifyImageAttribute&OperationType=add&Attribute=launchPermission&ImageId=imageId&UserId.1=bob&UserId.2=sue&UserGroup.1=all"); + "Version=2009-11-30&Action=ModifyImageAttribute&OperationType=add&Attribute=launchPermission&ImageId=imageId&UserGroup.1=all&UserId.1=bob&UserId.2=sue"); filter.filter(httpMethod); assertPayloadEquals( httpMethod, @@ -333,22 +352,17 @@ public class AMIAsyncClientTest extends RestClientTest { public void testRemoveLaunchPermissionsFromImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("removeLaunchPermissionsFromImage", - Iterable.class, Iterable.class, String.class); + Method method = AMIAsyncClient.class.getMethod("removeLaunchPermissionsFromImageInRegion", + Region.class, Iterable.class, Iterable.class, String.class); GeneratedHttpRequest httpMethod = processor.createRequest(method, - ImmutableList.of("bob", "sue"), ImmutableList.of("all"), "imageId"); + Region.DEFAULT, ImmutableList.of("bob", "sue"), ImmutableList.of("all"), "imageId"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, "Content-Length: 110\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); assertPayloadEquals( httpMethod, - "Version=2009-11-30&Action=ModifyImageAttribute&OperationType=remove&Attribute=launchPermission&ImageId=imageId&UserId.1=bob&UserId.2=sue&UserGroup.1=all"); - filter.filter(httpMethod); - assertPayloadEquals( - httpMethod, - "Action=ModifyImageAttribute&Attribute=launchPermission&ImageId=imageId&OperationType=remove&Signature=hgjXXq6PXEuHCIsp5izCTJqS%2Biv2ZdnIv0VSV1kYy%2BE%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&UserGroup.1=all&UserId.1=bob&UserId.2=sue&Version=2009-11-30&AWSAccessKeyId=user"); - + "Version=2009-11-30&Action=ModifyImageAttribute&OperationType=remove&Attribute=launchPermission&ImageId=imageId&UserGroup.1=all&UserId.1=bob&UserId.2=sue"); assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); assertSaxResponseParserClassEquals(method, null); assertExceptionParserClassEquals(method, null); @@ -358,8 +372,10 @@ public class AMIAsyncClientTest extends RestClientTest { public void testResetLaunchPermissionsOnImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("resetLaunchPermissionsOnImage", String.class); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "imageId"); + Method method = AMIAsyncClient.class.getMethod("resetLaunchPermissionsOnImageInRegion", + Region.class, String.class); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT, "imageId"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -375,10 +391,10 @@ public class AMIAsyncClientTest extends RestClientTest { public void testAddProductCodesToImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("addProductCodesToImage", Iterable.class, - String.class); + Method method = AMIAsyncClient.class.getMethod("addProductCodesToImageInRegion", + Region.class, Iterable.class, String.class); GeneratedHttpRequest httpMethod = processor.createRequest(method, - ImmutableList.of("code1", "code2"), "imageId"); + Region.DEFAULT, ImmutableList.of("code1", "code2"), "imageId"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -396,10 +412,10 @@ public class AMIAsyncClientTest extends RestClientTest { public void testRemoveProductCodesFromImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("removeProductCodesFromImage", Iterable.class, - String.class); + Method method = AMIAsyncClient.class.getMethod("removeProductCodesFromImageInRegion", + Region.class, Iterable.class, String.class); GeneratedHttpRequest httpMethod = processor.createRequest(method, - ImmutableList.of("code1", "code2"), "imageId"); + Region.DEFAULT, ImmutableList.of("code1", "code2"), "imageId"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -460,6 +476,16 @@ public class AMIAsyncClientTest extends RestClientTest { String provide() { return "2009-11-08T15:54:08.897Z"; } + + @SuppressWarnings("unused") + @Singleton + @Provides + Map provideMap() { + return ImmutableMap. of(Region.DEFAULT, URI.create("https://booya"), + Region.EU_WEST_1, URI.create("https://ec2.eu-west-1.amazonaws.com"), + Region.US_EAST_1, URI.create("https://ec2.us-east-1.amazonaws.com"), + Region.US_WEST_1, URI.create("https://ec2.us-west-1.amazonaws.com")); + } }; } } diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIClientLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIClientLiveTest.java index dc581e393a..5086da47bd 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIClientLiveTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIClientLiveTest.java @@ -25,9 +25,8 @@ package org.jclouds.aws.ec2.services; import static com.google.common.base.Preconditions.checkNotNull; import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.imageIds; -import static org.jclouds.aws.ec2.options.RegisterImageOptions.Builder.withDescription; import static org.jclouds.aws.ec2.options.RegisterImageBackedByEbsOptions.Builder.addNewBlockDevice; - +import static org.jclouds.aws.ec2.options.RegisterImageOptions.Builder.withDescription; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; @@ -39,6 +38,7 @@ import org.jclouds.aws.ec2.EC2AsyncClient; import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2ContextFactory; import org.jclouds.aws.ec2.domain.Image; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.domain.Image.ImageType; import org.jclouds.aws.ec2.domain.Image.RootDeviceType; import org.jclouds.logging.log4j.config.Log4JLoggingModule; @@ -47,6 +47,7 @@ import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import com.google.inject.internal.ImmutableMap; @@ -78,25 +79,30 @@ public class AMIClientLiveTest { } public void testDescribeImages() { - SortedSet allResults = Sets.newTreeSet(client.describeImages()); - assertNotNull(allResults); - assert allResults.size() >= 2 : allResults.size(); - Iterator iterator = allResults.iterator(); - String id1 = iterator.next().getImageId(); - String id2 = iterator.next().getImageId(); - SortedSet twoResults = Sets.newTreeSet(client.describeImages(imageIds(id1, id2))); - assertNotNull(twoResults); - assertEquals(twoResults.size(), 2); - iterator = twoResults.iterator(); - assertEquals(iterator.next().getImageId(), id1); - assertEquals(iterator.next().getImageId(), id2); + for (Region region : ImmutableSet.of(Region.DEFAULT, Region.EU_WEST_1, Region.US_EAST_1, + Region.US_WEST_1)) { + SortedSet allResults = Sets.newTreeSet(client.describeImagesInRegion(region)); + assertNotNull(allResults); + assert allResults.size() >= 2 : allResults.size(); + Iterator iterator = allResults.iterator(); + String id1 = iterator.next().getImageId(); + String id2 = iterator.next().getImageId(); + SortedSet twoResults = Sets.newTreeSet(client.describeImagesInRegion(region, + imageIds(id1, id2))); + assertNotNull(twoResults); + assertEquals(twoResults.size(), 2); + iterator = twoResults.iterator(); + assertEquals(iterator.next().getImageId(), id1); + assertEquals(iterator.next().getImageId(), id2); + } } public void testRegisterImageFromManifest() { - String imageRegisteredId = client.registerImageFromManifest("jcloudstest1", DEFAULT_MANIFEST); + String imageRegisteredId = client.registerImageFromManifestInRegion(Region.DEFAULT, + "jcloudstest1", DEFAULT_MANIFEST); imagesToDeregister.add(imageRegisteredId); - Image imageRegisteredFromManifest = Iterables.getOnlyElement(client - .describeImages(imageIds(imageRegisteredId))); + Image imageRegisteredFromManifest = Iterables.getOnlyElement(client.describeImagesInRegion( + Region.DEFAULT, imageIds(imageRegisteredId))); assertEquals(imageRegisteredFromManifest.getName(), "jcloudstest1"); assertEquals(imageRegisteredFromManifest.getImageLocation(), DEFAULT_MANIFEST); assertEquals(imageRegisteredFromManifest.getImageType(), ImageType.MACHINE); @@ -105,11 +111,11 @@ public class AMIClientLiveTest { } public void testRegisterImageFromManifestOptions() { - String imageRegisteredWithOptionsId = client.registerImageFromManifest("jcloudstest2", - DEFAULT_MANIFEST, withDescription("adrian")); + String imageRegisteredWithOptionsId = client.registerImageFromManifestInRegion( + Region.DEFAULT, "jcloudstest2", DEFAULT_MANIFEST, withDescription("adrian")); imagesToDeregister.add(imageRegisteredWithOptionsId); Image imageRegisteredFromManifestWithOptions = Iterables.getOnlyElement(client - .describeImages(imageIds(imageRegisteredWithOptionsId))); + .describeImagesInRegion(Region.DEFAULT, imageIds(imageRegisteredWithOptionsId))); assertEquals(imageRegisteredFromManifestWithOptions.getName(), "jcloudstest2"); assertEquals(imageRegisteredFromManifestWithOptions.getImageLocation(), DEFAULT_MANIFEST); assertEquals(imageRegisteredFromManifestWithOptions.getImageType(), ImageType.MACHINE); @@ -122,10 +128,11 @@ public class AMIClientLiveTest { @Test(enabled = false) // awaiting EBS functionality to be added to jclouds public void testRegisterImageBackedByEBS() { - String imageRegisteredId = client.registerImageBackedByEbs("jcloudstest1", DEFAULT_MANIFEST); + String imageRegisteredId = client.registerImageBackedByEbsInRegion(Region.DEFAULT, + "jcloudstest1", DEFAULT_MANIFEST); imagesToDeregister.add(imageRegisteredId); - Image imageRegistered = Iterables.getOnlyElement(client - .describeImages(imageIds(imageRegisteredId))); + Image imageRegistered = Iterables.getOnlyElement(client.describeImagesInRegion( + Region.DEFAULT, imageIds(imageRegisteredId))); assertEquals(imageRegistered.getName(), "jcloudstest1"); assertEquals(imageRegistered.getImageType(), ImageType.MACHINE); assertEquals(imageRegistered.getRootDeviceType(), RootDeviceType.EBS); @@ -135,12 +142,12 @@ public class AMIClientLiveTest { @Test(enabled = false) // awaiting EBS functionality to be added to jclouds public void testRegisterImageBackedByEBSOptions() { - String imageRegisteredWithOptionsId = client.registerImageBackedByEbs("jcloudstest2", - DEFAULT_SNAPSHOT, addNewBlockDevice("/dev/sda2", "myvirtual", 1).withDescription( - "adrian")); + String imageRegisteredWithOptionsId = client.registerImageBackedByEbsInRegion(Region.DEFAULT, + "jcloudstest2", DEFAULT_SNAPSHOT, addNewBlockDevice("/dev/sda2", "myvirtual", 1) + .withDescription("adrian")); imagesToDeregister.add(imageRegisteredWithOptionsId); - Image imageRegisteredWithOptions = Iterables.getOnlyElement(client - .describeImages(imageIds(imageRegisteredWithOptionsId))); + Image imageRegisteredWithOptions = Iterables.getOnlyElement(client.describeImagesInRegion( + Region.DEFAULT, imageIds(imageRegisteredWithOptionsId))); assertEquals(imageRegisteredWithOptions.getName(), "jcloudstest2"); assertEquals(imageRegisteredWithOptions.getImageType(), ImageType.MACHINE); assertEquals(imageRegisteredWithOptions.getRootDeviceType(), RootDeviceType.EBS); @@ -153,46 +160,48 @@ public class AMIClientLiveTest { @Test(enabled = false) public void testCreateImage() { - // TODO client.createImage(name, instanceId, options); + // TODO client.createImageInRegion(Region.DEFAULT, name, instanceId, options); } @Test(enabled = false) public void testAddLaunchPermissionsToImage() { - // TODO client.addLaunchPermissionsToImage(userIds, userGroups, imageId); + // TODO client.addLaunchPermissionsToImageInRegion(Region.DEFAULT, userIds, userGroups, + // imageId); } @Test(enabled = false) public void testAddProductCodesToImage() { - // TODO client.addProductCodesToImage(productCodes, imageId); + // TODO client.addProductCodesToImageInRegion(Region.DEFAULT, productCodes, imageId); } @Test(enabled = false) public void testRemoveLaunchPermissionsFromImage() { - // TODO client.removeLaunchPermissionsFromImage(userIds, userGroups, imageId); + // TODO client.removeLaunchPermissionsFromImageInRegion(Region.DEFAULT, userIds, userGroups, + // imageId); } @Test(enabled = false) public void testResetLaunchPermissionsOnImage() { - // TODO client.resetLaunchPermissionsOnImage(imageId); + // TODO client.resetLaunchPermissionsOnImageInRegion(Region.DEFAULT, imageId); } public void testGetLaunchPermissionForImage() { - System.out.println(client.getLaunchPermissionForImage(imageId)); + System.out.println(client.getLaunchPermissionForImageInRegion(Region.DEFAULT, imageId)); } public void testGetProductCodesForImage() { - System.out.println(client.getProductCodesForImage(imageId)); + System.out.println(client.getProductCodesForImageInRegion(Region.DEFAULT, imageId)); } @Test(enabled = false) // awaiting ebs support public void testGetBlockDeviceMappingsForImage() { - System.out.println(client.getBlockDeviceMappingsForImage(imageId)); + System.out.println(client.getBlockDeviceMappingsForImageInRegion(Region.DEFAULT, imageId)); } @AfterTest public void deregisterImages() { for (String imageId : imagesToDeregister) - client.deregisterImage(imageId); + client.deregisterImageInRegion(Region.DEFAULT, imageId); } } diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/ElasticIPAddressAsyncClientTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/ElasticIPAddressAsyncClientTest.java index b1353234c7..3441c89a13 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/services/ElasticIPAddressAsyncClientTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/ElasticIPAddressAsyncClientTest.java @@ -30,8 +30,12 @@ import java.lang.reflect.Array; import java.lang.reflect.Method; import java.net.InetAddress; import java.net.URI; +import java.util.Map; + +import javax.inject.Singleton; import org.jclouds.aws.ec2.EC2; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.filters.FormSigner; import org.jclouds.aws.ec2.xml.AllocateAddressResponseHandler; import org.jclouds.aws.ec2.xml.DescribeAddressesResponseHandler; @@ -47,6 +51,7 @@ import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.util.Jsr330; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableMap; import com.google.inject.AbstractModule; import com.google.inject.Module; import com.google.inject.Provides; @@ -62,10 +67,10 @@ public class ElasticIPAddressAsyncClientTest extends RestClientTest httpMethod = processor.createRequest( - method, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 })); + method, Region.DEFAULT, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 })); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -81,16 +86,16 @@ public class ElasticIPAddressAsyncClientTest extends RestClientTest httpMethod = processor.createRequest( - method, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }), "me"); + method, Region.DEFAULT, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }), "me"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, "Content-Length: 75\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); assertPayloadEquals(httpMethod, - "Version=2009-11-30&Action=AssociateAddress&PublicIp=127.0.0.1&InstanceId=me"); + "Version=2009-11-30&Action=AssociateAddress&InstanceId=me&PublicIp=127.0.0.1"); assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); assertSaxResponseParserClassEquals(method, null); @@ -100,10 +105,10 @@ public class ElasticIPAddressAsyncClientTest extends RestClientTest httpMethod = processor.createRequest( - method, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 })); + method, Region.DEFAULT, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 })); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -118,10 +123,10 @@ public class ElasticIPAddressAsyncClientTest extends RestClientTest httpMethod = processor.createRequest( - method, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 })); + method, Region.DEFAULT, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 })); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -137,9 +142,10 @@ public class ElasticIPAddressAsyncClientTest extends RestClientTest httpMethod = processor - .createRequest(method); + Method method = ElasticIPAddressAsyncClient.class.getMethod("allocateAddressInRegion", + Region.class); + GeneratedHttpRequest httpMethod = processor.createRequest( + method, Region.DEFAULT); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -189,6 +195,16 @@ public class ElasticIPAddressAsyncClientTest extends RestClientTest provideMap() { + return ImmutableMap. of(Region.DEFAULT, URI.create("https://booya"), + Region.EU_WEST_1, URI.create("https://ec2.eu-west-1.amazonaws.com"), + Region.US_EAST_1, URI.create("https://ec2.us-east-1.amazonaws.com"), + Region.US_WEST_1, URI.create("https://ec2.us-west-1.amazonaws.com")); + } }; } } diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/ElasticIPAddressClientLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/ElasticIPAddressClientLiveTest.java new file mode 100644 index 0000000000..8eb45985c7 --- /dev/null +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/ElasticIPAddressClientLiveTest.java @@ -0,0 +1,88 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ +package org.jclouds.aws.ec2.services; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +import java.util.SortedSet; + +import org.jclouds.aws.ec2.EC2AsyncClient; +import org.jclouds.aws.ec2.EC2Client; +import org.jclouds.aws.ec2.EC2ContextFactory; +import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair; +import org.jclouds.aws.ec2.domain.Region; +import org.jclouds.logging.log4j.config.Log4JLoggingModule; +import org.jclouds.rest.RestContext; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; + +/** + * Tests behavior of {@code ElasticIPAddressClient} + * + * @author Adrian Cole + */ +@Test(groups = "live", sequential = true, testName = "ec2.ElasticIPAddressClientLiveTest") +public class ElasticIPAddressClientLiveTest { + + private ElasticIPAddressClient client; + private RestContext context; + + @BeforeGroups(groups = { "live" }) + public void setupClient() { + String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); + String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); + + context = EC2ContextFactory.createContext(user, password, new Log4JLoggingModule()); + client = context.getApi().getElasticIPAddressServices(); + } + + @Test + void testDescribeAddresses() { + for (Region region : ImmutableSet.of(Region.DEFAULT, Region.EU_WEST_1, Region.US_EAST_1, + Region.US_WEST_1)) { + SortedSet allResults = Sets.newTreeSet(client + .describeAddressesInRegion(region)); + assertNotNull(allResults); + if (allResults.size() >= 1) { + PublicIpInstanceIdPair pair = allResults.last(); + SortedSet result = Sets.newTreeSet(client + .describeAddressesInRegion(region, pair.getPublicIp())); + assertNotNull(result); + PublicIpInstanceIdPair compare = result.last(); + assertEquals(compare, pair); + } + } + } + + @AfterTest + public void shutdown() { + context.close(); + } +} diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/InstanceAsyncClientTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/InstanceAsyncClientTest.java index dbdd355e93..4c2b739333 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/services/InstanceAsyncClientTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/InstanceAsyncClientTest.java @@ -29,8 +29,13 @@ import java.io.IOException; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.net.URI; +import java.util.Map; + +import javax.inject.Singleton; import org.jclouds.aws.ec2.EC2; +import org.jclouds.aws.ec2.domain.AvailabilityZone; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.filters.FormSigner; import org.jclouds.aws.ec2.options.RunInstancesOptions; import org.jclouds.aws.ec2.xml.DescribeInstancesResponseHandler; @@ -47,6 +52,7 @@ import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.util.Jsr330; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableMap; import com.google.inject.AbstractModule; import com.google.inject.Module; import com.google.inject.Provides; @@ -61,9 +67,10 @@ import com.google.inject.TypeLiteral; public class InstanceAsyncClientTest extends RestClientTest { public void testDescribeInstances() throws SecurityException, NoSuchMethodException, IOException { - Method method = InstanceAsyncClient.class.getMethod("describeInstances", Array.newInstance( - String.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method); + Method method = InstanceAsyncClient.class.getMethod("describeInstancesInRegion", + Region.class, Array.newInstance(String.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -79,10 +86,10 @@ public class InstanceAsyncClientTest extends RestClientTest public void testDescribeInstancesArgs() throws SecurityException, NoSuchMethodException, IOException { - Method method = InstanceAsyncClient.class.getMethod("describeInstances", Array.newInstance( - String.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "1", - "2"); + Method method = InstanceAsyncClient.class.getMethod("describeInstancesInRegion", + Region.class, Array.newInstance(String.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT, "1", "2"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -99,10 +106,10 @@ public class InstanceAsyncClientTest extends RestClientTest public void testTerminateInstances() throws SecurityException, NoSuchMethodException, IOException { - Method method = InstanceAsyncClient.class.getMethod("terminateInstances", String.class, Array - .newInstance(String.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "1", - "2"); + Method method = InstanceAsyncClient.class.getMethod("terminateInstancesInRegion", + Region.class, String.class, Array.newInstance(String.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT, "1", "2"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -118,16 +125,17 @@ public class InstanceAsyncClientTest extends RestClientTest } public void testRunInstances() throws SecurityException, NoSuchMethodException, IOException { - Method method = InstanceAsyncClient.class.getMethod("runInstances", String.class, int.class, - int.class, Array.newInstance(RunInstancesOptions.class, 0).getClass()); + Method method = InstanceAsyncClient.class.getMethod("runInstancesInRegion", Region.class, + AvailabilityZone.class, String.class, int.class, int.class, Array.newInstance( + RunInstancesOptions.class, 0).getClass()); GeneratedHttpRequest httpMethod = processor.createRequest(method, - "ami-voo", 1, 1); + Region.DEFAULT, null, "ami-voo", 1, 1); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, "Content-Length: 76\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); assertPayloadEquals(httpMethod, - "Version=2009-11-30&Action=RunInstances&ImageId=ami-voo&MaxCount=1&MinCount=1"); + "Version=2009-11-30&Action=RunInstances&ImageId=ami-voo&MinCount=1&MaxCount=1"); assertResponseParserClassEquals(method, httpMethod, ParseSax.class); assertSaxResponseParserClassEquals(method, RunInstancesResponseHandler.class); @@ -138,18 +146,20 @@ public class InstanceAsyncClientTest extends RestClientTest public void testRunInstancesOptions() throws SecurityException, NoSuchMethodException, IOException { - Method method = InstanceAsyncClient.class.getMethod("runInstances", String.class, int.class, - int.class, Array.newInstance(RunInstancesOptions.class, 0).getClass()); + Method method = InstanceAsyncClient.class.getMethod("runInstancesInRegion", Region.class, + AvailabilityZone.class, String.class, int.class, int.class, Array.newInstance( + RunInstancesOptions.class, 0).getClass()); GeneratedHttpRequest httpMethod = processor.createRequest(method, - "ami-voo", 1, 5, new RunInstancesOptions().withKernelId("kernelId") - .enableMonitoring()); + Region.EU_WEST_1, AvailabilityZone.EU_WEST_1A, "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"); + assertRequestLineEquals(httpMethod, "POST https://ec2.eu-west-1.amazonaws.com/ HTTP/1.1"); + assertHeadersEqual( + httpMethod, + "Content-Length: 118\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.eu-west-1.amazonaws.com\n"); assertPayloadEquals( httpMethod, - "Version=2009-11-30&Action=RunInstances&ImageId=ami-voo&MaxCount=5&MinCount=1&KernelId=kernelId&Monitoring.Enabled=true"); + "Version=2009-11-30&Action=RunInstances&ImageId=ami-voo&MinCount=1&MaxCount=5&KernelId=kernelId&Monitoring.Enabled=true&Placement.AvailabilityZone=eu-west-1a"); assertResponseParserClassEquals(method, httpMethod, ParseSax.class); assertSaxResponseParserClassEquals(method, RunInstancesResponseHandler.class); @@ -194,6 +204,16 @@ public class InstanceAsyncClientTest extends RestClientTest String provide() { return "2009-11-08T15:54:08.897Z"; } + + @SuppressWarnings("unused") + @Singleton + @Provides + Map provideMap() { + return ImmutableMap. of(Region.DEFAULT, URI.create("https://booya"), + Region.EU_WEST_1, URI.create("https://ec2.eu-west-1.amazonaws.com"), + Region.US_EAST_1, URI.create("https://ec2.us-east-1.amazonaws.com"), + Region.US_WEST_1, URI.create("https://ec2.us-west-1.amazonaws.com")); + } }; } } diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/InstanceClientLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/InstanceClientLiveTest.java new file mode 100644 index 0000000000..25a6a581fb --- /dev/null +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/InstanceClientLiveTest.java @@ -0,0 +1,84 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ +package org.jclouds.aws.ec2.services; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +import java.util.Iterator; +import java.util.SortedSet; + +import org.jclouds.aws.ec2.EC2ContextFactory; +import org.jclouds.aws.ec2.domain.Region; +import org.jclouds.aws.ec2.domain.Reservation; +import org.jclouds.logging.log4j.config.Log4JLoggingModule; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * Tests behavior of {@code EC2Client} + * + * @author Adrian Cole + */ +@Test(groups = "live", sequential = true, testName = "ec2.InstanceClientLiveTest") +public class InstanceClientLiveTest { + public static final String PREFIX = System.getProperty("user.name") + "-ec2"; + + private InstanceClient client; + private String user; + + @BeforeGroups(groups = { "live" }) + public void setupClient() { + 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() + .getInstanceServices(); + } + + @Test + void testDescribeInstances() { + for (Region region : ImmutableSet.of(Region.DEFAULT, Region.EU_WEST_1, Region.US_EAST_1, + Region.US_WEST_1)) { + SortedSet allResults = client.describeInstancesInRegion(region); + assertNotNull(allResults); + assert allResults.size() >= 0 : allResults.size(); + if (allResults.size() >= 2) { + Iterator iterator = allResults.iterator(); + String id1 = iterator.next().getRunningInstances().first().getInstanceId(); + String id2 = iterator.next().getRunningInstances().first().getInstanceId(); + SortedSet twoResults = client.describeInstancesInRegion(region, id1, id2); + assertNotNull(twoResults); + assertEquals(twoResults.size(), 2); + iterator = allResults.iterator(); + assertEquals(iterator.next().getRunningInstances().first().getInstanceId(), id1); + assertEquals(iterator.next().getRunningInstances().first().getInstanceId(), id2); + } + } + } + +} diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/KeyPairAsyncClientTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/KeyPairAsyncClientTest.java index 9e5eabd9cc..764667745f 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/services/KeyPairAsyncClientTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/KeyPairAsyncClientTest.java @@ -29,8 +29,12 @@ import java.io.IOException; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.net.URI; +import java.util.Map; + +import javax.inject.Singleton; import org.jclouds.aws.ec2.EC2; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.filters.FormSigner; import org.jclouds.aws.ec2.xml.DescribeKeyPairsResponseHandler; import org.jclouds.aws.reference.AWSConstants; @@ -45,6 +49,7 @@ import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.util.Jsr330; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableMap; import com.google.inject.AbstractModule; import com.google.inject.Module; import com.google.inject.Provides; @@ -59,9 +64,10 @@ import com.google.inject.TypeLiteral; public class KeyPairAsyncClientTest extends RestClientTest { public void testDeleteKeyPair() throws SecurityException, NoSuchMethodException, IOException { - Method method = KeyPairAsyncClient.class.getMethod("deleteKeyPair", String.class); - GeneratedHttpRequest httpMethod = processor - .createRequest(method, "mykey"); + Method method = KeyPairAsyncClient.class.getMethod("deleteKeyPairInRegion", Region.class, + String.class); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT, "mykey"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -76,9 +82,10 @@ public class KeyPairAsyncClientTest extends RestClientTest { } public void testDescribeKeyPairs() throws SecurityException, NoSuchMethodException, IOException { - Method method = KeyPairAsyncClient.class.getMethod("describeKeyPairs", Array.newInstance( - String.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method); + Method method = KeyPairAsyncClient.class.getMethod("describeKeyPairsInRegion", Region.class, + Array.newInstance(String.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -94,10 +101,10 @@ public class KeyPairAsyncClientTest extends RestClientTest { public void testDescribeKeyPairsArgs() throws SecurityException, NoSuchMethodException, IOException { - Method method = KeyPairAsyncClient.class.getMethod("describeKeyPairs", Array.newInstance( - String.class, 0).getClass()); - GeneratedHttpRequest httpMethod = processor.createRequest(method, "1", - "2"); + Method method = KeyPairAsyncClient.class.getMethod("describeKeyPairsInRegion", Region.class, + Array.newInstance(String.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT, "1", "2"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -148,6 +155,16 @@ public class KeyPairAsyncClientTest extends RestClientTest { String provide() { return "2009-11-08T15:54:08.897Z"; } + + @SuppressWarnings("unused") + @Singleton + @Provides + Map provideMap() { + return ImmutableMap. of(Region.DEFAULT, URI.create("https://booya"), + Region.EU_WEST_1, URI.create("https://ec2.eu-west-1.amazonaws.com"), + Region.US_EAST_1, URI.create("https://ec2.us-east-1.amazonaws.com"), + Region.US_WEST_1, URI.create("https://ec2.us-west-1.amazonaws.com")); + } }; } } diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/KeyPairClientLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/KeyPairClientLiveTest.java new file mode 100644 index 0000000000..ce86f5cf74 --- /dev/null +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/KeyPairClientLiveTest.java @@ -0,0 +1,114 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ +package org.jclouds.aws.ec2.services; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +import java.util.SortedSet; + +import org.jclouds.aws.ec2.EC2AsyncClient; +import org.jclouds.aws.ec2.EC2Client; +import org.jclouds.aws.ec2.EC2ContextFactory; +import org.jclouds.aws.ec2.domain.KeyPair; +import org.jclouds.aws.ec2.domain.Region; +import org.jclouds.logging.log4j.config.Log4JLoggingModule; +import org.jclouds.rest.RestContext; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; + +/** + * Tests behavior of {@code KeyPairClient} + * + * @author Adrian Cole + */ +@Test(groups = "live", sequential = true, testName = "ec2.KeyPairClientLiveTest") +public class KeyPairClientLiveTest { + + private KeyPairClient client; + private RestContext context; + + @BeforeGroups(groups = { "live" }) + public void setupClient() { + String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); + String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); + + context = EC2ContextFactory.createContext(user, password, new Log4JLoggingModule()); + client = context.getApi().getKeyPairServices(); + } + + @Test + void testDescribeAddresses() { + for (Region region : ImmutableSet.of(Region.DEFAULT, Region.EU_WEST_1, Region.US_EAST_1, + Region.US_WEST_1)) { + SortedSet allResults = Sets.newTreeSet(client.describeKeyPairsInRegion(region)); + assertNotNull(allResults); + if (allResults.size() >= 1) { + KeyPair pair = allResults.last(); + SortedSet result = Sets.newTreeSet(client.describeKeyPairsInRegion(region, + pair.getKeyName())); + assertNotNull(result); + KeyPair compare = result.last(); + assertEquals(compare, pair); + } + } + } + + public static final String PREFIX = System.getProperty("user.name") + "-ec2"; + + @Test + void testCreateKeyPair() { + String keyName = PREFIX + "1"; + try { + client.deleteKeyPairInRegion(Region.DEFAULT, keyName); + } catch (Exception e) { + + } + client.deleteKeyPairInRegion(Region.DEFAULT, keyName); + + KeyPair result = client.createKeyPairInRegion(Region.DEFAULT, keyName); + assertNotNull(result); + assertNotNull(result.getKeyMaterial()); + assertNotNull(result.getKeyFingerprint()); + assertEquals(result.getKeyName(), keyName); + + SortedSet twoResults = Sets.newTreeSet(client.describeKeyPairsInRegion( + Region.DEFAULT, keyName)); + assertNotNull(twoResults); + assertEquals(twoResults.size(), 1); + KeyPair listPair = twoResults.iterator().next(); + assertEquals(listPair.getKeyName(), result.getKeyName()); + assertEquals(listPair.getKeyFingerprint(), result.getKeyFingerprint()); + } + + @AfterTest + public void shutdown() { + context.close(); + } +} diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/MonitoringAsyncClientTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/MonitoringAsyncClientTest.java index 6e1c586a8f..e6c0e76746 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/services/MonitoringAsyncClientTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/MonitoringAsyncClientTest.java @@ -29,8 +29,12 @@ import java.io.IOException; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.net.URI; +import java.util.Map; + +import javax.inject.Singleton; import org.jclouds.aws.ec2.EC2; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.filters.FormSigner; import org.jclouds.aws.ec2.xml.MonitoringStateHandler; import org.jclouds.aws.reference.AWSConstants; @@ -44,6 +48,7 @@ import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.util.Jsr330; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableMap; import com.google.inject.AbstractModule; import com.google.inject.Module; import com.google.inject.Provides; @@ -59,10 +64,10 @@ public class MonitoringAsyncClientTest extends RestClientTest httpMethod = processor.createRequest(method, - "instance1", "instance2"); + Region.DEFAULT, "instance1", "instance2"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -77,12 +82,11 @@ public class MonitoringAsyncClientTest extends RestClientTest httpMethod = processor.createRequest(method, - "instance1", "instance2"); + Region.DEFAULT, "instance1", "instance2"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -96,6 +100,7 @@ public class MonitoringAsyncClientTest extends RestClientTest httpMethod) { assertEquals(httpMethod.getFilters().size(), 1); @@ -132,6 +137,16 @@ public class MonitoringAsyncClientTest extends RestClientTest provideMap() { + return ImmutableMap. of(Region.DEFAULT, URI.create("https://booya"), + Region.EU_WEST_1, URI.create("https://ec2.eu-west-1.amazonaws.com"), + Region.US_EAST_1, URI.create("https://ec2.us-east-1.amazonaws.com"), + Region.US_WEST_1, URI.create("https://ec2.us-west-1.amazonaws.com")); + } }; } } diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/MonitoringClientLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/MonitoringClientLiveTest.java index 9646b5a466..ac131df912 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/services/MonitoringClientLiveTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/MonitoringClientLiveTest.java @@ -32,6 +32,7 @@ import org.jclouds.aws.ec2.EC2AsyncClient; import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2ContextFactory; import org.jclouds.aws.ec2.domain.MonitoringState; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.rest.RestContext; import org.testng.annotations.BeforeGroups; @@ -61,14 +62,16 @@ public class MonitoringClientLiveTest { @Test(enabled = false) // TODO get instance public void testMonitorInstances() { - Map monitoringState = client.monitorInstances(DEFAULT_INSTANCE); + Map monitoringState = client.monitorInstancesInRegion( + Region.DEFAULT, DEFAULT_INSTANCE); assertEquals(monitoringState.get(DEFAULT_INSTANCE), MonitoringState.PENDING); } @Test(enabled = false) // TODO get instance public void testUnmonitorInstances() { - Map monitoringState = client.unmonitorInstances(DEFAULT_INSTANCE); + Map monitoringState = client.unmonitorInstancesInRegion( + Region.DEFAULT, DEFAULT_INSTANCE); assertEquals(monitoringState.get(DEFAULT_INSTANCE), MonitoringState.PENDING); } diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/SecurityGroupAsyncClientTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/SecurityGroupAsyncClientTest.java index 616f2ab73b..9f99223d5a 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/services/SecurityGroupAsyncClientTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/SecurityGroupAsyncClientTest.java @@ -29,9 +29,13 @@ import java.io.IOException; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.net.URI; +import java.util.Map; + +import javax.inject.Singleton; import org.jclouds.aws.ec2.EC2; import org.jclouds.aws.ec2.domain.IpProtocol; +import org.jclouds.aws.ec2.domain.Region; import org.jclouds.aws.ec2.domain.UserIdGroupPair; import org.jclouds.aws.ec2.filters.FormSigner; import org.jclouds.aws.ec2.functions.ReturnVoidOnGroupNotFound; @@ -48,6 +52,7 @@ import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.util.Jsr330; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableMap; import com.google.inject.AbstractModule; import com.google.inject.Module; import com.google.inject.Provides; @@ -63,9 +68,10 @@ public class SecurityGroupAsyncClientTest extends RestClientTest httpMethod = processor.createRequest(method, - "name"); + Region.DEFAULT, "name"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -82,16 +88,16 @@ public class SecurityGroupAsyncClientTest extends RestClientTest httpMethod = processor.createRequest(method, - "name", "description"); + Region.DEFAULT, "name", "description"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, "Content-Length: 89\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); assertPayloadEquals(httpMethod, - "Version=2009-11-30&Action=CreateSecurityGroup&GroupName=name&GroupDescription=description"); + "Version=2009-11-30&Action=CreateSecurityGroup&GroupDescription=description&GroupName=name"); assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); assertSaxResponseParserClassEquals(method, null); @@ -102,9 +108,10 @@ public class SecurityGroupAsyncClientTest extends RestClientTest httpMethod = processor.createRequest(method); + Method method = SecurityGroupAsyncClient.class.getMethod("describeSecurityGroupsInRegion", + Region.class, Array.newInstance(String.class, 0).getClass()); + GeneratedHttpRequest httpMethod = processor.createRequest(method, + Region.DEFAULT); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -120,10 +127,10 @@ public class SecurityGroupAsyncClientTest extends RestClientTest httpMethod = processor.createRequest(method, - "1", "2"); + Region.DEFAULT, "1", "2"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -140,10 +147,11 @@ public class SecurityGroupAsyncClientTest extends RestClientTest httpMethod = processor.createRequest(method, - "group", new UserIdGroupPair("sourceUser", "sourceGroup")); + Region.DEFAULT, "group", new UserIdGroupPair("sourceUser", "sourceGroup")); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -161,17 +169,18 @@ public class SecurityGroupAsyncClientTest extends RestClientTest httpMethod = processor.createRequest(method, - "group", IpProtocol.TCP, 6000, 7000, "0.0.0.0/0"); + Region.DEFAULT, "group", IpProtocol.TCP, 6000, 7000, "0.0.0.0/0"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, "Content-Length: 131\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); assertPayloadEquals( httpMethod, - "Version=2009-11-30&Action=AuthorizeSecurityGroupIngress&GroupName=group&FromPort=6000&IpProtocol=tcp&ToPort=7000&CidrIp=0.0.0.0%2F0"); + "Version=2009-11-30&Action=AuthorizeSecurityGroupIngress&CidrIp=0.0.0.0%2F0&IpProtocol=tcp&GroupName=group&FromPort=6000&ToPort=7000"); assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); assertSaxResponseParserClassEquals(method, null); @@ -182,10 +191,11 @@ public class SecurityGroupAsyncClientTest extends RestClientTest httpMethod = processor.createRequest(method, - "group", new UserIdGroupPair("sourceUser", "sourceGroup")); + Region.DEFAULT, "group", new UserIdGroupPair("sourceUser", "sourceGroup")); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, @@ -203,17 +213,18 @@ public class SecurityGroupAsyncClientTest extends RestClientTest httpMethod = processor.createRequest(method, - "group", IpProtocol.TCP, 6000, 7000, "0.0.0.0/0"); + Region.DEFAULT, "group", IpProtocol.TCP, 6000, 7000, "0.0.0.0/0"); assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1"); assertHeadersEqual(httpMethod, "Content-Length: 128\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n"); assertPayloadEquals( httpMethod, - "Version=2009-11-30&Action=RevokeSecurityGroupIngress&GroupName=group&FromPort=6000&IpProtocol=tcp&ToPort=7000&CidrIp=0.0.0.0%2F0"); + "Version=2009-11-30&Action=RevokeSecurityGroupIngress&CidrIp=0.0.0.0%2F0&IpProtocol=tcp&GroupName=group&FromPort=6000&ToPort=7000"); assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class); assertSaxResponseParserClassEquals(method, null); @@ -258,6 +269,16 @@ public class SecurityGroupAsyncClientTest extends RestClientTest provideMap() { + return ImmutableMap. of(Region.DEFAULT, URI.create("https://booya"), + Region.EU_WEST_1, URI.create("https://ec2.eu-west-1.amazonaws.com"), + Region.US_EAST_1, URI.create("https://ec2.us-east-1.amazonaws.com"), + Region.US_WEST_1, URI.create("https://ec2.us-west-1.amazonaws.com")); + } }; } } diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/SecurityGroupClientLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/SecurityGroupClientLiveTest.java new file mode 100644 index 0000000000..8cb1ccb849 --- /dev/null +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/SecurityGroupClientLiveTest.java @@ -0,0 +1,278 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ +package org.jclouds.aws.ec2.services; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +import java.util.Iterator; +import java.util.Set; +import java.util.SortedSet; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + +import org.jclouds.aws.ec2.EC2AsyncClient; +import org.jclouds.aws.ec2.EC2Client; +import org.jclouds.aws.ec2.EC2ContextFactory; +import org.jclouds.aws.ec2.domain.IpPermission; +import org.jclouds.aws.ec2.domain.IpProtocol; +import org.jclouds.aws.ec2.domain.Region; +import org.jclouds.aws.ec2.domain.SecurityGroup; +import org.jclouds.aws.ec2.domain.UserIdGroupPair; +import org.jclouds.logging.log4j.config.Log4JLoggingModule; +import org.jclouds.rest.RestContext; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeGroups; +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 SecurityGroupClient} + * + * @author Adrian Cole + */ +@Test(groups = "live", sequential = true, testName = "ec2.SecurityGroupClientLiveTest") +public class SecurityGroupClientLiveTest { + + private SecurityGroupClient client; + private RestContext context; + + @BeforeGroups(groups = { "live" }) + public void setupClient() { + String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); + String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); + + context = EC2ContextFactory.createContext(user, password, new Log4JLoggingModule()); + client = context.getApi().getSecurityGroupServices(); + } + + @Test + void testDescribe() { + for (Region region : ImmutableSet.of(Region.DEFAULT, Region.EU_WEST_1, Region.US_EAST_1, + Region.US_WEST_1)) { + SortedSet allResults = Sets.newTreeSet(client + .describeSecurityGroupsInRegion(region)); + assertNotNull(allResults); + if (allResults.size() >= 1) { + SecurityGroup group = allResults.last(); + SortedSet result = Sets.newTreeSet(client + .describeSecurityGroupsInRegion(region, group.getName())); + assertNotNull(result); + SecurityGroup compare = result.last(); + assertEquals(compare, group); + } + } + } + + @Test + void testCreateSecurityGroup() { + String groupName = PREFIX + "1"; + String groupDescription = PREFIX + "1 description"; + try { + client.deleteSecurityGroupInRegion(Region.DEFAULT, groupName); + } catch (Exception e) { + + } + client.deleteSecurityGroupInRegion(Region.DEFAULT, groupName); + + client.createSecurityGroupInRegion(Region.DEFAULT, groupName, groupDescription); + + verifySecurityGroup(groupName, groupDescription); + } + + @Test + void testAuthorizeSecurityGroupIngressCidr() throws InterruptedException, ExecutionException, + TimeoutException { + String groupName = PREFIX + "ingress"; + + try { + client.deleteSecurityGroupInRegion(Region.DEFAULT, groupName); + } catch (Exception e) { + } + + client.createSecurityGroupInRegion(Region.DEFAULT, groupName, groupName); + client.authorizeSecurityGroupIngressInRegion(Region.DEFAULT, groupName, IpProtocol.TCP, 80, + 80, "0.0.0.0/0"); + assertEventually(new GroupHasPermission(client, groupName, new IpPermission(80, 80, Sets + . newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0")))); + + client.revokeSecurityGroupIngressInRegion(Region.DEFAULT, groupName, IpProtocol.TCP, 80, 80, + "0.0.0.0/0"); + assertEventually(new GroupHasNoPermissions(client, groupName)); + + } + + private void verifySecurityGroup(String groupName, String description) { + SortedSet oneResult = client.describeSecurityGroupsInRegion(Region.DEFAULT, + groupName); + 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 { + String group1Name = PREFIX + "ingress1"; + String group2Name = PREFIX + "ingress2"; + + try { + client.deleteSecurityGroupInRegion(Region.DEFAULT, group1Name); + } catch (Exception e) { + + } + try { + client.deleteSecurityGroupInRegion(Region.DEFAULT, group2Name); + } catch (Exception e) { + + } + + client.createSecurityGroupInRegion(Region.DEFAULT, group1Name, group1Name); + client.createSecurityGroupInRegion(Region.DEFAULT, group2Name, group2Name); + ensureGroupsExist(group1Name, group2Name); + client.authorizeSecurityGroupIngressInRegion(Region.DEFAULT, group1Name, IpProtocol.TCP, 80, + 80, "0.0.0.0/0"); + assertEventually(new GroupHasPermission(client, group2Name, new IpPermission(80, 80, Sets + . newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0")))); + + SortedSet oneResult = client.describeSecurityGroupsInRegion(Region.DEFAULT, + group1Name); + assertNotNull(oneResult); + assertEquals(oneResult.size(), 1); + SecurityGroup group = oneResult.iterator().next(); + assertEquals(group.getName(), group1Name); + + client.authorizeSecurityGroupIngressInRegion(Region.DEFAULT, group2Name, new UserIdGroupPair( + group.getOwnerId(), group1Name)); + assertEventually(new GroupHasPermission(client, group2Name, new IpPermission(80, 80, Sets + . newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0")))); + + client.revokeSecurityGroupIngressInRegion(Region.DEFAULT, group2Name, new UserIdGroupPair( + group.getOwnerId(), group1Name)); + assertEventually(new GroupHasNoPermissions(client, group2Name)); + } + + private static final class GroupHasPermission implements Runnable { + private final SecurityGroupClient client; + private final String group; + private final IpPermission permission; + + private GroupHasPermission(SecurityGroupClient client, String group, IpPermission permission) { + this.client = client; + this.group = group; + this.permission = permission; + } + + public void run() { + try { + SortedSet oneResult = client.describeSecurityGroupsInRegion( + Region.DEFAULT, group); + 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 SecurityGroupClient client; + private final String group; + + private GroupHasNoPermissions(SecurityGroupClient client, String group) { + this.client = client; + this.group = group; + } + + public void run() { + try { + Set oneResult = client.describeSecurityGroupsInRegion(Region.DEFAULT, + group); + 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) { + SortedSet twoResults = client.describeSecurityGroupsInRegion(Region.DEFAULT, + group1Name, group2Name); + assertNotNull(twoResults); + assertEquals(twoResults.size(), 2); + Iterator 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; + + } + + public static final String PREFIX = System.getProperty("user.name") + "-ec2"; + + @AfterTest + public void shutdown() { + context.close(); + } +} diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/xml/DescribeAddressesResponseHandlerTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/xml/DescribeAddressesResponseHandlerTest.java index d9c2bf6597..a1fcff7f08 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/xml/DescribeAddressesResponseHandlerTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/xml/DescribeAddressesResponseHandlerTest.java @@ -28,13 +28,13 @@ import static org.testng.Assert.assertEquals; import java.io.InputStream; import java.net.InetAddress; import java.net.UnknownHostException; -import java.util.SortedSet; +import java.util.Set; import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair; import org.jclouds.http.functions.BaseHandlerTest; import org.testng.annotations.Test; -import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.ImmutableList; /** * Tests behavior of {@code DescribeAddressesResponseHandler} @@ -47,11 +47,11 @@ public class DescribeAddressesResponseHandlerTest extends BaseHandlerTest { InputStream is = getClass().getResourceAsStream("/ec2/describe_addresses.xml"); - SortedSet result = factory.create( + Set result = factory.create( injector.getInstance(DescribeAddressesResponseHandler.class)).parse(is); - assertEquals(result, ImmutableSortedSet.of(new PublicIpInstanceIdPair(InetAddress - .getByName("67.202.55.233"), null), new PublicIpInstanceIdPair(InetAddress - .getByName("67.202.55.255"), "i-f15ebb98"))); + assertEquals(result, ImmutableList.of(new PublicIpInstanceIdPair(InetAddress + .getByName("67.202.55.255"), "i-f15ebb98"), new PublicIpInstanceIdPair(InetAddress + .getByName("67.202.55.233"), null))); } } diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/xml/DescribeKeyPairsResponseHandlerTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/xml/DescribeKeyPairsResponseHandlerTest.java index 5d30ba3361..0fb28d7a46 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/xml/DescribeKeyPairsResponseHandlerTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/xml/DescribeKeyPairsResponseHandlerTest.java @@ -26,13 +26,13 @@ package org.jclouds.aws.ec2.xml; import static org.testng.Assert.assertEquals; import java.io.InputStream; -import java.util.SortedSet; +import java.util.Set; import org.jclouds.aws.ec2.domain.KeyPair; import org.jclouds.http.functions.BaseHandlerTest; import org.testng.annotations.Test; -import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.ImmutableSet; /** * Tests behavior of {@code DescribeKeyPairsHandler} @@ -45,10 +45,10 @@ public class DescribeKeyPairsResponseHandlerTest extends BaseHandlerTest { InputStream is = getClass().getResourceAsStream("/ec2/describe_keypairs.xml"); - SortedSet expected = ImmutableSortedSet.of(new KeyPair("gsg-keypair", + Set expected = ImmutableSet.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 result = factory.create( + Set result = factory.create( injector.getInstance(DescribeKeyPairsResponseHandler.class)).parse(is); assertEquals(result, expected); diff --git a/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java b/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java index 4101cea4ce..d94fcd2bf2 100755 --- a/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java +++ b/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java @@ -756,7 +756,8 @@ public class RestAnnotationProcessor { boolean shouldBreak = false; BinderParam payloadAnnotation = (BinderParam) entry.getValue().iterator().next(); Binder binder = injector.getInstance(payloadAnnotation.value()); - if (request.getArgs().length != 0) { + if (request.getArgs().length >= entry.getKey() + 1 + && request.getArgs()[entry.getKey()] != null) { Object input; Class parameterType = request.getJavaMethod().getParameterTypes()[entry.getKey()]; Class argType = request.getArgs()[entry.getKey()].getClass(); diff --git a/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java b/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java index f9ba4f088e..d1984a182f 100755 --- a/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java +++ b/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java @@ -44,6 +44,7 @@ import java.util.Date; import java.util.Map; import java.util.concurrent.Future; +import javax.annotation.Nullable; import javax.inject.Named; import javax.inject.Qualifier; import javax.ws.rs.Consumes; @@ -339,7 +340,7 @@ public class RestAnnotationProcessorTest { @Endpoint(Localhost.class) public class TestPost { @POST - public void post(@BinderParam(BindToStringPayload.class) String content) { + public void post(@Nullable @BinderParam(BindToStringPayload.class) String content) { } @POST @@ -361,8 +362,7 @@ public class RestAnnotationProcessorTest { public void testCreatePostRequest() throws SecurityException, NoSuchMethodException { Method method = TestPost.class.getMethod("post", String.class); - GeneratedHttpRequest httpMethod = factory(TestPost.class).createRequest(method, - new Object[] { "data" }); + GeneratedHttpRequest httpMethod = factory(TestPost.class).createRequest(method, "data"); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), ""); assertEquals(httpMethod.getMethod(), HttpMethod.POST); @@ -374,6 +374,19 @@ public class RestAnnotationProcessorTest { assertEquals(httpMethod.getPayload().toString(), "data"); } + public void testCreatePostRequestNullOk() throws SecurityException, NoSuchMethodException { + Method method = TestPost.class.getMethod("post", String.class); + GeneratedHttpRequest httpMethod = factory(TestPost.class).createRequest(method, + new Object[] { null }); + assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); + assertEquals(httpMethod.getEndpoint().getPath(), ""); + assertEquals(httpMethod.getMethod(), HttpMethod.POST); + assertEquals(httpMethod.getHeaders().size(), 0); + assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE).size(), 0); + assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH).size(), 0); + assertEquals(httpMethod.getPayload(), null); + } + public void testCreatePostJsonRequest() throws SecurityException, NoSuchMethodException { Method method = TestPost.class.getMethod("postAsJson", String.class); GeneratedHttpRequest httpMethod = factory(TestPost.class).createRequest(method,