package com.dgrid.helpers.impl; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jets3t.service.S3Service; import org.jets3t.service.S3ServiceException; import org.jets3t.service.acl.AccessControlList; import org.jets3t.service.impl.rest.httpclient.RestS3Service; import org.jets3t.service.model.S3Bucket; import org.jets3t.service.model.S3Object; import org.jets3t.service.security.AWSCredentials; import com.dgrid.errors.AWSException; import com.dgrid.errors.TransportException; import com.dgrid.gen.InvalidApiKey; import com.dgrid.helpers.AWSConstants; import com.dgrid.helpers.MimeTypeHelper; import com.dgrid.helpers.S3Helper; import com.dgrid.service.DGridClient; import com.dgrid.util.io.OutputStreamUtils; public class S3HelperImpl implements S3Helper { private static final int BUFFSIZE = 2048; private Log log = LogFactory.getLog(getClass()); private DGridClient gridClient; private MimeTypeHelper mimeTypes; public void setGridClient(DGridClient gridClient) { this.gridClient = gridClient; } public void setMimeTypeHelper(MimeTypeHelper mimeTypes) { this.mimeTypes = mimeTypes; } public String[] listBuckets() throws TransportException, IOException, AWSException { log.trace("listBuckets()"); try { S3Service s3Service = getS3Service(); S3Bucket[] s3buckets = s3Service.listAllBuckets(); String[] buckets = new String[s3buckets.length]; for (int i = 0; i < s3buckets.length; ++i) { buckets[i] = s3buckets[i].getName(); } return buckets; } catch (InvalidApiKey e) { throw new AWSException(e); } catch (S3ServiceException e) { throw new AWSException(e); } finally { } } public void createBucket(String bucket) throws TransportException, IOException, AWSException { log.trace("createBucket()"); try { S3Service s3Service = getS3Service(); s3Service.createBucket(bucket); } catch (InvalidApiKey e) { throw new AWSException(e); } catch (S3ServiceException e) { throw new AWSException(e); } finally { } } public void deleteBucket(String bucket) throws TransportException, IOException, AWSException { log.trace("deleteBucket()"); try { S3Service s3Service = getS3Service(); s3Service.deleteBucket(bucket); } catch (InvalidApiKey e) { throw new AWSException(e); } catch (S3ServiceException e) { throw new AWSException(e); } finally { } } public String[] listKeys(String bucket) throws TransportException, IOException, AWSException { log.trace("listKeys()"); try { S3Service s3Service = getS3Service(); S3Bucket s3bucket = new S3Bucket(bucket); S3Object[] s3objects = s3Service.listObjects(s3bucket); String[] keys = new String[s3objects.length]; for (int i = 0; i < s3objects.length; ++i) { keys[i] = s3objects[i].getKey(); } return keys; } catch (S3ServiceException e) { throw new AWSException(e); } catch (TransportException e) { throw new AWSException(e); } catch (InvalidApiKey e) { throw new AWSException(e); } finally { } } public String[] listKeys(String bucket, String prefix, String delimiter) throws TransportException, IOException, AWSException { log.trace("listKeys()"); try { S3Service s3Service = getS3Service(); S3Bucket s3bucket = new S3Bucket(bucket); S3Object[] s3objects = s3Service.listObjects(s3bucket, prefix, delimiter); String[] keys = new String[s3objects.length]; for (int i = 0; i < s3objects.length; ++i) { keys[i] = s3objects[i].getKey(); } return keys; } catch (S3ServiceException e) { throw new AWSException(e); } catch (TransportException e) { throw new AWSException(e); } catch (InvalidApiKey e) { throw new AWSException(e); } finally { } } public void get(String bucket, String key, File dest) throws IOException, AWSException { log.trace("get()"); try { S3Service s3Service = getS3Service(); S3Bucket s3bucket = new S3Bucket(bucket); S3Object s3object = s3Service.getObject(s3bucket, key); InputStream is = s3object.getDataInputStream(); FileOutputStream fos = new FileOutputStream(dest); int read = 0; byte[] buffer = new byte[BUFFSIZE]; while ((read = is.read(buffer)) > 0) { fos.write(buffer, 0, read); } fos.close(); is.close(); s3object.closeDataInputStream(); } catch (S3ServiceException e) { throw new AWSException(e); } catch (TransportException e) { throw new AWSException(e); } catch (InvalidApiKey e) { throw new AWSException(e); } finally { } } public void get(String bucket, String key, String filename) throws IOException, AWSException { log.trace("get()"); this.get(bucket, key, new File(filename)); } public String getString(String bucket, String key) throws TransportException, IOException, AWSException { log.trace("getString()"); try { S3Service s3Service = getS3Service(); S3Bucket s3bucket = new S3Bucket(bucket); S3Object s3object = s3Service.getObject(s3bucket, key); InputStream is = s3object.getDataInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); OutputStreamUtils.writeStreamToStream(is, baos); baos.close(); is.close(); s3object.closeDataInputStream(); return new String(baos.toByteArray()); } catch (S3ServiceException e) { throw new AWSException(e); } catch (TransportException e) { throw new AWSException(e); } catch (InvalidApiKey e) { throw new AWSException(e); } finally { } } public String put(File file, String bucket, String key, boolean isPublic) throws IOException, AWSException, TransportException { log.trace("put()"); return this.put(file, bucket, key, null, isPublic); } public String put(File file, String bucket, String key, Map<String, Object> metadata, boolean isPublic) throws IOException, AWSException, TransportException { log.trace("put()"); try { S3Bucket s3bucket = new S3Bucket(bucket); S3Object fileObject = new S3Object(s3bucket, key); if (isPublic) fileObject.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ); else fileObject.setAcl(AccessControlList.REST_CANNED_PRIVATE); fileObject.setContentType(mimeTypes.getContentType(file)); fileObject.setDataInputFile(file); fileObject.setContentLength(file.length()); if (metadata != null) fileObject.addAllMetadata(metadata); S3Service s3Service = getS3Service(); s3Service.putObject(bucket, fileObject); fileObject.closeDataInputStream(); return getUrl(fileObject); } catch (InvalidApiKey e) { throw new AWSException(e); } catch (S3ServiceException e) { throw new AWSException(e); } finally { } } public String put(String filename, String bucket, String key, boolean isPublic) throws IOException, AWSException, TransportException { log.trace("put()"); return this.put(new File(filename), bucket, key, null, isPublic); } public String putString(String content, String bucket, String key, String contentType, boolean isPublic) throws TransportException, IOException, AWSException { log.trace("putString()"); try { S3Bucket s3bucket = new S3Bucket(bucket); S3Object s3object = new S3Object(s3bucket, key); if (isPublic) s3object.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ); else s3object.setAcl(AccessControlList.REST_CANNED_PRIVATE); s3object.setContentType(contentType); s3object.setDataInputStream(new ByteArrayInputStream(content .getBytes())); S3Service s3Service = getS3Service(); s3Service.putObject(bucket, s3object); s3object.closeDataInputStream(); return getUrl(s3object); } catch (InvalidApiKey e) { throw new AWSException(e); } catch (S3ServiceException e) { throw new AWSException(e); } finally { } } public void delete(String bucket, String key) throws TransportException, IOException, AWSException { log.trace("delete()"); try { S3Bucket s3bucket = new S3Bucket(bucket); S3Service s3Service = getS3Service(); s3Service.deleteObject(s3bucket, key); } catch (InvalidApiKey e) { throw new AWSException(e); } catch (S3ServiceException e) { throw new AWSException(e); } } public S3Service getS3Service() throws TransportException, InvalidApiKey, S3ServiceException { log.trace("getS3Service()"); String awsAccessKey = gridClient.getSetting( AWSConstants.AWS_ACCESS_KEY_SETTING, ""); String awsSecretKey = gridClient.getSetting( AWSConstants.AWS_SECRET_KEY_SETTING, ""); AWSCredentials awsCredentials = new AWSCredentials(awsAccessKey, awsSecretKey); S3Service s3Service = new RestS3Service(awsCredentials); return s3Service; } private String getUrl(S3Object s3object) { return String.format("http://s3.amazonaws.com/%1$s/%2$s", s3object .getBucketName(), s3object.getKey()); } }