org.cloudfoundry.multiapps.controller.persistence.services.FileService Maven / Gradle / Ivy
package org.cloudfoundry.multiapps.controller.persistence.services;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import jakarta.xml.bind.DatatypeConverter;
import org.cloudfoundry.multiapps.controller.persistence.Constants;
import org.cloudfoundry.multiapps.controller.persistence.DataSourceWithDialect;
import org.cloudfoundry.multiapps.controller.persistence.Messages;
import org.cloudfoundry.multiapps.controller.persistence.model.FileEntry;
import org.cloudfoundry.multiapps.controller.persistence.model.ImmutableFileEntry;
import org.cloudfoundry.multiapps.controller.persistence.query.providers.ExternalSqlFileQueryProvider;
import org.cloudfoundry.multiapps.controller.persistence.query.providers.SqlFileQueryProvider;
import org.cloudfoundry.multiapps.controller.persistence.util.SqlQueryExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FileService {
protected static final String DEFAULT_TABLE_NAME = "LM_SL_PERSISTENCE_FILE";
private static final int INPUT_STREAM_BUFFER_SIZE = 16 * 1024;
protected final Logger logger = LoggerFactory.getLogger(getClass());
private final FileStorage fileStorage;
private final SqlQueryExecutor sqlQueryExecutor;
private final SqlFileQueryProvider sqlFileQueryProvider;
public FileService(DataSourceWithDialect dataSourceWithDialect, FileStorage fileStorage) {
this(DEFAULT_TABLE_NAME, dataSourceWithDialect, fileStorage);
}
public FileService(String tableName, DataSourceWithDialect dataSourceWithDialect, FileStorage fileStorage) {
this(dataSourceWithDialect, new ExternalSqlFileQueryProvider(tableName, dataSourceWithDialect.getDataSourceDialect()), fileStorage);
}
protected FileService(DataSourceWithDialect dataSourceWithDialect, SqlFileQueryProvider sqlFileQueryProvider, FileStorage fileStorage) {
this.sqlQueryExecutor = new SqlQueryExecutor(dataSourceWithDialect.getDataSource());
this.sqlFileQueryProvider = sqlFileQueryProvider.withLogger(logger);
this.fileStorage = fileStorage;
}
public FileEntry addFile(FileEntry baseEntry, InputStream content) throws FileStorageException {
FileEntry entryWithoutDigest = ImmutableFileEntry.copyOf(baseEntry)
.withId(generateRandomId())
.withModified(LocalDateTime.now());
FileEntry fileEntry = storeFile(entryWithoutDigest, content);
logger.debug(MessageFormat.format(Messages.STORED_FILE_0, fileEntry));
return fileEntry;
}
public FileEntry addFile(FileEntry fileEntry, File existingFile) throws FileStorageException {
try (InputStream content = new BufferedInputStream(new FileInputStream(existingFile), INPUT_STREAM_BUFFER_SIZE)) {
return addFile(ImmutableFileEntry.copyOf(fileEntry)
.withSize(BigInteger.valueOf(existingFile.length())),
content);
} catch (FileNotFoundException e) {
throw new FileStorageException(MessageFormat.format(Messages.ERROR_FINDING_FILE_TO_UPLOAD, existingFile.getName()), e);
} catch (IOException e) {
throw new FileStorageException(MessageFormat.format(Messages.ERROR_READING_FILE_CONTENT, existingFile.getName()), e);
}
}
public List listFiles(String space, String namespace) throws FileStorageException {
try {
return getSqlQueryExecutor().execute(getSqlFileQueryProvider().getListFilesQuery(space, namespace));
} catch (SQLException e) {
throw new FileStorageException(MessageFormat.format(Messages.ERROR_GETTING_FILES_WITH_SPACE_AND_NAMESPACE, space, namespace),
e);
}
}
public List listFilesBySpaceAndOperationId(String space, String operationId) throws FileStorageException {
try {
return getSqlQueryExecutor().execute(getSqlFileQueryProvider().getListFilesBySpaceAndOperationId(space, operationId));
} catch (SQLException e) {
throw new FileStorageException(MessageFormat.format(Messages.ERROR_GETTING_FILES_WITH_SPACE_AND_OPERATION_ID, space,
operationId),
e);
}
}
public List listFilesCreatedAfterAndBeforeWithoutOperationId(LocalDateTime after, LocalDateTime before)
throws FileStorageException {
try {
return getSqlQueryExecutor().execute(getSqlFileQueryProvider().getListFilesCreatedAfterAndBeforeWithoutOperationQuery(after,
before));
} catch (SQLException e) {
throw new FileStorageException(MessageFormat.format(Messages.ERROR_GETTING_FILES_CREATED_AFTER_0_AND_BEFORE_1, after, before),
e);
}
}
public FileEntry getFile(String space, String id) throws FileStorageException {
try {
return getSqlQueryExecutor().execute(getSqlFileQueryProvider().getRetrieveFileQuery(space, id));
} catch (SQLException e) {
throw new FileStorageException(e.getMessage(), e);
}
}
public int updateFilesOperationId(List fileIds, String operationId) throws FileStorageException {
try {
return getSqlQueryExecutor().execute(getSqlFileQueryProvider().getUpdateFilesOperationIdQuery(fileIds, operationId));
} catch (SQLException e) {
throw new FileStorageException(e.getMessage(), e);
}
}
public void consumeFileContent(String space, String id, FileContentConsumer fileContentConsumer) throws FileStorageException {
processFileContent(space, id, inputStream -> {
fileContentConsumer.consume(inputStream);
return null;
});
}
public T processFileContent(String space, String id, FileContentProcessor fileContentProcessor) throws FileStorageException {
return fileStorage.processFileContent(space, id, fileContentProcessor);
}
public InputStream openInputStream(String space, String id) throws FileStorageException {
return fileStorage.openInputStream(space, id);
}
public int deleteBySpaceAndNamespace(String space, String namespace) throws FileStorageException {
fileStorage.deleteFilesBySpaceAndNamespace(space, namespace);
return deleteFileAttributesBySpaceAndNamespace(space, namespace);
}
public int deleteBySpaceIds(List spaceIds) throws FileStorageException {
fileStorage.deleteFilesBySpaceIds(spaceIds);
return deleteFileAttributesBySpaceIds(spaceIds);
}
public int deleteModifiedBefore(LocalDateTime modificationTime) throws FileStorageException {
int deletedItems = fileStorage.deleteFilesModifiedBefore(modificationTime);
return deleteFileAttributesModifiedBefore(modificationTime) + deletedItems;
}
public boolean deleteFile(String space, String id) throws FileStorageException {
fileStorage.deleteFile(id, space);
return deleteFileAttribute(space, id);
}
public int deleteFilesByIds(List fileIds) throws FileStorageException {
fileStorage.deleteFilesByIds(fileIds);
return deleteFilesAttributesByIds(fileIds);
}
public int deleteFilesEntriesWithoutContent() throws FileStorageException {
try {
List entries = getSqlQueryExecutor().execute(getSqlFileQueryProvider().getListAllFilesQuery());
List missing = fileStorage.getFileEntriesWithoutContent(entries);
List missingFilesIds = missing.stream()
.map(FileEntry::getId)
.toList();
logger.info(MessageFormat.format(Messages.DELETING_FILES_WITHOUT_CONTENT_WITH_IDS_0, missingFilesIds));
return deleteFilesAttributesByIds(missingFilesIds);
} catch (SQLException e) {
throw new FileStorageException(Messages.ERROR_GETTING_ALL_FILES, e);
}
}
protected FileEntry storeFile(FileEntry fileEntry, InputStream content) throws FileStorageException {
try (DigestInputStream dis = new DigestInputStream(content, MessageDigest.getInstance(Constants.DIGEST_ALGORITHM))) {
fileStorage.addFile(fileEntry, dis);
FileEntry completeFileEntry = ImmutableFileEntry.copyOf(fileEntry)
.withDigest(DatatypeConverter.printHexBinary(dis.getMessageDigest()
.digest()))
.withDigestAlgorithm(Constants.DIGEST_ALGORITHM);
storeFileAttributes(completeFileEntry);
return completeFileEntry;
} catch (NoSuchAlgorithmException | IOException e) {
throw new FileStorageException(e);
}
}
protected boolean deleteFileAttribute(String space, String id) throws FileStorageException {
try {
return getSqlQueryExecutor().execute(getSqlFileQueryProvider().getDeleteFileEntryQuery(space, id));
} catch (SQLException e) {
throw new FileStorageException(e.getMessage(), e);
}
}
protected int deleteFileAttributesModifiedBefore(LocalDateTime modificationTime) throws FileStorageException {
try {
return getSqlQueryExecutor().execute(getSqlFileQueryProvider().getDeleteModifiedBeforeQuery(modificationTime));
} catch (SQLException e) {
throw new FileStorageException(e.getMessage(), e);
}
}
protected int deleteFileAttributesBySpaceAndNamespace(String space, String namespace) throws FileStorageException {
try {
return getSqlQueryExecutor().execute(getSqlFileQueryProvider().getDeleteBySpaceAndNamespaceQuery(space, namespace));
} catch (SQLException e) {
throw new FileStorageException(e.getMessage(), e);
}
}
protected int deleteFilesAttributesByIds(List fileIds) throws FileStorageException {
try {
return getSqlQueryExecutor().execute(getSqlFileQueryProvider().getDeleteByFileIdsQuery(fileIds));
} catch (SQLException e) {
throw new FileStorageException(e.getMessage(), e);
}
}
protected int deleteFileAttributesBySpaceIds(List spaceIds) throws FileStorageException {
try {
return getSqlQueryExecutor().execute(getSqlFileQueryProvider().getDeleteBySpaceIdsQuery(spaceIds));
} catch (SQLException e) {
throw new FileStorageException(e.getMessage(), e);
}
}
protected SqlQueryExecutor getSqlQueryExecutor() {
return sqlQueryExecutor;
}
protected SqlFileQueryProvider getSqlFileQueryProvider() {
return sqlFileQueryProvider;
}
protected String generateRandomId() {
return UUID.randomUUID()
.toString();
}
private boolean storeFileAttributes(FileEntry fileEntry) throws FileStorageException {
try {
return getSqlQueryExecutor().execute(getSqlFileQueryProvider().getStoreFileAttributesQuery(fileEntry));
} catch (SQLException e) {
throw new FileStorageException(e.getMessage(), e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy