/** * Stores a photo on S3 and then updates the underlying Photo object with the URL's that point to * the image locations on S3. * * <p>The scaling process creates three separate images, a web size, a thumbnail, and then the * untouched original upload. The original is stored using full S3 redundancy, but the thumbnail * and web size versions are stored using reduced redundancy. In the event of a loss of reduced * redundancy data, the thumbnail and websize data could be regenerated if need be but that's not * implemented here. * * @param photo the photo data to be stored (should be initialized with a photo ID before being * passed in) * @param photoData raw data for the photo itself * @throws IOException */ public static Photo storePhoto(Photo photo, byte[] photoData) throws IOException { // Store various photo sizes String thumbnailPath = storeThumbnail(photo, photoData); photo.setThumbnailPath(thumbnailPath); String websizePath = storeWebsize(photo, photoData); photo.setWebsizePath(websizePath); String originalPath = storeOriginal(photo, photoData); photo.setOriginalPath(originalPath); return photo; }
/** * Scales the incoming photo data to a web size, stores it on S3, and then returns the storage * path for the photo on S3. This method uses reduced redundancy storage to reduce storage costs. * Should there be a loss of the data on S3, it could be regenerated from the original full size * image. * * @param photo metadata for the photo * @param photoData the raw data from the photo * @return storage path used on S3 (derived from the id of the photo and a predetermined suffix) * @throws IOException */ private static String storeWebsize(Photo photo, byte[] photoData) throws IOException { byte[] websize = scalePhoto(WEBSIZE_LONG_EDGE, photoData); TravelLogStorageObject obj = getStorageObject(websize, photo.getId() + WEBSIZE_SUFFIX); S3StorageManager mgr = new S3StorageManager(); mgr.storePublicRead(obj, true); return obj.getAwsUrl(); }
/** * Scales the incoming photo data to a thumbnail size, stores it on S3, and then returns the * storage path for the photo on S3. This method uses reduced redundancy storage to reduce storage * costs. Should there be a loss of the thumbnail data on S3, it could be regenerated from the * original full size image. * * @param photo metadata for the photo * @param photoData the raw data from the photo * @return storage path used on S3 (derived from the id of the photo and a predetermined suffix) * @throws IOException */ private static String storeThumbnail(Photo photo, byte[] photoData) throws IOException { byte[] thumbnail = scalePhoto(THUMBNAIL_LONG_EDGE, photoData); TravelLogStorageObject obj = getStorageObject(thumbnail, photo.getId() + THUMB_SUFFIX); S3StorageManager mgr = new S3StorageManager(); mgr.storePublicRead(obj, true); return obj.getAwsUrl(); }
/** * Loads original photo from S3, returning the raw image data. * * @param photo the photo object specifying storage path of the original photo * @return raw image data * @throws IOException */ public static InputStream loadOriginalPhoto(Photo photo) throws IOException { S3StorageManager mgr = new S3StorageManager(); TravelLogStorageObject obj = new TravelLogStorageObject(); obj.setBucketName(uniqueBucketName); obj.setStoragePath(photo.getId() + FULLSIZE_SUFFIX); return mgr.loadInputStream(obj); }
/** * Deletes a photo from S3 based on the paths stored in the Photo object. This will delete both * the original photo and the resized versions that were created during the storage process. * * @param photo the photo to be deleted */ public static void deletePhotoFromS3(Photo photo) { if (photo.getOriginalPath() != null) { deleteFromPath(photo.getId() + FULLSIZE_SUFFIX); } if (photo.getThumbnailPath() != null) { deleteFromPath(photo.getId() + THUMB_SUFFIX); } if (photo.getWebsizePath() != null) { deleteFromPath(photo.getId() + WEBSIZE_SUFFIX); } }
/** * Stores the original full size image on S3, and then returns the storage path for the photo on * S3. This method uses full redundancy storage because if we lose the original there's no way to * recreate it. Also, in the event of data loss of a thumbnail or web size of the original, this * could be used to recreate the smaller images. * * @param photo metadata for the photo * @param photoData the raw data from the photo * @return storage path used on S3 (derived from the id of the photo and a predetermined suffix) * @throws IOException */ private static String storeOriginal(Photo photo, byte[] photoData) throws IOException { TravelLogStorageObject obj = getStorageObject(photoData, photo.getId() + FULLSIZE_SUFFIX); S3StorageManager mgr = new S3StorageManager(); mgr.storePublicRead(obj, false); return obj.getAwsUrl(); }