Issue 29: elastic ip support

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2269 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-11-12 18:49:38 +00:00
parent fedf3ac2cd
commit ba60357f21
15 changed files with 730 additions and 16 deletions

View File

@ -26,6 +26,7 @@ package org.jclouds.aws.ec2;
import static org.jclouds.aws.ec2.reference.EC2Parameters.ACTION; import static org.jclouds.aws.ec2.reference.EC2Parameters.ACTION;
import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION; import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION;
import java.net.InetAddress;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -34,6 +35,7 @@ import javax.ws.rs.POST;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import org.jclouds.aws.ec2.binders.BindGroupNameToIndexedFormParams; import org.jclouds.aws.ec2.binders.BindGroupNameToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindInetAddressesToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindInstanceIdsToIndexedFormParams; import org.jclouds.aws.ec2.binders.BindInstanceIdsToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindKeyNameToIndexedFormParams; import org.jclouds.aws.ec2.binders.BindKeyNameToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindUserIdGroupPairToSourceSecurityGroupFormParams; import org.jclouds.aws.ec2.binders.BindUserIdGroupPairToSourceSecurityGroupFormParams;
@ -41,14 +43,18 @@ import org.jclouds.aws.ec2.domain.Image;
import org.jclouds.aws.ec2.domain.ImageAttribute; import org.jclouds.aws.ec2.domain.ImageAttribute;
import org.jclouds.aws.ec2.domain.IpProtocol; import org.jclouds.aws.ec2.domain.IpProtocol;
import org.jclouds.aws.ec2.domain.KeyPair; 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.Reservation;
import org.jclouds.aws.ec2.domain.SecurityGroup; import org.jclouds.aws.ec2.domain.SecurityGroup;
import org.jclouds.aws.ec2.domain.TerminatedInstance; import org.jclouds.aws.ec2.domain.TerminatedInstance;
import org.jclouds.aws.ec2.domain.UserIdGroupPair; import org.jclouds.aws.ec2.domain.UserIdGroupPair;
import org.jclouds.aws.ec2.filters.FormSigner; import org.jclouds.aws.ec2.filters.FormSigner;
import org.jclouds.aws.ec2.functions.InetAddressToHostAddress;
import org.jclouds.aws.ec2.functions.ReturnVoidOnGroupNotFound; import org.jclouds.aws.ec2.functions.ReturnVoidOnGroupNotFound;
import org.jclouds.aws.ec2.options.DescribeImagesOptions; import org.jclouds.aws.ec2.options.DescribeImagesOptions;
import org.jclouds.aws.ec2.options.RunInstancesOptions; import org.jclouds.aws.ec2.options.RunInstancesOptions;
import org.jclouds.aws.ec2.xml.AllocateAddressResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeAddressesResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandler; import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeInstancesResponseHandler; import org.jclouds.aws.ec2.xml.DescribeInstancesResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeKeyPairsResponseHandler; import org.jclouds.aws.ec2.xml.DescribeKeyPairsResponseHandler;
@ -60,6 +66,7 @@ import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint; import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.FormParams; import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.rest.annotations.XMLResponseParser;
@ -115,6 +122,101 @@ public interface EC2Client {
String describeImageAttribute(@FormParam("ImageId") String imageId, String describeImageAttribute(@FormParam("ImageId") String imageId,
@FormParam("Attribute") ImageAttribute attribute); @FormParam("Attribute") ImageAttribute attribute);
/**
* Acquires an elastic IP address for use with your account.
*
* @see #describeAddresses
* @see #releaseAddress
* @see #associateAddress
* @see #disassociateAddress
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-AllocateAddress.html"
*/
@POST
@Path("/")
@XMLResponseParser(AllocateAddressResponseHandler.class)
@FormParams(keys = ACTION, values = "AllocateAddress")
Future<InetAddress> allocateAddress();
/**
* Associates an elastic IP address with an instance. If the IP address is currently assigned to
* another instance, the IP address is assigned to the new instance. This is an idempotent
* operation. If you enter it more than once, Amazon EC2 does not return an error.
*
* @param publicIp
* IP address that you are assigning to the instance.
* @param instanceId
* The instance to associate with the IP address.
*
* @see #allocateAddress
* @see #describeAddresses
* @see #releaseAddress
* @see #disassociateAddress
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-AssociateAddress.html"
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "AssociateAddress")
Future<Void> associateAddress(
@FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp,
@FormParam("InstanceId") String instanceId);
/**
* Disassociates the specified elastic IP address from the instance to which it is assigned. This
* is an idempotent operation. If you enter it more than once, Amazon EC2 does not return an
* error.
*
* @param publicIp
* IP address that you are assigning to the instance.
*
* @see #allocateAddress
* @see #describeAddresses
* @see #releaseAddress
* @see #associateAddress
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DisdisassociateAddress.html"
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DisassociateAddress")
Future<Void> disassociateAddress(
@FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp);
/**
* Releases an elastic IP address associated with your account.
*
* @param publicIp
* The IP address that you are releasing from your account.
* @see #allocateAddress
* @see #describeAddresses
* @see #associateAddress
* @see #disassociateAddress
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-ReleaseAddress.html"
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "ReleaseAddress")
Future<Void> releaseAddress(
@FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp);
/**
* Lists elastic IP addresses assigned to your account or provides information about a specific
* address.
*
* @param publicIps
* Elastic IP address to describe.
* @throws AWSResponseException
* if the requested publicIp is not found
* @see #allocateAddress
* @see #releaseAddress
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeAddresses.html"
* />
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeAddresses")
@XMLResponseParser(DescribeAddressesResponseHandler.class)
Future<? extends SortedSet<PublicIpInstanceIdPair>> describeAddresses(
@BinderParam(BindInetAddressesToIndexedFormParams.class) InetAddress... publicIps);
/** /**
* Returns information about instances that you own. * Returns information about instances that you own.
* <p/> * <p/>
@ -131,7 +233,6 @@ public interface EC2Client {
* @see #terminateInstances * @see #terminateInstances
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html" * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html"
* /> * />
* @see DescribeInstancesOptions
*/ */
@POST @POST
@Path("/") @Path("/")

View File

@ -0,0 +1,36 @@
package org.jclouds.aws.ec2.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.InetAddress;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
import org.jclouds.rest.internal.GeneratedHttpRequest;
/**
* Binds the String [] to form parameters named with InstanceId.index
*
* @author Adrian Cole
* @since 4.0
*/
public class BindInetAddressesToIndexedFormParams implements Binder {
@SuppressWarnings("unchecked")
public void bindToRequest(HttpRequest request, Object input) {
checkArgument(checkNotNull(request, "input") instanceof GeneratedHttpRequest,
"this binder is only valid for GeneratedHttpRequests!");
checkArgument(checkNotNull(input, "input") instanceof InetAddress[],
"this binder is only valid for InetAddress[] : " + input.getClass());
InetAddress[] addresses = (InetAddress[]) input;
String[] addressStrings = new String[addresses.length];
for (int i = 0; i < addresses.length; i++) {
addressStrings[i] = addresses[i].getHostAddress();
}
EC2Utils.indexFormValuesWithPrefix((GeneratedHttpRequest<?>) request, "PublicIp",
addressStrings);
}
}

View File

@ -0,0 +1,78 @@
package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.InetAddress;
import com.google.inject.internal.Nullable;
/**
*
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-DescribeAddressesResponseInfoType.html"
* />
* @author Adrian Cole
*/
public class PublicIpInstanceIdPair implements Comparable<PublicIpInstanceIdPair> {
@Nullable
private final String instanceId;
private final InetAddress publicIp;
public PublicIpInstanceIdPair(InetAddress publicIp, @Nullable String instanceId) {
this.instanceId = instanceId;
this.publicIp = checkNotNull(publicIp, "publicIp");
}
/**
* {@inheritDoc}
*/
public int compareTo(PublicIpInstanceIdPair o) {
return (this == o) ? 0 : getPublicIp().getHostAddress().compareTo(
o.getPublicIp().getHostAddress());
}
/**
* The ID of the instance.
*/
public String getInstanceId() {
return instanceId;
}
/**
* The public IP address.
*/
public InetAddress getPublicIp() {
return publicIp;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
result = prime * result + ((publicIp == null) ? 0 : publicIp.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PublicIpInstanceIdPair other = (PublicIpInstanceIdPair) obj;
if (instanceId == null) {
if (other.instanceId != null)
return false;
} else if (!instanceId.equals(other.instanceId))
return false;
if (publicIp == null) {
if (other.publicIp != null)
return false;
} else if (!publicIp.equals(other.publicIp))
return false;
return true;
}
}

View File

@ -0,0 +1,49 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.functions;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.InetAddress;
import javax.inject.Singleton;
import com.google.common.base.Function;
/**
* @author Adrian Cole
*/
@Singleton
public class InetAddressToHostAddress implements Function<Object, String> {
@Override
public String apply(Object from) {
checkArgument(checkNotNull(from, "from") instanceof InetAddress,
"this binder is only valid for InetAddress!");
return ((InetAddress) from).getHostAddress();
}
}

View File

@ -0,0 +1,77 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.xml;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.annotation.Resource;
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
import org.jclouds.logging.Logger;
public class AllocateAddressResponseHandler extends HandlerWithResult<InetAddress> {
@Resource
protected Logger logger = Logger.NULL;
private InetAddress ipAddress;
private StringBuilder currentText = new StringBuilder();
protected String currentOrNull() {
String returnVal = currentText.toString().trim();
return returnVal.equals("") ? null : returnVal;
}
public void endElement(String uri, String name, String qName) {
if (qName.equals("publicIp")) {
ipAddress = parseInetAddress(currentOrNull());
}
currentText = new StringBuilder();
}
private InetAddress parseInetAddress(String string) {
String[] byteStrings = string.split("\\.");
byte[] bytes = new byte[4];
for (int i = 0; i < 4; i++) {
bytes[i] = (byte) Integer.parseInt(byteStrings[i]);
}
try {
return InetAddress.getByAddress(bytes);
} catch (UnknownHostException e) {
logger.warn(e, "error parsing ipAddress", currentText);
throw new RuntimeException(e);
}
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
@Override
public InetAddress getResult() {
return ipAddress;
}
}

View File

@ -0,0 +1,94 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.xml;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.SortedSet;
import javax.annotation.Resource;
import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair;
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
import org.jclouds.logging.Logger;
import com.google.common.collect.Sets;
/**
*
* @author Adrian Cole
*/
public class DescribeAddressesResponseHandler extends
HandlerWithResult<SortedSet<PublicIpInstanceIdPair>> {
@Resource
protected Logger logger = Logger.NULL;
private SortedSet<PublicIpInstanceIdPair> pairs = Sets.newTreeSet();
private InetAddress ipAddress;
private StringBuilder currentText = new StringBuilder();
private String instanceId;
protected String currentOrNull() {
String returnVal = currentText.toString().trim();
return returnVal.equals("") ? null : returnVal;
}
public void endElement(String uri, String name, String qName) {
if (qName.equals("publicIp")) {
ipAddress = parseInetAddress(currentOrNull());
} else if (qName.equals("instanceId")) {
instanceId = currentOrNull();
} else if (qName.equals("item")) {
pairs.add(new PublicIpInstanceIdPair(ipAddress, instanceId));
ipAddress = null;
instanceId = null;
}
currentText = new StringBuilder();
}
private InetAddress parseInetAddress(String string) {
String[] byteStrings = string.split("\\.");
byte[] bytes = new byte[4];
for (int i = 0; i < 4; i++) {
bytes[i] = (byte) Integer.parseInt(byteStrings[i]);
}
try {
return InetAddress.getByAddress(bytes);
} catch (UnknownHostException e) {
logger.warn(e, "error parsing ipAddress", currentText);
throw new RuntimeException(e);
}
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
@Override
public SortedSet<PublicIpInstanceIdPair> getResult() {
return pairs;
}
}

View File

@ -39,7 +39,7 @@ import java.util.SortedSet;
* any way you like and the bucket will remain yours for as long as you like and as long as you have * any way you like and the bucket will remain yours for as long as you like and as long as you have
* the Amazon S3 account. * the Amazon S3 account.
* <p/> * <p/>
* The similarities between buckets and domain names is not a coincidenceÑthere is a direct mapping * The similarities between buckets and domain names is not a coincidence there is a direct mapping
* between Amazon S3 buckets and subdomains of s3.amazonaws.com. Objects stored in Amazon S3 are * between Amazon S3 buckets and subdomains of s3.amazonaws.com. Objects stored in Amazon S3 are
* addressable using the REST API under the domain bucketname.s3.amazonaws.com. For example, if the * addressable using the REST API under the domain bucketname.s3.amazonaws.com. For example, if the
* object homepage.html?is stored in the Amazon S3 bucket mybucket its address would be * object homepage.html?is stored in the Amazon S3 bucket mybucket its address would be

View File

@ -39,6 +39,7 @@ import org.jclouds.aws.ec2.domain.ImageAttribute;
import org.jclouds.aws.ec2.domain.IpPermission; import org.jclouds.aws.ec2.domain.IpPermission;
import org.jclouds.aws.ec2.domain.IpProtocol; import org.jclouds.aws.ec2.domain.IpProtocol;
import org.jclouds.aws.ec2.domain.KeyPair; 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.Reservation;
import org.jclouds.aws.ec2.domain.SecurityGroup; import org.jclouds.aws.ec2.domain.SecurityGroup;
import org.jclouds.aws.ec2.domain.UserIdGroupPair; import org.jclouds.aws.ec2.domain.UserIdGroupPair;
@ -71,7 +72,7 @@ public class EC2ClientLiveTest {
@Test @Test
void testDescribeImages() throws InterruptedException, ExecutionException, TimeoutException { void testDescribeImages() throws InterruptedException, ExecutionException, TimeoutException {
SortedSet<Image> allResults = client.describeImages().get(30, TimeUnit.SECONDS); SortedSet<Image> allResults = client.describeImages().get(120, TimeUnit.SECONDS);
assertNotNull(allResults); assertNotNull(allResults);
assert allResults.size() >= 2 : allResults.size(); assert allResults.size() >= 2 : allResults.size();
Iterator<Image> iterator = allResults.iterator(); Iterator<Image> iterator = allResults.iterator();
@ -86,7 +87,22 @@ public class EC2ClientLiveTest {
assertEquals(iterator.next().getImageId(), id2); assertEquals(iterator.next().getImageId(), id2);
} }
@Test(dependsOnMethods = "testDescribeImages", enabled=false) @Test
void testDescribeAddresses() throws InterruptedException, ExecutionException, TimeoutException {
SortedSet<PublicIpInstanceIdPair> allResults = client.describeAddresses().get(30,
TimeUnit.SECONDS);
assertNotNull(allResults);
if (allResults.size() >= 1) {
PublicIpInstanceIdPair pair = allResults.last();
SortedSet<PublicIpInstanceIdPair> result = client.describeAddresses(pair.getPublicIp())
.get(30, TimeUnit.SECONDS);
assertNotNull(result);
PublicIpInstanceIdPair compare = result.last();
assertEquals(compare, pair);
}
}
@Test(dependsOnMethods = "testDescribeImages", enabled = false)
void testDescribeImageAttribute() throws InterruptedException, ExecutionException, void testDescribeImageAttribute() throws InterruptedException, ExecutionException,
TimeoutException { TimeoutException {
SortedSet<Image> oneResult = client.describeImages(imageIds(imageId)).get(30, SortedSet<Image> oneResult = client.describeImages(imageIds(imageId)).get(30,

View File

@ -29,6 +29,7 @@ import static org.testng.Assert.assertEquals;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.URI; import java.net.URI;
import org.jclouds.aws.ec2.domain.ImageAttribute; import org.jclouds.aws.ec2.domain.ImageAttribute;
@ -38,6 +39,8 @@ import org.jclouds.aws.ec2.filters.FormSigner;
import org.jclouds.aws.ec2.functions.ReturnVoidOnGroupNotFound; import org.jclouds.aws.ec2.functions.ReturnVoidOnGroupNotFound;
import org.jclouds.aws.ec2.options.DescribeImagesOptions; import org.jclouds.aws.ec2.options.DescribeImagesOptions;
import org.jclouds.aws.ec2.options.RunInstancesOptions; import org.jclouds.aws.ec2.options.RunInstancesOptions;
import org.jclouds.aws.ec2.xml.AllocateAddressResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeAddressesResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandler; import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeInstancesResponseHandler; import org.jclouds.aws.ec2.xml.DescribeInstancesResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeKeyPairsResponseHandler; import org.jclouds.aws.ec2.xml.DescribeKeyPairsResponseHandler;
@ -248,6 +251,96 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
checkFilters(httpMethod); checkFilters(httpMethod);
} }
public void testDisassociateAddress() throws SecurityException, NoSuchMethodException,
IOException {
Method method = EC2Client.class.getMethod("disassociateAddress", InetAddress.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, InetAddress
.getByAddress(new byte[] { 127, 0, 0, 1 }));
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 64\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod,
"Version=2009-08-15&Action=DisassociateAddress&PublicIp=127.0.0.1");
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testAssociateAddress() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class
.getMethod("associateAddress", InetAddress.class, String.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, InetAddress
.getByAddress(new byte[] { 127, 0, 0, 1 }), "me");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 75\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod,
"Version=2009-08-15&Action=AssociateAddress&PublicIp=127.0.0.1&InstanceId=me");
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testReleaseAddress() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("releaseAddress", InetAddress.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, InetAddress
.getByAddress(new byte[] { 127, 0, 0, 1 }));
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 59\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod, "Version=2009-08-15&Action=ReleaseAddress&PublicIp=127.0.0.1");
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testDescribeAddresses() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("describeAddresses", Array.newInstance(
InetAddress.class, 0).getClass());
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, InetAddress
.getByAddress(new byte[] { 127, 0, 0, 1 }));
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 43\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod,
"Version=2009-08-15&Action=DescribeAddresses&PublicIp.1=127.0.0.1");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeAddressesResponseHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testAllocateAddress() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("allocateAddress");
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method);
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 41\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
assertEntityEquals(httpMethod, "Version=2009-08-15&Action=AllocateAddress");
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, AllocateAddressResponseHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testDeleteKeyPair() throws SecurityException, NoSuchMethodException, IOException { public void testDeleteKeyPair() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("deleteKeyPair", String.class); Method method = EC2Client.class.getMethod("deleteKeyPair", String.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "mykey"); GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "mykey");

View File

@ -26,11 +26,13 @@ package org.jclouds.aws.ec2;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKeyName; import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKeyName;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.UndeclaredThrowableException; import java.lang.reflect.UndeclaredThrowableException;
import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -40,6 +42,8 @@ import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.InstanceType; import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.domain.IpProtocol; import org.jclouds.aws.ec2.domain.IpProtocol;
import org.jclouds.aws.ec2.domain.KeyPair; 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.RunningInstance; import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.concurrent.WithinThreadExecutorService; import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.concurrent.config.ExecutorServiceModule;
@ -72,6 +76,7 @@ public class ExpensiveEC2ClientLiveTest {
private KeyPair keyPair; private KeyPair keyPair;
private String securityGroupName; private String securityGroupName;
private String serverId; private String serverId;
private InetAddress address;
@BeforeGroups(groups = { "live" }) @BeforeGroups(groups = { "live" })
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException { public void setupClient() throws InterruptedException, ExecutionException, TimeoutException {
@ -87,7 +92,7 @@ public class ExpensiveEC2ClientLiveTest {
sshFactory = injector.getInstance(SshClient.Factory.class); sshFactory = injector.getInstance(SshClient.Factory.class);
} }
@Test(enabled=false) @Test(enabled = false)
void testCreateSecurityGroupIngressCidr() throws InterruptedException, ExecutionException, void testCreateSecurityGroupIngressCidr() throws InterruptedException, ExecutionException,
TimeoutException { TimeoutException {
securityGroupName = serverPrefix + "ingress"; securityGroupName = serverPrefix + "ingress";
@ -107,7 +112,7 @@ public class ExpensiveEC2ClientLiveTest {
.get(30, TimeUnit.SECONDS); .get(30, TimeUnit.SECONDS);
} }
@Test(enabled=false) @Test(enabled = false)
void testCreateKeyPair() throws InterruptedException, ExecutionException, TimeoutException { void testCreateKeyPair() throws InterruptedException, ExecutionException, TimeoutException {
String keyName = serverPrefix + "1"; String keyName = serverPrefix + "1";
try { try {
@ -122,10 +127,10 @@ public class ExpensiveEC2ClientLiveTest {
assertNotNull(keyPair.getKeyMaterial()); assertNotNull(keyPair.getKeyMaterial());
assertNotNull(keyPair.getKeyFingerprint()); assertNotNull(keyPair.getKeyFingerprint());
assertEquals(keyPair.getKeyName(), keyName); assertEquals(keyPair.getKeyName(), keyName);
} }
@Test(enabled = false, dependsOnMethods = { "testCreateKeyPair", "testCreateSecurityGroupIngressCidr" }) @Test(enabled = false, dependsOnMethods = { "testCreateKeyPair",
"testCreateSecurityGroupIngressCidr" })
public void testCreateRunningInstance() throws Exception { public void testCreateRunningInstance() throws Exception {
String imageId = "ami-1fd73376"; String imageId = "ami-1fd73376";
RunningInstance server = null; RunningInstance server = null;
@ -153,6 +158,43 @@ public class ExpensiveEC2ClientLiveTest {
sshPing(server); sshPing(server);
} }
@Test(enabled = false, dependsOnMethods = "testCreateRunningInstance")
void testElasticIpAddress() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
address = client.allocateAddress().get(30, TimeUnit.SECONDS);
assertNotNull(address);
PublicIpInstanceIdPair compare = client.describeAddresses(address).get(30, TimeUnit.SECONDS)
.last();
assertEquals(compare.getPublicIp(), address);
assert compare.getInstanceId() == null;
client.associateAddress(address, serverId).get(30, TimeUnit.SECONDS);
compare = client.describeAddresses(address).get(30, TimeUnit.SECONDS).last();
assertEquals(compare.getPublicIp(), address);
assertEquals(compare.getInstanceId(), serverId);
Reservation reservation = client.describeInstances(serverId).get(30, TimeUnit.SECONDS).last();
assertNotNull(reservation.getRunningInstances().last().getIpAddress());
assertFalse(reservation.getRunningInstances().last().getIpAddress().equals(address));
doCheckKey(address);
client.disassociateAddress(address).get(30, TimeUnit.SECONDS);
compare = client.describeAddresses(address).get(30, TimeUnit.SECONDS).last();
assertEquals(compare.getPublicIp(), address);
assert compare.getInstanceId() == null;
reservation = client.describeInstances(serverId).get(30, TimeUnit.SECONDS).last();
assert reservation.getRunningInstances().last().getIpAddress() == null;
}
/** /**
* this tests "personality" as the file looked up was sent during server creation * this tests "personality" as the file looked up was sent during server creation
*/ */
@ -169,8 +211,12 @@ public class ExpensiveEC2ClientLiveTest {
} }
private void doCheckKey(RunningInstance newDetails) throws IOException { private void doCheckKey(RunningInstance newDetails) throws IOException {
SshClient connection = sshFactory.create(new InetSocketAddress(newDetails.getDnsName(), 22), doCheckKey(InetAddress.getByName(newDetails.getDnsName()));
"root", keyPair.getKeyMaterial().getBytes()); }
private void doCheckKey(InetAddress address) throws IOException {
SshClient connection = sshFactory.create(new InetSocketAddress(address, 22), "root", keyPair
.getKeyMaterial().getBytes());
try { try {
connection.connect(); connection.connect();
InputStream etcPasswd = connection.get("/etc/passwd"); InputStream etcPasswd = connection.get("/etc/passwd");
@ -195,13 +241,15 @@ public class ExpensiveEC2ClientLiveTest {
} }
@AfterTest @AfterTest
void cleanup() { void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (address != null)
client.releaseAddress(address).get(30, TimeUnit.SECONDS);
if (serverId != null) if (serverId != null)
client.terminateInstances(serverId); client.terminateInstances(serverId).get(30, TimeUnit.SECONDS);
if (keyPair != null) if (keyPair != null)
client.deleteKeyPair(keyPair.getKeyName()); client.deleteKeyPair(keyPair.getKeyName()).get(30, TimeUnit.SECONDS);
if (securityGroupName != null) if (securityGroupName != null)
client.deleteSecurityGroup(securityGroupName); client.deleteSecurityGroup(securityGroupName).get(30, TimeUnit.SECONDS);
} }
private RunningInstance getRunningInstance(String serverId) throws InterruptedException, private RunningInstance getRunningInstance(String serverId) throws InterruptedException,

View File

@ -0,0 +1,51 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.xml;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code AllocateAddressResponseHandler}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ec2.AllocateAddressResponseHandlerTest")
public class AllocateAddressResponseHandlerTest extends BaseHandlerTest {
public void testApplyInputStream() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/ec2/allocate_address.xml");
InetAddress result = factory.create(
injector.getInstance(AllocateAddressResponseHandler.class)).parse(is);
assertEquals(result, InetAddress.getByName("67.202.55.255"));
}
}

View File

@ -0,0 +1,57 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.xml;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.SortedSet;
import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair;
import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSortedSet;
/**
* Tests behavior of {@code DescribeAddressesResponseHandler}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ec2.DescribeAddressesResponseHandlerTest")
public class DescribeAddressesResponseHandlerTest extends BaseHandlerTest {
public void testApplyInputStream() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/ec2/describe_addresses.xml");
SortedSet<PublicIpInstanceIdPair> 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")));
}
}

View File

@ -0,0 +1,3 @@
<AllocateAddressResponse xmlns="http://ec2.amazonaws.com/doc/2009-08-15/">
<publicIp>67.202.55.255</publicIp>
</AllocateAddressResponse>

View File

@ -0,0 +1,11 @@
<DescribeAddressesResponse xmlns="http://ec2.amazonaws.com/doc/2009-08-15/">
<addressesSet>
<item>
<instanceId>i-f15ebb98</instanceId>
<publicIp>67.202.55.255</publicIp>
</item>
<item>
<publicIp>67.202.55.233</publicIp>
</item>
</addressesSet>
</DescribeAddressesResponse>

View File

@ -97,13 +97,13 @@
<category name="jclouds.http.headers"> <category name="jclouds.http.headers">
<priority value="DEBUG" /> <priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" /> <appender-ref ref="ASYNCWIRE" />
</category> </category><!--
<category name="jclouds.http.wire"> <category name="jclouds.http.wire">
<priority value="DEBUG" /> <priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" /> <appender-ref ref="ASYNCWIRE" />
</category> </category>
<!-- ======================= --> --><!-- ======================= -->
<!-- Setup the Root category --> <!-- Setup the Root category -->
<!-- ======================= --> <!-- ======================= -->