org.yestech.publish.publisher.AmazonS3Publisher.java Source code

Java tutorial

Introduction

Here is the source code for org.yestech.publish.publisher.AmazonS3Publisher.java

Source

/*
 * Copyright LGPL3
 * YES Technology Association
 * http://yestech.org
 *
 * http://www.opensource.org/licenses/lgpl-3.0.html
 */

/*
 *
 * Author:  Artie Copeland
 * Last Modified Date: $DateTime: $
 */
package org.yestech.publish.publisher;

import org.apache.commons.lang.StringUtils;
import static org.apache.commons.io.FileUtils.openOutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.FileUtils;
import org.jets3t.service.S3Service;
import org.jets3t.service.S3ServiceException;
import org.jets3t.service.Constants;
import org.jets3t.service.acl.AccessControlList;
import org.jets3t.service.acl.GroupGrantee;
import org.jets3t.service.acl.Permission;
import org.jets3t.service.utils.ServiceUtils;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;
import org.yestech.publish.objectmodel.*;
import static org.yestech.publish.util.PublishUtils.generateUniqueIdentifier;
import org.yestech.publish.util.PublishUtils;
import org.yestech.lib.util.Pair;

import javax.annotation.PostConstruct;
import java.io.*;

/**
 * Publishes to Amazons S3 storage.
 * <br/>
 * Valid Properties
 * <ul>
 * <li>urlPrefix = Mandatory</li>
 * <li>tempDirectory = Mandatory</li>
 * <li>secretKey = Mandatory</li>
 * <li>accessKey = Mandatory</li>
 * <li>bucketName = Mandatory</li>
 * </ul>
 *
 * @author Artie Copeland
 * @version $Revision: $
 */
@ProducerArtifactType(type = { ArtifactType.IMAGE, ArtifactType.VIDEO, ArtifactType.TEXT, ArtifactType.AUDIO })
public class AmazonS3Publisher extends BasePublisher implements IPublisher<IFileArtifact> {
    final private static Logger logger = LoggerFactory.getLogger(AmazonS3Publisher.class);

    private AWSCredentials awsCredentials;
    private S3Service s3Service;
    private S3Bucket artifactBucket;
    private static final String HTTP_SEPARATOR = "/";
    private PublisherProperties properties;
    private ArtifactType artifactType;

    public AmazonS3Publisher() {
        properties = new PublisherProperties();
    }

    public File getTempDirectory() {
        return properties.getProperty(Pair.create(getArtifactType(), "tempDirectory"));
    }

    public PublisherProperties getProperties() {
        return properties;
    }

    public ArtifactType getArtifactType() {
        return artifactType;
    }

    @Required
    public void setArtifactType(ArtifactType artifactType) {
        this.artifactType = artifactType;
    }

    @Required
    public void setProperties(PublisherProperties properties) {
        this.properties = properties;
    }

    private String getUrlPrefix() {
        return properties.getProperty(Pair.create(getArtifactType(), "urlPrefix"));
    }

    public String getAccessKey() {
        return properties.getProperty(Pair.create(getArtifactType(), "accessKey"));
    }

    public String getBucketName() {
        return properties.getProperty(Pair.create(getArtifactType(), "bucketName"));
    }

    public String getSecretKey() {
        return properties.getProperty(Pair.create(getArtifactType(), "secretKey"));
    }

    public S3Service getS3Service() {
        return s3Service;
    }

    public void setS3Service(S3Service s3Service) {
        this.s3Service = s3Service;
    }

    @PostConstruct
    public void init() {
        try {
            awsCredentials = new AWSCredentials(getAccessKey(), getSecretKey());
            s3Service = new RestS3Service(awsCredentials);
            S3Bucket[] myBuckets = s3Service.listAllBuckets();
            if (logger.isDebugEnabled()) {
                //test s3 connection
                logger.debug("How many buckets to I have in S3? " + myBuckets.length);
            }
            boolean createNewBucket = true;
            for (S3Bucket bucket : myBuckets) {
                if (StringUtils.equals(getBucketName(), bucket.getName())) {
                    artifactBucket = bucket;
                    createNewBucket = false;
                    break;
                }
            }
            if (createNewBucket) {
                artifactBucket = s3Service.createBucket(getBucketName());
                setACLOnBucket();
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Created test bucket: " + artifactBucket.getName());
            }
        } catch (S3ServiceException e) {
            logger.error("Error initializing Amazon S3 Publisher...", e);
        }
    }

    private void setACLOnBucket() throws S3ServiceException {
        AccessControlList bucketAcl = s3Service.getBucketAcl(artifactBucket);
        bucketAcl.grantPermission(GroupGrantee.ALL_USERS, Permission.PERMISSION_READ);
        artifactBucket.setAcl(bucketAcl);
        s3Service.putBucketAcl(artifactBucket);
    }

    @Override
    public void publish(IFileArtifact artifact) {
        IFileArtifactMetaData metaData = artifact.getArtifactMetaData();
        InputStream artifactStream = artifact.getStream();
        String artifactDirectoryName = generateUniqueIdentifier(metaData.getArtifactOwner());
        String uniqueFileName = generateUniqueIdentifier(metaData);

        Pair<String, String> names = metaData.getUniqueNames();
        if (names != null) {
            String path = names.getFirst();
            if (StringUtils.isNotBlank(path)) {
                artifactDirectoryName = path;
            }
        }
        if (names != null) {
            String fileName = names.getSecond();
            if (StringUtils.isNotBlank(fileName)) {
                uniqueFileName = fileName;
            }
        }

        final String tempFileFqn = saveToDisk(artifactDirectoryName, artifactStream, uniqueFileName);
        try {
            final StringBuilder s3LocationBuilder = new StringBuilder();
            final String s3Location = s3LocationBuilder.append(artifactDirectoryName)
                    .append(Constants.FILE_PATH_DELIM).append(uniqueFileName).toString();
            S3Object s3Artifact = new S3Object(s3Location);
            s3Artifact.setContentLength(metaData.getSize());
            s3Artifact.setContentType(metaData.getMimeType());

            s3Artifact.setMd5Hash(ServiceUtils.computeMD5Hash(new FileInputStream(new File(tempFileFqn))));
            s3Artifact.setDataInputStream(new FileInputStream(new File(tempFileFqn)));

            setCredentials(s3Artifact);
            // Upload the data objects.
            s3Service.putObject(artifactBucket, s3Artifact);
            setFinalLocationInMetaData(metaData, artifactDirectoryName, uniqueFileName);

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (logger.isInfoEnabled()) {
                logger.info("removing file: " + tempFileFqn);
            }
            File uploadedFile = new File(tempFileFqn);
            if (uploadedFile.exists()) {
                uploadedFile.delete();
            }
            PublishUtils.reset(artifact);
        }
    }

    private void setCredentials(S3Object s3Artifact) {
        //TODO:  added better
        s3Artifact.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
    }

    private void setFinalLocationInMetaData(IFileArtifactMetaData metaData, String artifactDirectoryName,
            String uniqueFileName) {
        String defaultLocation = metaData.getLocation();
        if (StringUtils.isBlank(defaultLocation)) {
            final StringBuilder builder = new StringBuilder();
            String location = builder.append(getUrlPrefix()).append(HTTP_SEPARATOR).append(artifactDirectoryName)
                    .append(HTTP_SEPARATOR).append(uniqueFileName).toString();
            metaData.setLocation(location);
        }
    }

    private String saveToDisk(String artifactDirectoryName, InputStream artifact, String uniqueFileName) {
        File fullPath = new File(getTempDirectory() + File.separator + artifactDirectoryName);
        if (!fullPath.exists()) {
            fullPath.mkdirs();
        }
        String location = fullPath.getAbsolutePath() + File.separator + uniqueFileName;
        FileOutputStream outputStream = null;
        try {
            if (logger.isDebugEnabled()) {
                logger.debug("Saving file: " + location);
            }
            outputStream = openOutputStream(new File(location));
            IOUtils.copyLarge(artifact, outputStream);
            outputStream.flush();
            if (logger.isDebugEnabled()) {
                logger.debug("Saved file: " + location);
            }
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        } finally {
            IOUtils.closeQuietly(artifact);
            IOUtils.closeQuietly(outputStream);
        }
        return location;
    }
}