All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mapfish.print.config.S3ReportStorage Maven / Gradle / Ivy

There is a newer version: 3.22.0
Show newest version
package org.mapfish.print.config;

import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Configuration for storing the reports in a S3 compatible storage.
 * 

* By default, authentication is done using the {@link DefaultAWSCredentialsProviderChain} which uses * Environment Variables, Java System Properties, Credential profiles file, ... */ public class S3ReportStorage implements ReportStorage { private static final Logger LOGGER = LoggerFactory.getLogger(S3ReportStorage.class); private static final long PURGE_INTERVAL_MS = 6 * 60 * 60 * 1000; private static long nextPurge = 0; private String bucket = null; private String prefix = ""; private String accessKey = null; private String secretKey = null; private String region = null; private String endpointUrl = null; private int retentionDays = 7; private void maybePurge(final AmazonS3 client) { boolean needPurge = false; synchronized (S3ReportStorage.class) { if (System.currentTimeMillis() >= nextPurge) { needPurge = true; nextPurge = System.currentTimeMillis() + PURGE_INTERVAL_MS; } } if (needPurge) { purge(client); } } private void purge(final AmazonS3 client) { LOGGER.debug("Checking for reports to delete"); final Date now = new Date(); final long retentionMs = TimeUnit.MILLISECONDS.convert(retentionDays, TimeUnit.DAYS); try { final ObjectListing objects = client.listObjects(bucket, prefix); for (S3ObjectSummary object: objects.getObjectSummaries()) { final Date lastModified = object.getLastModified(); final long ageMs = now.getTime() - lastModified.getTime(); if (ageMs > retentionMs) { LOGGER.info("Deleting old report: {}/{}", bucket, object.getKey()); client.deleteObject(bucket, object.getKey()); } } } catch (SdkClientException ex) { LOGGER.warn("Error while trying the delete old reports", ex); } } private AmazonS3 connect() { AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard(); if (accessKey != null) { final AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey); builder.withCredentials(new AWSStaticCredentialsProvider(credentials)); } if (endpointUrl != null) { builder.withEndpointConfiguration( new AwsClientBuilder.EndpointConfiguration(endpointUrl, region)); } else if (region != null) { builder.withRegion(region); } return builder.build(); } @Override public URL save( final String ref, final String filename, final String extension, final String mimeType, final File file) { final AmazonS3 client = connect(); maybePurge(client); final PutObjectRequest request = createPutRequest(ref, filename, extension, mimeType, file); client.putObject(request); final URL url = client.getUrl(bucket, request.getKey()); LOGGER.info("Report stored on S3: {}", url); return url; } private PutObjectRequest createPutRequest( final String ref, final String filename, final String extension, final String mimeType, final File file) { final PutObjectRequest request = new PutObjectRequest(bucket, getKey(ref, filename, extension), file); request.withCannedAcl(CannedAccessControlList.PublicRead); final ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType(mimeType); request.withMetadata(metadata); return request; } /** * Compute the key to use. * * @param ref The reference number. * @param filename The filename. * @param extension The file extension. */ protected String getKey(final String ref, final String filename, final String extension) { return prefix + ref + "/" + filename + "." + extension; } @Override public void validate( final List validationErrors, final Configuration configuration) { if (bucket == null) { validationErrors.add(new ConfigurationException("You must define a bucket")); } if (accessKey != null && secretKey == null) { validationErrors.add(new ConfigurationException( "If you define the accessKey, you must define the secretKey")); } if (!prefix.endsWith("/") && !prefix.isEmpty()) { prefix = prefix + "/"; } if (retentionDays <= 0) { validationErrors.add(new ConfigurationException("retentionDays must be bigger that 0")); } } public String getAccessKey() { return accessKey; } /** * To set the access key. * * @param accessKey the value. */ public void setAccessKey(final String accessKey) { this.accessKey = accessKey; } public String getSecretKey() { return secretKey; } /** * To set the secret key. * * @param secretKey the value. */ public void setSecretKey(final String secretKey) { this.secretKey = secretKey; } public String getRegion() { return region; } /** * To set the region to use. * * @param region the value. */ public void setRegion(final String region) { this.region = region; } public String getEndpointUrl() { return endpointUrl; } /** * To override the endpoint URL (for non-Amazon, S3 compatible servers). * * @param endpointUrl the value. */ public void setEndpointUrl(final String endpointUrl) { this.endpointUrl = endpointUrl; } public String getBucket() { return bucket; } /** * The S3 bucket to use. * * @param bucket the value. */ public void setBucket(final String bucket) { this.bucket = bucket; } public String getPrefix() { return prefix; } /** * The key prefix to use. * * @param prefix the value. */ public void setPrefix(final String prefix) { this.prefix = prefix; } public int getRetentionDays() { return retentionDays; } /** * The number of day the reports must be kept. *

* Passed this delay, they will be deleted and the links included in the corresponding emails will become * invalid. Defaults to 7 days. * * @param retentionDays the value. */ public void setRetentionDays(final int retentionDays) { this.retentionDays = retentionDays; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy