From ac4bdf43b8f8582f4353cc3b4390a5bc75369fb8 Mon Sep 17 00:00:00 2001 From: LE SAULNIER Kevin Date: Wed, 11 Dec 2024 10:58:06 +0100 Subject: [PATCH] feat: migrate run security-analysis endpoint to path with root network Signed-off-by: LE SAULNIER Kevin --- .../study/server/StudyController.java | 5 +- .../gridsuite/study/server/GenericTest.java | 4 +- .../study/server/SecurityAnalysisTest.java | 48 +++++++++++-------- .../study/server/utils/StudyTestUtils.java | 22 +++++++++ 4 files changed, 55 insertions(+), 24 deletions(-) create mode 100644 src/test/java/org/gridsuite/study/server/utils/StudyTestUtils.java diff --git a/src/main/java/org/gridsuite/study/server/StudyController.java b/src/main/java/org/gridsuite/study/server/StudyController.java index 674b23479..408074785 100644 --- a/src/main/java/org/gridsuite/study/server/StudyController.java +++ b/src/main/java/org/gridsuite/study/server/StudyController.java @@ -791,16 +791,17 @@ public ResponseEntity exportNetwork( return ResponseEntity.ok().headers(header).contentType(MediaType.APPLICATION_OCTET_STREAM).body(exportNetworkInfos.getNetworkData()); } - @PostMapping(value = "/studies/{studyUuid}/nodes/{nodeUuid}/security-analysis/run") + @PostMapping(value = "/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/security-analysis/run") @Operation(summary = "run security analysis on study") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis has started")}) public ResponseEntity runSecurityAnalysis(@Parameter(description = "studyUuid") @PathVariable("studyUuid") UUID studyUuid, + @Parameter(description = "rootNetworkUuid") @PathVariable("rootNetworkUuid") UUID rootNetworkUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @Parameter(description = "Contingency list names") @RequestParam(name = "contingencyListName", required = false) List contingencyListNames, @RequestHeader(HEADER_USER_ID) String userId) { List nonNullcontingencyListNames = contingencyListNames != null ? contingencyListNames : Collections.emptyList(); studyService.assertIsNodeNotReadOnly(nodeUuid); - studyService.runSecurityAnalysis(studyUuid, nonNullcontingencyListNames, nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), userId); + studyService.runSecurityAnalysis(studyUuid, nonNullcontingencyListNames, nodeUuid, rootNetworkUuid, userId); return ResponseEntity.ok().build(); } diff --git a/src/test/java/org/gridsuite/study/server/GenericTest.java b/src/test/java/org/gridsuite/study/server/GenericTest.java index f2a65b09d..4a63c7170 100644 --- a/src/test/java/org/gridsuite/study/server/GenericTest.java +++ b/src/test/java/org/gridsuite/study/server/GenericTest.java @@ -12,7 +12,7 @@ import org.gridsuite.study.server.service.client.util.UrlUtil; import org.gridsuite.study.server.utils.JsonUtils; import org.gridsuite.study.server.utils.PropertyUtils; -import org.gridsuite.study.server.utils.StudyUtils; +import org.gridsuite.study.server.utils.StudyTestUtils; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -41,7 +41,7 @@ void partialResultExceptionConstructor() { } @ParameterizedTest - @ValueSource(classes = {JsonUtils.class, UrlUtil.class, PropertyUtils.class, StudyUtils.class}) + @ValueSource(classes = {JsonUtils.class, UrlUtil.class, PropertyUtils.class, StudyTestUtils.class}) void utilityClassConstructor(@NonNull final Class utilsClass) { assertThat(utilsClass).hasSuperclass(Object.class).isNotInterface().isNotAnnotation().isFinal().satisfiesAnyOf( clazz -> assertThat(clazz).isPublic(), diff --git a/src/test/java/org/gridsuite/study/server/SecurityAnalysisTest.java b/src/test/java/org/gridsuite/study/server/SecurityAnalysisTest.java index 50029b0e2..da9907e60 100644 --- a/src/test/java/org/gridsuite/study/server/SecurityAnalysisTest.java +++ b/src/test/java/org/gridsuite/study/server/SecurityAnalysisTest.java @@ -30,6 +30,7 @@ import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; import org.gridsuite.study.server.service.*; import org.gridsuite.study.server.service.securityanalysis.SecurityAnalysisResultType; +import org.gridsuite.study.server.utils.StudyTestUtils; import org.gridsuite.study.server.utils.TestUtils; import org.gridsuite.study.server.utils.elasticsearch.DisableElasticsearch; import org.jetbrains.annotations.NotNull; @@ -164,6 +165,8 @@ class SecurityAnalysisTest { private RootNetworkNodeInfoService rootNetworkNodeInfoService; @Autowired private StudyService studyService; + @Autowired + private StudyTestUtils studyTestUtils; @BeforeEach void setup(final MockWebServer server) throws Exception { @@ -286,19 +289,20 @@ void testSecurityAnalysis(final MockWebServer server) throws Exception { UUID modificationNode2Uuid = modificationNode2.getId(); NetworkModificationNode modificationNode3 = createNetworkModificationNode(studyNameUserIdUuid, modificationNode2Uuid, UUID.randomUUID(), VARIANT_ID_3, "node 3"); UUID modificationNode3Uuid = modificationNode3.getId(); + UUID firstRootNetworkUuid = studyTestUtils.getStudyFirstRootNetworkUuid(studyNameUserIdUuid); // run security analysis on root node (not allowed) - mockMvc.perform(post("/v1/studies/{studyUuid}/nodes/{nodeUuid}/security-analysis/run?contingencyListName={contingencyListName}", - studyNameUserIdUuid, rootNodeUuid, CONTINGENCY_LIST_NAME) + mockMvc.perform(post("/v1/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/security-analysis/run?contingencyListName={contingencyListName}", + studyNameUserIdUuid, firstRootNetworkUuid, rootNodeUuid, CONTINGENCY_LIST_NAME) .header(HEADER_USER_ID, "testUserId")) .andExpect(status().isForbidden()); - testSecurityAnalysisWithNodeUuid(server, studyNameUserIdUuid, modificationNode1Uuid, UUID.fromString(SECURITY_ANALYSIS_RESULT_UUID), SECURITY_ANALYSIS_PARAMETERS); - testSecurityAnalysisWithNodeUuid(server, studyNameUserIdUuid, modificationNode3Uuid, UUID.fromString(SECURITY_ANALYSIS_OTHER_NODE_RESULT_UUID), null); + testSecurityAnalysisWithRootNetworkUuidAndNodeUuid(server, studyNameUserIdUuid, firstRootNetworkUuid, modificationNode1Uuid, UUID.fromString(SECURITY_ANALYSIS_RESULT_UUID), SECURITY_ANALYSIS_PARAMETERS); + testSecurityAnalysisWithRootNetworkUuidAndNodeUuid(server, studyNameUserIdUuid, firstRootNetworkUuid, modificationNode3Uuid, UUID.fromString(SECURITY_ANALYSIS_OTHER_NODE_RESULT_UUID), null); // run additional security analysis for deletion test - MockHttpServletRequestBuilder requestBuilder = post("/v1/studies/{studyUuid}/nodes/{nodeUuid}/security-analysis/run?contingencyListName={contingencyListName}", - studyNameUserIdUuid, modificationNode1Uuid, CONTINGENCY_LIST_NAME); + MockHttpServletRequestBuilder requestBuilder = post("/v1/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/security-analysis/run?contingencyListName={contingencyListName}", + studyNameUserIdUuid, firstRootNetworkUuid, modificationNode1Uuid, CONTINGENCY_LIST_NAME); requestBuilder.contentType(MediaType.APPLICATION_JSON) .content(objectWriter.writeValueAsString(SECURITY_ANALYSIS_PARAMETERS)) @@ -379,10 +383,11 @@ void testSecurityAnalysisFailedForNotification(final MockWebServer server) throw UUID rootNodeUuid = getRootNode(studyUuid).getId(); NetworkModificationNode modificationNode1 = createNetworkModificationNode(studyUuid, rootNodeUuid, UUID.randomUUID(), VARIANT_ID, "node 1"); UUID modificationNode1Uuid = modificationNode1.getId(); + UUID firstRootNetworkUuid = studyTestUtils.getStudyFirstRootNetworkUuid(studyUuid); //run failing security analysis (because in network 2) - mockMvc.perform(post("/v1/studies/{studyUuid}/nodes/{nodeUuid}/security-analysis/run?contingencyListName={contingencyListName}", - studyUuid, modificationNode1Uuid, CONTINGENCY_LIST_NAME) + mockMvc.perform(post("/v1/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/security-analysis/run?contingencyListName={contingencyListName}", + studyUuid, firstRootNetworkUuid, modificationNode1Uuid, CONTINGENCY_LIST_NAME) .header(HEADER_USER_ID, "testUserId")) .andExpect(status().isOk()); @@ -408,9 +413,10 @@ void testSecurityAnalysisFailedForNotification(final MockWebServer server) throw UUID rootNodeUuid2 = getRootNode(studyUuid2).getId(); NetworkModificationNode modificationNode2 = createNetworkModificationNode(studyUuid2, rootNodeUuid2, UUID.randomUUID(), VARIANT_ID, "node 2"); UUID modificationNode1Uuid2 = modificationNode2.getId(); + UUID firstRootNetworkUuid2 = studyTestUtils.getStudyFirstRootNetworkUuid(studyUuid2); - mockMvc.perform(post("/v1/studies/{studyUuid}/nodes/{nodeUuid}/security-analysis/run?contingencyListName={contingencyListName}", - studyUuid2, modificationNode1Uuid2, CONTINGENCY_LIST_NAME) + mockMvc.perform(post("/v1/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/security-analysis/run?contingencyListName={contingencyListName}", + studyUuid2, firstRootNetworkUuid2, modificationNode1Uuid2, CONTINGENCY_LIST_NAME) .header(HEADER_USER_ID, "testUserId")) .andExpect(status().isOk()); @@ -425,7 +431,7 @@ void testSecurityAnalysisFailedForNotification(final MockWebServer server) throw assertTrue(TestUtils.getRequestsDone(1, server).stream().anyMatch(r -> r.matches("/v1/networks/" + NETWORK_UUID_3_STRING + "/run-and-save.*contingencyListName=" + CONTINGENCY_LIST_NAME + "&receiver=.*nodeUuid.*"))); } - private void testSecurityAnalysisWithNodeUuid(final MockWebServer server, UUID studyUuid, UUID nodeUuid, UUID resultUuid, SecurityAnalysisParameters securityAnalysisParameters) throws Exception { + private void testSecurityAnalysisWithRootNetworkUuidAndNodeUuid(final MockWebServer server, UUID studyUuid, UUID rootNetworkUuid, UUID nodeUuid, UUID resultUuid, SecurityAnalysisParameters securityAnalysisParameters) throws Exception { MvcResult mvcResult; String resultAsString; @@ -433,8 +439,8 @@ private void testSecurityAnalysisWithNodeUuid(final MockWebServer server, UUID s mockMvc.perform(get("/v1/security-analysis/results/{resultUuid}", NOT_FOUND_SECURITY_ANALYSIS_UUID)).andExpect(status().isNotFound()); // run security analysis - MockHttpServletRequestBuilder requestBuilder = post("/v1/studies/{studyUuid}/nodes/{nodeUuid}/security-analysis/run?contingencyListName={contingencyListName}", - studyUuid, nodeUuid, CONTINGENCY_LIST_NAME); + MockHttpServletRequestBuilder requestBuilder = post("/v1/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/security-analysis/run?contingencyListName={contingencyListName}", + studyUuid, rootNetworkUuid, nodeUuid, CONTINGENCY_LIST_NAME); if (securityAnalysisParameters != null) { requestBuilder.contentType(MediaType.APPLICATION_JSON) .content(objectWriter.writeValueAsString(securityAnalysisParameters)); @@ -658,12 +664,13 @@ void getResultZippedCsv(final MockWebServer server) throws Exception { UUID rootNodeUuid = getRootNode(studyUuid).getId(); NetworkModificationNode modificationNode = createNetworkModificationNode(studyUuid, rootNodeUuid, UUID.randomUUID(), VARIANT_ID, "node 1"); UUID nodeUuid = modificationNode.getId(); + UUID firstRootNetworkUuid = studyTestUtils.getStudyFirstRootNetworkUuid(studyUuid); /* * RUN SECURITY ANALYSIS START */ - mockMvc.perform(post("/v1/studies/{studyUuid}/nodes/{nodeUuid}/security-analysis/run?contingencyListName={contingencyListName}", - studyUuid, nodeUuid, CONTINGENCY_LIST_NAME).header(HEADER_USER_ID, "testUserId")).andExpect(status().isOk()); + mockMvc.perform(post("/v1/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/security-analysis/run?contingencyListName={contingencyListName}", + studyUuid, firstRootNetworkUuid, nodeUuid, CONTINGENCY_LIST_NAME).header(HEADER_USER_ID, "testUserId")).andExpect(status().isOk()); Message securityAnalysisStatusMessage = output.receive(TIMEOUT, studyUpdateDestination); assertEquals(studyUuid, securityAnalysisStatusMessage.getHeaders().get(NotificationService.HEADER_STUDY_UUID)); @@ -728,12 +735,13 @@ void getResultZippedCsvNotFound(final MockWebServer server) throws Exception { NetworkModificationNode modificationNode = createNetworkModificationNode(studyUuid, rootNodeUuid, UUID.randomUUID(), VARIANT_ID_3, "node 1"); UUID nodeUuid = modificationNode.getId(); - /* - * RUN SECURITY ANALYSIS START - */ - mockMvc.perform(post("/v1/studies/{studyUuid}/nodes/{nodeUuid}/security-analysis/run?contingencyListName={contingencyListName}", - studyUuid, nodeUuid, CONTINGENCY_LIST_NAME).header(HEADER_USER_ID, "testUserId")).andExpect(status().isOk()); + UUID firstRootNetworkUuid = studyTestUtils.getStudyFirstRootNetworkUuid(studyUuid); + /* + * RUN SECURITY ANALYSIS START + */ + mockMvc.perform(post("/v1/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/security-analysis/run?contingencyListName={contingencyListName}", + studyUuid, firstRootNetworkUuid, nodeUuid, CONTINGENCY_LIST_NAME).header(HEADER_USER_ID, "testUserId")).andExpect(status().isOk()); Message securityAnalysisStatusMessage = output.receive(TIMEOUT, studyUpdateDestination); assertEquals(studyUuid, securityAnalysisStatusMessage.getHeaders().get(NotificationService.HEADER_STUDY_UUID)); String updateType = (String) securityAnalysisStatusMessage.getHeaders().get(NotificationService.HEADER_UPDATE_TYPE); diff --git a/src/test/java/org/gridsuite/study/server/utils/StudyTestUtils.java b/src/test/java/org/gridsuite/study/server/utils/StudyTestUtils.java new file mode 100644 index 000000000..804ee558a --- /dev/null +++ b/src/test/java/org/gridsuite/study/server/utils/StudyTestUtils.java @@ -0,0 +1,22 @@ +package org.gridsuite.study.server.utils; + + +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.UUID; + +@Service +public class StudyTestUtils { + private final RootNetworkRepository rootNetworkRepository; + + public StudyTestUtils(RootNetworkRepository rootNetworkRepository) { + this.rootNetworkRepository = rootNetworkRepository; + } + + @Transactional + public UUID getStudyFirstRootNetworkUuid(UUID studyUuid) { + return rootNetworkRepository.findAllByStudyId(studyUuid).get(0).getId(); + } +}