// // typica - A client library for Amazon Web Services // Copyright (C) 2007 Xerox Corporation // // Licensed 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 com.xerox.amazonws.ec2; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.StringWriter; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.xml.bind.JAXBException; import org.apache.commons.codec.binary.Base64; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.StringRequestEntity; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.xerox.amazonws.typica.jaxb.AllocateAddressResponse; import com.xerox.amazonws.typica.jaxb.AssociateAddressResponse; import com.xerox.amazonws.typica.jaxb.AvailabilityZoneItemType; import com.xerox.amazonws.typica.jaxb.AvailabilityZoneSetType; import com.xerox.amazonws.typica.jaxb.AuthorizeSecurityGroupIngressResponse; import com.xerox.amazonws.typica.jaxb.BlockDeviceMappingType; import com.xerox.amazonws.typica.jaxb.BlockDeviceMappingItemType; import com.xerox.amazonws.typica.jaxb.CreateKeyPairResponse; import com.xerox.amazonws.typica.jaxb.ConfirmProductInstanceResponse; import com.xerox.amazonws.typica.jaxb.CreateSecurityGroupResponse; import com.xerox.amazonws.typica.jaxb.DeleteKeyPairResponse; import com.xerox.amazonws.typica.jaxb.DeleteSecurityGroupResponse; import com.xerox.amazonws.typica.jaxb.DescribeAddressesResponse; import com.xerox.amazonws.typica.jaxb.DescribeAddressesResponseInfoType; import com.xerox.amazonws.typica.jaxb.DescribeAddressesResponseItemType; import com.xerox.amazonws.typica.jaxb.DescribeAvailabilityZonesResponse; import com.xerox.amazonws.typica.jaxb.DeregisterImageResponse; import com.xerox.amazonws.typica.jaxb.DescribeImageAttributeResponse; import com.xerox.amazonws.typica.jaxb.DescribeImagesResponse; import com.xerox.amazonws.typica.jaxb.DescribeImagesResponseInfoType; import com.xerox.amazonws.typica.jaxb.DescribeImagesResponseItemType; import com.xerox.amazonws.typica.jaxb.DescribeInstancesResponse; import com.xerox.amazonws.typica.jaxb.DescribeKeyPairsResponse; import com.xerox.amazonws.typica.jaxb.DescribeKeyPairsResponseInfoType; import com.xerox.amazonws.typica.jaxb.DescribeKeyPairsResponseItemType; import com.xerox.amazonws.typica.jaxb.DescribeSecurityGroupsResponse; import com.xerox.amazonws.typica.jaxb.DisassociateAddressResponse; import com.xerox.amazonws.typica.jaxb.GetConsoleOutputResponse; import com.xerox.amazonws.typica.jaxb.GroupItemType; import com.xerox.amazonws.typica.jaxb.GroupSetType; import com.xerox.amazonws.typica.jaxb.IpPermissionSetType; import com.xerox.amazonws.typica.jaxb.IpPermissionSetType; import com.xerox.amazonws.typica.jaxb.IpPermissionType; import com.xerox.amazonws.typica.jaxb.IpRangeItemType; import com.xerox.amazonws.typica.jaxb.IpRangeSetType; import com.xerox.amazonws.typica.jaxb.LaunchPermissionItemType; import com.xerox.amazonws.typica.jaxb.LaunchPermissionListType; import com.xerox.amazonws.typica.jaxb.ModifyImageAttributeResponse; import com.xerox.amazonws.typica.jaxb.NullableAttributeValueType; import com.xerox.amazonws.typica.jaxb.ObjectFactory; import com.xerox.amazonws.typica.jaxb.ProductCodeListType; import com.xerox.amazonws.typica.jaxb.ProductCodeItemType; import com.xerox.amazonws.typica.jaxb.ProductCodesSetType; import com.xerox.amazonws.typica.jaxb.ProductCodesSetItemType; import com.xerox.amazonws.typica.jaxb.RebootInstancesResponse; import com.xerox.amazonws.typica.jaxb.RegisterImageResponse; import com.xerox.amazonws.typica.jaxb.ReleaseAddressResponse; import com.xerox.amazonws.typica.jaxb.RevokeSecurityGroupIngressResponse; import com.xerox.amazonws.typica.jaxb.ReservationSetType; import com.xerox.amazonws.typica.jaxb.ResetImageAttributeResponse; import com.xerox.amazonws.typica.jaxb.RunningInstancesItemType; import com.xerox.amazonws.typica.jaxb.RunningInstancesSetType; import com.xerox.amazonws.typica.jaxb.RunInstancesResponse; import com.xerox.amazonws.typica.jaxb.SecurityGroupSetType; import com.xerox.amazonws.typica.jaxb.SecurityGroupItemType; import com.xerox.amazonws.typica.jaxb.TerminateInstancesResponse; import com.xerox.amazonws.typica.jaxb.TerminateInstancesResponseInfoType; import com.xerox.amazonws.typica.jaxb.TerminateInstancesResponseItemType; import com.xerox.amazonws.typica.jaxb.UserIdGroupPairType; import com.xerox.amazonws.typica.jaxb.UserIdGroupPairSetType; import com.xerox.amazonws.common.AWSQueryConnection; /** * A Java wrapper for the EC2 web services API */ public class Jec2 extends AWSQueryConnection { private static Log logger = LogFactory.getLog(Jec2.class); /** * Initializes the ec2 service with your AWS login information. * * @param awsAccessId The your user key into AWS * @param awsSecretKey The secret string used to generate signatures for authentication. */ public Jec2(String awsAccessId, String awsSecretKey) { this(awsAccessId, awsSecretKey, true); } /** * Initializes the ec2 service with your AWS login information. * * @param awsAccessId The your user key into AWS * @param awsSecretKey The secret string used to generate signatures for authentication. * @param isSecure True if the data should be encrypted on the wire on the way to or from EC2. */ public Jec2(String awsAccessId, String awsSecretKey, boolean isSecure) { this(awsAccessId, awsSecretKey, isSecure, "ec2.amazonaws.com"); } /** * Initializes the ec2 service with your AWS login information. * * @param awsAccessId The your user key into AWS * @param awsSecretKey The secret string used to generate signatures for authentication. * @param isSecure True if the data should be encrypted on the wire on the way to or from EC2. * @param server Which host to connect to. Usually, this will be ec2.amazonaws.com */ public Jec2(String awsAccessId, String awsSecretKey, boolean isSecure, String server) { this(awsAccessId, awsSecretKey, isSecure, server, isSecure ? 443 : 80); } /** * Initializes the ec2 service with your AWS login information. * * @param awsAccessId The your user key into AWS * @param awsSecretKey The secret string used to generate signatures for authentication. * @param isSecure True if the data should be encrypted on the wire on the way to or from EC2. * @param server Which host to connect to. Usually, this will be ec2.amazonaws.com * @param port Which port to use. */ public Jec2(String awsAccessId, String awsSecretKey, boolean isSecure, String server, int port) { super(awsAccessId, awsSecretKey, isSecure, server, port); ArrayList vals = new ArrayList(); vals.add("2008-02-01"); super.headers.put("Version", vals); } /** * Register the given AMI. * * @param imageLocation An AMI path within S3. * @return A unique AMI ID that can be used to create and manage instances of this AMI. * @throws EC2Exception wraps checked exceptions */ public String registerImage(String imageLocation) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("ImageLocation", imageLocation); GetMethod method = new GetMethod(); try { RegisterImageResponse response = makeRequest(method, "RegisterImage", params, RegisterImageResponse.class); return response.getImageId(); } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Deregister the given AMI. * * @param imageId An AMI ID as returned by {@link #registerImage(String)}. * @throws EC2Exception wraps checked exceptions */ public void deregisterImage(String imageId) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("ImageId", imageId); GetMethod method = new GetMethod(); try { DeregisterImageResponse response = makeRequest(method, "DeregisterImage", params, DeregisterImageResponse.class); if (!response.isReturn()) { throw new EC2Exception("Could not deregister image : "+imageId+". No reason given."); } } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Describe the given AMIs. * * @param imageIds An array of AMI IDs as returned by {@link #registerImage(String)}. * @return A list of {@link ImageDescription} instances describing each AMI ID. * @throws EC2Exception wraps checked exceptions */ public List<ImageDescription> describeImages(String[] imageIds) throws EC2Exception { return describeImages(Arrays.asList(imageIds)); } /** * Describe the given AMIs. * * @param imageIds A list of AMI IDs as returned by {@link #registerImage(String)}. * @return A list of {@link ImageDescription} instances describing each AMI ID. * @throws EC2Exception wraps checked exceptions */ public List<ImageDescription> describeImages(List<String> imageIds) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); for (int i=0 ; i<imageIds.size(); i++) { params.put("ImageId."+(i+1), imageIds.get(i)); } return describeImages(params); } /** * Describe the AMIs belonging to the supplied owners. * * @param owners A list of owners. * @return A list of {@link ImageDescription} instances describing each AMI ID. * @throws EC2Exception wraps checked exceptions */ public List<ImageDescription> describeImagesByOwner(List<String> owners) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); for (int i=0 ; i<owners.size(); i++) { params.put("Owner."+(i+1), owners.get(i)); } return describeImages(params); } /** * Describe the AMIs executable by supplied users. * * @param users A list of users. * @return A list of {@link ImageDescription} instances describing each AMI ID. * @throws EC2Exception wraps checked exceptions */ public List<ImageDescription> describeImagesByExecutability(List<String> users) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); for (int i=0 ; i<users.size(); i++) { params.put("ExecutableBy."+(i+1), users.get(i)); } return describeImages(params); } /** * Describe the AMIs image type (machine, kernel, ramdisk). * * @param type An image type. * @return A list of {@link ImageDescription} instances describing each AMI ID. * @throws EC2Exception wraps checked exceptions */ public List<ImageDescription> describeImagesByImageType(ImageType type) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("ImageType", type.getTypeId()); return describeImages(params); } /** * Describe the AMIs that match the intersection of the criteria supplied * * @param imageIds A list of AMI IDs as returned by {@link #registerImage(String)}. * @param owners A list of owners. * @param users A list of users. * @param type An image type. * @return A list of {@link ImageDescription} instances describing each AMI ID. * @throws EC2Exception wraps checked exceptions */ public List<ImageDescription> describeImages(List<String> imageIds, List<String> owners, List<String> users, ImageType type) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); for (int i=0 ; i<imageIds.size(); i++) { params.put("ImageId."+(i+1), imageIds.get(i)); } for (int i=0 ; i<owners.size(); i++) { params.put("Owner."+(i+1), owners.get(i)); } for (int i=0 ; i<users.size(); i++) { params.put("ExecutableBy."+(i+1), users.get(i)); } if (type != null) { params.put("ImageType", type.getTypeId()); } return describeImages(params); } protected List<ImageDescription> describeImages(Map<String, String> params) throws EC2Exception { GetMethod method = new GetMethod(); try { DescribeImagesResponse response = makeRequest(method, "DescribeImages", params, DescribeImagesResponse.class); List<ImageDescription> result = new ArrayList<ImageDescription>(); DescribeImagesResponseInfoType set = response.getImagesSet(); Iterator set_iter = set.getItems().iterator(); while (set_iter.hasNext()) { DescribeImagesResponseItemType item = (DescribeImagesResponseItemType) set_iter .next(); ArrayList<String> codes = new ArrayList<String>(); ProductCodesSetType code_set = item.getProductCodes(); if (code_set != null) { for (ProductCodesSetItemType code : code_set.getItems()) { codes.add(code.getProductCode()); } } result.add(new ImageDescription(item.getImageId(), item .getImageLocation(), item.getImageOwnerId(), item .getImageState(), item.isIsPublic(), codes)); } return result; } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Requests reservation of a number of instances. * <p> * This will begin launching those instances for which a reservation was * successfully obtained. * <p> * If less than <code>minCount</code> instances are available no instances * will be reserved. * <p> * NOTE: this method defaults to the AWS desired "public" addressing type. * NOTE: this method defaults to the small(traditional) instance type. * * @param imageId An AMI ID as returned by {@link #registerImage(String)}. * @param minCount The minimum number of instances to attempt to reserve. * @param maxCount The maximum number of instances to attempt to reserve. * @param groupSet A (possibly empty) set of security group definitions. * @param userData User supplied data that will be made available to the instance(s) * @return A {@link com.xerox.amazonws.ec2.ReservationDescription} describing the instances that * have been reserved. * @throws EC2Exception wraps checked exceptions */ public ReservationDescription runInstances(String imageId, int minCount, int maxCount, List<String> groupSet, String userData, String keyName) throws EC2Exception { return runInstances(imageId, minCount, maxCount, groupSet, userData, keyName, true, InstanceType.DEFAULT); } /** * Requests reservation of a number of instances. * <p> * This will begin launching those instances for which a reservation was * successfully obtained. * <p> * If less than <code>minCount</code> instances are available no instances * will be reserved. * NOTE: this method defaults to the small(traditional) instance type. * * @param imageId An AMI ID as returned by {@link #registerImage(String)}. * @param minCount The minimum number of instances to attempt to reserve. * @param maxCount The maximum number of instances to attempt to reserve. * @param groupSet A (possibly empty) set of security group definitions. * @param userData User supplied data that will be made available to the instance(s) * @param publicAddr sets addressing mode to public * @return A {@link com.xerox.amazonws.ec2.ReservationDescription} describing the instances that * have been reserved. * @throws EC2Exception wraps checked exceptions */ public ReservationDescription runInstances(String imageId, int minCount, int maxCount, List<String> groupSet, String userData, String keyName, boolean publicAddr) throws EC2Exception { return runInstances(imageId, minCount, maxCount, groupSet, userData, keyName, publicAddr, InstanceType.DEFAULT); } /** * Requests reservation of a number of instances. * <p> * This will begin launching those instances for which a reservation was * successfully obtained. * <p> * If less than <code>minCount</code> instances are available no instances * will be reserved. * NOTE: this method defaults to the AWS desired "public" addressing type. * * @param imageId An AMI ID as returned by {@link #registerImage(String)}. * @param minCount The minimum number of instances to attempt to reserve. * @param maxCount The maximum number of instances to attempt to reserve. * @param groupSet A (possibly empty) set of security group definitions. * @param userData User supplied data that will be made available to the instance(s) * @param type instance type * @return A {@link com.xerox.amazonws.ec2.ReservationDescription} describing the instances that * have been reserved. * @throws EC2Exception wraps checked exceptions */ public ReservationDescription runInstances(String imageId, int minCount, int maxCount, List<String> groupSet, String userData, String keyName, InstanceType type) throws EC2Exception { return runInstances(imageId, minCount, maxCount, groupSet, userData, keyName, true, type); } /** * Requests reservation of a number of instances. * <p> * This will begin launching those instances for which a reservation was * successfully obtained. * <p> * If less than <code>minCount</code> instances are available no instances * will be reserved. * * @param imageId An AMI ID as returned by {@link #registerImage(String)}. * @param minCount The minimum number of instances to attempt to reserve. * @param maxCount The maximum number of instances to attempt to reserve. * @param groupSet A (possibly empty) set of security group definitions. * @param userData User supplied data that will be made available to the instance(s) * @param publicAddr sets addressing mode to public * @param type instance type * @return A {@link com.xerox.amazonws.ec2.ReservationDescription} describing the instances that * have been reserved. * @throws EC2Exception wraps checked exceptions */ public ReservationDescription runInstances(String imageId, int minCount, int maxCount, List<String> groupSet, String userData, String keyName, boolean publicAddr, InstanceType type) throws EC2Exception { return runInstances(imageId, minCount, maxCount, groupSet, userData, keyName, publicAddr, type, null, null, null, null); } /** * Requests reservation of a number of instances. * <p> * This will begin launching those instances for which a reservation was * successfully obtained. * <p> * If less than <code>minCount</code> instances are available no instances * will be reserved. * * @param imageId An AMI ID as returned by {@link #registerImage(String)}. * @param minCount The minimum number of instances to attempt to reserve. * @param maxCount The maximum number of instances to attempt to reserve. * @param groupSet A (possibly empty) set of security group definitions. * @param userData User supplied data that will be made available to the instance(s) * @param publicAddr sets addressing mode to public * @param type instance type * @param availabilityZone the zone in which to launch the instance(s) * @param kernelId id of the kernel with which to launch the instance(s) * @param ramdiskId id of the RAM disk with wich to launch the imstance(s) * @param blockDeviceMappings mappings of virtual to device names * @return A {@link com.xerox.amazonws.ec2.ReservationDescription} describing the instances that * have been reserved. * @throws EC2Exception wraps checked exceptions */ public ReservationDescription runInstances(String imageId, int minCount, int maxCount, List<String> groupSet, String userData, String keyName, boolean publicAddr, InstanceType type, String availabilityZone, String kernelId, String ramdiskId, List<BlockDeviceMapping> blockDeviceMappings) throws EC2Exception { LaunchConfiguration lc = new LaunchConfiguration(imageId); lc.setMinCount(minCount); lc.setMaxCount(maxCount); lc.setSecurityGroup(groupSet); if (userData != null) { lc.setUserData(userData.getBytes()); } lc.setKeyName(keyName); lc.setInstanceType(type); lc.setAvailabilityZone(availabilityZone); lc.setKernelId(kernelId); lc.setRamdiskId(ramdiskId); lc.setBlockDevicemappings(blockDeviceMappings); return runInstances(lc); } /** * Requests reservation of a number of instances. * <p> * This will begin launching those instances for which a reservation was * successfully obtained. * <p> * If less than <code>minCount</code> instances are available no instances * will be reserved. * * @param lc object containing launch configuration * @return A {@link com.xerox.amazonws.ec2.ReservationDescription} describing the instances that * have been reserved. * @throws EC2Exception wraps checked exceptions */ public ReservationDescription runInstances(LaunchConfiguration lc) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("ImageId", lc.getImageId()); params.put("MinCount", "" + lc.getMinCount()); params.put("MaxCount", "" + lc.getMaxCount()); byte[] userData = lc.getUserData(); if (userData != null && userData.length > 0) { params.put("UserData", new String(Base64.encodeBase64(userData))); } params.put("AddressingType", "public"); String keyName = lc.getKeyName(); if (keyName != null && !keyName.trim().equals("")) { params.put("KeyName", keyName); } if (lc.getSecurityGroup() != null) { for(int i = 0; i < lc.getSecurityGroup().size(); i++) { params.put("SecurityGroup." + (i + 1), lc.getSecurityGroup().get(i)); } } params.put("InstanceType", lc.getInstanceType().getTypeId()); if (lc.getAvailabilityZone() != null && !lc.getAvailabilityZone().trim().equals("")) { params.put("Placement.AvailabilityZone", lc.getAvailabilityZone()); } if (lc.getKernelId() != null && !lc.getKernelId().trim().equals("")) { params.put("KernelId", lc.getKernelId()); } if (lc.getRamdiskId() != null && !lc.getRamdiskId().trim().equals("")) { params.put("RamdiskId", lc.getRamdiskId()); } if (lc.getBlockDevicemappings() != null) { for(int i = 0; i < lc.getBlockDevicemappings().size(); i++) { BlockDeviceMapping bdm = lc.getBlockDevicemappings().get(i); params.put("BlockDeviceMapping." + (i + 1) + ".VirtualName", bdm.getVirtualName()); params.put("BlockDeviceMapping." + (i + 1) + ".DeviceName", bdm.getDeviceName()); } } GetMethod method = new GetMethod(); try { RunInstancesResponse response = makeRequest(method, "RunInstances", params, RunInstancesResponse.class); ReservationDescription res = new ReservationDescription(response.getOwnerId(), response.getReservationId()); GroupSetType grp_set = response.getGroupSet(); Iterator groups_iter = grp_set.getItems().iterator(); while (groups_iter.hasNext()) { GroupItemType rsp_item = (GroupItemType) groups_iter.next(); res.addGroup(rsp_item.getGroupId()); } RunningInstancesSetType set = response.getInstancesSet(); Iterator instances_iter = set.getItems().iterator(); while (instances_iter.hasNext()) { RunningInstancesItemType rsp_item = (RunningInstancesItemType) instances_iter .next(); res.addInstance(rsp_item.getImageId(), rsp_item.getInstanceId(), rsp_item.getPrivateDnsName(), rsp_item.getDnsName(), rsp_item.getInstanceState(), rsp_item.getReason(), rsp_item.getKeyName(), rsp_item.getLaunchTime().toGregorianCalendar(), InstanceType.getTypeFromString(rsp_item.getInstanceType()), rsp_item.getPlacement().getAvailabilityZone(), rsp_item.getKernelId(), rsp_item.getRamdiskId()); } return res; } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Terminates a selection of running instances. * * @param instanceIds An array of instances ({@link com.xerox.amazonws.ec2.ReservationDescription.Instance#instanceId}. * @return A list of {@link TerminatingInstanceDescription} instances. * @throws EC2Exception wraps checked exceptions */ public List<TerminatingInstanceDescription> terminateInstances( String[] instanceIds) throws EC2Exception { return this.terminateInstances(Arrays.asList(instanceIds)); } /** * Terminates a selection of running instances. * * @param instanceIds A list of instances ({@link com.xerox.amazonws.ec2.ReservationDescription.Instance#instanceId}. * @return A list of {@link TerminatingInstanceDescription} instances. * @throws EC2Exception wraps checked exceptions */ public List<TerminatingInstanceDescription> terminateInstances(List<String> instanceIds) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); for (int i=0 ; i<instanceIds.size(); i++) { params.put("InstanceId."+(i+1), instanceIds.get(i)); } GetMethod method = new GetMethod(); try { TerminateInstancesResponse response = makeRequest(method, "TerminateInstances", params, TerminateInstancesResponse.class); response.getInstancesSet(); List<TerminatingInstanceDescription> res = new ArrayList<TerminatingInstanceDescription>(); TerminateInstancesResponseInfoType set = response.getInstancesSet(); Iterator instances_iter = set.getItems().iterator(); while (instances_iter.hasNext()) { TerminateInstancesResponseItemType rsp_item = (TerminateInstancesResponseItemType) instances_iter.next(); res.add(new TerminatingInstanceDescription( rsp_item.getInstanceId(), rsp_item.getPreviousState() .getName(), rsp_item.getPreviousState().getCode(), rsp_item.getShutdownState().getName(), rsp_item .getShutdownState().getCode())); } return res; } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Gets a list of running instances. * <p> * If the array of instance IDs is empty then a list of all instances owned * by the caller will be returned. Otherwise the list will contain * information for the requested instances only. * * @param instanceIds An array of instances ({@link com.xerox.amazonws.ec2.ReservationDescription.Instance#instanceId}. * @return A list of {@link com.xerox.amazonws.ec2.ReservationDescription} instances. * @throws EC2Exception wraps checked exceptions */ public List<ReservationDescription> describeInstances(String[] instanceIds) throws EC2Exception { return this.describeInstances(Arrays.asList(instanceIds)); } /** * Gets a list of running instances. * <p> * If the list of instance IDs is empty then a list of all instances owned * by the caller will be returned. Otherwise the list will contain * information for the requested instances only. * * @param instanceIds A list of instances ({@link com.xerox.amazonws.ec2.ReservationDescription.Instance#instanceId}. * @return A list of {@link com.xerox.amazonws.ec2.ReservationDescription} instances. * @throws EC2Exception wraps checked exceptions */ public List<ReservationDescription> describeInstances(List<String> instanceIds) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); for (int i=0 ; i<instanceIds.size(); i++) { params.put("InstanceId."+(i+1), instanceIds.get(i)); } GetMethod method = new GetMethod(); try { DescribeInstancesResponse response = makeRequest(method, "DescribeInstances", params, DescribeInstancesResponse.class); List<ReservationDescription> result = new ArrayList<ReservationDescription>(); ReservationSetType res_set = response.getReservationSet(); Iterator reservations_iter = res_set.getItems().iterator(); while (reservations_iter.hasNext()) { RunInstancesResponse item = (RunInstancesResponse) reservations_iter.next(); ReservationDescription res = new ReservationDescription(item .getOwnerId(), item.getReservationId()); GroupSetType grp_set = item.getGroupSet(); Iterator groups_iter = grp_set.getItems().iterator(); while (groups_iter.hasNext()) { GroupItemType rsp_item = (GroupItemType) groups_iter.next(); res.addGroup(rsp_item.getGroupId()); } RunningInstancesSetType set = item.getInstancesSet(); Iterator instances_iter = set.getItems().iterator(); while (instances_iter.hasNext()) { RunningInstancesItemType rsp_item = (RunningInstancesItemType) instances_iter .next(); res.addInstance(rsp_item.getImageId(), rsp_item.getInstanceId(), rsp_item.getPrivateDnsName(), rsp_item.getDnsName(), rsp_item.getInstanceState(), rsp_item.getReason(), rsp_item.getKeyName(), rsp_item.getLaunchTime().toGregorianCalendar(), InstanceType.getTypeFromString(rsp_item.getInstanceType()), rsp_item.getPlacement().getAvailabilityZone(), rsp_item.getKernelId(), rsp_item.getRamdiskId()); } result.add(res); } return result; } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Reboot a selection of running instances. * * @param instanceIds A list of instances ({@link com.xerox.amazonws.ec2.ReservationDescription.Instance#instanceId}. * @throws EC2Exception wraps checked exceptions */ public void rebootInstances(String [] instanceIds) throws EC2Exception { this.rebootInstances(Arrays.asList(instanceIds)); } /** * Reboot a selection of running instances. * * @param instanceIds A list of instances ({@link com.xerox.amazonws.ec2.ReservationDescription.Instance#instanceId}. * @throws EC2Exception wraps checked exceptions */ public void rebootInstances(List<String> instanceIds) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); for (int i=0 ; i<instanceIds.size(); i++) { params.put("InstanceId."+(i+1), instanceIds.get(i)); } GetMethod method = new GetMethod(); try { RebootInstancesResponse response = makeRequest(method, "RebootInstances", params, RebootInstancesResponse.class); if (!response.isReturn()) { throw new EC2Exception("Could not reboot instances. No reason given."); } } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Get an instance's console output. * * @param instanceId An instance's id ({@link com.xerox.amazonws.ec2.ReservationDescription.Instance#instanceId}. * @return ({@link ConsoleOutput}) * @throws EC2Exception wraps checked exceptions */ public ConsoleOutput getConsoleOutput(String instanceId) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("InstanceId", instanceId); GetMethod method = new GetMethod(); try { GetConsoleOutputResponse response = makeRequest(method, "GetConsoleOutput", params, GetConsoleOutputResponse.class); return new ConsoleOutput(response.getInstanceId(), response.getTimestamp().toGregorianCalendar(), new String(Base64.decodeBase64(response.getOutput().getBytes()))); } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Creates a security group. * * @param name The name of the security group. * @param desc The description of the security group. * @throws EC2Exception wraps checked exceptions */ public void createSecurityGroup(String name, String desc) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("GroupName", name); params.put("GroupDescription", desc); GetMethod method = new GetMethod(); try { CreateSecurityGroupResponse response = makeRequest(method, "CreateSecurityGroup", params, CreateSecurityGroupResponse.class); if (!response.isReturn()) { throw new EC2Exception("Could not create security group : "+name+". No reason given."); } } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Deletes a security group. * * @param name The name of the security group. * @throws EC2Exception wraps checked exceptions */ public void deleteSecurityGroup(String name) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("GroupName", name); GetMethod method = new GetMethod(); try { DeleteSecurityGroupResponse response = makeRequest(method, "DeleteSecurityGroup", params, DeleteSecurityGroupResponse.class); if (!response.isReturn()) { throw new EC2Exception("Could not delete security group : "+name+". No reason given."); } } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Gets a list of security groups and their associated permissions. * * @param groupNames An array of groups to describe. * @return A list of groups ({@link GroupDescription}. * @throws EC2Exception wraps checked exceptions */ public List<GroupDescription> describeSecurityGroups(String[] groupNames) throws EC2Exception { return describeSecurityGroups(Arrays.asList(groupNames)); } /** * Gets a list of security groups and their associated permissions. * * @param groupNames A list of groups to describe. * @return A list of groups ({@link GroupDescription}. * @throws EC2Exception wraps checked exceptions */ public List<GroupDescription> describeSecurityGroups(List<String> groupNames) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); for (int i=0 ; i<groupNames.size(); i++) { params.put("GroupName."+(i+1), groupNames.get(i)); } GetMethod method = new GetMethod(); try { DescribeSecurityGroupsResponse response = makeRequest(method, "DescribeSecurityGroups", params, DescribeSecurityGroupsResponse.class); List<GroupDescription> result = new ArrayList<GroupDescription>(); SecurityGroupSetType rsp_set = response.getSecurityGroupInfo(); Iterator set_iter = rsp_set.getItems().iterator(); while (set_iter.hasNext()) { SecurityGroupItemType item = (SecurityGroupItemType) set_iter .next(); GroupDescription group = new GroupDescription(item.getGroupName(), item.getGroupDescription(), item.getOwnerId()); IpPermissionSetType perms = item.getIpPermissions(); Iterator perm_iter = perms.getItems().iterator(); while (perm_iter.hasNext()) { IpPermissionType perm = (IpPermissionType) perm_iter.next(); GroupDescription.IpPermission group_perms = group .addPermission(perm.getIpProtocol(), perm.getFromPort(), perm.getToPort()); Iterator group_iter = perm.getGroups().getItems().iterator(); while (group_iter.hasNext()) { UserIdGroupPairType uid_group = (UserIdGroupPairType) group_iter .next(); group_perms.addUserGroupPair(uid_group.getUserId(), uid_group.getGroupName()); } Iterator iprange_iter = perm.getIpRanges().getItems().iterator(); while (iprange_iter.hasNext()) { IpRangeItemType range = (IpRangeItemType) iprange_iter .next(); group_perms.addIpRange(range.getCidrIp()); } } result.add(group); } return result; } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Adds incoming permissions to a security group. * * @param groupName name of group to modify * @param secGroupName name of security group to authorize access to * @param secGroupOwnerId owner of security group to authorize access to * @throws EC2Exception wraps checked exceptions */ public void authorizeSecurityGroupIngress(String groupName, String secGroupName, String secGroupOwnerId) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("GroupName", groupName); params.put("SourceSecurityGroupOwnerId", secGroupOwnerId); params.put("SourceSecurityGroupName", secGroupName); GetMethod method = new GetMethod(); try { AuthorizeSecurityGroupIngressResponse response = makeRequest(method, "AuthorizeSecurityGroupIngress", params, AuthorizeSecurityGroupIngressResponse.class); if (!response.isReturn()) { throw new EC2Exception("Could not authorize security ingress : "+groupName+". No reason given."); } } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Adds incoming permissions to a security group. * * @param groupName name of group to modify * @param ipProtocol protocol to authorize (tcp, udp, icmp) * @param fromPort bottom of port range to authorize * @param toPort top of port range to authorize * @param cidrIp CIDR IP range to authorize (i.e. 0.0.0.0/0) * @throws EC2Exception wraps checked exceptions */ public void authorizeSecurityGroupIngress(String groupName, String ipProtocol, int fromPort, int toPort, String cidrIp) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("GroupName", groupName); params.put("IpProtocol", ipProtocol); params.put("FromPort", ""+fromPort); params.put("ToPort", ""+toPort); params.put("CidrIp", cidrIp); GetMethod method = new GetMethod(); try { AuthorizeSecurityGroupIngressResponse response = makeRequest(method, "AuthorizeSecurityGroupIngress", params, AuthorizeSecurityGroupIngressResponse.class); if (!response.isReturn()) { throw new EC2Exception("Could not authorize security ingress : "+groupName+". No reason given."); } } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Revokes incoming permissions from a security group. * * @param groupName name of group to modify * @param secGroupName name of security group to revoke access from * @param secGroupOwnerId owner of security group to revoke access from * @throws EC2Exception wraps checked exceptions */ public void revokeSecurityGroupIngress(String groupName, String secGroupName, String secGroupOwnerId) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("GroupName", groupName); params.put("SourceSecurityGroupOwnerId", secGroupOwnerId); params.put("SourceSecurityGroupName", secGroupName); GetMethod method = new GetMethod(); try { RevokeSecurityGroupIngressResponse response = makeRequest(method, "RevokeSecurityGroupIngress", params, RevokeSecurityGroupIngressResponse.class); if (!response.isReturn()) { throw new EC2Exception("Could not revoke security ingress : "+groupName+". No reason given."); } } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Revokes incoming permissions from a security group. * * @param groupName name of group to modify * @param ipProtocol protocol to revoke (tcp, udp, icmp) * @param fromPort bottom of port range to revoke * @param toPort top of port range to revoke * @param cidrIp CIDR IP range to revoke (i.e. 0.0.0.0/0) * @throws EC2Exception wraps checked exceptions */ public void revokeSecurityGroupIngress(String groupName, String ipProtocol, int fromPort, int toPort, String cidrIp) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("GroupName", groupName); params.put("IpProtocol", ipProtocol); params.put("FromPort", ""+fromPort); params.put("ToPort", ""+toPort); params.put("CidrIp", cidrIp); GetMethod method = new GetMethod(); try { RevokeSecurityGroupIngressResponse response = makeRequest(method, "RevokeSecurityGroupIngress", params, RevokeSecurityGroupIngressResponse.class); if (!response.isReturn()) { throw new EC2Exception("Could not revoke security ingress : "+groupName+". No reason given."); } } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Creates a public/private keypair. * * @param keyName Name of the keypair. * @return A keypair description ({@link KeyPairInfo}). * @throws EC2Exception wraps checked exceptions */ public KeyPairInfo createKeyPair(String keyName) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("KeyName", keyName); GetMethod method = new GetMethod(); try { CreateKeyPairResponse response = makeRequest(method, "CreateKeyPair", params, CreateKeyPairResponse.class); return new KeyPairInfo(response.getKeyName(), response.getKeyFingerprint(), response.getKeyMaterial()); } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Lists public/private keypairs. * * @param keyIds An array of keypairs. * @return A list of keypair descriptions ({@link KeyPairInfo}). * @throws EC2Exception wraps checked exceptions */ public List<KeyPairInfo> describeKeyPairs(String[] keyIds) throws EC2Exception { return describeKeyPairs(Arrays.asList(keyIds)); } /** * Lists public/private keypairs. * * @param keyIds A list of keypairs. * @return A list of keypair descriptions ({@link KeyPairInfo}). * @throws EC2Exception wraps checked exceptions */ public List<KeyPairInfo> describeKeyPairs(List<String> keyIds) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); for (int i=0 ; i<keyIds.size(); i++) { params.put("KeyName."+(i+1), keyIds.get(i)); } GetMethod method = new GetMethod(); try { DescribeKeyPairsResponse response = makeRequest(method, "DescribeKeyPairs", params, DescribeKeyPairsResponse.class); List<KeyPairInfo> result = new ArrayList<KeyPairInfo>(); DescribeKeyPairsResponseInfoType set = response.getKeySet(); Iterator set_iter = set.getItems().iterator(); while (set_iter.hasNext()) { DescribeKeyPairsResponseItemType item = (DescribeKeyPairsResponseItemType) set_iter.next(); result.add(new KeyPairInfo(item.getKeyName(), item.getKeyFingerprint(), null)); } return result; } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Deletes a public/private keypair. * * @param keyName Name of the keypair. * @throws EC2Exception wraps checked exceptions */ public void deleteKeyPair(String keyName) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("KeyName", keyName); GetMethod method = new GetMethod(); try { DeleteKeyPairResponse response = makeRequest(method, "DeleteKeyPair", params, DeleteKeyPairResponse.class); if (!response.isReturn()) { throw new EC2Exception("Could not delete keypair : "+keyName+". No reason given."); } } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Enumerates image list attribute operation types. */ public enum ImageListAttributeOperationType { add, remove } /** * Modifies an attribute by the given items with the given operation. * * @param imageId The ID of the AMI to modify the attributes for. * @param attribute The name of the attribute to change. * @param operationType The name of the operation to change. May be add or remove. * @throws EC2Exception wraps checked exceptions */ public void modifyImageAttribute(String imageId, ImageListAttribute attribute, ImageListAttributeOperationType operationType) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("ImageId", imageId); if (attribute.getType().equals(ImageAttribute.ImageAttributeType.launchPermission)) { params.put("Attribute", "launchPermission"); switch (operationType) { case add: params.put("OperationType", "add"); break; case remove: params.put("OperationType", "remove"); break; default: throw new IllegalArgumentException("Unknown attribute operation."); } } else if (attribute.getType().equals(ImageAttribute.ImageAttributeType.productCodes)) { params.put("Attribute", "productCodes"); } int gNum = 1; int iNum = 1; int pNum = 1; for(ImageListAttributeItem item : attribute.getImageListAttributeItems()) { switch (item.getType()) { case group: params.put("UserGroup."+gNum, item.getValue()); gNum++; break; case userId: params.put("UserId."+iNum, item.getValue()); iNum++; break; case productCode: params.put("ProductCode."+pNum, item.getValue()); pNum++; break; default: throw new IllegalArgumentException("Unknown item type."); } } GetMethod method = new GetMethod(); try { ModifyImageAttributeResponse response = makeRequest(method, "ModifyImageAttribute", params, ModifyImageAttributeResponse.class); if (!response.isReturn()) { throw new EC2Exception("Could not reset image attribute. No reason given."); } } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Resets an attribute on an AMI. * * @param imageId The AMI to reset the attribute on. * @param imageAttribute The attribute type to reset. * @throws EC2Exception wraps checked exceptions */ public void resetImageAttribute(String imageId, ImageAttribute.ImageAttributeType imageAttribute) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("ImageId", imageId); if (imageAttribute.equals(ImageAttribute.ImageAttributeType.launchPermission)) { params.put("Attribute", "launchPermission"); } else if (imageAttribute.equals(ImageAttribute.ImageAttributeType.productCodes)) { throw new IllegalArgumentException("Cannot reset productCodes attribute"); } GetMethod method = new GetMethod(); try { ResetImageAttributeResponse response = makeRequest(method, "ResetImageAttribute", params, ResetImageAttributeResponse.class); if (!response.isReturn()) { throw new EC2Exception("Could not reset image attribute. No reason given."); } } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Describes an attribute of an AMI. * * @param imageId The AMI for which the attribute is described. * @param imageAttribute The attribute type to describe. * @return An object containing the imageId and a list of list attribute item types and values. * @throws EC2Exception wraps checked exceptions */ public DescribeImageAttributeResult describeImageAttribute(String imageId, ImageAttribute.ImageAttributeType imageAttribute) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("ImageId", imageId); if (imageAttribute.equals(ImageAttribute.ImageAttributeType.launchPermission)) { params.put("Attribute", "launchPermission"); } else if (imageAttribute.equals(ImageAttribute.ImageAttributeType.productCodes)) { params.put("Attribute", "productCodes"); } GetMethod method = new GetMethod(); try { DescribeImageAttributeResponse response = makeRequest(method, "DescribeImageAttribute", params, DescribeImageAttributeResponse.class); ImageListAttribute attribute = null; if (response.getLaunchPermission() != null) { LaunchPermissionListType list = response.getLaunchPermission(); attribute = new LaunchPermissionAttribute(); java.util.ListIterator i = list.getItems().listIterator(); while (i.hasNext()) { LaunchPermissionItemType item = (LaunchPermissionItemType) i.next(); if (item.getGroup() != null) { attribute.addImageListAttributeItem(ImageListAttribute.ImageListAttributeItemType.group, item.getGroup()); } else if (item.getUserId() != null) { attribute.addImageListAttributeItem(ImageListAttribute.ImageListAttributeItemType.userId, item.getUserId()); } } } else if (response.getProductCodes() != null) { ProductCodeListType list = response.getProductCodes(); attribute = new ProductCodesAttribute(); java.util.ListIterator i = list.getItems().listIterator(); while (i.hasNext()) { ProductCodeItemType item = (ProductCodeItemType) i.next(); if (item.getProductCode() != null) { attribute.addImageListAttributeItem(ImageListAttribute.ImageListAttributeItemType.productCode, item.getProductCode()); } } } ArrayList<String> codes = new ArrayList<String>(); ProductCodeListType set = response.getProductCodes(); if (set != null) { for (ProductCodeItemType code : set.getItems()) { codes.add(code.getProductCode()); } } NullableAttributeValueType val = response.getKernel(); String kernel = (val != null)?val.getValue():""; val = response.getRamdisk(); String ramdisk = (val != null)?val.getValue():""; ArrayList<BlockDeviceMapping> bdm = new ArrayList<BlockDeviceMapping>(); BlockDeviceMappingType bdmSet = response.getBlockDeviceMapping(); if (bdmSet != null) { for (BlockDeviceMappingItemType mapping : bdmSet.getItems()) { bdm.add(new BlockDeviceMapping(mapping.getVirtualName(), mapping.getDeviceName())); } } return new DescribeImageAttributeResult(response.getImageId(), attribute, codes, kernel, ramdisk, bdm); } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Returns true if the productCode is associated with the instance. * * @param instanceId An instance's id ({@link com.xerox.amazonws.ec2.ReservationDescription.Instance#instanceId}. * @param productCode the code for the project you registered with AWS * @return null if no relationship exists, otherwise information about the owner * @throws EC2Exception wraps checked exceptions */ public ProductInstanceInfo confirmProductInstance(String instanceId, String productCode) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("InstanceId", instanceId); params.put("ProductCode", productCode); GetMethod method = new GetMethod(); try { ConfirmProductInstanceResponse response = makeRequest(method, "ConfirmProductInstance", params, ConfirmProductInstanceResponse.class); if (response.isReturn()) { return new ProductInstanceInfo(instanceId, productCode, response.getOwnerId()); } else return null; } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Returns a list of availability zones and their status. * * @param zones a list of zones to limit the results, or null * @return a list of zones and their availability * @throws EC2Exception wraps checked exceptions */ public List<AvailabilityZone> describeAvailabilityZones(List<String> zones) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); if (zones != null && zones.size() > 0) { for (int i=0 ; i<zones.size(); i++) { params.put("ZoneName."+(i+1), zones.get(i)); } } GetMethod method = new GetMethod(); try { DescribeAvailabilityZonesResponse response = makeRequest(method, "DescribeAvailabilityZones", params, DescribeAvailabilityZonesResponse.class); List<AvailabilityZone> ret = new ArrayList<AvailabilityZone>(); AvailabilityZoneSetType set = response.getAvailabilityZoneInfo(); Iterator set_iter = set.getItems().iterator(); while (set_iter.hasNext()) { AvailabilityZoneItemType item = (AvailabilityZoneItemType) set_iter.next(); ret.add(new AvailabilityZone(item.getZoneName(), item.getZoneState())); } return ret; } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Returns a list of addresses associated with this account. * * @param addresses a list of zones to limit the results, or null * @return a list of addresses and their associated instance * @throws EC2Exception wraps checked exceptions */ public List<AddressInfo> describeAddresses(List<String> addresses) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); if (addresses != null && addresses.size() > 0) { for (int i=0 ; i<addresses.size(); i++) { params.put("PublicIp."+(i+1), addresses.get(i)); } } GetMethod method = new GetMethod(); try { DescribeAddressesResponse response = makeRequest(method, "DescribeAddresses", params, DescribeAddressesResponse.class); List<AddressInfo> ret = new ArrayList<AddressInfo>(); DescribeAddressesResponseInfoType set = response.getAddressesSet(); Iterator set_iter = set.getItems().iterator(); while (set_iter.hasNext()) { DescribeAddressesResponseItemType item = (DescribeAddressesResponseItemType) set_iter.next(); ret.add(new AddressInfo(item.getPublicIp(), item.getInstanceId())); } return ret; } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Allocates an address for this account. * * @return the new address allocated * @throws EC2Exception wraps checked exceptions */ public String allocateAddress() throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); GetMethod method = new GetMethod(); try { AllocateAddressResponse response = makeRequest(method, "AllocateAddress", params, AllocateAddressResponse.class); return response.getPublicIp(); } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Associates an address with an instance. * * @param instanceId the instance * @param publicIp the ip address to associate * @throws EC2Exception wraps checked exceptions */ public void associateAddress(String instanceId, String publicIp) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("InstanceId", instanceId); params.put("PublicIp", publicIp); GetMethod method = new GetMethod(); try { AssociateAddressResponse response = makeRequest(method, "AssociateAddress", params, AssociateAddressResponse.class); if (!response.isReturn()) { throw new EC2Exception("Could not associate address with instance (no reason given)."); } } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Disassociates an address with an instance. * * @param publicIp the ip address to disassociate * @throws EC2Exception wraps checked exceptions */ public void disassociateAddress(String publicIp) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("PublicIp", publicIp); GetMethod method = new GetMethod(); try { DisassociateAddressResponse response = makeRequest(method, "DisassociateAddress", params, DisassociateAddressResponse.class); if (!response.isReturn()) { throw new EC2Exception("Could not disassociate address with instance (no reason given)."); } } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } /** * Releases an address * * @param publicIp the ip address to release * @throws EC2Exception wraps checked exceptions */ public void releaseAddress(String publicIp) throws EC2Exception { Map<String, String> params = new HashMap<String, String>(); params.put("PublicIp", publicIp); GetMethod method = new GetMethod(); try { ReleaseAddressResponse response = makeRequest(method, "ReleaseAddress", params, ReleaseAddressResponse.class); if (!response.isReturn()) { throw new EC2Exception("Could not release address (no reason given)."); } } catch (JAXBException ex) { throw new EC2Exception("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new EC2Exception(ex.getMessage(), ex); } catch (IOException ex) { throw new EC2Exception(ex.getMessage(), ex); } finally { method.releaseConnection(); } } }