All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.elastisys.scale.cloudpool.aws.commons.requests.ec2.TerminateInstances Maven / Gradle / Ivy

There is a newer version: 5.2.3
Show newest version
package com.elastisys.scale.cloudpool.aws.commons.requests.ec2;

import static com.elastisys.scale.cloudpool.aws.commons.predicates.InstancePredicates.allInAnyOfStates;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.ec2.model.InstanceStateChange;
import com.amazonaws.services.ec2.model.TerminateInstancesRequest;
import com.amazonaws.services.ec2.model.TerminateInstancesResult;
import com.elastisys.scale.commons.net.retryable.Retryable;
import com.elastisys.scale.commons.net.retryable.Retryers;

import jersey.repackaged.com.google.common.collect.ImmutableList;

/**
 * A {@link Callable} task that, when executed, terminates a collection of EC2
 * instances terminated and waits for the instance to appear
 * terminating/terminated in {@code DescribeInstances}, which may not be
 * immediate due to the eventual consistency semantics of the Amazon API.
 */
public class TerminateInstances
		extends AmazonEc2Request> {

	/** Initial exponential back-off delay in ms. */
	private static final int INITIAL_BACKOFF_DELAY = 1000;
	/** Maximum number of retries of operations. */
	private static final int MAX_RETRIES = 8;

	/** The identifiers of the instances to be terminated. */
	private final List instanceIds;

	public TerminateInstances(AWSCredentials awsCredentials, String region,
			ClientConfiguration clientConfig, String... instanceIds) {
		this(awsCredentials, region, clientConfig,
				ImmutableList.copyOf(instanceIds));
	}

	public TerminateInstances(AWSCredentials awsCredentials, String region,
			ClientConfiguration clientConfig, Collection instanceIds) {
		super(awsCredentials, region, clientConfig);
		this.instanceIds = ImmutableList.copyOf(instanceIds);
	}

	@Override
	public List call() {
		TerminateInstancesRequest request = new TerminateInstancesRequest()
				.withInstanceIds(this.instanceIds);
		TerminateInstancesResult result = getClient().getApi()
				.terminateInstances(request);
		List stateChanges = result
				.getTerminatingInstances();

		awaitTermination(this.instanceIds);

		return stateChanges;
	}

	private void awaitTermination(List instanceIds) {
		String name = String.format("await-terminal-state{%s}", instanceIds);

		Callable> stateRequester = new GetInstances(
				getAwsCredentials(), getRegion(), getClientConfig(),
				instanceIds);
		Retryable> retryer = Retryers.exponentialBackoffRetryer(
				name, stateRequester, INITIAL_BACKOFF_DELAY,
				TimeUnit.MILLISECONDS, MAX_RETRIES,
				allInAnyOfStates("shutting-down", "terminated"));

		try {
			retryer.call();
		} catch (Exception e) {
			throw new RuntimeException(String.format(
					"gave up waiting for instances to terminate %s: %s",
					instanceIds, e.getMessage()), e);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy