From 42406a03e42bd00183bde4276c5fdaec137879b7 Mon Sep 17 00:00:00 2001 From: LE SAULNIER Kevin Date: Thu, 15 Jan 2026 10:09:20 +0100 Subject: [PATCH 1/3] feat: add endpoint to get unpaged nmk results Signed-off-by: LE SAULNIER Kevin --- .../server/SecurityAnalysisController.java | 24 +++++++++---- .../SecurityAnalysisControllerTest.java | 34 +++++++++++++++++++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java b/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java index f646d15e..683dcc9d 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java @@ -159,12 +159,12 @@ public ResponseEntity getNResultZippedCsv(@Parameter(description = "Resu @Operation(summary = "Get a security analysis result from the database - NMK contingencies result") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result"), @ApiResponse(responseCode = "404", description = "Security analysis result has not been found")}) - public ResponseEntity> getNmKContingenciesResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid, - @Parameter(description = "network Uuid") @RequestParam(name = "networkUuid", required = false) UUID networkUuid, - @Parameter(description = "variant Id") @RequestParam(name = "variantId", required = false) String variantId, - @Parameter(description = "Filters") @RequestParam(name = "filters", required = false) String stringFilters, - @Parameter(description = "Global Filters") @RequestParam(name = "globalFilters", required = false) String globalFilters, - @Parameter(description = "Pagination parameters") Pageable pageable) { + public ResponseEntity> getPagedNmKContingenciesResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid, + @Parameter(description = "network Uuid") @RequestParam(name = "networkUuid", required = false) UUID networkUuid, + @Parameter(description = "variant Id") @RequestParam(name = "variantId", required = false) String variantId, + @Parameter(description = "Filters") @RequestParam(name = "filters", required = false) String stringFilters, + @Parameter(description = "Global Filters") @RequestParam(name = "globalFilters", required = false) String globalFilters, + @Parameter(description = "Pagination parameters") Pageable pageable) { String decodedStringFilters = stringFilters != null ? URLDecoder.decode(stringFilters, StandardCharsets.UTF_8) : null; String decodedStringGlobalFilters = globalFilters != null ? URLDecoder.decode(globalFilters, StandardCharsets.UTF_8) : null; Page result = securityAnalysisResultService.findNmKContingenciesPaged(resultUuid, networkUuid, variantId, decodedStringFilters, decodedStringGlobalFilters, pageable); @@ -174,6 +174,18 @@ public ResponseEntity> getNmKContingenciesResult(@Par : ResponseEntity.notFound().build(); } + @GetMapping(value = "/results/{resultUuid}/nmk-contingencies-result", produces = APPLICATION_JSON_VALUE) + @Operation(summary = "Get a security analysis result from the database - NMK contingencies result") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result"), + @ApiResponse(responseCode = "404", description = "Security analysis result has not been found")}) + public ResponseEntity> getNmKContingenciesResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) { + List result = securityAnalysisResultService.findNmKContingenciesResult(resultUuid); + + return result != null + ? ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result) + : ResponseEntity.notFound().build(); + } + @PostMapping(value = "/results/{resultUuid}/nmk-contingencies-result/csv", produces = APPLICATION_OCTET_STREAM_VALUE, consumes = APPLICATION_JSON_VALUE) @Operation(summary = "Get a security analysis result from the database - NMK contingencies result - CSV export") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result csv export"), diff --git a/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisControllerTest.java b/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisControllerTest.java index 8b961d16..a507adf1 100644 --- a/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisControllerTest.java +++ b/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisControllerTest.java @@ -26,6 +26,7 @@ import org.assertj.core.api.Assertions; import org.gridsuite.computation.dto.GlobalFilter; import org.gridsuite.computation.dto.ResourceFilterDTO; +import org.gridsuite.computation.error.ComputationException; import org.gridsuite.computation.service.AbstractFilterService; import org.gridsuite.computation.service.ReportService; import org.gridsuite.computation.service.UuidGeneratorService; @@ -75,6 +76,7 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import static com.powsybl.network.store.model.NetworkStoreApi.VERSION; +import static org.gridsuite.computation.error.ComputationBusinessErrorCode.RESULT_NOT_FOUND; import static org.gridsuite.computation.service.NotificationService.*; import static org.gridsuite.securityanalysis.server.SecurityAnalysisProviderMock.*; import static org.gridsuite.securityanalysis.server.service.SecurityAnalysisService.COMPUTATION_TYPE; @@ -864,6 +866,38 @@ void saveResultTest() throws Exception { .isEqualTo(securityAnalysisResult); } + @Test + void getNmKContingenciesResult() throws Exception { + UUID resultUuid = UUID.randomUUID(); + + List serviceResult = SecurityAnalysisProviderMock.RESULT_CONTINGENCIES; + + doReturn(serviceResult).when(securityAnalysisResultService).findNmKContingenciesResult(resultUuid); + + mockMvc.perform(get("/" + VERSION + "/results/" + resultUuid + "/nmk-contingencies-result") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(content().json(mapper.writeValueAsString(serviceResult))); + + verify(securityAnalysisResultService, times(1)) + .findNmKContingenciesResult(resultUuid); + } + + @Test + void getNmKContingenciesResultNotFound() throws Exception { + UUID resultUuid = UUID.randomUUID(); + + doReturn(null).when(securityAnalysisResultService).findNmKContingenciesResult(resultUuid); + + mockMvc.perform(get("/" + VERSION + "/results/" + resultUuid + "/nmk-contingencies-result") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isNotFound()); + + verify(securityAnalysisResultService, times(1)) + .findNmKContingenciesResult(resultUuid); + } + @Test void getZippedCsvResults() throws Exception { // running computation to create some results From 5e3c7bd6aed237841cbd1e4adea1d58ff91fc1ea Mon Sep 17 00:00:00 2001 From: LE SAULNIER Kevin Date: Mon, 19 Jan 2026 10:08:40 +0100 Subject: [PATCH 2/3] fix: checkstyle Signed-off-by: LE SAULNIER Kevin --- .../securityanalysis/server/SecurityAnalysisControllerTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisControllerTest.java b/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisControllerTest.java index a507adf1..eb9404ab 100644 --- a/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisControllerTest.java +++ b/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisControllerTest.java @@ -26,7 +26,6 @@ import org.assertj.core.api.Assertions; import org.gridsuite.computation.dto.GlobalFilter; import org.gridsuite.computation.dto.ResourceFilterDTO; -import org.gridsuite.computation.error.ComputationException; import org.gridsuite.computation.service.AbstractFilterService; import org.gridsuite.computation.service.ReportService; import org.gridsuite.computation.service.UuidGeneratorService; @@ -76,7 +75,6 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import static com.powsybl.network.store.model.NetworkStoreApi.VERSION; -import static org.gridsuite.computation.error.ComputationBusinessErrorCode.RESULT_NOT_FOUND; import static org.gridsuite.computation.service.NotificationService.*; import static org.gridsuite.securityanalysis.server.SecurityAnalysisProviderMock.*; import static org.gridsuite.securityanalysis.server.service.SecurityAnalysisService.COMPUTATION_TYPE; From 9a28d360ad08218416182d1c5dbdd9a5b4731e88 Mon Sep 17 00:00:00 2001 From: LE SAULNIER Kevin Date: Tue, 20 Jan 2026 13:25:10 +0100 Subject: [PATCH 3/3] PR review Signed-off-by: LE SAULNIER Kevin --- .../securityanalysis/server/SecurityAnalysisController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java b/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java index 683dcc9d..f359bfe8 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java @@ -156,7 +156,7 @@ public ResponseEntity getNResultZippedCsv(@Parameter(description = "Resu } @GetMapping(value = "/results/{resultUuid}/nmk-contingencies-result/paged", produces = APPLICATION_JSON_VALUE) - @Operation(summary = "Get a security analysis result from the database - NMK contingencies result") + @Operation(summary = "Get a paged security analysis result from the database - NMK contingencies result") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result"), @ApiResponse(responseCode = "404", description = "Security analysis result has not been found")}) public ResponseEntity> getPagedNmKContingenciesResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid, @@ -175,7 +175,7 @@ public ResponseEntity> getPagedNmKContingenciesResult } @GetMapping(value = "/results/{resultUuid}/nmk-contingencies-result", produces = APPLICATION_JSON_VALUE) - @Operation(summary = "Get a security analysis result from the database - NMK contingencies result") + @Operation(summary = "Get a full security analysis result from the database - NMK contingencies result") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result"), @ApiResponse(responseCode = "404", description = "Security analysis result has not been found")}) public ResponseEntity> getNmKContingenciesResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {