Java tutorial
/* * Copyright (C) 2014 Indeed 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.indeed.imhotep.iql.cache; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.ObjectListing; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.Region; import org.apache.log4j.Logger; import org.springframework.core.env.PropertyResolver; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * @author darren */ public class S3QueryCache implements QueryCache { static final Logger log = Logger.getLogger(S3QueryCache.class); private boolean enabled; private AmazonS3Client client; private String bucket; public S3QueryCache(PropertyResolver props) { String awsRegion; String awsKey; String awsSecret; enabled = true; try { bucket = props.getProperty("query.cache.s3.bucket", String.class); awsKey = props.getProperty("query.cache.s3.s3key", String.class); awsSecret = props.getProperty("query.cache.s3.s3secret", String.class); if (awsKey == null || awsSecret == null) { log.warn("No AWS key or Secret found. Using Anonymous access."); client = new AmazonS3Client(); } else { client = new AmazonS3Client(new BasicAWSCredentials(awsKey, awsSecret)); } boolean exists = client.doesBucketExist(bucket); if (!exists) { awsRegion = props.getProperty("aws.s3.region", String.class, Region.US_Standard.toString()); client.createBucket(bucket, awsRegion); } } catch (Exception e) { log.info("Failed to initialize the S3 client. Caching disabled.", e); enabled = false; } } /** * Returns whether the cache is available. */ @Override public boolean isEnabled() { return enabled; } /** * Returns whether the cache was requested to be enabled in the app config. */ @Override public boolean isEnabledInConfig() { return true; } @Override public boolean isFileCached(String fileName) { if (!enabled) { return false; } try { ObjectListing objs; objs = client.listObjects(bucket, fileName); return !objs.getObjectSummaries().isEmpty(); } catch (Exception e) { return false; } } @Override public InputStream getInputStream(String cachedFileName) throws IOException { if (!enabled) { throw new IllegalStateException("Can't send data from S3 cache as it is disabled"); } return client.getObject(bucket, cachedFileName).getObjectContent(); } @Override public OutputStream getOutputStream(final String cachedFileName) throws IOException { if (!enabled) { throw new IllegalStateException("Can't send data to S3 cache as it is disabled"); } final ByteArrayOutputStream os = new ByteArrayOutputStream(); // Wrap the returned OutputStream so that we can write to buffer and do actual write on close() return new OutputStream() { private boolean closed = false; @Override public void write(byte[] b) throws IOException { os.write(b); } @Override public void write(byte[] b, int off, int len) throws IOException { os.write(b, off, len); } @Override public void flush() throws IOException { os.flush(); } @Override public void write(int b) throws IOException { os.write(b); } @Override public void close() throws IOException { if (closed) { return; } closed = true; os.close(); // do actual write byte[] csvData = os.toByteArray(); ByteArrayInputStream is = new ByteArrayInputStream(csvData); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(csvData.length); client.putObject(bucket, cachedFileName, is, metadata); } }; } @Override public void writeFromFile(String cachedFileName, File localFile) throws IOException { if (!enabled) { throw new IllegalStateException("Can't send data to S3 cache as it is disabled"); } client.putObject(bucket, cachedFileName, localFile); } /** * Tries to see if the S3 is accessible by listing the files in the bucket * @throws IOException */ @Override public void healthcheck() throws IOException { if (!enabled) { throw new IllegalStateException("S3 cache is not available"); } client.listObjects(bucket); } }