com.intuit.tank.vmManager.environment.amazon.CloudwatchInstance.java Source code

Java tutorial

Introduction

Here is the source code for com.intuit.tank.vmManager.environment.amazon.CloudwatchInstance.java

Source

package com.intuit.tank.vmManager.environment.amazon;

/*
 * #%L
 * VmManager
 * %%
 * Copyright (C) 2011 - 2015 Intuit Inc.
 * %%
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * #L%
 */

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Executors;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchAsyncClient;
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.MetricAlarm;
import com.amazonaws.services.cloudwatch.model.PutMetricAlarmRequest;
import com.amazonaws.services.cloudwatch.model.Statistic;
import com.amazonaws.services.sns.AmazonSNSAsyncClient;
import com.amazonaws.services.sns.model.CreateTopicResult;
import com.amazonaws.services.sns.model.ListTopicsResult;
import com.amazonaws.services.sns.model.SubscribeRequest;
import com.amazonaws.services.sns.model.Topic;
import com.intuit.tank.vm.api.enumerated.VMRegion;
import com.intuit.tank.vm.settings.CloudCredentials;
import com.intuit.tank.vm.settings.CloudProvider;
import com.intuit.tank.vm.settings.TankConfig;

/**
 * 
 * CloudwatchInstance
 * 
 * @author dangleton
 * 
 */
public class CloudwatchInstance {

    protected static final long ASSOCIATE_IP_MAX_WAIT_MILIS = 1000 * 60 * 10;// ten minutes
    private static Logger logger = Logger.getLogger(CloudwatchInstance.class);

    private AmazonCloudWatchAsyncClient asynchCloudWatchClient;

    private AmazonSNSAsyncClient asyncSnsClient;

    private TankConfig config = new TankConfig();

    /**
     * 
     * @param request
     * @param vmRegion
     */
    public CloudwatchInstance(VMRegion vmRegion) {
        // In case vmRegion is passed as null, use default region from settings file
        if (vmRegion == null) {
            vmRegion = config.getVmManagerConfig().getDefaultRegion();
        }
        try {
            CloudCredentials creds = config.getVmManagerConfig().getCloudCredentials(CloudProvider.amazon);
            AWSCredentials credentials = new BasicAWSCredentials(creds.getKeyId(), creds.getKey());
            ClientConfiguration clientConfig = new ClientConfiguration();
            clientConfig.setMaxConnections(2);
            if (StringUtils.isNotBlank(creds.getProxyHost())) {
                try {
                    clientConfig.setProxyHost(creds.getProxyHost());

                    if (StringUtils.isNotBlank(creds.getProxyPort())) {
                        clientConfig.setProxyPort(Integer.valueOf(creds.getProxyPort()));
                    }
                } catch (NumberFormatException e) {
                    logger.error("invalid proxy setup.");
                }

            }
            if (StringUtils.isNotBlank(creds.getKeyId()) && StringUtils.isNotBlank(creds.getKey())) {
                asynchCloudWatchClient = new AmazonCloudWatchAsyncClient(credentials, clientConfig,
                        Executors.newFixedThreadPool(2));
                asyncSnsClient = new AmazonSNSAsyncClient(credentials, clientConfig,
                        Executors.newFixedThreadPool(2));
            } else {
                asynchCloudWatchClient = new AmazonCloudWatchAsyncClient(clientConfig);
                asyncSnsClient = new AmazonSNSAsyncClient(clientConfig);
            }
            asynchCloudWatchClient.setRegion(Region.getRegion(Regions.fromName(vmRegion.getRegion())));
            asyncSnsClient.setRegion(Region.getRegion(Regions.fromName(vmRegion.getRegion())));
        } catch (Exception ex) {
            logger.error(ex.getMessage());
            throw new RuntimeException(ex);
        }
    }

    /**
     * 
     * @param email
     * @param jobId
     */
    public void removeWatch(String email, String jobId) {
        String alarmName = getAlarmName(email, jobId);
        for (MetricAlarm a : asynchCloudWatchClient.describeAlarms().getMetricAlarms()) {
            if (a.getAlarmName().equalsIgnoreCase(alarmName)) {
                DeleteAlarmsRequest req = new DeleteAlarmsRequest().withAlarmNames(alarmName);
                asynchCloudWatchClient.deleteAlarmsAsync(req);
            }
        }
    }

    /**
     * 
     * @param instances
     * @param email
     * @param jobId
     */
    public void addWatch(Collection<String> instances, String email, String jobId) {

        String alarmName = getAlarmName(email, jobId);
        for (MetricAlarm a : asynchCloudWatchClient.describeAlarms().getMetricAlarms()) {
            if (a.getAlarmName().equalsIgnoreCase(alarmName)) {
                logger.info("Alarm for job " + jobId + " and email " + email + " already exists.");
                return;
            }
        }
        List<Dimension> dimensions = new ArrayList<Dimension>();
        for (String instanceId : instances) {
            Dimension d = new Dimension().withName("InstanceId").withValue(instanceId);
            dimensions.add(d);

        }
        PutMetricAlarmRequest request = new PutMetricAlarmRequest().withActionsEnabled(true)
                .withAlarmName(alarmName).withComparisonOperator(ComparisonOperator.GreaterThanOrEqualToThreshold)
                .withDimensions(dimensions).withAlarmActions(getOrCreateNotification(email))
                .withEvaluationPeriods(1).withPeriod(60).withThreshold(60.0D).withStatistic(Statistic.Average)
                .withMetricName("CPUUtilization").withNamespace("AWS/EC2");
        asynchCloudWatchClient.putMetricAlarm(request);
        logger.info("Created alarm " + alarmName);
    }

    /**
     * 
     * @param email
     * @return
     */
    public String getOrCreateNotification(String email) {
        String ret = null;
        String topicName = getTopicName(email);
        String nextToken = null;
        do {
            ListTopicsResult listTopics = asyncSnsClient.listTopics(nextToken);
            List<Topic> topics = listTopics.getTopics();
            for (Topic s : topics) {
                if (s.getTopicArn().endsWith(topicName)) {
                    ret = s.getTopicArn();
                    break;
                }
            }
            nextToken = listTopics.getNextToken();
        } while (ret == null && nextToken != null);
        if (ret == null) {
            // create the topic and the subscription
            CreateTopicResult topic = asyncSnsClient.createTopic(topicName);
            SubscribeRequest req = new SubscribeRequest(topic.getTopicArn(), "email", email);
            asyncSnsClient.subscribeAsync(req);
            ret = topic.getTopicArn();
        }

        return ret;
    }

    private String getTopicName(String email) {
        String ret = "AgentEmailTopicFor_" + email.replaceAll("\\W+", "_");
        return ret;
    }

    private String getAlarmName(String email, String jobId) {
        String ret = "Job " + jobId + " Alarm Excessive CPU for Email " + email;
        ret = ret.replaceAll("\\W+", "_");
        return ret;
    }

}