Skip to content

Commit

Permalink
feat: migrate run security-analysis endpoint to path with root network
Browse files Browse the repository at this point in the history
Signed-off-by: LE SAULNIER Kevin <[email protected]>
  • Loading branch information
LE SAULNIER Kevin committed Dec 11, 2024
1 parent ea0d2b9 commit ac4bdf4
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 24 deletions.
5 changes: 3 additions & 2 deletions src/main/java/org/gridsuite/study/server/StudyController.java
Original file line number Diff line number Diff line change
Expand Up @@ -791,16 +791,17 @@ public ResponseEntity<byte[]> 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<Void> 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<String> contingencyListNames,
@RequestHeader(HEADER_USER_ID) String userId) {
List<String> 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();
}

Expand Down
4 changes: 2 additions & 2 deletions src/test/java/org/gridsuite/study/server/GenericTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(),
Expand Down
48 changes: 28 additions & 20 deletions src/test/java/org/gridsuite/study/server/SecurityAnalysisTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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());

Expand All @@ -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());

Expand All @@ -425,16 +431,16 @@ 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;

// security analysis not found
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));
Expand Down Expand Up @@ -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<byte[]> securityAnalysisStatusMessage = output.receive(TIMEOUT, studyUpdateDestination);
assertEquals(studyUuid, securityAnalysisStatusMessage.getHeaders().get(NotificationService.HEADER_STUDY_UUID));
Expand Down Expand Up @@ -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<byte[]> securityAnalysisStatusMessage = output.receive(TIMEOUT, studyUpdateDestination);
assertEquals(studyUuid, securityAnalysisStatusMessage.getHeaders().get(NotificationService.HEADER_STUDY_UUID));
String updateType = (String) securityAnalysisStatusMessage.getHeaders().get(NotificationService.HEADER_UPDATE_TYPE);
Expand Down
22 changes: 22 additions & 0 deletions src/test/java/org/gridsuite/study/server/utils/StudyTestUtils.java
Original file line number Diff line number Diff line change
@@ -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();
}
}

0 comments on commit ac4bdf4

Please sign in to comment.