package com.github.sbugat.ec2tools.service.aws;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.slf4j.ext.XLogger;
import org.slf4j.ext.XLoggerFactory;
import com.amazonaws.AmazonClientException;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.DescribeInstanceStatusRequest;
import com.amazonaws.services.ec2.model.DescribeInstanceStatusResult;
import com.amazonaws.services.ec2.model.InstanceStateChange;
import com.amazonaws.services.ec2.model.InstanceStateName;
import com.amazonaws.services.ec2.model.InstanceStatus;
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;
/**
* Amazon EC2 simple service, init credentials with default file $HOME/.aws/credentials .
*
* @author Sylvain Bugat
*/
@Singleton
public class AmazonEC2Service {
/*** SLF4J XLogger. */
private static final XLogger LOG = XLoggerFactory.getXLogger(AmazonEC2Service.class);
/** Amazon EC2 service access. */
@Inject
private AmazonEC2Client amazonEC2Client;
/**
* Amazon EC2 service initialization.
*/
public void initialize() {
LOG.entry();
LOG.info("Initialize ECS AWS client");
// AWS client initialization
// TODO region customization
amazonEC2Client.setRegion(Region.getRegion(Regions.EU_WEST_1));
// Simple connection test
LOG.info("AWS configuration loaded, now doing connection test...");
amazonEC2Client.describeAvailabilityZones();
LOG.info("Connection with AWS OK");
LOG.exit();
}
/**
* Check the instance status and order to start it if it's stopped.
*
* @param instanceId Instance du start
*/
public void startInstance(final String instanceId) {
LOG.entry();
LOG.info("Starting instance {}", instanceId);
// Check the instance state
final InstanceStateName instanteState = getInstanceStatus(instanceId);
if (InstanceStateName.Stopped != instanteState) {
final String message = "Instance " + instanceId + " is not stopped, current state: " + instanteState;
LOG.error(message);
final AmazonClientException exception = new AmazonClientException(message);
LOG.exit(exception);
throw exception;
}
// Start instance order
final StartInstancesRequest startInstancesRequest = new StartInstancesRequest().withInstanceIds(instanceId);
final StartInstancesResult startInstancesResult = amazonEC2Client.startInstances(startInstancesRequest);
final List<InstanceStateChange> instanceStateChangeList = startInstancesResult.getStartingInstances();
for (final InstanceStateChange instanceStateChange : instanceStateChangeList) {
LOG.info("Instance {} has changing state: {} -> {}", instanceStateChange.getInstanceId(), instanceStateChange.getPreviousState(), instanceStateChange.getCurrentState());
}
LOG.info("Instance {} is starting", instanceId);
LOG.exit();
}
/**
* Check the instance status and order to stop it if it's running.
*
* @param instanceId instance to stop
*/
public void stopInstance(final String instanceId) {
LOG.entry();
LOG.info("Stoping instance {}", instanceId);
// Check the instance state
final InstanceStateName instanteState = getInstanceStatus(instanceId);
if (InstanceStateName.Running != instanteState) {
final String message = "Instance " + instanceId + " is not running, current status: " + instanteState;
LOG.error(message);
LOG.exit(message);
throw new AmazonClientException(message);
}
// Stop instance order
final StopInstancesRequest stopInstancesRequest = new StopInstancesRequest().withInstanceIds(instanceId);
final StopInstancesResult stopInstancesResult = amazonEC2Client.stopInstances(stopInstancesRequest);
final List<InstanceStateChange> instanceStateChangeList = stopInstancesResult.getStoppingInstances();
for (final InstanceStateChange instanceStateChange : instanceStateChangeList) {
LOG.info("Instance {} has changing state: {} -> {}", instanceStateChange.getInstanceId(), instanceStateChange.getPreviousState(), instanceStateChange.getCurrentState());
}
LOG.info("Instance {} is stoping", instanceId);
LOG.exit();
}
/**
* Method to return a current instance status.
*
* @param instanceId id of the instance
* @return instance status
*/
public InstanceStateName getInstanceStatus(final String instanceId) {
LOG.entry();
final DescribeInstanceStatusRequest describeInstanceStatusRequest = new DescribeInstanceStatusRequest().withIncludeAllInstances(true).withInstanceIds(instanceId);
final DescribeInstanceStatusResult describeInstanceStatusResult = amazonEC2Client.describeInstanceStatus(describeInstanceStatusRequest);
// Result error
if (null == describeInstanceStatusResult) {
final AmazonClientException exception = new AmazonClientException("No instance found with id:" + instanceId);
LOG.exit(exception);
throw exception;
}
final List<InstanceStatus> instanceStatusList = describeInstanceStatusResult.getInstanceStatuses();
// If none or more than one instances is found
if (instanceStatusList.isEmpty()) {
final AmazonClientException exception = new AmazonClientException("No instance found with id:" + instanceId);
LOG.exit(exception);
throw exception;
}
else if (instanceStatusList.size() > 1) {
final AmazonClientException exception = new AmazonClientException("Multiple instances found with id:" + instanceId);
LOG.exit(exception);
throw exception;
}
// Return the current state
final InstanceStateName instanceState = InstanceStateName.fromValue(instanceStatusList.get(0).getInstanceState().getName());
LOG.info("Instance {} current state is {}", instanceId, instanceState);
LOG.exit(instanceState);
return instanceState;
}
}