diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/PublicIpInstanceIdPair.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/PublicIpInstanceIdPair.java index f2f673edd1e..be1d3894bd3 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/PublicIpInstanceIdPair.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/domain/PublicIpInstanceIdPair.java @@ -34,13 +34,15 @@ public class PublicIpInstanceIdPair implements Comparable tags; public PublicIpInstanceIdPair(final String region, final String publicIp, @Nullable final String instanceId, - @Nullable final Map tags) { + @Nullable final String allocationId, @Nullable final Map tags) { this.region = checkNotNull(region, "region"); this.instanceId = instanceId; + this.allocationId = allocationId; this.publicIp = checkNotNull(publicIp, "publicIp"); this.tags = tags == null ? ImmutableMap. of() : ImmutableMap.copyOf(tags); } @@ -71,6 +73,13 @@ public String getInstanceId() { return instanceId; } + /** + * The ID of the IP allocation (e.g., eipalloc-0ca038968f2a2c986). + */ + public String getAllocationId() { + return allocationId; + } + /** * The public IP address. */ @@ -87,6 +96,7 @@ public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode()); + result = prime * result + ((allocationId == null) ? 0 : allocationId.hashCode()); result = prime * result + ((publicIp == null) ? 0 : publicIp.hashCode()); result = prime * result + ((region == null) ? 0 : region.hashCode()); result = prime * result + ((tags == null) ? 0 : tags.hashCode()); @@ -107,6 +117,11 @@ public boolean equals(Object obj) { return false; } else if (!instanceId.equals(other.instanceId)) return false; + if (allocationId == null) { + if (other.allocationId != null) + return false; + } else if (!allocationId.equals(other.allocationId)) + return false; if (publicIp == null) { if (other.publicIp != null) return false; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/features/ElasticIPAddressApi.java b/apis/ec2/src/main/java/org/jclouds/ec2/features/ElasticIPAddressApi.java index a02f8f2c87d..fc8222d14f3 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/features/ElasticIPAddressApi.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/features/ElasticIPAddressApi.java @@ -144,6 +144,28 @@ void releaseAddressInRegion( @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("PublicIp") String publicIp); + /** + * Releases an elastic IP address associated with your identity. + * + * @param region + * Elastic IP addresses are tied to a Region and cannot be mapped across Regions. + * @param allocationId + * The Allocation ID (e.g., eipalloc-0ca038968f2a2c986) of the IP address that you are releasing from your identity. + * + * @see #allocateAddress + * @see #describeAddresses + * @see #associateAddress + * @see #disassociateAddress + * @see defaultRegion; + private String allocationId; private String instanceId; private final TagSetHandler tagSetHandler; private boolean inTagSet; @@ -80,14 +81,17 @@ public void endElement(final String uri, final String name, final String qName) ipAddress = currentOrNull(); } else if (qName.equals("instanceId")) { instanceId = currentOrNull(); + } else if (qName.equals("allocationId")) { + allocationId = currentOrNull(); } else if (qName.equals("item")) { String region = AWSUtils.findRegionInArgsOrNull(getRequest()); if (region == null) region = defaultRegion.get(); - pairs.add(new PublicIpInstanceIdPair(region, ipAddress, instanceId, tagResults)); + pairs.add(new PublicIpInstanceIdPair(region, ipAddress, instanceId, allocationId, tagResults)); ipAddress = null; instanceId = null; + allocationId = null; tagResults = null; } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/LoadPublicIpForInstanceOrNullTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/LoadPublicIpForInstanceOrNullTest.java index c4dd09e25f1..6b77f8d2ffc 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/LoadPublicIpForInstanceOrNullTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/LoadPublicIpForInstanceOrNullTest.java @@ -41,7 +41,7 @@ public void testReturnsPublicIpOnMatch() throws Exception { expect(client.getElasticIPAddressApi()).andReturn((Optional) Optional.of(ipClient)).atLeastOnce(); expect(ipClient.describeAddressesInRegion("region")).andReturn( - ImmutableSet. of(new PublicIpInstanceIdPair("region", "1.1.1.1", "i-blah", null))) + ImmutableSet. of(new PublicIpInstanceIdPair("region", "1.1.1.1", "i-blah", null, null))) .atLeastOnce(); replay(client); @@ -85,7 +85,7 @@ public void testReturnsNullWhenNotAssigned() throws Exception { expect(client.getElasticIPAddressApi()).andReturn((Optional) Optional.of(ipClient)).atLeastOnce(); expect(ipClient.describeAddressesInRegion("region")).andReturn( - ImmutableSet. of(new PublicIpInstanceIdPair("region", "1.1.1.1", null, null))) + ImmutableSet. of(new PublicIpInstanceIdPair("region", "1.1.1.1", null, null, null))) .atLeastOnce(); replay(client); diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeAddressesResponseHandlerTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeAddressesResponseHandlerTest.java index b9684d08709..3099f678c48 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeAddressesResponseHandlerTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeAddressesResponseHandlerTest.java @@ -46,8 +46,8 @@ public void testApplyInputStream() throws UnknownHostException { Set result = factory.create(handler).parse(is); - assertEquals(result, ImmutableSet.of(new PublicIpInstanceIdPair(defaultRegion, "67.202.55.255", "i-f15ebb98", - Collections. emptyMap()), new PublicIpInstanceIdPair(defaultRegion, "67.202.55.233", null, + assertEquals(result, ImmutableSet.of(new PublicIpInstanceIdPair(defaultRegion, "67.202.55.255", "i-f15ebb98", "eipalloc-0ca038968f2a2c986", + Collections. emptyMap()), new PublicIpInstanceIdPair(defaultRegion, "67.202.55.233", null, null, Collections. emptyMap()))); } @@ -61,9 +61,9 @@ public void testApplyInputStreamWithTags() throws UnknownHostException { Set result = factory.create(handler).parse(is); assertEquals(result.size(), 3); - assertEquals(result, ImmutableSet.of(new PublicIpInstanceIdPair(defaultRegion, "67.202.55.255", "i-f15ebb98", - Collections. emptyMap()), new PublicIpInstanceIdPair(defaultRegion, "67.202.55.233", null, - Collections. emptyMap()), new PublicIpInstanceIdPair(defaultRegion, "54.76.27.192", null, + assertEquals(result, ImmutableSet.of(new PublicIpInstanceIdPair(defaultRegion, "67.202.55.255", "i-f15ebb98", "eipalloc-0ca038968f2a2c986", + Collections. emptyMap()), new PublicIpInstanceIdPair(defaultRegion, "67.202.55.233", null, null, + Collections. emptyMap()), new PublicIpInstanceIdPair(defaultRegion, "54.76.27.192", null, null, ImmutableMap.of("Name", "value-fa97d19c", "Empty", "")))); } diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/RouteTableApi.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/RouteTableApi.java index 9a37850a2be..bfadd37fe7a 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/RouteTableApi.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/RouteTableApi.java @@ -33,6 +33,7 @@ import org.jclouds.aws.ec2.xml.DescribeRouteTablesResponseHandler; import org.jclouds.aws.ec2.xml.ReturnValueHandler; import org.jclouds.aws.filters.FormSigner; +import org.jclouds.ec2.binders.BindFiltersToIndexedFormParams; import org.jclouds.javax.annotation.Nullable; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.rest.annotations.BinderParam; @@ -44,6 +45,7 @@ import org.jclouds.rest.annotations.XMLResponseParser; import com.google.common.collect.FluentIterable; +import com.google.common.collect.Multimap; /** * Provides access to AWS Route Table services. @@ -267,6 +269,10 @@ boolean deleteRoute( /** * Describes route tables. * @param region The region to search for route tables. + * @param routeTableIds One or more identifiers for existing RouteTable instances + * + * @return a set of RouteTable objects that matched the routeTableIds passed + * */ @Named("DescribeRouteTables") @POST @@ -276,4 +282,21 @@ boolean deleteRoute( FluentIterable describeRouteTables( @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @BinderParam(BindRouteTableIdsToIndexedFormParams.class) String... routeTableIds); + + /** + * Describes route tables. + * @param region The region to search for route tables. + * @param filter One or more filters utilized to search for RouteTable instances + * + * @link ... + */ + @Named("DescribeRouteTables") + @POST + @FormParams(keys = ACTION, values = "DescribeRouteTables") + @XMLResponseParser(DescribeRouteTablesResponseHandler.class) + @Fallback(Fallbacks.EmptyFluentIterableOnNotFoundOr404.class) + FluentIterable describeRouteTablesWithFilter( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @BinderParam(BindFiltersToIndexedFormParams.class) Multimap filter); + } diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/RouteTableApiLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/RouteTableApiLiveTest.java index 3c579840fd1..b05060d51f3 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/RouteTableApiLiveTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/RouteTableApiLiveTest.java @@ -48,6 +48,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; +import com.google.common.collect.ImmutableMultimap; /** * Tests behavior of {@link RouteTableApi} @@ -106,6 +107,22 @@ public void testDescribe() { } }); assertTrue(vpcRT.isPresent(), "Could not find VPC " + vpc.id() + " in described route tables"); + + //Now test the Find by Filter version of the describeRouteTables + final FluentIterable routeTablesByFilter = routeTableApi.describeRouteTablesWithFilter(TEST_REGION, + ImmutableMultimap.builder() + .put("vpc-id", vpc.id()) + .build() + ); + assertNotNull(routeTablesByFilter, "Failed to return list of routeTablesByFilter"); + Optional vpcRTByFilter = Iterables.tryFind(routeTablesByFilter, new Predicate() { + @Override public boolean apply(RouteTable input) { + return vpc.id().equals(input.vpcId()); + } + }); + assertTrue(vpcRTByFilter.isPresent(), "Could not find VPC " + vpc.id() + " in described route tables"); + + RouteTable rt = vpcRT.get(); assertEquals(rt.associationSet().size(), 1, "Route for test VPC has wrong number of associations, should be 1: " + rt.associationSet());