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

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);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy