com.amazonaws.services.kinesis.scaling.auto.AutoscalingConfiguration.java Source code

Java tutorial

Introduction

Here is the source code for com.amazonaws.services.kinesis.scaling.auto.AutoscalingConfiguration.java

Source

/**
 * Amazon Kinesis Scaling Utility
 *
 * Copyright 2014, Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Amazon Software License (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/asl/
 *
 * 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.
 */
package com.amazonaws.services.kinesis.scaling.auto;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.transfer.Download;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Transfer Object for the Autoscaling Configuration, which can be built from a
 * variety of file locations
 */
@SuppressWarnings("serial")
public class AutoscalingConfiguration implements Serializable {
    private static final Log LOG = LogFactory.getLog(AutoscalingConfiguration.class);

    private static ObjectMapper mapper = new ObjectMapper();

    private String streamName;

    private String region = "us-east-1";

    private List<KinesisOperationType> scaleOnOperations;

    private ScalingConfig scaleUp;

    private ScalingConfig scaleDown;

    private Integer minShards;

    private Integer maxShards;

    private Integer refreshShardsNumberAfterMin = 10;

    private IScalingOperationReportListener scalingOperationReportListener;

    @JsonIgnoreProperties
    private Integer checkInterval = 45;

    public String getStreamName() {
        return streamName;
    }

    public void setStreamName(String streamName) {
        this.streamName = streamName;
    }

    public String getRegion() {
        return region;
    }

    public void setRegion(String region) {
        this.region = region;
    }

    public List<KinesisOperationType> getScaleOnOperations() {
        return scaleOnOperations;
    }

    public void setScaleOnOperation(List<KinesisOperationType> scaleOnOperations) {
        this.scaleOnOperations = scaleOnOperations;
    }

    public ScalingConfig getScaleUp() {
        return scaleUp;
    }

    public void setScaleUp(ScalingConfig scaleUp) {
        this.scaleUp = scaleUp;
    }

    public ScalingConfig getScaleDown() {
        return scaleDown;
    }

    public void setScaleDown(ScalingConfig scaleDown) {
        this.scaleDown = scaleDown;
    }

    public Integer getMinShards() {
        return minShards;
    }

    public void setMinShards(Integer minShards) {
        this.minShards = minShards;
    }

    public Integer getMaxShards() {
        return maxShards;
    }

    public void setMaxShards(Integer maxShards) {
        this.maxShards = maxShards;
    }

    public Integer getRefreshShardsNumberAfterMin() {
        return refreshShardsNumberAfterMin;
    }

    public void setRefreshShardsNumberAfterMin(Integer refreshShardsNumberAfterMin) {
        this.refreshShardsNumberAfterMin = refreshShardsNumberAfterMin;
    }

    public IScalingOperationReportListener getScalingOperationReportListener() {
        return scalingOperationReportListener;
    }

    public Integer getCheckInterval() {
        return checkInterval;
    }

    public void setCheckInterval(Integer checkInterval) {
        this.checkInterval = checkInterval;
    }

    public static AutoscalingConfiguration[] loadFromURL(String url)
            throws IOException, InvalidConfigurationException {
        File configFile = null;

        if (url.startsWith("s3://")) {
            // download the configuration from S3
            AmazonS3 s3Client = new AmazonS3Client(new DefaultAWSCredentialsProviderChain());

            TransferManager tm = new TransferManager(s3Client);

            // parse the config path to get the bucket name and prefix
            final String s3ProtoRegex = "s3:\\/\\/";
            String bucket = url.replaceAll(s3ProtoRegex, "").split("/")[0];
            String prefix = url.replaceAll(String.format("%s%s\\/", s3ProtoRegex, bucket), "");

            // download the file using TransferManager
            configFile = File.createTempFile(url, null);
            Download download = tm.download(bucket, prefix, configFile);
            try {
                download.waitForCompletion();
            } catch (InterruptedException e) {
                throw new IOException(e);
            }

            // shut down the transfer manager
            tm.shutdownNow();

            LOG.info(String.format("Loaded Configuration from Amazon S3 %s/%s to %s", bucket, prefix,
                    configFile.getAbsolutePath()));
        } else if (url.startsWith("http")) {
            configFile = File.createTempFile("kinesis-autoscaling-config", null);
            FileUtils.copyURLToFile(new URL(url), configFile, 1000, 1000);
            LOG.info(String.format("Loaded Configuration from %s to %s", url, configFile.getAbsolutePath()));
        } else {
            try {
                InputStream classpathConfig = AutoscalingConfiguration.class.getClassLoader()
                        .getResourceAsStream(url);
                if (classpathConfig != null && classpathConfig.available() > 0) {
                    configFile = new File(AutoscalingConfiguration.class
                            .getResource((url.startsWith("/") ? "" : "/") + url).toURI());
                } else {
                    // last fallback to a FS location
                    configFile = new File(url);

                    if (!configFile.exists()) {
                        throw new IOException("Unable to load local file from " + url);
                    }
                }
            } catch (URISyntaxException e) {
                throw new IOException(e);
            }
            LOG.info(String.format("Loaded Configuration local %s", url));
        }

        // read the json config into an array of autoscaling
        // configurations
        AutoscalingConfiguration[] configuration;
        try {
            configuration = mapper.readValue(configFile, AutoscalingConfiguration[].class);
        } catch (Exception e) {
            throw new InvalidConfigurationException(e);
        }

        // validate each of the configurations
        for (AutoscalingConfiguration conf : configuration) {
            conf.validate();
        }

        return configuration;
    }

    public void validate() throws InvalidConfigurationException {
        if (this.streamName == null || this.streamName.equals("")) {
            throw new InvalidConfigurationException("Stream Name must be specified");
        }

        if (this.scaleUp == null && this.scaleDown == null) {
            throw new InvalidConfigurationException(
                    "Must provide at least one scale up or scale down configuration");
        }

        if (this.minShards != null && this.maxShards != null && this.minShards > this.maxShards) {
            throw new InvalidConfigurationException("Min Shard Count must be less than Max Shard Count");
        }

        // set the default operation types to 'all' if none were provided
        if (this.scaleOnOperations == null || this.scaleOnOperations.size() == 0) {
            this.scaleOnOperations = Arrays.asList(KinesisOperationType.values());
        }

        // set a 0 cool off if none was provided
        if (this.scaleDown.getCoolOffMins() == null) {
            this.scaleDown.setCoolOffMins(0);
        }
    }
}