001/*
002 * Stallion Core: A Modern Web Framework
003 *
004 * Copyright (C) 2015 - 2016 Stallion Software LLC.
005 *
006 * This program is free software: you can redistribute it and/or modify it under the terms of the
007 * GNU General Public License as published by the Free Software Foundation, either version 2 of
008 * the License, or (at your option) any later version. This program is distributed in the hope that
009 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
011 * License for more details. You should have received a copy of the GNU General Public License
012 * along with this program.  If not, see <http://www.gnu.org/licenses/gpl-2.0.html>.
013 *
014 *
015 *
016 */
017
018package io.stallion.services;
019
020import com.amazonaws.HttpMethod;
021import com.amazonaws.auth.AWSCredentials;
022import com.amazonaws.auth.BasicAWSCredentials;
023import com.amazonaws.services.s3.AmazonS3Client;
024import com.amazonaws.services.s3.model.CannedAccessControlList;
025import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
026import com.amazonaws.services.s3.model.ObjectMetadata;
027import com.amazonaws.services.s3.model.PutObjectRequest;
028import io.stallion.exceptions.ConfigException;
029import io.stallion.settings.Settings;
030import io.stallion.settings.childSections.CloudStorageSettings;
031import io.stallion.utils.GeneralUtils;
032
033import java.io.File;
034import java.lang.annotation.Documented;
035import java.sql.Date;
036import java.util.Map;
037
038import static io.stallion.utils.Literals.*;
039
040
041public class S3StorageService extends CloudStorageService {
042    private String accessToken = "";
043    private String secret = "";
044    private AmazonS3Client client;
045
046    public S3StorageService() {
047        CloudStorageSettings settings = Settings.instance().getCloudStorage();
048        if (settings == null) {
049            throw new ConfigException("You are missing the section [cloudStorage]\naccessToken=...\nsecret=... in your stallion.toml");
050        }
051        if (empty(settings.getAccessToken())) {
052            throw new ConfigException("You are missing the setting accessKey in the stallion.toml section [cloudStorage]");
053        }
054        if (empty(settings.getSecret())) {
055            throw new ConfigException("You are missing the setting secret in the stallion.toml section [cloudStorage]");
056        }
057        accessToken = settings.getAccessToken();
058        secret = settings.getSecret();
059        AWSCredentials credentials = new BasicAWSCredentials(accessToken, secret);
060        client =  new AmazonS3Client(credentials);
061    }
062
063    public void uploadFile(File file, String bucket, String fileKey, boolean isPublic) {
064        String contentType = GeneralUtils.guessMimeType(fileKey);
065        uploadFile(file, bucket, fileKey, isPublic, contentType, null);
066    }
067
068    public void uploadFile(File file, String bucket, String fileKey, boolean isPublic, String contentType, Map<String, String> headers) {
069        client.putObject(bucket, fileKey, file);
070        PutObjectRequest req = new PutObjectRequest(bucket, fileKey, file);
071        if (isPublic) {
072            req.withCannedAcl(CannedAccessControlList.PublicRead);
073        }
074        ObjectMetadata meta = new ObjectMetadata();
075
076        if (headers != null) {
077            for (String key: headers.keySet()) {
078                meta.setHeader(key, headers.get(key));
079            }
080        }
081        if (!empty(contentType)) {
082            meta.setContentType(contentType);
083        }
084        req.setMetadata(meta);
085        client.putObject(req);
086
087    }
088
089    public String getSignedUploadUrl(String bucket, String fileKey, String contentType, Map headers) {
090        GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucket, fileKey);
091        if (!empty(contentType)) {
092            req.setContentType(contentType);
093        }
094        if  (headers != null) {
095            for (Object key: headers.keySet())
096            req.addRequestParameter(key.toString(), headers.get(key).toString());
097        }
098        req.setExpiration(Date.from(utcNow().plusDays(2).toInstant()));
099        req.setMethod(HttpMethod.PUT);
100        return client.generatePresignedUrl(req).toString();
101    }
102
103
104    public AmazonS3Client getClient() {
105        return client;
106    }
107}