Package com.netflix.ice.common

Source Code of com.netflix.ice.common.AwsUtils

/*
*
*  Copyright 2013 Netflix, Inc.
*
*     Licensed under the Apache License, Version 2.0 (the "License");
*     you may not use this file except in compliance with the License.
*     You may obtain a copy of the License at
*
*         http://www.apache.org/licenses/LICENSE-2.0
*
*     Unless required by applicable law or agreed to in writing, software
*     distributed under the License 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.netflix.ice.common;

import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient;
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
import com.amazonaws.services.securitytoken.model.AssumeRoleResult;
import com.amazonaws.services.securitytoken.model.Credentials;
import com.amazonaws.services.simpledb.AmazonSimpleDBClient;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClient;
import com.amazonaws.ClientConfiguration;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Utility class to handle interactions with aws.
*/
public class AwsUtils {
    private final static Logger logger = LoggerFactory.getLogger(AwsUtils.class);
    private static Pattern billingFileWithTagsPattern = Pattern.compile(".+-aws-billing-detailed-line-items-with-resources-and-tags-(\\d\\d\\d\\d-\\d\\d).csv.zip");
    private static Pattern billingFileWithMonitoringPattern = Pattern.compile(".+-aws-billing-detailed-line-items-with-monitoring-(\\d\\d\\d\\d-\\d\\d).csv");
    private static Pattern billingFilePattern = Pattern.compile(".+-aws-billing-detailed-line-items-(\\d\\d\\d\\d-\\d\\d).csv.zip");
    public static final DateTimeFormatter monthDateFormat = DateTimeFormat.forPattern("yyyy-MM").withZone(DateTimeZone.UTC);
    public static final DateTimeFormatter dayDateFormat = DateTimeFormat.forPattern("yyyy-MM-dd").withZone(DateTimeZone.UTC);
    public static final DateTimeFormatter dateFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HHa").withZone(DateTimeZone.UTC);
    public static long hourMillis = 3600000L;

    private static AmazonS3Client s3Client;
    private static AmazonSimpleEmailServiceClient emailServiceClient;
    private static AmazonSimpleDBClient simpleDBClient;
    private static AWSSecurityTokenServiceClient securityClient;
    public static AWSCredentialsProvider awsCredentialsProvider;
    public static ClientConfiguration clientConfig;

    /**
     * Get assumes IAM credentials.
     * @param accountId
     * @param assumeRole
     * @return assumes IAM credentials
     */
    public static Credentials getAssumedCredentials(String accountId, String assumeRole, String externalId) {
        AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest()
                .withRoleArn("arn:aws:iam::" + accountId + ":role/" + assumeRole)
                .withRoleSessionName(assumeRole.substring(0, Math.min(assumeRole.length(), 32)));
        if (!StringUtils.isEmpty(externalId))
            assumeRoleRequest.setExternalId(externalId);
        AssumeRoleResult roleResult = securityClient.assumeRole(assumeRoleRequest);
        return roleResult.getCredentials();
    }

    /**
     * This method must be called before all methods can be used.
     * @param credentialsProvider
     */
    public static void init(AWSCredentialsProvider credentialsProvider) {
        awsCredentialsProvider = credentialsProvider;
        clientConfig = new ClientConfiguration();
        String proxyHost = System.getProperty("https.proxyHost");
        String proxyPort = System.getProperty("https.proxyPort");
        if(proxyHost != null && proxyPort != null) {
            clientConfig.setProxyHost(proxyHost);
            clientConfig.setProxyPort(Integer.parseInt(proxyPort));
        }
        s3Client = new AmazonS3Client(awsCredentialsProvider, clientConfig);
        securityClient = new AWSSecurityTokenServiceClient(awsCredentialsProvider, clientConfig);
        if (System.getProperty("EC2_REGION") != null && !"us-east-1".equals(System.getProperty("EC2_REGION"))) {
            if ("global".equals(System.getProperty("EC2_REGION"))) {
                s3Client.setEndpoint("s3.amazonaws.com");
            }
            else {
                s3Client.setEndpoint("s3-" + System.getProperty("EC2_REGION") + ".amazonaws.com");
            }
        }
    }

    public static AmazonS3Client getAmazonS3Client() {
        return s3Client;
    }

    public static AmazonSimpleEmailServiceClient getAmazonSimpleEmailServiceClient() {
        if (emailServiceClient == null)
            emailServiceClient = new AmazonSimpleEmailServiceClient(awsCredentialsProvider, clientConfig);
        return emailServiceClient;
    }

    public static AmazonSimpleDBClient getAmazonSimpleDBClient() {
        if (simpleDBClient == null) {
            simpleDBClient = new AmazonSimpleDBClient(awsCredentialsProvider, clientConfig);
            if (System.getProperty("EC2_REGION") != null && !"us-east-1".equals(System.getProperty("EC2_REGION"))) {
                if ("global".equals(System.getProperty("EC2_REGION"))) {
                    simpleDBClient.setEndpoint("sdb.amazonaws.com");
                }
                else {
                    simpleDBClient.setEndpoint("sdb." + System.getProperty("EC2_REGION") + ".amazonaws.com");
                }
            }
        }
        return simpleDBClient;
    }
    /**
     * List all object summary with given prefix in the s3 bucket.
     * @param bucket
     * @param prefix
     * @return
     */
    public static List<S3ObjectSummary> listAllObjects(String bucket, String prefix) {
        ListObjectsRequest request = new ListObjectsRequest().withBucketName(bucket).withPrefix(prefix);
        List<S3ObjectSummary> result = Lists.newLinkedList();
        ObjectListing page = null;
        do {
            if (page != null)
                request.setMarker(page.getNextMarker());
            page = s3Client.listObjects(request);
            result.addAll(page.getObjectSummaries());

        } while (page.isTruncated());

        return result;
    }

    /**
     * List all object summary with given prefix in the s3 bucket.
     * @param bucket
     * @param prefix
     * @return
     */
    public static List<S3ObjectSummary> listAllObjects(String bucket, String prefix, String accountId,
                                                       String assumeRole, String externalId) {
        AmazonS3Client s3Client = AwsUtils.s3Client;

        try {
            ListObjectsRequest request = new ListObjectsRequest().withBucketName(bucket).withPrefix(prefix);
            List<S3ObjectSummary> result = Lists.newLinkedList();

            if (!StringUtils.isEmpty(accountId) && !StringUtils.isEmpty(assumeRole)) {
                Credentials assumedCredentials = getAssumedCredentials(accountId, assumeRole, externalId);
                s3Client = new AmazonS3Client(
                        new BasicSessionCredentials(assumedCredentials.getAccessKeyId(),
                                assumedCredentials.getSecretAccessKey(),
                                assumedCredentials.getSessionToken()),
                                clientConfig);
            }

            ObjectListing page = null;
            do {
                if (page != null)
                    request.setMarker(page.getNextMarker());
                page = s3Client.listObjects(request);
                result.addAll(page.getObjectSummaries());

            } while (page.isTruncated());

            return result;
        }
        finally {
            if (s3Client != AwsUtils.s3Client)
                s3Client.shutdown();
        }
    }

    /**
     * Get list of months in from the file names.
     * @param bucket
     * @param prefix
     * @return
     */
    public static Set<DateTime> listMonths(String bucket, String prefix) {
        List<S3ObjectSummary> objects = listAllObjects(bucket, prefix);
        Set<DateTime> result = Sets.newTreeSet();
        for (S3ObjectSummary object : objects) {
            String fileName = object.getKey().substring(prefix.length());
            result.add(monthDateFormat.parseDateTime(fileName));
        }

        return result;
    }

    public static DateTime getDateTimeFromFileNameWithMonitoring(String fileName) {
        Matcher matcher = billingFileWithMonitoringPattern.matcher(fileName);
        if (matcher.matches())
            return monthDateFormat.parseDateTime(matcher.group(1));
        else
            return null;
    }

    public static DateTime getDateTimeFromFileNameWithTags(String fileName) {
        Matcher matcher = billingFileWithTagsPattern.matcher(fileName);
        if (matcher.matches())
            return monthDateFormat.parseDateTime(matcher.group(1));
        else
            return null;
    }

    public static DateTime getDateTimeFromFileName(String fileName) {
        Matcher matcher = billingFilePattern.matcher(fileName);
        if (matcher.matches())
            return monthDateFormat.parseDateTime(matcher.group(1));
        else
            return null;
    }

    public static void upload(String bucketName, String prefix, File file) {
        s3Client.putObject(bucketName, prefix + file.getName(), file);
    }

    public static void upload(String bucketName, String prefix, String localDir, final String filePrefix) {

        File dir = new File(localDir);
        File[] files = dir.listFiles(new FilenameFilter() {
            public boolean accept(File file, String fileName) {
                return fileName.startsWith(filePrefix);
            }
        });
        for (File file: files)
            s3Client.putObject(bucketName, prefix + file.getName(), file);
    }

    public static long getLastModified(String bucketName, String fileKey) {
        try {
            long result = s3Client.listObjects(bucketName, fileKey).getObjectSummaries().get(0).getLastModified().getTime();
            return result;
        }
        catch (Exception e) {
            logger.error("failed to find " + fileKey);
            return 0;
        }
    }

    public static boolean downloadFileIfChangedSince(String bucketName, String bucketFilePrefix, File file, long milles, String accountId,
                                                     String assumeRole, String externalId) {
        AmazonS3Client s3Client = AwsUtils.s3Client;

        try {
            if (!StringUtils.isEmpty(accountId) && !StringUtils.isEmpty(assumeRole)) {
                Credentials assumedCredentials = getAssumedCredentials(accountId, assumeRole, externalId);
                s3Client = new AmazonS3Client(
                        new BasicSessionCredentials(assumedCredentials.getAccessKeyId(),
                                assumedCredentials.getSecretAccessKey(),
                                assumedCredentials.getSessionToken()),
                                clientConfig);
            }

            ObjectMetadata metadata = s3Client.getObjectMetadata(bucketName, bucketFilePrefix + file.getName());
            boolean download = !file.exists() || metadata.getLastModified().getTime() > milles;

            if (download) {
                return download(s3Client, bucketName, bucketFilePrefix + file.getName(), file);
            }
            else
                return download;
        }
        finally {
            if (s3Client != AwsUtils.s3Client)
                s3Client.shutdown();
        }
    }

    public static boolean downloadFileIfChangedSince(String bucketName, String bucketFilePrefix, File file, long milles) {
        ObjectMetadata metadata = s3Client.getObjectMetadata(bucketName, bucketFilePrefix + file.getName());
        boolean download = !file.exists() || metadata.getLastModified().getTime() > milles;

        if (download) {
            return download(bucketName, bucketFilePrefix + file.getName(), file);
        }
        else
            return download;
    }

    public static boolean downloadFileIfChanged(String bucketName, String bucketFilePrefix, File file, long milles) {
        ObjectMetadata metadata = s3Client.getObjectMetadata(bucketName, bucketFilePrefix + file.getName());
        boolean download = !file.exists() || metadata.getLastModified().getTime() > file.lastModified() + milles;
        logger.info("downloadFileIfChanged " + file + " " + metadata.getLastModified().getTime() + " " + (file.lastModified() + milles));

        if (download) {
            return download(bucketName, bucketFilePrefix + file.getName(), file);
        }
        else
            return false;
    }

    public static boolean downloadFileIfNotExist(String bucketName, String bucketFilePrefix, File file) {
        boolean download = !file.exists();
        if (download) {
            try {
                return download(bucketName, bucketFilePrefix + file.getName(), file);
            }
            catch (AmazonS3Exception e) {
                if (e.getStatusCode() != 404)
                    throw e;
                logger.info("file not found in s3 " + file);
            }
        }
        return false;
    }

    private static boolean download(String bucketName, String fileKey, File file) {
        return download(s3Client, bucketName, fileKey, file);
    }

    private static boolean download(AmazonS3Client s3Client, String bucketName, String fileKey, File file) {
        do {
            S3Object s3Object = s3Client.getObject(bucketName, fileKey);
            InputStream input = s3Object.getObjectContent();
            long targetSize = s3Object.getObjectMetadata().getContentLength();
            FileOutputStream output = null;

            boolean downloaded = false;
            long size = 0;
            try {
                output = new FileOutputStream(file);
                byte buf[]=new byte[1024000];
                int len;
                while ((len=input.read(buf)) > 0) {
                    output.write(buf, 0, len);
                    size += len;
                }
                downloaded = true;
            }
            catch (IOException e) {
                logger.error("error in downloading " + file, e);
            }
            finally {
                if (input != null) try {input.close();} catch (IOException e){}
                if (output != null) try {output.close();} catch (IOException e){}
            }

            if (downloaded) {
                long contentLenth = s3Client.getObjectMetadata(bucketName, fileKey).getContentLength();
                if (contentLenth != size) {
                    logger.warn("size does not match contentLenth=" + contentLenth +
                            " downloadSize=" + size + "targetSize=" + targetSize + " ... re-downlaoding " + fileKey);
                }
                else
                    return true;
            }
            try {Thread.sleep(2000L);}catch (Exception e){}
        }
        while (true);
    }
}
TOP

Related Classes of com.netflix.ice.common.AwsUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.