package com.github.windbender.core; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import javax.imageio.ImageIO; import org.imgscalr.Scalr; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.AmazonS3Exception; import com.amazonaws.services.s3.model.Bucket; import com.amazonaws.services.s3.model.CannedAccessControlList; import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.Owner; import com.amazonaws.services.s3.model.S3Object; import com.github.windbender.domain.ImageRecord; public class S3ImageStore implements ImageStore { Logger log = LoggerFactory.getLogger(S3ImageStore.class); private String bucketName; private String myAccessKeyID; private String mySecretKey; AmazonS3 s3Client; public S3ImageStore(String accessKey, String secretKey, String bucketName) { this.bucketName = bucketName; this.myAccessKeyID = accessKey; this.mySecretKey = secretKey; AWSCredentials myCredentials = new BasicAWSCredentials( myAccessKeyID, mySecretKey); s3Client = new AmazonS3Client(myCredentials); Owner o = s3Client.getS3AccountOwner(); log.info("using S3 as "+o.getDisplayName()); List<Bucket> bl =s3Client.listBuckets(); for(Bucket b : bl) { log.info(" bucket:"+b.getName()); } } @Override public InputStream getInputStreamFor(ImageRecord ir, String id, int displayWidth) throws IOException { log.info("attempting to get an inpustream for "+id); String szs = "native"; try { if(displayWidth == 0) displayWidth=1300; for(int sz : sizes) { if(sz > displayWidth) { szs = ""+sz; } } String s3Key = szs+"/"+ ir.getId(); S3Object object = s3Client.getObject(new GetObjectRequest(bucketName, s3Key)); InputStream objectData = object.getObjectContent(); return objectData; } catch (AmazonS3Exception e) { if( 404 == e.getStatusCode()) { // com.amazonaws.services.s3.model.AmazonS3Exception: // Status Code: 404, AWS Service: Amazon S3, AWS Request ID: 4E801215FAEB5EF5, AWS Error Code: NoSuchKey, // AWS Error Message: The specified key does not exist. try { String s3Key2 = "native"+"/"+ ir.getId(); S3Object object = s3Client.getObject(new GetObjectRequest(bucketName, s3Key2)); InputStream objectData = object.getObjectContent(); BufferedImage bi = ImageIO.read(objectData); BufferedImage outImage = Scalr.resize(bi, SMALLEST_SIZE); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(outImage, "jpg", baos); byte[] imageInByteArray = baos.toByteArray(); upload(""+SMALLEST_SIZE,ir,imageInByteArray); baos.flush(); outImage.flush(); baos.close(); S3Object object2 = s3Client.getObject(new GetObjectRequest(bucketName, ""+SMALLEST_SIZE+"/"+ ir.getId())); InputStream objectData2 = object2.getObjectContent(); return objectData2; } catch(Exception e2) { log.error("failed because ",e2); throw e; } } else { log.error("failed because ",e); throw e; } } catch (Exception e) { log.error("failed because ",e); throw e; } } @Override public void saveImages(BufferedImage bi, ImageRecord newImage) throws IOException { // we should make a 640X480 at 1280X960 and then a native. for (int maxSize : sizes) { BufferedImage outImage = bi; String szs; szs = "native"; if (maxSize == -1) { maxSize = bi.getWidth(); } else { szs = "" + maxSize; } outImage = Scalr.resize(bi, maxSize); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(outImage, "jpg", baos); byte[] imageInByteArray = baos.toByteArray(); upload(szs,newImage,imageInByteArray); baos.flush(); outImage.flush(); baos.close(); } } private void upload(String szs, ImageRecord newImage, byte[] imageInByteArray) { InputStream stream = null; try { log.info("attempting to upload to S3 for "+newImage.getId()); stream = new ByteArrayInputStream(imageInByteArray); ObjectMetadata meta = new ObjectMetadata(); meta.setContentLength(imageInByteArray.length); meta.setContentType("image/jpeg"); String s3Key = szs+"/"+ newImage.getId(); s3Client.putObject(bucketName, s3Key, stream, meta); s3Client.setObjectAcl(bucketName, s3Key,CannedAccessControlList.PublicRead); log.info("in theory finished"); } catch(Exception e) { log.error("unable to do an upload because ",e); } finally { try { stream.close(); } catch (IOException e) { } } } }