com.elastisys.scale.cloudpool.aws.commons.requests.ec2.TerminateInstances Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cloudpool.aws.commons Show documentation
Show all versions of cloudpool.aws.commons Show documentation
Common utility classes for building Amazon AWS-based cloud pools.
The newest version!
package com.elastisys.scale.cloudpool.aws.commons.requests.ec2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.ec2.model.TerminateInstancesRequest;
import com.amazonaws.services.ec2.model.TerminateInstancesResult;
import com.elastisys.scale.cloudpool.aws.commons.predicates.InstancePredicates;
import com.elastisys.scale.commons.net.retryable.Retryable;
import com.elastisys.scale.commons.net.retryable.Retryers;
/**
* A {@link Callable} task that, when executed, terminates a collection of EC2
* instances and waits for the instances 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, Arrays.asList(instanceIds));
}
public TerminateInstances(AWSCredentials awsCredentials, String region, ClientConfiguration clientConfig,
Collection instanceIds) {
super(awsCredentials, region, clientConfig);
this.instanceIds = new ArrayList<>(instanceIds);
}
@Override
public TerminateInstancesResult call() {
TerminateInstancesRequest request = new TerminateInstancesRequest().withInstanceIds(this.instanceIds);
TerminateInstancesResult result = getClient().getApi().terminateInstances(request);
awaitTermination(this.instanceIds);
return result;
}
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);
}
}
private Predicate> allInAnyOfStates(String... acceptableStates) {
return instances -> InstancePredicates.allInAnyOfStates(acceptableStates).test(instances);
}
}