All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cc.protea.foundation.integrations.AmazonS3Util Maven / Gradle / Ivy

package cc.protea.foundation.integrations;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.AmazonClientException;
import com.amazonaws.HttpMethod;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.Headers;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.CopyObjectRequest;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import com.google.common.io.ByteStreams;

import cc.protea.foundation.model.ProteaException;
import cc.protea.foundation.util.GzipUtil;

public class AmazonS3Util {

//	public final static AmazonS3 s3 = new AmazonS3Client(AmazonS3Util.getCredentials());
	
	public final static AmazonS3 s3 = AmazonS3ClientBuilder.standard()
			.withCredentials(new AWSStaticCredentialsProvider(AmazonS3Util.getCredentials()))
			.withRegion("us-east-1")
			.withForceGlobalBucketAccessEnabled(true)
			.build();

	public final static String bucketName = System.getenv("S3_BUCKET_NAME");

	static Logger log = LoggerFactory.getLogger(AmazonS3Util.class);

	static AWSCredentials getCredentials() {
		return new AWSCredentials() {
			final String accessKey = System.getenv("AWS_ACCESS_KEY_ID");
			final String secretKey = System.getenv("AWS_SECRET_ACCESS_KEY");
			public String getAWSSecretKey() { return secretKey; }
			public String getAWSAccessKeyId() { return accessKey; }
		};
	}

	public static byte[] get(final String key) {
		InputStream stream = AmazonS3Util.getAsStream(key);
		try {
			return ByteStreams.toByteArray(stream);
		} catch (IOException e) {
			throw new ProteaException(e.getLocalizedMessage());
		} finally {
			try {
				if (stream != null) {
					stream.close();
				}
			} catch (IOException e) {
				log.error("Could not close InputStream - suppressing error", e);
			}
		}
	}
	
	public static ObjectMetadata getObjectMetadata(final String key) {
		ObjectMetadata metadata = AmazonS3Util.s3.getObjectMetadata(AmazonS3Util.bucketName, key);
		return metadata;
	}

	static void close(InputStream stream) {
		try {
			if (stream == null) {
				return;
			}
			stream.close();
		} catch (IOException e) {
			log.error("Could not close InputStream - suppressing error", e);
		}
	}

	public static InputStream getAsStream(final String key) {
		try (S3Object o = AmazonS3Util.s3.getObject(AmazonS3Util.bucketName, key)) {
			return o.getObjectContent();
		} catch (AmazonClientException | IOException e) {
			throw new ProteaException(e.getLocalizedMessage());
		}
	}

	public static String put(final String key, final byte[] in, final String contentType,  final boolean compress, final boolean publicRead) {
		ByteArrayInputStream stream = new ByteArrayInputStream(in);
		try {
			return AmazonS3Util.put(key, stream, contentType, compress, publicRead);
		} catch (Exception e) {
			throw e;
		} finally {
			try {
				if (stream != null) {
					stream.close();
				}
			} catch (IOException e) {
				log.error("Could not close InputStream - suppressing error", e);
			}
		}
	}

	public static String put(final String key, final InputStream is, final String contentType,  final boolean compress, final boolean publicRead) {
		String normalKey = normalizeKey(key);
		InputStream stream = is;
		try {
			if (compress) {
				byte[] compressed = GzipUtil.compress(is);
				close(is);
				stream = new ByteArrayInputStream(compressed);
			}
			AmazonS3Util.s3.putObject(new PutObjectRequest(AmazonS3Util.bucketName, normalKey, stream, AmazonS3Util.buildMetadata(contentType, compress)).withCannedAcl(AmazonS3Util.getAcl(publicRead)));
		} catch (AmazonClientException e) {
			throw new ProteaException(e.getLocalizedMessage());
		} catch (Exception e) {
			if (compress) {
				AmazonS3Util.put(key, is, contentType, false, publicRead);
			} else {
				throw new ProteaException(e.getLocalizedMessage());
			}
		} finally {
			close(stream);
		}
		return "https://" + AmazonS3Util.bucketName + ".s3.amazonaws.com/" + normalKey;
	}

	public static void remove(String key) {
		if (StringUtils.startsWith(key, "https://" + AmazonS3Util.bucketName + ".s3.amazonaws.com/")) {
			key = StringUtils.substringAfter(key, "https://" + AmazonS3Util.bucketName + ".s3.amazonaws.com/");
		}
		try {
			String normalKey = normalizeKey(key);
			AmazonS3Util.s3.deleteObject(AmazonS3Util.bucketName, normalKey);
		} catch (AmazonClientException e) {
			throw new ProteaException(e.getLocalizedMessage());
		}
	}

	public static String copy(final String oldKey, final String newKey, final boolean publicRead) {
		String normalOldKey = normalizeKey(oldKey);
		String normalNewKey = normalizeKey(newKey);
		try {
			AmazonS3Util.s3.copyObject(new CopyObjectRequest(AmazonS3Util.bucketName, normalOldKey, AmazonS3Util.bucketName, normalNewKey).withCannedAccessControlList(AmazonS3Util.getAcl(publicRead)));
		} catch (AmazonClientException e) {
			throw new ProteaException(e.getLocalizedMessage());
		}
		return "https://" + AmazonS3Util.bucketName + ".s3.amazonaws.com/" + normalNewKey;
	}

	static ObjectMetadata buildMetadata(final String contentType, final boolean compressed) {
		ObjectMetadata metadata = new ObjectMetadata();
		metadata.setCacheControl("must-revalidate");
		metadata.setContentType(contentType);
		if (compressed) {
			metadata.setContentEncoding("gzip");
		}
		metadata.setLastModified(new Date());
		return metadata;
	}

	static CannedAccessControlList getAcl(final boolean publicRead) {
		return publicRead ? CannedAccessControlList.PublicRead : CannedAccessControlList.AuthenticatedRead;
	}

	public static String getUploadRequest(final String key) {
		return AmazonS3Util.getUploadRequest(key, (1000 * 60 * 60), null);  // One hour in the future
	}

	public static String getUploadRequest(final String key, final int expirationMilliseconds, String contentType) {
		return getUploadRequest(key, expirationMilliseconds, contentType, false);
	}
	
	public static String getUploadRequest(final String key, final int expirationMilliseconds, String contentType, boolean publicRead) {
		Date expiration = new Date(System.currentTimeMillis() + expirationMilliseconds);
		String normalKey = normalizeKey(key);
		GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(AmazonS3Util.bucketName, normalKey);
		generatePresignedUrlRequest.setMethod(HttpMethod.PUT);
		generatePresignedUrlRequest.setExpiration(expiration);
		if(publicRead) {
			generatePresignedUrlRequest.addRequestParameter(Headers.S3_CANNED_ACL, CannedAccessControlList.PublicRead.toString());
		}
		if(contentType != null) {
			generatePresignedUrlRequest.setContentType(contentType);
		}
		return AmazonS3Util.s3.generatePresignedUrl(generatePresignedUrlRequest).toExternalForm();
	}

	public static boolean isBucketResource(final String url) {
		if (StringUtils.startsWith(url, "https://" + AmazonS3Util.bucketName + ".s3.amazonaws.com/")) {
			return true;
		}
		return false;
	}
	
	public static String getKeyFromUrl(final String url) {
		if (StringUtils.startsWith(url, "https://" + AmazonS3Util.bucketName + ".s3.amazonaws.com/")) {
			return StringUtils.substringAfter(url, "https://" + AmazonS3Util.bucketName + ".s3.amazonaws.com/");
		}
		return null;
	}

	static String normalizeKey(String in) {
		while (StringUtils.contains(in, "//")) {
			in = StringUtils.replace(in, "//", "/");
		}
		if (StringUtils.startsWith(in, "/")) {
			in = StringUtils.replaceOnce(in, "/", "");
		}
		return in;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy