
com.crabshue.commons.archive.s3.AwsS3ArchiveService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of commons-archive-s3 Show documentation
Show all versions of commons-archive-s3 Show documentation
Library for structured AWS-S3-based archives.
The newest version!
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 com.amazonaws.services.s3.model.S3ObjectSummary;
import com.crabshue.commons.archive.Archivable;
import com.crabshue.commons.archive.ArchiveService;
import com.crabshue.commons.aws.s3.service.AwsS3Client;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
/**
* Abstract class for AWS-S3-based archive service.
*
* @param the type of archivable.
*/
@Slf4j
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(@NonNull final T archivable) {
if (archivable.getArchiveId() == null) {
throw new IllegalArgumentException("Archivable has a blank archive id: " + archivable);
}
final String ret = FilenameUtils.separatorsToUnix(
Paths.get(this.getArchiveRootPath()).resolve(archivable.getArchiveId()).toString()
) + "/";
logger.info("Archive folder path for archivable [{}] is [{}]", archivable, ret);
return ret;
}
@Override
public Collection listFilesInArchive(@NonNull final T archivable) {
final String folderPath = this.getArchiveFolderPath(archivable);
final List ret = this.awsS3Client.listObjects(folderPath)
.stream()
.map(S3ObjectSummary::getKey)
.collect(Collectors.toList());
logger.info("Listed files in [{}] for archivable [{}] : [{}]", folderPath, archivable, ret);
return ret;
}
@Override
public File retrieveUniqueFileInArchive(@NonNull final T archivable,
@NonNull final String filename) {
final String filePath = this.buildFilePath(archivable, filename);
final File outputFile = new File(this.provideNewTemporaryFolder(), filename);
this.awsS3Client.downloadObject(filePath, outputFile);
logger.info("Retrieved file [{}] for archivable [{}] and filename [{}]", filePath, archivable, filename);
return outputFile;
}
@Override
public void deleteArchiveFolder(@NonNull final T archivable) {
this.cleanArchiveFolder(archivable);
final String folderPath = this.getArchiveFolderPath(archivable);
this.awsS3Client.deleteObject(folderPath);
logger.info("Deleted archive folder [{}] for archivable [{}]", folderPath, archivable);
}
@Override
public void cleanArchiveFolder(@NonNull final T 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);
logger.info("Deleted content of folder [{}] for archivable [{}]", folderPath, archivable);
}
@Override
public void cleanArchiveRoot() {
this.awsS3Client.listObjects(this.getArchiveRootPath())
.forEach(s3ObjectSummary -> this.awsS3Client.deleteObject(s3ObjectSummary.getKey()));
logger.info("Cleaned all elements in archive root [{}]", this.getArchiveRootPath());
}
@Override
public void storeInArchive(@NonNull final T archivable,
@NonNull final File file) {
final String filePath = this.buildFilePath(archivable, file.getName());
this.awsS3Client.uploadObject(filePath, file);
logger.info("Stored file [{}] file in [{}] for archivable [{}]", file, filePath, archivable);
}
@Override
public void storeInArchive(@NonNull final T archivable,
@NonNull final String filename,
@NonNull final InputStream inputStream) {
final String filePath = this.buildFilePath(archivable, filename);
this.awsS3Client.uploadObject(filePath, inputStream);
logger.info("Stored input stream to [{}] for archivable [{}]", filePath, archivable);
}
@Override
public void storeFolderContentInArchive(@NonNull final T archivable,
@NonNull final File 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);
});
logger.info("Copied content of folder [{}] to archive folder for archivable [{}]", folder, archivable);
}
/**
* 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(@NonNull final T archivable,
@NonNull final String filePath) {
final String ret = FilenameUtils.separatorsToUnix(Paths.get(this.getArchiveFolderPath(archivable)).resolve(filePath).toString());
logger.debug("Built file path [{}] for file path [{}] and archivable [{}]", ret, filePath, archivable);
return ret;
}
/**
* 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