com.crabshue.commons.archive.s3.AwsS3ArchiveService Maven / Gradle / Ivy
package com.crabshue.commons.archive.s3;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.lang3.Validate;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.crabshue.commons.archive.Archivable;
import com.crabshue.commons.archive.ArchiveService;
import com.crabshue.commons.aws.s3.AwsS3Client;
/**
* Abstract class for AWS-S3-based archive service.
*
* @param the type of archivable.
*/
public abstract class AwsS3ArchiveService implements ArchiveService {
protected final AwsS3Client awsS3Client;
protected AwsS3ArchiveService(final AwsS3Client awsS3Client) {
this.awsS3Client = awsS3Client;
}
@Override
public abstract String getArchiveRootPath();
@Override
public String getArchiveFolderPath(final T archivable) {
Validate.notNull(archivable);
if (archivable.getArchiveId() == null) {
throw new IllegalArgumentException("Archivable has a blank archive id: " + archivable);
}
return FilenameUtils.separatorsToUnix(
Paths.get(this.getArchiveRootPath()).resolve(archivable.getArchiveId()).toString()
) + "/";
}
@Override
public Collection listFilesInArchive(final T archivable) {
Validate.notNull(archivable);
final String folderPath = this.getArchiveFolderPath(archivable);
return this.awsS3Client.listObjects(folderPath)
.stream()
.map(S3ObjectSummary::getKey)
.collect(Collectors.toList());
}
@Override
public File retrieveUniqueFileInArchive(final T archivable, final String filename) {
Validate.notNull(archivable);
final String filePath = this.buildFilePath(archivable, filename);
final File outputFile = new File(this.provideNewTemporaryFolder(), filename);
this.awsS3Client.downloadObject(filePath, outputFile);
return outputFile;
}
@Override
public void deleteArchiveFolder(final T archivable) {
Validate.notNull(archivable);
this.cleanArchiveFolder(archivable);
final String folderPath = this.getArchiveFolderPath(archivable);
this.awsS3Client.deleteObject(folderPath);
}
@Override
public void cleanArchiveFolder(final T archivable) {
Validate.notNull(archivable);
final String folderPath = this.getArchiveFolderPath(archivable);
final List keysToDelete = this.awsS3Client.listObjects(folderPath).stream()
.map(S3ObjectSummary::getKey)
.collect(Collectors.toList());
this.awsS3Client.deleteObjects(keysToDelete);
}
@Override
public void cleanArchiveRoot() {
this.awsS3Client.listObjects(this.getArchiveRootPath())
.forEach(s3ObjectSummary -> this.awsS3Client.deleteObject(s3ObjectSummary.getKey()));
}
@Override
public void storeInArchive(final T archivable, final File file) {
Validate.notNull(archivable);
Validate.notNull(file);
final String filePath = this.buildFilePath(archivable, file.getName());
this.awsS3Client.uploadObject(filePath, file);
}
@Override
public void storeInArchive(final T archivable, final String filename, final InputStream inputStream) {
Validate.notNull(archivable);
Validate.notNull(filename);
Validate.notNull(inputStream);
final String filePath = this.buildFilePath(archivable, filename);
this.awsS3Client.uploadObject(filePath, inputStream);
}
@Override
public void storeFolderContentInArchive(final T archivable, final File folder) {
Validate.notNull(archivable);
Validate.notNull(folder);
FileUtils.listFiles(folder, FileFilterUtils.trueFileFilter(), FileFilterUtils.trueFileFilter())
.forEach(f -> {
final String relativePath = folder.toPath().relativize(f.toPath()).toString();
final String fileKey = this.buildFilePath(archivable, relativePath);
this.awsS3Client.uploadObject(fileKey, f);
});
}
/**
* Build key for a relative file path inside an archivable folder.
*
* @param archivable the archivable.
* @param filePath the file path.
* @return the storage key
*/
protected String buildFilePath(final T archivable, final String filePath) {
return FilenameUtils.separatorsToUnix(Paths.get(this.getArchiveFolderPath(archivable)).resolve(filePath).toString());
}
/**
* Provide an empty temporary folder.
* By default, use {@link FileUtils#getTempDirectory()}
*
* @return the temporary folder.
*/
protected File provideNewTemporaryFolder() {
return FileUtils.getTempDirectory();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy