// Path: instance/src/main/java/jp/gr/java_conf/uzresk/aws/ope/instance/model/InstanceCheckStateRequest.java
// @Data
// public class InstanceCheckStateRequest {
// 
// 	private String queueName;
// 
// 	private String sqsEndpoint;
// 
// 	private int numberOfMessages = 10;
// 
// }
// 
// Path: instance/src/main/java/jp/gr/java_conf/uzresk/aws/ope/instance/model/InstanceRequest.java
// @Data
// public class InstanceRequest {
// 
// 	private String instanceId;
// 
// 	private String queueName;
// 
// 	private String sqsEndpoint;
// 
// 	private int instanceStateCheckTimeoutSec = 300;
// 
// 	private long sendMessageTimeMillis;
// 
// }


import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import java.util.concurrent.Future;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.regions.RegionUtils;
import com.amazonaws.services.ec2.AmazonEC2Async;
import com.amazonaws.services.ec2.AmazonEC2AsyncClient;
import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.sqs.AmazonSQSAsync;
import com.amazonaws.services.sqs.AmazonSQSAsyncClient;
import com.amazonaws.services.sqs.model.CreateQueueRequest;
import com.amazonaws.services.sqs.model.Message;
import com.amazonaws.services.sqs.model.SendMessageRequest;
import com.amazonaws.services.sqs.model.SendMessageResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import jp.gr.java_conf.uzresk.aws.ope.instance.model.InstanceCheckStateRequest;
import jp.gr.java_conf.uzresk.aws.ope.instance.model.InstanceRequest;

		long now = System.currentTimeMillis();

		// Status check of the instance has timed out or not
		if (sendMessageTime < now) {
			deleteQueueMessage(message, checkInstanceStateRequest, context);
			throw new RuntimeException("Status check of the instance has timed out. " + instanceRequest);
		}

		AmazonEC2Async client = createEC2Client();
		try {
			DescribeInstancesResult result = client
					.describeInstances(new DescribeInstancesRequest().withInstanceIds(instanceRequest.getInstanceId()));
			List<Instance> instances = result.getReservations().get(0).getInstances();
			if (instances.size() != 1) {
				deleteQueueMessage(message, checkInstanceStateRequest, context);
				throw new RuntimeException("instance can not be found.");
			}
			Instance instance = instances.get(0);

			if (stateName.equals(instance.getState().getName())) {
				deleteQueueMessage(message, checkInstanceStateRequest, context);
				logger.log("[SUCCESS][" + instanceRequest.getInstanceId() + "][checkInstanceState][" + stateName
						+ "] Status check of the instance is completed successfully. " + instanceRequest + "]");
			}

		} finally {
			client.shutdown();
		}
	}


// Path: instance/src/main/java/jp/gr/java_conf/uzresk/aws/ope/instance/model/InstanceCheckStateRequest.java
// @Data
// public class InstanceCheckStateRequest {
// 
// 	private String queueName;
// 
// 	private String sqsEndpoint;
// 
// 	private int numberOfMessages = 10;
// 
// }
// 
// Path: instance/src/main/java/jp/gr/java_conf/uzresk/aws/ope/instance/model/InstanceRequest.java
// @Data
// public class InstanceRequest {
// 
// 	private String instanceId;
// 
// 	private String queueName;
// 
// 	private String sqsEndpoint;
// 
// 	private int instanceStateCheckTimeoutSec = 300;
// 
// 	private long sendMessageTimeMillis;
// 
// }


// Path: instance/src/main/java/jp/gr/java_conf/uzresk/aws/ope/instance/InstanceOperation.java
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import java.util.concurrent.Future;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.regions.RegionUtils;
import com.amazonaws.services.ec2.AmazonEC2Async;
import com.amazonaws.services.ec2.AmazonEC2AsyncClient;
import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.sqs.AmazonSQSAsync;
import com.amazonaws.services.sqs.AmazonSQSAsyncClient;
import com.amazonaws.services.sqs.model.CreateQueueRequest;
import com.amazonaws.services.sqs.model.Message;
import com.amazonaws.services.sqs.model.SendMessageRequest;
import com.amazonaws.services.sqs.model.SendMessageResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import jp.gr.java_conf.uzresk.aws.ope.instance.model.InstanceCheckStateRequest;
import jp.gr.java_conf.uzresk.aws.ope.instance.model.InstanceRequest;

		long now = System.currentTimeMillis();

		// Status check of the instance has timed out or not
		if (sendMessageTime < now) {
			deleteQueueMessage(message, checkInstanceStateRequest, context);
			throw new RuntimeException("Status check of the instance has timed out. " + instanceRequest);
		}

		AmazonEC2Async client = createEC2Client();
		try {
			DescribeInstancesResult result = client
					.describeInstances(new DescribeInstancesRequest().withInstanceIds(instanceRequest.getInstanceId()));
			List<Instance> instances = result.getReservations().get(0).getInstances();
			if (instances.size() != 1) {
				deleteQueueMessage(message, checkInstanceStateRequest, context);
				throw new RuntimeException("instance can not be found.");
			}
			Instance instance = instances.get(0);

			if (stateName.equals(instance.getState().getName())) {
				deleteQueueMessage(message, checkInstanceStateRequest, context);
				logger.log("[SUCCESS][" + instanceRequest.getInstanceId() + "][checkInstanceState][" + stateName
						+ "] Status check of the instance is completed successfully. " + instanceRequest + "]");
			}

		} finally {
			client.shutdown();
		}
	}


	SendMessageResult createQueueMessage(InstanceRequest instanceRequest, Context context) {
