AwsAuto.java Source code

Java tutorial

Introduction

Here is the source code for AwsAuto.java

Source

/*
 * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ConnectException;
import java.net.URL;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.autoscaling.AmazonAutoScalingClient;
import com.amazonaws.services.autoscaling.model.CreateAutoScalingGroupRequest;
import com.amazonaws.services.autoscaling.model.CreateLaunchConfigurationRequest;
import com.amazonaws.services.autoscaling.model.DeleteAutoScalingGroupRequest;
import com.amazonaws.services.autoscaling.model.DeleteLaunchConfigurationRequest;
import com.amazonaws.services.autoscaling.model.DeletePolicyRequest;
import com.amazonaws.services.autoscaling.model.InstanceMonitoring;
import com.amazonaws.services.autoscaling.model.PutScalingPolicyRequest;
import com.amazonaws.services.autoscaling.model.PutScalingPolicyResult;
import com.amazonaws.services.autoscaling.model.StepAdjustment;
import com.amazonaws.services.autoscaling.model.UpdateAutoScalingGroupRequest;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClient;
import com.amazonaws.services.cloudwatch.model.ComparisonOperator;
import com.amazonaws.services.cloudwatch.model.DeleteAlarmsRequest;
import com.amazonaws.services.cloudwatch.model.Dimension;
import com.amazonaws.services.cloudwatch.model.PutMetricAlarmRequest;
import com.amazonaws.services.cloudwatch.model.Statistic;
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.DeleteSecurityGroupRequest;
import com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancingClient;
import com.amazonaws.services.elasticloadbalancing.model.ConfigureHealthCheckRequest;
import com.amazonaws.services.elasticloadbalancing.model.ConfigureHealthCheckResult;
import com.amazonaws.services.elasticloadbalancing.model.CreateLoadBalancerRequest;
import com.amazonaws.services.elasticloadbalancing.model.CreateLoadBalancerResult;
import com.amazonaws.services.elasticloadbalancing.model.DeleteLoadBalancerRequest;
import com.amazonaws.services.elasticloadbalancing.model.HealthCheck;
import com.amazonaws.services.elasticloadbalancing.model.Listener;

public class AwsAuto {
    private static final long SHORT_BREAK = 10 * 1000;

    public static void main(String[] args) throws Exception {

        // initialize/determine parameters
        String instanceType = "m3.medium";
        String loadGeneratorAmi = "ami-8ac4e9e0";
        String dataCenterAmi = "ami-349fbb5e";
        String bidPrice = "0.1";
        String loadGeneratorDns = null; // load generator DNS
        String dashboardUrl = null; // the URL where we check our performance
        String testId = null;

        // create project tag for instances
        ArrayList<com.amazonaws.services.ec2.model.Tag> loadGeneratorTags = new ArrayList<>();
        com.amazonaws.services.ec2.model.Tag loadGeneratorTag = new com.amazonaws.services.ec2.model.Tag("Project",
                "2.1");
        loadGeneratorTags.add(loadGeneratorTag);

        // create project tag for auto-scaling
        com.amazonaws.services.autoscaling.model.Tag asgTag = new com.amazonaws.services.autoscaling.model.Tag();
        asgTag.setKey("Project");
        asgTag.setValue("2.1");

        // create project tag for load balancer
        ArrayList<com.amazonaws.services.elasticloadbalancing.model.Tag> loadBalancerTags = new ArrayList<>();
        com.amazonaws.services.elasticloadbalancing.model.Tag loadBalancerTag = new com.amazonaws.services.elasticloadbalancing.model.Tag();
        loadBalancerTag.setKey("Project");
        loadBalancerTag.setValue("2.1");
        loadBalancerTags.add(loadBalancerTag);

        /**
         * =========================================================================
         * ================= Create security groups
         * =========================================================================
         * =================
         */

        String loadGeneratorSecurityName = "LoadGeneratorSGP2";
        String allPurposeSecurityName = "AllPurposeSGP2";
        SecurityGroup loadGeneratorSecurityGroup = new SecurityGroup(loadGeneratorSecurityName);
        SecurityGroup allPurposeSecurityGroup = new SecurityGroup(allPurposeSecurityName);

        /**
         * =========================================================================
         * ================= Grant permission and credentials
         * =========================================================================
         * =================
         */

        AWSCredentials credentials = null;
        try {
            credentials = new ProfileCredentialsProvider("School").getCredentials();
        } catch (Exception e) {
            throw new AmazonClientException("Cannot load the credentials from the credential profiles file. "
                    + "Please make sure that your credentials file is at the correct "
                    + "location (C:\\Users\\Jiabei\\.aws\\credentials), and is in valid format.", e);
        }

        // set region
        AmazonEC2 ec2 = new AmazonEC2Client(credentials);
        Region usEast1 = Region.getRegion(Regions.US_EAST_1);
        ec2.setRegion(usEast1);

        /**
         * =========================================================================
         * ================= Create a load generator and submit password
         * =========================================================================
         * =================
         */

        Requests requestsLg = new Requests(instanceType, loadGeneratorAmi, bidPrice, loadGeneratorSecurityName,
                loadGeneratorTags);
        loadGeneratorDns = requestsLg.submitRequests();
        String submissionUrl = "http://" + loadGeneratorDns
                + "/password?passwd=0WSb4ufhYI7SkxfLWnnIWU0MC1NdcNKT&andrewId=jiabeip";
        sendGET(submissionUrl);

        try {

            /**
             * =======================================================================
             * =================== Create a load balancer
             * =======================================================================
             * ===================
             */

            String loadBalancerDns = null;
            String loadBalancerName = "LoadBalancerProj2";
            String healthCheckPage = "/heartbeat?lg=" + loadGeneratorDns;
            AmazonElasticLoadBalancingClient loadBalancerClient = new AmazonElasticLoadBalancingClient(credentials);

            // configure a request
            CreateLoadBalancerRequest loadBalancerRequest = new CreateLoadBalancerRequest()
                    .withAvailabilityZones("us-east-1b").withListeners(new Listener("HTTP", 80, 80))
                    .withLoadBalancerName(loadBalancerName).withSecurityGroups(allPurposeSecurityGroup.getGroupId())
                    .withTags(loadBalancerTags);

            CreateLoadBalancerResult loadBalancerResult = loadBalancerClient
                    .createLoadBalancer(loadBalancerRequest);
            loadBalancerDns = loadBalancerResult.getDNSName();

            // configure health check setting
            HealthCheck loadBalancerHealthCheck = new HealthCheck().withTarget("HTTP:80" + healthCheckPage)
                    .withTimeout(5).withInterval(30).withUnhealthyThreshold(2).withHealthyThreshold(10);

            ConfigureHealthCheckRequest healthCheckRequest = new ConfigureHealthCheckRequest()
                    .withLoadBalancerName(loadBalancerName).withHealthCheck(loadBalancerHealthCheck);

            // attach health check setting to load balancer
            ConfigureHealthCheckResult healthCheckResult = loadBalancerClient
                    .configureHealthCheck(healthCheckRequest);

            System.out.println("Load balancer created!\nDNS: " + loadBalancerDns);

            /**
             * =======================================================================
             * =================== Create launch configuration
             * =======================================================================
             * ===================
             */

            String launchConfigName = "LaunchConfigProj2";
            String autoScalingGroupName = "AutoScalingGroupProj2";

            AmazonAutoScalingClient autoScalingGroupClient = new AmazonAutoScalingClient(credentials);
            AmazonCloudWatchClient cloudWatchClient = new AmazonCloudWatchClient(credentials);

            System.out.println("Creating launch configuration...");

            // configure the request
            CreateLaunchConfigurationRequest launchConfigRequest = new CreateLaunchConfigurationRequest()
                    .withImageId(dataCenterAmi).withInstanceType(instanceType)
                    .withLaunchConfigurationName(launchConfigName)
                    .withSecurityGroups(allPurposeSecurityGroup.getGroupId()).withSpotPrice(bidPrice)
                    .withKeyName("primary");

            // enable detail monitoring
            InstanceMonitoring monitor = new InstanceMonitoring();
            monitor.setEnabled(true);
            launchConfigRequest.setInstanceMonitoring(monitor);

            // attach the configuration to the ASG client
            autoScalingGroupClient.createLaunchConfiguration(launchConfigRequest);

            System.out.println("Configuration complete!\nCreating auto-scaling group...");

            /**
             * =======================================================================
             * =================== Create auto-scaling group
             * =======================================================================
             * ===================
             */

            // configure ASG request
            CreateAutoScalingGroupRequest asgRequest = new CreateAutoScalingGroupRequest()
                    .withAutoScalingGroupName(autoScalingGroupName).withAvailabilityZones("us-east-1b")
                    .withLoadBalancerNames(loadBalancerName).withNewInstancesProtectedFromScaleIn(false)
                    .withTags(asgTag).withDefaultCooldown(120).withMinSize(1).withMaxSize(8).withDesiredCapacity(1) // Start
                    // from
                    // one
                    .withHealthCheckGracePeriod(120).withHealthCheckType("ELB")
                    .withLaunchConfigurationName(launchConfigName);

            // attach group configuration to ASG client
            autoScalingGroupClient.createAutoScalingGroup(asgRequest);

            /**
             * =======================================================================
             * =================== Create scaling up policy for ASG
             * =======================================================================
             * ===================
             */

            StepAdjustment upRule1 = new StepAdjustment().withMetricIntervalLowerBound(0.0)
                    .withMetricIntervalUpperBound(25.0).withScalingAdjustment(1);

            StepAdjustment upRule2 = new StepAdjustment().withMetricIntervalLowerBound(25.0)
                    .withMetricIntervalUpperBound(30.0).withScalingAdjustment(2);

            StepAdjustment upRule3 = new StepAdjustment().withMetricIntervalLowerBound(30.0)
                    .withMetricIntervalUpperBound(null).withScalingAdjustment(3);

            String upPolicyName = "Scaling Up";

            PutScalingPolicyRequest scalingUpPolicy = new PutScalingPolicyRequest()
                    .withAdjustmentType("ChangeInCapacity").withPolicyType("StepScaling")
                    .withStepAdjustments(upRule1, upRule2, upRule3).withAutoScalingGroupName(autoScalingGroupName)
                    .withPolicyName(upPolicyName).withEstimatedInstanceWarmup(120);

            StepAdjustment downRule1 = new StepAdjustment().withMetricIntervalLowerBound(-20.0)
                    .withMetricIntervalUpperBound(-0.0).withScalingAdjustment(-1);

            StepAdjustment downRule2 = new StepAdjustment().withMetricIntervalLowerBound(-30.0)
                    .withMetricIntervalUpperBound(-20.0).withScalingAdjustment(-2);

            StepAdjustment downRule3 = new StepAdjustment().withMetricIntervalLowerBound(null)
                    .withMetricIntervalUpperBound(-30.0).withScalingAdjustment(-3);

            String downPolicyName = "Scaling Down";

            PutScalingPolicyRequest scalingDownPolicy = new PutScalingPolicyRequest().withAdjustmentType("")
                    .withPolicyType("ChangeInCapacity").withStepAdjustments(downRule1, downRule2, downRule3)
                    .withAutoScalingGroupName(autoScalingGroupName).withPolicyName(downPolicyName)
                    .withEstimatedInstanceWarmup(60);

            // attach policies to ASG and get ARN for setting alarm
            PutScalingPolicyResult scaleUpResult = autoScalingGroupClient.putScalingPolicy(scalingUpPolicy);
            String upArn = scaleUpResult.getPolicyARN();
            PutScalingPolicyResult scaleDownResult = autoScalingGroupClient.putScalingPolicy(scalingDownPolicy);
            String downArn = scaleDownResult.getPolicyARN();

            /**
             * =======================================================================
             * =================== Create alarms for policies
             * =======================================================================
             * ===================
             */

            String upAlarmName = "UpAlarm_Mild";
            String downAlarmName = "DownAlarm_Mild";
            Dimension dimension = new Dimension();
            dimension.setName("AutoScalingGroupName");
            dimension.setValue(autoScalingGroupName);

            PutMetricAlarmRequest upAlarmRequest = new PutMetricAlarmRequest().withAlarmName(upAlarmName)
                    .withMetricName("CPUUtilization").withNamespace("AWS/EC2").withDimensions(dimension)
                    .withStatistic(Statistic.SampleCount)
                    .withComparisonOperator(ComparisonOperator.GreaterThanOrEqualToThreshold).withThreshold(65.0)
                    .withEvaluationPeriods(1).withPeriod(120).withAlarmActions(upArn);

            PutMetricAlarmRequest downAlarmRequest = new PutMetricAlarmRequest().withAlarmName(downAlarmName)
                    .withNamespace("AWS/EC2").withDimensions(dimension).withMetricName("CPUUtilization")
                    .withStatistic(Statistic.Average)
                    .withComparisonOperator(ComparisonOperator.LessThanOrEqualToThreshold).withThreshold(60.0)
                    .withEvaluationPeriods(1).withPeriod(120).withAlarmActions(downArn);

            cloudWatchClient.putMetricAlarm(upAlarmRequest);
            cloudWatchClient.putMetricAlarm(downAlarmRequest);

            System.out.println("All settings complete! \nReady for warmup...");

            /**
             * =======================================================================
             * =================== Warm up ELB
             * =======================================================================
             * ===================
             */

            String warmUpUrl = "http://" + loadGeneratorDns + "/warmup?dns=" + loadBalancerDns;
            sendGET(warmUpUrl);
            System.out.println("Warmup link: " + warmUpUrl);

            try {
                Thread.sleep(15 * 60 * 1000);
            } catch (Exception e) {
                e.printStackTrace();
            }

            System.out.println("Warmup complete!\nReady for battle...");

            /**
             * =======================================================================
             * =================== Start the test
             * =======================================================================
             * ===================
             */

            String testUrl = "http://" + loadGeneratorDns + "/junior?dns=" + loadBalancerDns;
            testId = sendGET(testUrl);
            System.out.println("Test ID is: " + testId);

            System.out.println("Test link: " + testUrl);

            try {
                Thread.sleep(60 * 60 * 1000);
            } catch (Exception e) {
                e.printStackTrace();
            }

            System.out.println("Test finished!");

            /**
             * =======================================================================
             * =================== Delete resources
             * =======================================================================
             * ===================
             */

            // clear ASG
            UpdateAutoScalingGroupRequest asgClearRequest = new UpdateAutoScalingGroupRequest()
                    .withAutoScalingGroupName(autoScalingGroupName).withMaxSize(0).withMinSize(0);
            autoScalingGroupClient.updateAutoScalingGroup(asgClearRequest);

            // delete policies
            DeletePolicyRequest upPolicyDeleteRequest = new DeletePolicyRequest()
                    .withAutoScalingGroupName(autoScalingGroupName).withPolicyName(upPolicyName);
            autoScalingGroupClient.deletePolicy(upPolicyDeleteRequest);

            DeletePolicyRequest downPolicyDeleteRequest = new DeletePolicyRequest()
                    .withAutoScalingGroupName(autoScalingGroupName).withPolicyName(downPolicyName);
            autoScalingGroupClient.deletePolicy(downPolicyDeleteRequest);
            System.out.println("Policies deleted...");

            // delete alarms
            DeleteAlarmsRequest alarmsDeleteRequest = new DeleteAlarmsRequest().withAlarmNames(upAlarmName,
                    downAlarmName);
            cloudWatchClient.deleteAlarms(alarmsDeleteRequest);
            System.out.println("Alarms deleted...");

            // delete load balancer
            DeleteLoadBalancerRequest lgDeleteRequest = new DeleteLoadBalancerRequest()
                    .withLoadBalancerName(loadBalancerName);
            loadBalancerClient.deleteLoadBalancer(lgDeleteRequest);
            System.out.println("Load generator deleted...");

            // delete ASG
            DeleteAutoScalingGroupRequest asgDeleteRequest = new DeleteAutoScalingGroupRequest()
                    .withForceDelete(true).withAutoScalingGroupName(autoScalingGroupName);
            autoScalingGroupClient.deleteAutoScalingGroup(asgDeleteRequest);
            System.out.println("ASG deleted...");

            // delete launch configuration
            DeleteLaunchConfigurationRequest launchConfigDeleteRequest = new DeleteLaunchConfigurationRequest()
                    .withLaunchConfigurationName(launchConfigName);
            autoScalingGroupClient.deleteLaunchConfiguration(launchConfigDeleteRequest);
            System.out.println("Launch configuration deleted...");

            // delete security group
            DeleteSecurityGroupRequest sgDeleteRequest = new DeleteSecurityGroupRequest()
                    .withGroupName(allPurposeSecurityName);
            ec2.deleteSecurityGroup(sgDeleteRequest);
            System.out.println("Security group deleted...");

            /**
             * =======================================================================
             * =================== All done
             * =======================================================================
             * ===================
             */
            System.out.println("All done :)");

        } catch (AmazonServiceException ase) {
            // Write out any exceptions that may have occurred.
            System.out.println("Caught Exception: " + ase.getMessage());
            System.out.println("Reponse Status Code: " + ase.getStatusCode());
            System.out.println("Error Code: " + ase.getErrorCode());
            System.out.println("Request ID: " + ase.getRequestId());

        } catch (Exception e) {
            System.out.println("Unexcepted error!");
            System.out.println(e.getMessage());
        }

    }

    /**
     * Send GET request
     * 
     * @param url the target url
     * @throws Exception
     */
    public static String sendGET(String url) throws Exception {

        int responseCode = 0;
        HttpURLConnection submitCon = null;
        do {

            try {

                // send another request if the server returns error
                URL send = new URL(url);
                submitCon = (HttpURLConnection) send.openConnection();
                submitCon.setRequestMethod("GET");
                responseCode = submitCon.getResponseCode();
                System.out.println("Response: " + submitCon.getResponseMessage());
                Thread.sleep(SHORT_BREAK);

            } catch (ConnectException con) {
                con.printStackTrace();
                Thread.sleep(SHORT_BREAK);
                continue;
            } catch (Exception e) {
                e.printStackTrace();
                Thread.sleep(SHORT_BREAK);
                continue;
            }
        } while (responseCode != 200);

        System.out.println("Send complete!");

        // read and print log
        try (BufferedReader input = new BufferedReader(new InputStreamReader(submitCon.getInputStream()));) {
            String newLine;
            StringBuilder log = new StringBuilder();

            while ((newLine = input.readLine()) != null) {
                log.append(newLine);
            }

            System.out.println("Server log: " + log);

            // if the log contains test ID, get and return it
            if (log.indexOf("log?name=test") != -1) {
                Matcher testId = Pattern.compile("test\\.(\\d+)\\.log").matcher(log);
                if (testId.find())
                    return testId.group(1);
            }

        } catch (IOException io) {
            io.printStackTrace();
        }

        return null;
    }

}