/******************************************************************************* * Copyright 2010-2017 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. *******************************************************************************/ package com.amazonaws.services.cloudtrail.processinglibrary.utils; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.TimeZone; /** * Utility methods used by the AWS CloudTrail Processing Library. */ public class LibraryUtils { private static final String UNDER_SCORE = "_"; private static final String FORWARD_SLASH = "/"; private static final String AMAZONAWS_COM = ".amazonaws.com/"; private static final String UTC_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; private static final String UTC_TIME_ZONE = "UTC"; /** * Check that an object is not <code>null</code>; throw an exception if it * is. * * @param argument the Object to check. * @param message a description string that will be sent with the exception. * @throws IllegalStateException if the passed-in object is <code>null</code>. */ public static void checkArgumentNotNull(Object argument, String message) { if (argument == null) { throw new IllegalStateException(message); } } /** * Check a conditional value or expression, if <code>true</code>, throw an * exception. * * @param condition a boolean value or an expression to check. * @param message a description string that will be sent with the exception. * @throws IllegalStateException if the condition expression is <code>true</code>. */ public static void checkCondition(boolean condition, String message) { if (condition) { throw new IllegalStateException(message); } } /** * Convert an * <a href="http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html">InputSteam</a> to a byte array. * * @param inputStream the <code>InputStream</code> to convert. * @return a byte array containing the data from the input stream. * @throws IOException if the <code>InputStream</code> could not be converted. */ public static byte[] toByteArray(InputStream inputStream) throws IOException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead = 0; byte[] bytes = new byte[1024]; while ((nRead = inputStream.read(bytes, 0, 1024)) != -1) { buffer.write(bytes, 0, nRead); } return buffer.toByteArray(); } /** * Split an HTTP representation of an Amazon S3 URL to bucket name and object key. * <p> * For example: * <pre> * input: s3ObjectHttpUrl = http://s3-us-west-2.amazonaws.com/mybucket/myobjectpath1/myobjectpath2/myobject.extension * output: {"mybucket", "myobjectpath1/myobjectpath2/myobject.extension"} * </pre> * * @param s3ObjectHttpUrl the URL of the S3 object to split. * @return a two-element string array: the first element is the bucket name, * and the second element is the object key. */ public static String[] toBucketNameObjectKey(String s3ObjectHttpUrl) { if (s3ObjectHttpUrl == null) { return null; } int start = s3ObjectHttpUrl.indexOf(AMAZONAWS_COM); int length = s3ObjectHttpUrl.length(); if (start != -1) { String bucketNameAndObjectKey = s3ObjectHttpUrl.substring(start + AMAZONAWS_COM.length(), length); return bucketNameAndObjectKey.split(FORWARD_SLASH, 2); } return null; } /** * Extract the account ID from an S3 object key. * <p> * For example: * <pre> * input: https://s3-us-west-2.amazonaws.com/mybucket/AWSLogs/123456789012/CloudTrail/us-east-1/2014/02/14/123456789012_CloudTrail_us-east-1_20140214T2230Z_K0UsfksWvF8TBJZy.json.gz * output: 1234567890 * </pre> * * @param objectKey The object key to query. * @return the account ID used to access the object. */ public static String extractAccountIdFromObjectKey(String objectKey) { if (objectKey == null) { return null; } int start = objectKey.lastIndexOf(FORWARD_SLASH); if (start != -1) { int end = objectKey.indexOf(UNDER_SCORE, start + FORWARD_SLASH.length()); if (end != -1) { return objectKey.substring(start + FORWARD_SLASH.length(), end); } } return null; } /** * SimpleDateFormat is not thread safe. Defining it as a static ThreadLocal to synchronize is less expensive than * creating a SimpleDateFormat object each time. */ private static ThreadLocal<SimpleDateFormat> utcSdf = new ThreadLocal<SimpleDateFormat>() { @Override protected SimpleDateFormat initialValue() { SimpleDateFormat sdf = new SimpleDateFormat(UTC_DATE_FORMAT, Locale.US); // $NON_NLS_L$ sdf.setTimeZone(TimeZone.getTimeZone(UTC_TIME_ZONE)); return sdf; } }; /** * Get a timestamp in * <a href="http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a>. * * @return the current timestamp. */ public static SimpleDateFormat getUtcSdf() { return utcSdf.get(); } }