This is an automated email from the ASF dual-hosted git repository. gaul pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/jclouds.git
commit b979e15529968aad9fd4b309da1c54eba0ec2162 Author: Gary Teichrow <[email protected]> AuthorDate: Mon Oct 7 15:01:02 2024 -0700 Added allocationId to PublicIpInstanceIdPair so that IP addresses can be tracked by that AWS concept. Added a releaseAddressInRegionByAllocationId so that an IP address can be released by that addresses AllocationId Modified the DescribeAddressesResponseHandler so that it can optionally take allocationId into account on a Describe Added a use case to test allocationId --- .../loaders/LoadAllocationIdForInstanceOrNull.java | 55 ++++++++++++++++++++++ .../jclouds/ec2/domain/PublicIpInstanceIdPair.java | 17 ++++++- .../jclouds/ec2/features/ElasticIPAddressApi.java | 22 +++++++++ .../ec2/xml/DescribeAddressesResponseHandler.java | 6 ++- .../loaders/LoadPublicIpForInstanceOrNullTest.java | 25 +++++++++- .../xml/DescribeAddressesResponseHandlerTest.java | 8 ++-- 6 files changed, 125 insertions(+), 8 deletions(-) diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/loaders/LoadAllocationIdForInstanceOrNull.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/loaders/LoadAllocationIdForInstanceOrNull.java new file mode 100644 index 0000000000..43e9690cf9 --- /dev/null +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/loaders/LoadAllocationIdForInstanceOrNull.java @@ -0,0 +1,55 @@ +/* + * 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.ec2.compute.loaders; + +import com.google.common.base.Predicate; +import com.google.common.cache.CacheLoader; +import com.google.common.collect.Iterables; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import org.jclouds.ec2.EC2Api; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.domain.PublicIpInstanceIdPair; + +import java.util.NoSuchElementException; + +@Singleton +public class LoadAllocationIdForInstanceOrNull extends CacheLoader<RegionAndName, String> { + private final EC2Api client; + + @Inject + public LoadAllocationIdForInstanceOrNull(EC2Api client) { + this.client = client; + } + + @Override + public String load(final RegionAndName key) throws Exception { + try { + return Iterables.find(client.getElasticIPAddressApi().get().describeAddressesInRegion(key.getRegion()), + new Predicate<PublicIpInstanceIdPair>() { + + @Override + public boolean apply(PublicIpInstanceIdPair input) { + return key.getName().equals(input.getInstanceId()); + } + + }).getAllocationId(); + } catch (NoSuchElementException e) { + return null; + } + } +} 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 f2f673edd1..be1d3894bd 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<PublicIpInstanceIdPair private final String region; @Nullable private final String instanceId; + private final String allocationId; private final String publicIp; private final Map<String, String> tags; public PublicIpInstanceIdPair(final String region, final String publicIp, @Nullable final String instanceId, - @Nullable final Map<String, String> tags) { + @Nullable final String allocationId, @Nullable final Map<String, String> tags) { this.region = checkNotNull(region, "region"); this.instanceId = instanceId; + this.allocationId = allocationId; this.publicIp = checkNotNull(publicIp, "publicIp"); this.tags = tags == null ? ImmutableMap.<String, String> of() : ImmutableMap.copyOf(tags); } @@ -71,6 +73,13 @@ public class PublicIpInstanceIdPair implements Comparable<PublicIpInstanceIdPair 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 class PublicIpInstanceIdPair implements Comparable<PublicIpInstanceIdPair 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 class PublicIpInstanceIdPair implements Comparable<PublicIpInstanceIdPair 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 a02f8f2c87..fc8222d14f 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 @@ public interface ElasticIPAddressApi { @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 <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-ReleaseAddress.html" + */ + @Named("ReleaseAddress") + @POST + @Path("/") + @FormParams(keys = ACTION, values = "ReleaseAddress") + void releaseAddressInRegionByAllocationId( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @FormParam("AllocationId") String allocationId); + /** * Lists elastic IP addresses assigned to your identity or provides information about a specific * address. diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeAddressesResponseHandler.java b/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeAddressesResponseHandler.java index 3f6a9a5f86..0a2c7fd753 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeAddressesResponseHandler.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeAddressesResponseHandler.java @@ -44,6 +44,7 @@ public class DescribeAddressesResponseHandler extends HandlerForGeneratedRequest @Inject @Region Supplier<String> defaultRegion; + private String allocationId; private String instanceId; private final TagSetHandler tagSetHandler; private boolean inTagSet; @@ -80,14 +81,17 @@ public class DescribeAddressesResponseHandler extends HandlerForGeneratedRequest 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 c4dd09e25f..27be60fd92 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 class LoadPublicIpForInstanceOrNullTest { expect(client.getElasticIPAddressApi()).andReturn((Optional) Optional.of(ipClient)).atLeastOnce(); expect(ipClient.describeAddressesInRegion("region")).andReturn( - ImmutableSet.<PublicIpInstanceIdPair> of(new PublicIpInstanceIdPair("region", "1.1.1.1", "i-blah", null))) + ImmutableSet.<PublicIpInstanceIdPair> of(new PublicIpInstanceIdPair("region", "1.1.1.1", "i-blah", null, null))) .atLeastOnce(); replay(client); @@ -55,6 +55,27 @@ public class LoadPublicIpForInstanceOrNullTest { verify(ipClient); } + @Test + public void testReturnsPublicIpAndAllocIdOnMatch() throws Exception { + EC2Api client = createMock(EC2Api.class); + ElasticIPAddressApi ipClient = createMock(ElasticIPAddressApi.class); + + expect(client.getElasticIPAddressApi()).andReturn((Optional) Optional.of(ipClient)).atLeastOnce(); + expect(ipClient.describeAddressesInRegion("region")).andReturn( + ImmutableSet.<PublicIpInstanceIdPair> of(new PublicIpInstanceIdPair("region", "1.1.1.1", "i-blah", "a-foobar", null))) + .atLeastOnce(); + + replay(client); + replay(ipClient); + + LoadAllocationIdForInstanceOrNull parser = new LoadAllocationIdForInstanceOrNull(client); + + assertEquals(parser.load(new RegionAndName("region", "i-blah")), "a-foobar"); + + verify(client); + verify(ipClient); + } + @Test public void testReturnsNullWhenNotFound() throws Exception { EC2Api client = createMock(EC2Api.class); @@ -85,7 +106,7 @@ public class LoadPublicIpForInstanceOrNullTest { expect(client.getElasticIPAddressApi()).andReturn((Optional) Optional.of(ipClient)).atLeastOnce(); expect(ipClient.describeAddressesInRegion("region")).andReturn( - ImmutableSet.<PublicIpInstanceIdPair> of(new PublicIpInstanceIdPair("region", "1.1.1.1", null, null))) + ImmutableSet.<PublicIpInstanceIdPair> 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 b9684d0870..060a23dc1b 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 @@ -47,7 +47,7 @@ public class DescribeAddressesResponseHandlerTest extends BaseEC2HandlerTest { Set<PublicIpInstanceIdPair> result = factory.create(handler).parse(is); assertEquals(result, ImmutableSet.of(new PublicIpInstanceIdPair(defaultRegion, "67.202.55.255", "i-f15ebb98", - Collections.<String, String> emptyMap()), new PublicIpInstanceIdPair(defaultRegion, "67.202.55.233", null, + null, Collections.<String, String> emptyMap()), new PublicIpInstanceIdPair(defaultRegion, "67.202.55.233", null, null, Collections.<String, String> emptyMap()))); } @@ -62,9 +62,9 @@ public class DescribeAddressesResponseHandlerTest extends BaseEC2HandlerTest { assertEquals(result.size(), 3); assertEquals(result, ImmutableSet.of(new PublicIpInstanceIdPair(defaultRegion, "67.202.55.255", "i-f15ebb98", - Collections.<String, String> emptyMap()), new PublicIpInstanceIdPair(defaultRegion, "67.202.55.233", null, - Collections.<String, String> emptyMap()), new PublicIpInstanceIdPair(defaultRegion, "54.76.27.192", null, - ImmutableMap.of("Name", "value-fa97d19c", "Empty", "")))); + null, Collections.<String, String> emptyMap()), new PublicIpInstanceIdPair(defaultRegion, "67.202.55.233", null, + null, Collections.<String, String> emptyMap()), new PublicIpInstanceIdPair(defaultRegion, "54.76.27.192", null, + null, ImmutableMap.of("Name", "value-fa97d19c", "Empty", "")))); } private void addDefaultRegionToHandler(final ParseSax.HandlerWithResult<?> handler) {
