generated from pagopa/template-payments-java-repository
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[P4ADEV-1829] Moved file save logics to FileStorerService
- Loading branch information
mscarsel
committed
Jan 14, 2025
1 parent
0a9f22b
commit d6c5f62
Showing
10 changed files
with
348 additions
and
199 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
src/main/java/it/gov/pagopa/pu/fileshare/config/FoldersPathsConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package it.gov.pagopa.pu.fileshare.config; | ||
|
||
import it.gov.pagopa.pu.fileshare.dto.generated.IngestionFlowFileType; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
@Slf4j | ||
@Getter | ||
@Setter | ||
@Configuration | ||
@ConfigurationProperties(prefix = "folders") | ||
public class FoldersPathsConfig { | ||
private String shared; | ||
private Map<IngestionFlowFileType,String> ingestionFlowFileTypePaths; | ||
|
||
public String getIngestionFlowFilePath(IngestionFlowFileType ingestionFlowFileType) { | ||
return Optional.ofNullable( | ||
ingestionFlowFileTypePaths.get(ingestionFlowFileType)) | ||
.orElseThrow(()-> { | ||
log.debug("No path configured for ingestionFlowFileType {}",ingestionFlowFileType); | ||
return new UnsupportedOperationException(); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
src/main/java/it/gov/pagopa/pu/fileshare/service/FileStorerService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package it.gov.pagopa.pu.fileshare.service; | ||
|
||
import it.gov.pagopa.pu.fileshare.config.FoldersPathsConfig; | ||
import it.gov.pagopa.pu.fileshare.exception.custom.FileUploadException; | ||
import it.gov.pagopa.pu.fileshare.exception.custom.InvalidFileException; | ||
import it.gov.pagopa.pu.fileshare.util.AESUtils; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.nio.file.StandardCopyOption; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
@Slf4j | ||
@Service | ||
public class FileStorerService { | ||
private final FoldersPathsConfig foldersPathsConfig; | ||
private final String fileEncryptPassword; | ||
|
||
public FileStorerService(FoldersPathsConfig foldersPathsConfig, | ||
@Value(("${app.fileEncryptPassword}")) String fileEncryptPassword) { | ||
this.foldersPathsConfig = foldersPathsConfig; | ||
this.fileEncryptPassword = fileEncryptPassword; | ||
} | ||
|
||
private Path getFilePath(String relativePath, String filename) { | ||
String basePath = foldersPathsConfig.getShared()+relativePath; | ||
Path fileLocation = Paths.get(basePath,filename).normalize(); | ||
if(!fileLocation.startsWith(basePath)){ | ||
log.debug("Invalid file path"); | ||
throw new InvalidFileException("Invalid file path"); | ||
} | ||
return fileLocation; | ||
} | ||
|
||
public String saveToSharedFolder(MultipartFile file, String relativePath){ | ||
if(file==null){ | ||
log.debug("File is mandatory"); | ||
throw new FileUploadException("File is mandatory"); | ||
} | ||
|
||
String sharedFolderRootPath = foldersPathsConfig.getShared(); | ||
String filename = org.springframework.util.StringUtils.cleanPath( | ||
StringUtils.defaultString(file.getOriginalFilename())); | ||
FileService.validateFilename(filename); | ||
Path fileLocation = getFilePath(relativePath, filename); | ||
//create missing parent folder, if any | ||
try { | ||
if (!Files.exists(fileLocation.getParent())) | ||
Files.createDirectories(fileLocation.getParent()); | ||
encryptAndSaveFile(file, fileLocation); | ||
}catch (Exception e) { | ||
String errorMessage = "Error uploading file to folder %s%s".formatted( | ||
sharedFolderRootPath, | ||
relativePath); | ||
log.debug( | ||
errorMessage, e); | ||
throw new FileUploadException( | ||
errorMessage); | ||
} | ||
log.debug("File upload to folder %s%s completed".formatted(sharedFolderRootPath, | ||
relativePath)); | ||
return Paths.get(relativePath,filename).toString(); | ||
} | ||
|
||
private void encryptAndSaveFile(MultipartFile file, Path fileLocation) | ||
throws IOException { | ||
try(InputStream is = file.getInputStream(); | ||
InputStream cipherIs = AESUtils.encrypt(fileEncryptPassword, is)){ | ||
Files.copy(cipherIs, fileLocation, StandardCopyOption.REPLACE_EXISTING); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
src/test/java/it/gov/pagopa/pu/fileshare/config/FoldersPathsConfigTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package it.gov.pagopa.pu.fileshare.config; | ||
|
||
import it.gov.pagopa.pu.fileshare.dto.generated.IngestionFlowFileType; | ||
import java.util.EnumMap; | ||
import java.util.Map; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
import org.mockito.junit.jupiter.MockitoExtension; | ||
|
||
@ExtendWith(MockitoExtension.class) | ||
class FoldersPathsConfigTest { | ||
private FoldersPathsConfig foldersPathsConfig; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
foldersPathsConfig = new FoldersPathsConfig(); | ||
|
||
} | ||
|
||
@Test | ||
void givenPopulatedPathWhenGetIngestionFlowFilePathThenOK(){ | ||
String expected = "/receipt"; | ||
Map<IngestionFlowFileType,String> paths = new EnumMap<>( | ||
IngestionFlowFileType.class); | ||
paths.put(IngestionFlowFileType.RECEIPT, "/receipt"); | ||
foldersPathsConfig.setIngestionFlowFileTypePaths(paths); | ||
|
||
String result = foldersPathsConfig.getIngestionFlowFilePath( | ||
IngestionFlowFileType.RECEIPT); | ||
|
||
Assertions.assertEquals(expected,result); | ||
} | ||
|
||
@Test | ||
void givenNoPathWhenGetIngestionFlowFilePathThenUnsupportedOperation(){ | ||
foldersPathsConfig.setIngestionFlowFileTypePaths(new EnumMap<>(IngestionFlowFileType.class)); | ||
try { | ||
foldersPathsConfig.getIngestionFlowFilePath( | ||
IngestionFlowFileType.RECEIPT); | ||
Assertions.fail("Expected UnsupportedOperationException"); | ||
}catch (UnsupportedOperationException e){ | ||
//do nothing | ||
} | ||
} | ||
} |
Oops, something went wrong.