Skip to content

Comments

Add Endpoint to importCase from s3 directrory#143

Merged
etiennehomer merged 30 commits intomainfrom
Import_Case_From_S3
Jan 23, 2026
Merged

Add Endpoint to importCase from s3 directrory#143
etiennehomer merged 30 commits intomainfrom
Import_Case_From_S3

Conversation

@basseche
Copy link
Contributor

@basseche basseche commented Jan 7, 2026

Please check if the PR fulfills these requirements

  • The commit message follows our guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)
  • A PR or issue has been opened in all impacted repositories (if any)

Does this PR already have an issue describing the problem?
No.

What kind of change does this PR introduce?
Feature

What is the current behavior?
Cases can be imported from a file.

What is the new behavior (if this is a feature change)?
Cases can be imported also from an s3 key now.

Does this PR introduce a breaking change or deprecate an API?

  • Yes
  • No

@basseche basseche force-pushed the Import_Case_From_S3 branch from 76060e4 to df048e9 Compare January 7, 2026 16:42
@basseche basseche self-assigned this Jan 8, 2026
@basseche basseche force-pushed the Import_Case_From_S3 branch 2 times, most recently from 73d9dd2 to 88313fd Compare January 8, 2026 09:43
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
@basseche basseche force-pushed the Import_Case_From_S3 branch from 88313fd to ca19182 Compare January 8, 2026 09:46
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
… from S3

Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
@basseche basseche force-pushed the Import_Case_From_S3 branch from 1dec525 to 4251db0 Compare January 14, 2026 17:33
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
.param("fileName", fileName))
.andExpect(status().isOk());

assertNotNull(outputDestination.receive(1000, caseImportDestination));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can check content of notification,

THEN getObjet from s3 then check file size from resource and file size from s3

.param("caseUuid", caseUuid.toString())
.param("folderName", folderName)
.param("fileName", fileName))
.andExpect(status().isInternalServerError());
Copy link

@thangqp thangqp Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should detail which message error expected and why for example, bad folder name

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be named as testCase.zip ?

Copy link
Contributor Author

@basseche basseche Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No! If i do that another test will fail in another test file.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there's a weird behavior with datasources.
But test(2)Case.xiidm was to test a specific bug.
Name it zippedTestCase.zip and it will work

…artFile.java

Co-authored-by: Thang PHAM <117309322+thangqp@users.noreply.github.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
@RequestParam(value = "withExpiration", required = false, defaultValue = "false") boolean withExpiration,
@RequestParam(value = "withIndexation", required = false, defaultValue = "false") boolean withIndexation) {

try (S3MultiPartFile mpf = new S3MultiPartFile(caseService, caseUuid, folderName, fileName + ZIP_EXTENSION, "application/zip")) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this code to the service.
Just keep something like :
UUID uuid = caseService.importCaseFromS3(....)
return ResponseEntity.ok().body(uuid);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@ApiResponse(responseCode = "404", description = "Source case not found"),
@ApiResponse(responseCode = "500", description = "An error occurred during the case file creation")})
public ResponseEntity<UUID> createCase(
@RequestParam("caseUuid") UUID caseUuid,
Copy link
Collaborator

@etiennehomer etiennehomer Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

caseUuid, folderName are too specific to exportNetwork structure.
You can give only one parameter folderKey

And you fill the filename something like new Path(caseKey).getFileName()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@RequestParam(value = "withExpiration", required = false, defaultValue = "false") boolean withExpiration,
@RequestParam(value = "withIndexation", required = false, defaultValue = "false") boolean withIndexation) {

try (S3MultiPartFile mpf = new S3MultiPartFile(caseService, caseUuid, folderName, fileName + ZIP_EXTENSION, "application/zip")) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not give the service to the S3MultiPartFile constructor. It's a bad practice.
Write the file on /tmp in the service. And then only give the Path to the constructor

Copy link
Contributor Author

@basseche basseche Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the problem is if we don't do that we have to manage file lifecycle (create, delete) each time from outside

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
Files.copy(tempFile, dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throw new UnsupportedOperationException("Not supported.");

or

transferTo(dest.toPath());
?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

return UUID.fromString(keyWithoutRootDirectory.substring(0, firstSlash));
}

public Optional<InputStream> getInputStreamFromS3(UUID caseUuid, String folderName, String fileName) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicated code from getCaseStream(). Code to put in common in a method

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

basseche and others added 7 commits January 16, 2026 15:51
…artFile.java

Co-authored-by: etiennehomer <etiennehomer@gmail.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
}

public UUID importCase(String folderKey, String contentType, boolean withExpiration, boolean withIndexation) throws IOException {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no empty row


private final String name;
private final String contentType;
private final CaseService caseService;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to remove

return caseUuid;
}

public UUID importCase(String folderKey, String contentType, boolean withExpiration, boolean withIndexation) throws IOException {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public UUID importCase(String folderKey, String contentType, boolean withExpiration, boolean withIndexation) throws IOException {
public UUID importCase(String caseFileKey, String contentType, boolean withExpiration, boolean withIndexation) throws IOException {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there's a weird behavior with datasources.
But test(2)Case.xiidm was to test a specific bug.
Name it zippedTestCase.zip and it will work

basseche and others added 4 commits January 22, 2026 14:46
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Co-authored-by: etiennehomer <etiennehomer@gmail.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
…artFile.java

Co-authored-by: etiennehomer <etiennehomer@gmail.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
* @author Bassel El Cheikh <bassel.el-cheikh_externe at rte-france.com>
*/

public class S3MultiPartFile implements MultipartFile, Closeable {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public class S3MultiPartFile implements MultipartFile, Closeable {
public class TmpMultiPartFile implements MultipartFile, Closeable {

As there is no more S3 notion in this class now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
basseche and others added 2 commits January 23, 2026 11:44
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
Co-authored-by: etiennehomer <etiennehomer@gmail.com>
Signed-off-by: basseche <bassel.el-cheikh_externe@rte-france.com>
@sonarqubecloud
Copy link

@etiennehomer etiennehomer merged commit c43eb13 into main Jan 23, 2026
5 checks passed
@etiennehomer etiennehomer deleted the Import_Case_From_S3 branch January 23, 2026 17:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants