package com.intuit.tank.vmManager.environment.amazon; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Random; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.Future; import javax.annotation.Nonnull; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.amazonaws.ClientConfiguration; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.ec2.AmazonEC2AsyncClient; import com.amazonaws.services.ec2.model.Address; import com.amazonaws.services.ec2.model.AssociateAddressRequest; import com.amazonaws.services.ec2.model.AttachVolumeRequest; import com.amazonaws.services.ec2.model.CreateTagsRequest; import com.amazonaws.services.ec2.model.DescribeAddressesRequest; import com.amazonaws.services.ec2.model.DescribeAddressesResult; import com.amazonaws.services.ec2.model.DescribeInstancesRequest; import com.amazonaws.services.ec2.model.DescribeInstancesResult; import com.amazonaws.services.ec2.model.IamInstanceProfileSpecification; import com.amazonaws.services.ec2.model.Instance; import com.amazonaws.services.ec2.model.InstanceStateChange; import com.amazonaws.services.ec2.model.InstanceType; import com.amazonaws.services.ec2.model.Placement; import com.amazonaws.services.ec2.model.RebootInstancesRequest; import com.amazonaws.services.ec2.model.Reservation; import com.amazonaws.services.ec2.model.RunInstancesRequest; import com.amazonaws.services.ec2.model.RunInstancesResult; import com.amazonaws.services.ec2.model.StartInstancesRequest; import com.amazonaws.services.ec2.model.StartInstancesResult; import com.amazonaws.services.ec2.model.StopInstancesRequest; import com.amazonaws.services.ec2.model.StopInstancesResult; import com.amazonaws.services.ec2.model.Tag; import com.amazonaws.services.ec2.model.Tenancy; import com.amazonaws.services.ec2.model.TerminateInstancesRequest; import com.amazonaws.services.ec2.model.TerminateInstancesResult; import com.intuit.tank.dao.JobInstanceDao; import com.intuit.tank.project.JobInstance; import com.intuit.tank.vm.api.enumerated.VMImageType; import com.intuit.tank.vm.api.enumerated.VMRegion; import com.intuit.tank.vm.common.TankConstants; import com.intuit.tank.vm.settings.CloudCredentials; import com.intuit.tank.vm.settings.CloudProvider; import com.intuit.tank.vm.settings.InstanceDescription; import com.intuit.tank.vm.settings.InstanceTag; import com.intuit.tank.vm.settings.TankConfig; import com.intuit.tank.vm.settings.VmInstanceType; import com.intuit.tank.vm.vmManager.VMInformation; import com.intuit.tank.vm.vmManager.VMInstanceRequest; import com.intuit.tank.vm.vmManager.VMKillRequest; import com.intuit.tank.vm.vmManager.VMRequest; import com.intuit.tank.vmManager.environment.IEnvironmentInstance; public class AmazonInstance implements IEnvironmentInstance { protected static final long ASSOCIATE_IP_MAX_WAIT_MILIS = 1000 * 60 * 2;// 2 // minutes private static Logger LOG = LogManager.getLogger(AmazonInstance.class); private AmazonEC2AsyncClient asynchEc2Client; // private TypicaInterface ec2Interface; private VMRegion vmRegion; private VMRequest request; private TankConfig config = new TankConfig(); // private static final Set<String> reservedEipSet = // Collections.synchronizedSet(new HashSet<String>()); /** * * @param request * @param vmRegion */ public AmazonInstance(VMRequest request, VMRegion vmRegion) { // In case vmRegion is passed as null, use default region from settings // file if (vmRegion == null) { // vmRegion = VMRegion.US_EAST; vmRegion = config.getVmManagerConfig().getDefaultRegion(); } this.vmRegion = vmRegion; this.request = request; try { CloudCredentials creds = config.getVmManagerConfig().getCloudCredentials(CloudProvider.amazon); AWSCredentials credentials = null; if (StringUtils.isNotBlank(creds.getKey()) && StringUtils.isNotBlank(creds.getKeyId())) { credentials = new BasicAWSCredentials(creds.getKeyId(), creds.getKey()); } ClientConfiguration clientConfig = new ClientConfiguration(); if (StringUtils.isNotBlank(creds.getProxyHost())) { try { clientConfig.setProxyHost(creds.getProxyHost()); if (StringUtils.isNotBlank(creds.getProxyPort())) { clientConfig.setProxyPort(Integer.valueOf(creds.getProxyPort())); } } catch (NumberFormatException e) { LOG.error("invalid proxy setup."); } } if (credentials != null) { asynchEc2Client = new AmazonEC2AsyncClient(credentials, clientConfig, Executors.newFixedThreadPool(2)); } else { asynchEc2Client = new AmazonEC2AsyncClient(clientConfig); } // asynchEc2Client = new AmazonEC2AsyncClient(new // BasicAWSCredentials(creds.getKeyId(), creds.getKey())); asynchEc2Client.setEndpoint(vmRegion.getEndpoint()); } catch (Exception ex) { LOG.error("Error initializing amazonclient: " + ex, ex); throw new RuntimeException(ex); } } public void attachVolume(String volumneId, String instanceId, String device) { AttachVolumeRequest attachVolumeRequest = new AttachVolumeRequest(volumneId, instanceId, device); asynchEc2Client.attachVolume(attachVolumeRequest); RebootInstancesRequest rebootInstancesRequest = new RebootInstancesRequest(); rebootInstancesRequest.withInstanceIds(instanceId); asynchEc2Client.rebootInstances(rebootInstancesRequest); } /** * * @{inheritDoc */ @Override public List<VMInformation> describeInstances(String... instanceIds) { List<VMInformation> result = new ArrayList<VMInformation>(); try { DescribeInstancesResult results = asynchEc2Client.describeInstances(); HashSet<String> ids = new HashSet<String>(Arrays.asList(instanceIds)); for (Reservation reservationDescription : results.getReservations()) { for (com.amazonaws.services.ec2.model.Instance instance : reservationDescription.getInstances()) { if (ids.contains(instance.getInstanceId())) { result.add(new AmazonDataConverter().instanceToVmInformation(reservationDescription, instance, vmRegion)); } } // result.addAll(TypicaDataConverter.processReservationDescription(reservationDescription)); } } catch (Exception e) { LOG.error("Failed to retrieve instance from Amazon: " + e.getMessage()); throw new RuntimeException(e); } return result; } /** * * @{inheritDoc */ @Override public List<VMInformation> create() { List<VMInformation> result = null; try { VMInstanceRequest instanceRequest = (VMInstanceRequest) request; InstanceDescription instanceDescription = instanceRequest.getInstanceDescription(); if (instanceDescription == null) { instanceDescription = new TankConfig().getVmManagerConfig().getInstanceForRegionAndType(vmRegion, instanceRequest.getImage()); } // Get the required data int number = instanceRequest.getNumberOfInstances(); String image = instanceDescription.getAmi(); if (instanceRequest.getReuseStoppedInstance()) { List<VMInformation> instances = findAllInstancesOfType(this.vmRegion, instanceRequest.getImage()); LOG.info("looking for stopped instance with ami-id of " + instanceRequest.getImage()); for (VMInformation vmInfo : instances) { LOG.info("found instance with id " + vmInfo.getInstanceId() + " with state of " + vmInfo.getState()); if ("stopped".equalsIgnoreCase(vmInfo.getState())) { StartInstancesRequest startInstancesRequest = new StartInstancesRequest(); startInstancesRequest.withInstanceIds(vmInfo.getInstanceId()); // restart this instance StartInstancesResult startInstances = asynchEc2Client.startInstances(startInstancesRequest); result = new AmazonDataConverter().processStateChange(startInstances.getStartingInstances()); break; } } } if (result == null) { InstanceType size = AmazonInstance.getInstanceType(instanceRequest.getSize()); VmInstanceType vmType = config.getVmManagerConfig().getInstanceType(instanceRequest.getSize()); String keyPair = instanceDescription.getKeypair(); if (instanceRequest.getJobId() != null) { instanceRequest.addUserData(TankConstants.KEY_JOB_ID, instanceRequest.getJobId()); } if (instanceRequest.getReportingMode() != null) { LOG.info("Setting reporting mode to " + instanceRequest.getReportingMode()); instanceRequest.addUserData(TankConstants.KEY_REPORTING_MODE, instanceRequest.getReportingMode()); } else { LOG.warn("Reporting mode not set."); } if (vmType.getJvmArgs() != null) { instanceRequest.addUserData(TankConstants.KEY_JVM_ARGS, vmType.getJvmArgs()); } CloudCredentials cloudCredentials = config.getVmManagerConfig().getCloudCredentials(CloudProvider.amazon); if (StringUtils.isNotBlank(cloudCredentials.getKeyId()) && StringUtils.isNotBlank(cloudCredentials.getKey())) { instanceRequest.addUserData(TankConstants.KEY_AWS_SECRET_KEY_ID, cloudCredentials.getKeyId()); instanceRequest.addUserData(TankConstants.KEY_AWS_SECRET_KEY, cloudCredentials.getKey()); } instanceRequest.addUserData(TankConstants.KEY_CONTROLLER_URL, config.getControllerBase()); instanceRequest.addUserData(TankConstants.KEY_NUM_USERS_PER_AGENT, Integer.toString(instanceRequest.getNumUsersPerAgent())); if (instanceRequest.isUseEips()) { instanceRequest.addUserData(TankConstants.KEY_USING_BIND_EIP, Boolean.TRUE.toString()); } if (instanceRequest.getLoggingProfile() != null) { LOG.info("Setting loggingProfile to " + instanceRequest.getLoggingProfile()); instanceRequest.addUserData(TankConstants.KEY_LOGGING_PROFILE, instanceRequest.getLoggingProfile()); } else { LOG.warn("Logging profile not set."); } if (instanceRequest.getStopBehavior() != null) { LOG.info("Setting stopBehavior to " + instanceRequest.getStopBehavior()); instanceRequest.addUserData(TankConstants.KEY_STOP_BEHAVIOR, instanceRequest.getStopBehavior()); } else { LOG.warn("stop Behavior not set."); } String userData = buildUserData(instanceRequest.getUserData()); Set<Address> availableEips = new HashSet<Address>(); if (instanceRequest.isUseEips()) { synchronized (instanceRequest.getRegion()) { DescribeAddressesResult describeAddresses = asynchEc2Client.describeAddresses(new DescribeAddressesRequest()); Set<String> reserved = config.getVmManagerConfig().getReservedElasticIps(); for (Address address : describeAddresses.getAddresses()) { String elasticIPType = instanceDescription.isVPC() ? "vpc" : "standard"; if (elasticIPType.equalsIgnoreCase(address.getDomain()) && StringUtils.isBlank(address.getInstanceId())) { String ip = address.getPublicIp(); if (!reserved.contains(ip)) { availableEips.add(address); } } } } } List<Address> randomizedIps = new ArrayList<Address>(availableEips); Collections.shuffle(randomizedIps); RunInstancesRequest runInstancesRequest = new RunInstancesRequest(image, number, number); Tenancy tenancy = instanceDescription.isVPC() ? Tenancy.Dedicated : Tenancy.Default; runInstancesRequest.withInstanceType(size.toString()) .withKeyName(keyPair) .withPlacement(new Placement().withTenancy(tenancy)) .withMonitoring(true) .withUserData(userData); // add subnet if defined if (!StringUtils.isEmpty(instanceDescription.getSubnetId())) { runInstancesRequest.withSubnetId(instanceDescription.getSubnetId()); } Collection<String> c = instanceDescription.getSecurityGroupIds(); if (!c.isEmpty()) { LOG.info("Security Group IDs " + c.toString()); runInstancesRequest.withSecurityGroupIds(c); } else { runInstancesRequest.withSecurityGroups(instanceDescription.getSecurityGroup()); } if (StringUtils.isNotBlank(instanceDescription.getIamRole())) { IamInstanceProfileSpecification iamInstanceProfile = new IamInstanceProfileSpecification().withName(instanceDescription.getIamRole()); runInstancesRequest.withIamInstanceProfile(iamInstanceProfile); } // add zone info if specified if (!StringUtils.isEmpty(instanceDescription.getZone())) { runInstancesRequest.withPlacement(new Placement().withAvailabilityZone(instanceDescription.getZone())); } RunInstancesResult results = asynchEc2Client.runInstances(runInstancesRequest); result = new AmazonDataConverter().processReservation(results.getReservation(), vmRegion); if (instanceRequest.isUseEips()) { synchronized (instanceRequest.getRegion()) { Iterator<Address> iter = randomizedIps.iterator(); List<AssociateContainer> bindIps = new ArrayList<AssociateContainer>(); for (VMInformation info : result) { if (!iter.hasNext()) { break; } bindIps.add(new AssociateContainer(info.getInstanceId(), iter.next())); } CountDownLatch latch = new CountDownLatch(bindIps.size()); for (AssociateContainer container : bindIps) { associateAddress(container.instanceId, container.address, latch); } latch.await(); } } } if (instanceDescription.getPublicIp() != null && result.size() == 1) { // bind to the public ip String instanceId = result.get(0).getInstanceId(); // wait for instance to be in running state associateAddress(instanceId, new Address().withPublicIp(instanceDescription.getPublicIp()), null); // reboot(result); } if (result.size() > 0) { List<String> ids = new ArrayList<String>(); for (VMInformation inst : result) { ids.add(inst.getInstanceId()); } LOG.info("Setting tags for instances " + ids); tagInstance(ids, buildTags(instanceRequest)); } } catch (Exception ex) { LOG.error("Error starting instancs: " + ex.getMessage(), ex); throw new RuntimeException(ex); } return result; } /** * * @{inheritDoc */ @Override public void tagInstance(final List<String> instanceIds, KeyValuePair... tag) { if (tag.length != 0) { final List<Tag> tags = new ArrayList<Tag>(); for (KeyValuePair pair : tag) { tags.add(new Tag(pair.getKey(), pair.getValue())); } new Thread(new Runnable() { @Override public void run() { int count = 0; try { while (++count <= 5 && !instanceIds.isEmpty()) { Thread.sleep(5000); CreateTagsRequest createTagsRequest = new CreateTagsRequest().withResources(instanceIds).withTags(tags); asynchEc2Client.createTagsAsync(createTagsRequest); Thread.sleep(1000); Future<DescribeInstancesResult> describeInstances = asynchEc2Client.describeInstancesAsync(new DescribeInstancesRequest().withInstanceIds(instanceIds)); for (Reservation r : describeInstances.get().getReservations()) { for (Instance i : r.getInstances()) { if (i.getTags() != null && !i.getTags().isEmpty()) { instanceIds.remove(i.getInstanceId()); } } } } } catch (Exception e) { LOG.error("Error tagging instances: " + e, e); } }; }).start(); } } /** * @param instanceDescription * @param instance * @return */ private KeyValuePair[] buildTags(VMInstanceRequest instanceRequest) { List<KeyValuePair> pairs = new ArrayList<KeyValuePair>(); pairs.add(new KeyValuePair("Name", buildNameTag(instanceRequest))); if (instanceRequest.getJobId() != null) { instanceRequest.addUserData(TankConstants.KEY_JOB_ID, instanceRequest.getJobId()); instanceRequest.addUserData(TankConstants.KEY_CONTROLLER_URL, config.getControllerBase()); if (NumberUtils.isNumber(instanceRequest.getJobId())) { JobInstance jobInstance = new JobInstanceDao().findById(Integer.valueOf(instanceRequest.getJobId())); if (jobInstance != null) { pairs.add(new KeyValuePair("JobName", jobInstance.getName())); } } } List<InstanceTag> tags = config.getVmManagerConfig().getTags(); for (InstanceTag tag : tags) { pairs.add(new KeyValuePair(tag.getName(), tag.getValue())); } return pairs.toArray(new KeyValuePair[pairs.size()]); } /** * @param instanceDescription * @param instance * @return */ private String buildNameTag(VMInstanceRequest instanceRequest) { StringBuilder sb = new StringBuilder(instanceRequest.getImage().getConfigName()); if (instanceRequest.getJobId() != null) { sb.append(" job(" + instanceRequest.getJobId() + ")"); } return sb.toString(); } @Override public List<VMInformation> kill() { List<VMInformation> result = null; try { VMKillRequest killRequest = (VMKillRequest) request; TerminateInstancesRequest terminateInstancesRequest = new TerminateInstancesRequest(killRequest.getInstances()); TerminateInstancesResult terminateInstances = asynchEc2Client.terminateInstances(terminateInstancesRequest); result = new AmazonDataConverter().processStateChange(terminateInstances.getTerminatingInstances()); } catch (Exception ex) { LOG.error(ex.getMessage()); throw new RuntimeException(ex); } return result; } public void killInstances(List<VMInformation> instances) { List<String> instanceIds = new ArrayList<String>(instances.size()); for (VMInformation instance : instances) { instanceIds.add(instance.getInstanceId()); } asynchEc2Client.terminateInstances(new TerminateInstancesRequest(instanceIds)); } @Override public List<VMInformation> kill(List<String> instanceIds) { List<VMInformation> result = new ArrayList<VMInformation>(); try { for (VMRegion region : config.getVmManagerConfig().getRegions()) { result.addAll(killForRegion(region, instanceIds)); } asynchEc2Client.setEndpoint(vmRegion.getEndpoint()); } catch (Exception ex) { LOG.error(ex.getMessage()); throw new RuntimeException(ex); } return result; } private List<VMInformation> killForRegion(VMRegion region, List<String> instanceIds) { List<VMInformation> result = new ArrayList<VMInformation>(); try { asynchEc2Client.setEndpoint(region.getEndpoint()); List<VMInformation> instances = describeInstances(instanceIds.toArray(new String[instanceIds.size()])); List<String> ids = new ArrayList<String>(); for (VMInformation info : instances) { ids.add(info.getInstanceId()); } if (ids.size() > 0) { TerminateInstancesRequest terminateInstancesRequest = new TerminateInstancesRequest(ids); TerminateInstancesResult terminateInstances = asynchEc2Client.terminateInstances(terminateInstancesRequest); result = new AmazonDataConverter().processStateChange(terminateInstances.getTerminatingInstances()); } } catch (Exception ex) { LOG.error(ex.getMessage(), ex); throw new RuntimeException(ex); } return result; } private List<VMInformation> stopForRegion(VMRegion region, List<String> instanceIds) { List<VMInformation> result = new ArrayList<VMInformation>(); try { asynchEc2Client.setEndpoint(region.getEndpoint()); List<VMInformation> instances = describeInstances(instanceIds.toArray(new String[instanceIds.size()])); List<String> ids = new ArrayList<String>(); for (VMInformation info : instances) { ids.add(info.getInstanceId()); } if (ids.size() > 0) { StopInstancesRequest stopInstancesRequest = new StopInstancesRequest(ids); StopInstancesResult stopResult = asynchEc2Client.stopInstances(stopInstancesRequest); List<InstanceStateChange> stoppingInstances = stopResult.getStoppingInstances(); result = new AmazonDataConverter().processStateChange(stoppingInstances); } } catch (Exception ex) { LOG.error(ex.getMessage(), ex); throw new RuntimeException(ex); } return result; } /** * @{inheritDoc */ @Override public List<VMInformation> findInstancesOfType(VMRegion region, VMImageType type) { List<VMInformation> ret = new ArrayList<VMInformation>(); try { DescribeInstancesResult instances = asynchEc2Client.describeInstances(); InstanceDescription instanceForRegionAndType = new TankConfig().getVmManagerConfig().getInstanceForRegionAndType(region, type); for (Reservation res : instances.getReservations()) { if (res.getInstances() != null) { for (com.amazonaws.services.ec2.model.Instance inst : res.getInstances()) { if ((inst.getState().getName().equalsIgnoreCase("running") || inst.getState().getName().equalsIgnoreCase("pending")) && inst.getImageId().equals(instanceForRegionAndType.getAmi())) { ret.add(new AmazonDataConverter().instanceToVmInformation(res, inst, region)); } } } } } catch (Exception e) { LOG.error("Error getting instances: " + e.toString(), e); throw new RuntimeException(e); } return ret; } // /** // * @{inheritDoc // */ // public List<VMInformation> getTagInfo(String... instanceIds) { // List<VMInformation> ret = new ArrayList<VMInformation>(); // try { // DescribeTagsResult tags = asynchEc2Client.describeTags(); // for (TagDescription tag : tags.getTags()) { // tag.g // } // InstanceDescription instanceForRegionAndType = new // TankConfig().getVmManagerConfig() // .getInstanceForRegionAndType(region, type); // for (Reservation res : instances.getReservations()) { // if (res.getInstances() != null) { // for (com.amazonaws.services.ec2.model.Instance inst : res.getInstances()) // { // if ((inst.getState().getName().equalsIgnoreCase("running") || // inst.getState().getName() // .equalsIgnoreCase("pending")) // && inst.getImageId().equals(instanceForRegionAndType.getAmi())) { // ret.add(new AmazonDataConverter().instanceToVmInformation(res, inst)); // } // } // } // } // } catch (Exception e) { // LOG.error("Error getting instances: " + e.toString(), e); // throw new RuntimeException(e); // } // return ret; // } /** * @{inheritDoc */ private List<VMInformation> findAllInstancesOfType(VMRegion region, VMImageType type) { List<VMInformation> ret = new ArrayList<VMInformation>(); try { DescribeInstancesResult instances = asynchEc2Client.describeInstances(); InstanceDescription instanceForRegionAndType = new TankConfig().getVmManagerConfig().getInstanceForRegionAndType(region, type); for (Reservation res : instances.getReservations()) { if (res.getInstances() != null) { for (com.amazonaws.services.ec2.model.Instance inst : res.getInstances()) { if (inst.getImageId().equals(instanceForRegionAndType.getAmi())) { ret.add(new AmazonDataConverter().instanceToVmInformation(res, inst, region)); } } } } } catch (Exception e) { LOG.error("Error getting instances: " + e.toString(), e); throw new RuntimeException(e); } return ret; } /** * Get the size of the instance * * @param size * The size requested * @return The size assigned */ private static InstanceType getInstanceType(String size) { InstanceType output = InstanceType.C32xlarge; try { output = InstanceType.fromValue(size); } catch (Exception e) { LOG.warn("Error parsing vminstanceType " + size, e); } return output; } @Override public void associateAddress(final String instanceId, final Address address, final CountDownLatch latch) { new Thread(new Runnable() { @Override public void run() { boolean associated = false; try { long start = System.currentTimeMillis(); int count = 0; LOG.info("Setting ip for instance " + instanceId + " to " + address.getPublicIp()); while ((System.currentTimeMillis() - start) < ASSOCIATE_IP_MAX_WAIT_MILIS && !associated) { count++; try { long sleep = (new Random().nextInt(10) + 10) * 100L; Thread.sleep(sleep); if (address.getAllocationId() == null) { asynchEc2Client.associateAddressAsync(new AssociateAddressRequest() .withInstanceId(instanceId) .withPublicIp(address.getPublicIp())); } else { asynchEc2Client.associateAddressAsync(new AssociateAddressRequest() .withInstanceId(instanceId) .withAllocationId(address.getAllocationId())); } Thread.sleep(sleep); Future<DescribeInstancesResult> describeInstances = asynchEc2Client.describeInstancesAsync(new DescribeInstancesRequest().withInstanceIds(instanceId)); for (Reservation r : describeInstances.get().getReservations()) { for (Instance i : r.getInstances()) { if (address.getPublicIp().equals(i.getPublicIpAddress())) { associated = true; } } } if (associated) { LOG.info(instanceId + " associated with " + address.getPublicIp()); } else if (count % 5 == 0) { LOG.info(instanceId + " not associated yet " + address.getPublicIp() + ". Retrying... count = " + count); } } catch (Exception e) { if (count < 5) { LOG.warn("Error associating ip address: " + e + " Will retry."); } } } } catch (Exception e) { LOG.error("Error setting elastic ip: " + e, e); } finally { LOG.info("exiting associated = " + associated); if (latch != null) { latch.countDown(); } } }; }).start(); } @Override public void reboot(List<VMInformation> instances) { List<String> instanceIds = new ArrayList<String>(instances.size()); for (VMInformation instance : instances) { instanceIds.add(instance.getInstanceId()); } asynchEc2Client.rebootInstancesAsync(new RebootInstancesRequest(instanceIds)); // ec2Interface.rebootInstances(instanceIds); } /** * @param instanceIds */ public List<VMInformation> stopInstances(List<String> instanceIds) { List<VMInformation> result = new ArrayList<VMInformation>(); try { for (VMRegion region : config.getVmManagerConfig().getRegions()) { result.addAll(killForRegion(region, instanceIds)); } asynchEc2Client.setEndpoint(vmRegion.getEndpoint()); } catch (Exception ex) { LOG.error(ex.getMessage()); throw new RuntimeException(ex); } return result; } /** * @param jobId * @return */ private String buildUserData(@Nonnull Map<String, String> userDataMap) { StringBuilder sb = new StringBuilder(); for (Entry<String, String> entry : userDataMap.entrySet()) { if (sb.length() > 0) { sb.append('\n'); } sb.append(entry.getKey() + "=" + entry.getValue()); } return Base64.encodeBase64String(sb.toString().getBytes()); } private static class AssociateContainer { private String instanceId; private Address address; private AssociateContainer(String instanceId, Address address) { super(); this.instanceId = instanceId; this.address = address; } } public String findPublicName(String instanceId) { String ret = null; try { DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest().withInstanceIds(instanceId); DescribeInstancesResult result = asynchEc2Client.describeInstances(describeInstancesRequest); if (result.getReservations() != null && result.getReservations().size() == 1) { Reservation reservation = result.getReservations().get(0); String publicDnsName = reservation.getInstances().get(0).getPublicDnsName(); ret = publicDnsName; } } catch (Exception e) { LOG.error("Error getting public dns: " + e, e); } return ret; } }