From 523b7dc106ab1dd88c3a373c9d2d3ecb7f5a1622 Mon Sep 17 00:00:00 2001 From: Ayoub LABIDI Date: Wed, 6 Aug 2025 22:28:34 +0200 Subject: [PATCH 1/9] Simplify modification reports management Signed-off-by: Ayoub LABIDI --- .../study/server/dto/RootNetworkNodeInfo.java | 4 +-- .../dto/NetworkModificationNode.java | 10 +++--- .../entities/RootNetworkNodeInfoEntity.java | 8 ++--- .../NetworkModificationTreeService.java | 32 +++++-------------- .../service/RootNetworkNodeInfoService.java | 18 ++++------- .../study/server/service/StudyService.java | 16 +++------- .../changesets/changelog_20250716T142255Z.xml | 29 +++++++++++++++++ .../db/changelog/db.changelog-master.yaml | 4 ++- .../study/server/LoadFLowIntegrationTest.java | 2 +- .../gridsuite/study/server/LoadFlowTest.java | 3 +- .../server/ModificationIndexationTest.java | 12 +++---- .../study/server/NetworkModificationTest.java | 9 +----- .../server/NetworkModificationUnitTest.java | 3 +- .../org/gridsuite/study/server/StudyTest.java | 11 ------- .../study/server/VoltageInitTest.java | 2 +- 15 files changed, 71 insertions(+), 92 deletions(-) create mode 100644 src/main/resources/db/changelog/changesets/changelog_20250716T142255Z.xml diff --git a/src/main/java/org/gridsuite/study/server/dto/RootNetworkNodeInfo.java b/src/main/java/org/gridsuite/study/server/dto/RootNetworkNodeInfo.java index 5c6d80807..ae16ecf3e 100644 --- a/src/main/java/org/gridsuite/study/server/dto/RootNetworkNodeInfo.java +++ b/src/main/java/org/gridsuite/study/server/dto/RootNetworkNodeInfo.java @@ -28,7 +28,7 @@ public class RootNetworkNodeInfo { private Map computationReports; - private Map modificationReports; + private UUID modificationReportUuid; private UUID shortCircuitAnalysisResultUuid; @@ -59,7 +59,7 @@ public RootNetworkNodeInfoEntity toEntity() { .id(id) .variantId(variantId) .computationReports(computationReports) - .modificationReports(modificationReports) + .modificationReportUuid(modificationReportUuid) .shortCircuitAnalysisResultUuid(shortCircuitAnalysisResultUuid) .oneBusShortCircuitAnalysisResultUuid(oneBusShortCircuitAnalysisResultUuid) .loadFlowResultUuid(loadFlowResultUuid) diff --git a/src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/NetworkModificationNode.java b/src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/NetworkModificationNode.java index 770d114b1..fa133abcb 100644 --- a/src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/NetworkModificationNode.java +++ b/src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/NetworkModificationNode.java @@ -58,6 +58,10 @@ public class NetworkModificationNode extends AbstractNode { private NodeBuildStatus nodeBuildStatus; + private Map computationsReports; + + private UUID modificationReportUuid; + @Builder.Default private NetworkModificationNodeType nodeType = NetworkModificationNodeType.CONSTRUCTION; @@ -76,13 +80,9 @@ public void completeDtoFromRootNetworkNodeInfo(RootNetworkNodeInfoEntity rootNet this.setStateEstimationResultUuid(rootNetworkNodeInfoEntity.getStateEstimationResultUuid()); this.setNodeBuildStatus(rootNetworkNodeInfoEntity.getNodeBuildStatus().toDto()); this.setComputationsReports(new HashMap<>(rootNetworkNodeInfoEntity.getComputationReports())); - this.setModificationReports(new HashMap<>(rootNetworkNodeInfoEntity.getModificationReports())); + this.setModificationReportUuid(rootNetworkNodeInfoEntity.getModificationReportUuid()); } - private Map computationsReports; - - private Map modificationReports; - @Override public NodeType getType() { return NodeType.NETWORK_MODIFICATION; diff --git a/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/RootNetworkNodeInfoEntity.java b/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/RootNetworkNodeInfoEntity.java index 33f788f60..36dee0a84 100644 --- a/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/RootNetworkNodeInfoEntity.java +++ b/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/RootNetworkNodeInfoEntity.java @@ -63,11 +63,7 @@ public class RootNetworkNodeInfoEntity { foreignKey = @ForeignKey(name = "rootNetworkNodeInfoEntity_computationReports_fk1")) private Map computationReports; - @ElementCollection - @CollectionTable(name = "modificationReports", - indexes = {@Index(name = "root_network_node_info_entity_modificationReports_idx1", columnList = "root_network_node_info_entity_id")}, - foreignKey = @ForeignKey(name = "rootNetworkNodeInfoEntity_modificationReports_fk1")) - private Map modificationReports; + private UUID modificationReportUuid; @Column(name = "shortCircuitAnalysisResultUuid") private UUID shortCircuitAnalysisResultUuid; @@ -123,7 +119,7 @@ public RootNetworkNodeInfo toDto() { return RootNetworkNodeInfo.builder() .id(id) .computationReports(computationReports) - .modificationReports(modificationReports) + .modificationReportUuid(modificationReportUuid) .dynamicSimulationResultUuid(dynamicSimulationResultUuid) .dynamicSecurityAnalysisResultUuid(dynamicSecurityAnalysisResultUuid) .loadFlowResultUuid(loadFlowResultUuid) diff --git a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java index beff2c63b..436ef917c 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java @@ -498,12 +498,11 @@ public void createBasicTree(StudyEntity studyEntity) { .withAllResourceBundlesFromClasspath() .withMessageTemplate("study.server.modificationNodeId") .withUntypedValue("modificationNodeId", modificationNode.getId().toString()).build(); - reportService.sendReport(getModificationReportUuid(networkModificationNode.getId(), firstRootNetworkUuid, networkModificationNode.getId()), reportNode); + UUID modificationReportUuid = UUID.randomUUID(); + reportService.sendReport(modificationReportUuid, reportNode); - BuildInfos buildInfos = getBuildInfos(modificationNode.getId(), firstRootNetworkUuid); - Map nodeUuidToReportUuid = buildInfos.getReportsInfos().stream().collect(Collectors.toMap(ReportInfos::nodeUuid, ReportInfos::reportUuid)); rootNetworkNodeInfoService.updateRootNetworkNode(networkModificationNode.getId(), firstRootNetworkUuid, - RootNetworkNodeInfo.builder().variantId(FIRST_VARIANT_ID).nodeBuildStatus(NodeBuildStatus.from(BuildStatus.BUILT)).modificationReports(nodeUuidToReportUuid).build()); + RootNetworkNodeInfo.builder().variantId(FIRST_VARIANT_ID).nodeBuildStatus(NodeBuildStatus.from(BuildStatus.BUILT)).modificationReportUuid(modificationReportUuid).build()); } @Transactional @@ -746,7 +745,7 @@ public UUID getReportUuid(UUID nodeUuid, UUID rootNetworkUuid) { if (nodeEntity.getType().equals(NodeType.ROOT)) { return rootNetworkService.getRootReportUuid(rootNetworkUuid); } else { - return rootNetworkNodeInfoService.getRootNetworkNodeInfo(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(ROOT_NETWORK_NOT_FOUND)).getModificationReports().get(nodeUuid); + return rootNetworkNodeInfoService.getRootNetworkNodeInfo(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(ROOT_NETWORK_NOT_FOUND)).getModificationReportUuid(); } } @@ -811,16 +810,6 @@ public Map getComputationReports(UUID nodeUuid, UUID rootNetworkUu return rootNetworkNodeInfoService.getRootNetworkNodeInfo(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)).getComputationReports(); } - @Transactional - public void setModificationReports(UUID nodeUuid, UUID rootNetworkUuid, Map modificationReports) { - rootNetworkNodeInfoService.getRootNetworkNodeInfo(nodeUuid, rootNetworkUuid).ifPresent(tpNodeInfo -> tpNodeInfo.setModificationReports(modificationReports)); - } - - @Transactional - public Map getModificationReports(UUID nodeUuid, UUID rootNetworkUuid) { - return rootNetworkNodeInfoService.getRootNetworkNodeInfo(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)).getModificationReports(); - } - private void restoreNodeChildren(UUID studyId, UUID parentNodeId) { getChildren(parentNodeId).forEach(nodeEntity -> { NetworkModificationNodeInfoEntity modificationNodeToRestore = networkModificationNodeInfoRepository.findById(nodeEntity.getIdNode()).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)); @@ -840,19 +829,14 @@ public List getAllNodes(UUID studyUuid) { return nodesRepository.findAllByStudyId(studyUuid); } - private UUID getModificationReportUuid(UUID nodeUuid, UUID rootNetworkUuid, UUID nodeToBuildUuid) { - return self.getModificationReports(nodeToBuildUuid, rootNetworkUuid).getOrDefault(nodeUuid, UUID.randomUUID()); - } - - private void getBuildInfos(NodeEntity nodeEntity, UUID rootNetworkUuid, BuildInfos buildInfos, UUID nodeToBuildUuid) { + private void getBuildInfos(NodeEntity nodeEntity, UUID rootNetworkUuid, BuildInfos buildInfos) { AbstractNode node = getSimpleNode(nodeEntity.getIdNode()); if (node.getType() == NodeType.NETWORK_MODIFICATION) { NetworkModificationNode modificationNode = (NetworkModificationNode) node; RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoService.getRootNetworkNodeInfo(nodeEntity.getIdNode(), rootNetworkUuid).orElseThrow(() -> new StudyException(ROOT_NETWORK_NOT_FOUND)); if (!rootNetworkNodeInfoEntity.getNodeBuildStatus().toDto().isBuilt()) { - UUID reportUuid = getModificationReportUuid(nodeEntity.getIdNode(), rootNetworkUuid, nodeToBuildUuid); - buildInfos.insertModificationInfos(modificationNode.getModificationGroupUuid(), rootNetworkNodeInfoEntity.getModificationsUuidsToExclude(), new ReportInfos(reportUuid, modificationNode.getId())); - getBuildInfos(nodeEntity.getParentNode(), rootNetworkUuid, buildInfos, nodeToBuildUuid); + buildInfos.insertModificationInfos(modificationNode.getModificationGroupUuid(), rootNetworkNodeInfoEntity.getModificationsUuidsToExclude(), new ReportInfos(rootNetworkNodeInfoEntity.getModificationReportUuid(), modificationNode.getId())); + getBuildInfos(nodeEntity.getParentNode(), rootNetworkUuid, buildInfos); } else { buildInfos.setOriginVariantId(self.getVariantId(nodeEntity.getIdNode(), rootNetworkUuid)); } @@ -868,7 +852,7 @@ public BuildInfos getBuildInfos(UUID nodeUuid, UUID rootNetworkUuid) { throw new StudyException(BAD_NODE_TYPE, "The node " + entity.getIdNode() + " is not a modification node"); } else { buildInfos.setDestinationVariantId(self.getVariantId(nodeUuid, rootNetworkUuid)); - getBuildInfos(entity, rootNetworkUuid, buildInfos, nodeUuid); + getBuildInfos(entity, rootNetworkUuid, buildInfos); } }, () -> { throw new StudyException(ELEMENT_NOT_FOUND); diff --git a/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java b/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java index 9e116c413..2324522f9 100644 --- a/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java +++ b/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java @@ -39,7 +39,6 @@ import java.util.*; import java.util.concurrent.CompletableFuture; -import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -131,7 +130,7 @@ private static RootNetworkNodeInfoEntity createDefaultEntity(UUID nodeUuid, Set< return RootNetworkNodeInfoEntity.builder() .nodeBuildStatus(NodeBuildStatusEmbeddable.from(BuildStatus.NOT_BUILT)) .variantId(UUID.randomUUID().toString()) - .modificationReports(new HashMap<>(Map.of(nodeUuid, UUID.randomUUID()))) + .modificationReportUuid(UUID.randomUUID()) .modificationsUuidsToExclude(modificationsToExclude) .blockedBuild(false) .build(); @@ -172,7 +171,7 @@ public void fillDeleteNodeInfo(UUID nodeUuid, DeleteNodeInfos deleteNodeInfos) { //get all rootnetworknodeinfo info linked to node List rootNetworkNodeInfoEntities = rootNetworkNodeInfoRepository.findAllWithRootNetworkByNodeInfoId(nodeUuid); rootNetworkNodeInfoEntities.forEach(rootNetworkNodeInfoEntity -> { - rootNetworkNodeInfoEntity.getModificationReports().forEach((key, value) -> deleteNodeInfos.addReportUuid(value)); + deleteNodeInfos.addReportUuid(rootNetworkNodeInfoEntity.getModificationReportUuid()); rootNetworkNodeInfoEntity.getComputationReports().forEach((key, value) -> deleteNodeInfos.addReportUuid(value)); String variantId = rootNetworkNodeInfoEntity.getVariantId(); @@ -254,7 +253,6 @@ public InvalidateNodeInfos invalidateRootNetworkNode(RootNetworkNodeInfoEntity r InvalidateNodeInfos invalidateNodeInfos = getInvalidationComputationInfos(rootNetworkNodeInfoEntity, invalidateTreeParameters.computationsInvalidationMode()); if (notOnlyChildrenBuildStatus) { - rootNetworkNodeInfoEntity.getModificationReports().forEach((key, value) -> invalidateNodeInfos.addReportUuid(value)); invalidateNodeInfos.addVariantId(rootNetworkNodeInfoEntity.getVariantId()); invalidateBuildStatus(rootNetworkNodeInfoEntity, invalidateNodeInfos); } @@ -267,7 +265,6 @@ public InvalidateNodeInfos invalidateRootNetworkNode(RootNetworkNodeInfoEntity r private static void invalidateBuildStatus(RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity, InvalidateNodeInfos invalidateNodeInfos) { rootNetworkNodeInfoEntity.setNodeBuildStatus(NodeBuildStatusEmbeddable.from(BuildStatus.NOT_BUILT)); rootNetworkNodeInfoEntity.setVariantId(UUID.randomUUID().toString()); - rootNetworkNodeInfoEntity.setModificationReports(new HashMap<>(Map.of(rootNetworkNodeInfoEntity.getNodeInfo().getId(), UUID.randomUUID()))); invalidateNodeInfos.addNodeUuid(rootNetworkNodeInfoEntity.getNodeInfo().getIdNode()); } @@ -481,8 +478,8 @@ public void updateRootNetworkNode(UUID nodeUuid, UUID rootNetworkUuid, RootNetwo if (rootNetworkNodeInfo.getVoltageInitResultUuid() != null) { rootNetworkNodeInfoEntity.setVoltageInitResultUuid(rootNetworkNodeInfo.getVoltageInitResultUuid()); } - if (rootNetworkNodeInfo.getModificationReports() != null) { - rootNetworkNodeInfoEntity.setModificationReports(rootNetworkNodeInfo.getModificationReports()); + if (rootNetworkNodeInfo.getModificationReportUuid() != null) { + rootNetworkNodeInfoEntity.setModificationReportUuid(rootNetworkNodeInfo.getModificationReportUuid()); } } @@ -507,15 +504,14 @@ public Stream> getDeleteRootNetworkNodeInfosFutures(List public ModificationApplicationContext getNetworkModificationApplicationContext(UUID rootNetworkUuid, UUID nodeUuid, UUID networkUuid) { RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoRepository.findWithModificationsToExcludeByNodeInfoIdAndRootNetworkId(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(ROOT_NETWORK_NOT_FOUND)); String variantId = rootNetworkNodeInfoEntity.getVariantId(); - UUID reportUuid = rootNetworkNodeInfoEntity.getModificationReports().get(nodeUuid); + UUID reportUuid = rootNetworkNodeInfoEntity.getModificationReportUuid(); return new ModificationApplicationContext(networkUuid, variantId, reportUuid, nodeUuid, rootNetworkNodeInfoEntity.getModificationsUuidsToExclude()); } private List getReportUuids(RootNetworkNodeInfo rootNetworkNodeInfo) { - return Stream.of( - rootNetworkNodeInfo.getModificationReports().values().stream(), + return Stream.concat( + Stream.of(rootNetworkNodeInfo.getModificationReportUuid()), rootNetworkNodeInfo.getComputationReports().values().stream()) - .flatMap(Function.identity()) .toList(); } diff --git a/src/main/java/org/gridsuite/study/server/service/StudyService.java b/src/main/java/org/gridsuite/study/server/service/StudyService.java index 5f2ea75a4..60fa31049 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -1743,8 +1743,6 @@ public void buildNode(@NonNull UUID studyUuid, @NonNull UUID nodeUuid, @NonNull private void buildNode(@NonNull UUID studyUuid, @NonNull UUID nodeUuid, @NonNull UUID rootNetworkUuid, @NonNull String userId, AbstractWorkflowInfos workflowInfos) { assertCanBuildNode(studyUuid, rootNetworkUuid, userId); BuildInfos buildInfos = networkModificationTreeService.getBuildInfos(nodeUuid, rootNetworkUuid); - Map nodeUuidToReportUuid = buildInfos.getReportsInfos().stream().collect(Collectors.toMap(ReportInfos::nodeUuid, ReportInfos::reportUuid)); - networkModificationTreeService.setModificationReports(nodeUuid, rootNetworkUuid, nodeUuidToReportUuid); networkModificationTreeService.updateNodeBuildStatus(nodeUuid, rootNetworkUuid, NodeBuildStatus.from(BuildStatus.BUILDING)); try { networkModificationService.buildNode(nodeUuid, rootNetworkUuid, buildInfos, workflowInfos); @@ -2342,11 +2340,9 @@ private void checkStudyContainsNode(UUID studyUuid, UUID nodeUuid) { private ReportPage getParentNodesReportLogs(UUID nodeUuid, UUID rootNetworkUuid, String messageFilter, Set severityLevels, boolean paged, Pageable pageable) { List nodeIds = nodesTree(nodeUuid); - Map modificationReportsMap = networkModificationTreeService.getModificationReports(nodeUuid, rootNetworkUuid); List reportUuids = nodeIds.stream() - .map(nodeId -> modificationReportsMap.getOrDefault(nodeId, - networkModificationTreeService.getReportUuid(nodeId, rootNetworkUuid))) + .map(nodeId -> networkModificationTreeService.getReportUuid(nodeId, rootNetworkUuid)) .filter(Objects::nonNull) .toList(); return reportService.getPagedMultipleReportLogs(reportUuids, messageFilter, severityLevels, paged, pageable); @@ -2362,11 +2358,9 @@ public ReportPage getReportLogs(UUID nodeUuid, UUID rootNetworkUuid, UUID report private String getSearchTermMatchesInParentNodesFilteredLogs(UUID nodeUuid, UUID rootNetworkUuid, Set severityLevels, String messageFilter, String searchTerm, int pageSize) { List nodeIds = nodesTree(nodeUuid); - Map modificationReportsMap = networkModificationTreeService.getModificationReports(nodeUuid, rootNetworkUuid); List reportUuids = nodeIds.stream() - .map(nodeId -> modificationReportsMap.getOrDefault(nodeId, - networkModificationTreeService.getReportUuid(nodeId, rootNetworkUuid))) + .map(nodeId -> networkModificationTreeService.getReportUuid(nodeId, rootNetworkUuid)) .filter(Objects::nonNull) .toList(); return reportService.getSearchTermMatchesInMultipleFilteredLogs(reportUuids, severityLevels, messageFilter, searchTerm, pageSize); @@ -2383,10 +2377,9 @@ public String getSearchTermMatchesInFilteredLogs(UUID nodeUuid, UUID rootNetwork private Set getParentNodesAggregatedReportSeverities(UUID nodeUuid, UUID rootNetworkUuid) { List nodeIds = nodesTree(nodeUuid); Set severities = new HashSet<>(); - Map modificationReportsMap = networkModificationTreeService.getModificationReports(nodeUuid, rootNetworkUuid); for (UUID nodeId : nodeIds) { - UUID reportId = modificationReportsMap.getOrDefault(nodeId, networkModificationTreeService.getReportUuid(nodeId, rootNetworkUuid)); + UUID reportId = networkModificationTreeService.getReportUuid(nodeId, rootNetworkUuid); severities.addAll(reportService.getReportAggregatedSeverities(reportId)); } return severities; @@ -2430,10 +2423,9 @@ private List getNodeOnlyReport(UUID nodeUuid, UUID rootNetworkUuid, Set< private List getAllModificationReports(UUID nodeUuid, UUID rootNetworkUuid, Set severityLevels) { List nodeIds = nodesTree(nodeUuid); List modificationReports = new ArrayList<>(); - Map modificationReportsMap = networkModificationTreeService.getModificationReports(nodeUuid, rootNetworkUuid); for (UUID nodeId : nodeIds) { - UUID reportId = modificationReportsMap.getOrDefault(nodeId, networkModificationTreeService.getReportUuid(nodeId, rootNetworkUuid)); + UUID reportId = networkModificationTreeService.getReportUuid(nodeId, rootNetworkUuid); modificationReports.add(reportService.getReport(reportId, nodeId.toString(), severityLevels)); } diff --git a/src/main/resources/db/changelog/changesets/changelog_20250716T142255Z.xml b/src/main/resources/db/changelog/changesets/changelog_20250716T142255Z.xml new file mode 100644 index 000000000..62bff99e9 --- /dev/null +++ b/src/main/resources/db/changelog/changesets/changelog_20250716T142255Z.xml @@ -0,0 +1,29 @@ + + + + + + + + + + UPDATE root_network_node_info + SET modification_report_uuid = ( + SELECT mr.modification_reports + FROM modification_reports mr + WHERE mr.modification_reports_key = root_network_node_info.node_info_id + AND mr.root_network_node_info_entity_id = root_network_node_info.id + LIMIT 1 + ) + WHERE EXISTS ( + SELECT 1 + FROM modification_reports mr2 + WHERE mr2.modification_reports_key = root_network_node_info.node_info_id + AND mr2.root_network_node_info_entity_id = root_network_node_info.id + ); + + + + + + diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index 2559d7f0a..d50061501 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -329,4 +329,6 @@ databaseChangeLog: - include: file: changesets/changelog_20250719T002545Z.xml relativeToChangelogFile: true - + - include: + file: changesets/changelog_20250716T142255Z.xml + relativeToChangelogFile: true diff --git a/src/test/java/org/gridsuite/study/server/LoadFLowIntegrationTest.java b/src/test/java/org/gridsuite/study/server/LoadFLowIntegrationTest.java index 3e30d784a..58246dafb 100644 --- a/src/test/java/org/gridsuite/study/server/LoadFLowIntegrationTest.java +++ b/src/test/java/org/gridsuite/study/server/LoadFLowIntegrationTest.java @@ -263,7 +263,7 @@ private NodeEntity insertNode(StudyEntity study, UUID nodeId, String variantId, // We can't use the method RootNetworkNodeInfoService::createNodeLinks because there is no transaction in a session private void createNodeLinks(RootNetworkEntity rootNetworkEntity, NetworkModificationNodeInfoEntity modificationNodeInfoEntity, String variantId, UUID reportUuid, BuildStatus buildStatus) { - RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = RootNetworkNodeInfoEntity.builder().variantId(variantId).modificationReports(Map.of(modificationNodeInfoEntity.getId(), reportUuid)).nodeBuildStatus(NodeBuildStatus.from(buildStatus).toEntity()).blockedBuild(false).build(); + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = RootNetworkNodeInfoEntity.builder().variantId(variantId).modificationReportUuid(reportUuid).nodeBuildStatus(NodeBuildStatus.from(buildStatus).toEntity()).blockedBuild(false).build(); modificationNodeInfoEntity.addRootNetworkNodeInfo(rootNetworkNodeInfoEntity); rootNetworkEntity.addRootNetworkNodeInfo(rootNetworkNodeInfoEntity); rootNetworkNodeInfoRepository.save(rootNetworkNodeInfoEntity); diff --git a/src/test/java/org/gridsuite/study/server/LoadFlowTest.java b/src/test/java/org/gridsuite/study/server/LoadFlowTest.java index b1adbb702..fb95a2692 100644 --- a/src/test/java/org/gridsuite/study/server/LoadFlowTest.java +++ b/src/test/java/org/gridsuite/study/server/LoadFlowTest.java @@ -918,9 +918,8 @@ void testInvalidateNodesAfterLoadflow(final MockWebServer server) throws Excepti checkUpdateModelStatusMessagesReceived(studyUuid, NotificationService.UPDATE_TYPE_LOADFLOW_STATUS); - var requests = TestUtils.getRequestsDone(4, server); + var requests = TestUtils.getRequestsDone(2, server); assertTrue(requests.stream().anyMatch(r -> r.matches("/v1/results\\?resultsUuids=.*"))); - assertTrue(requests.stream().anyMatch(r -> r.matches("/v1/reports"))); assertEquals(NodeBuildStatusEmbeddable.from(BuildStatus.BUILT), rootNetworkNodeInfoService.getRootNetworkNodeInfo(node1.getId(), rootNetworkUuid).map(RootNetworkNodeInfoEntity::getNodeBuildStatus).orElseThrow()); assertEquals(NodeBuildStatusEmbeddable.from(BuildStatus.NOT_BUILT), rootNetworkNodeInfoService.getRootNetworkNodeInfo(node2.getId(), rootNetworkUuid).map(RootNetworkNodeInfoEntity::getNodeBuildStatus).orElseThrow()); diff --git a/src/test/java/org/gridsuite/study/server/ModificationIndexationTest.java b/src/test/java/org/gridsuite/study/server/ModificationIndexationTest.java index 75279b4fa..e07605e78 100644 --- a/src/test/java/org/gridsuite/study/server/ModificationIndexationTest.java +++ b/src/test/java/org/gridsuite/study/server/ModificationIndexationTest.java @@ -93,7 +93,7 @@ void testInvalidateBuiltNodeAndItsChildren() { node3.getModificationGroupUuid() )); - SQLStatementCountValidator.assertSelectCount(17); + SQLStatementCountValidator.assertSelectCount(16); } @Test @@ -105,7 +105,7 @@ void testInvalidateNotBuiltNodeAndItsChildren() { node5.getModificationGroupUuid() )); - SQLStatementCountValidator.assertSelectCount(17); + SQLStatementCountValidator.assertSelectCount(14); } @Test @@ -116,7 +116,7 @@ void testInvalidateBuiltNodeChildrenOnly() { node5.getModificationGroupUuid() )); - SQLStatementCountValidator.assertSelectCount(8); + SQLStatementCountValidator.assertSelectCount(7); } @Test @@ -128,7 +128,7 @@ void testInvalidateNotBuiltNodeChildrenOnly() { node3.getModificationGroupUuid() )); - SQLStatementCountValidator.assertSelectCount(17); + SQLStatementCountValidator.assertSelectCount(16); } @Test @@ -137,7 +137,7 @@ void testInvalidateBuiltNodeOnlyWithBuiltChildren() { assertThat(invalidateNodeInfos.getGroupUuids()).isEmpty(); - SQLStatementCountValidator.assertSelectCount(8); + SQLStatementCountValidator.assertSelectCount(6); } @Test @@ -149,7 +149,7 @@ void testInvalidateBuiltNodeOnlyWithoutBuiltChildren() { node3.getModificationGroupUuid() )); - SQLStatementCountValidator.assertSelectCount(19); + SQLStatementCountValidator.assertSelectCount(17); } private void createStudyAndNodesWithIndexedModification() { diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java index 6c55001d5..b023ec122 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java @@ -761,9 +761,6 @@ void testNetworkModificationSwitch(final MockWebServer server) throws Exception modificationBody = Pair.of(bodyJson, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); wireMockUtils.verifyNetworkModificationPostWithVariant(stubPostId, getModificationContextJsonString(mapper, modificationBody)); - Set requests = TestUtils.getRequestsWithBodyDone(1, server); - assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); - // modificationNode2 is still built assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode1Uuid, firstRootNetworkUuid).getGlobalBuildStatus()); @@ -2410,8 +2407,7 @@ void testNodesInvalidation(final MockWebServer server) throws Exception { checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); wireMockUtils.verifyNetworkModificationPut(stubUuid, MODIFICATION_UUID, generatorAttributesUpdated); - var requests = TestUtils.getRequestsWithBodyDone(15, server); - assertEquals(1, requests.stream().filter(r -> r.getPath().matches("/v1/reports")).count()); + var requests = TestUtils.getRequestsWithBodyDone(14, server); assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/results\\?resultsUuids=" + SECURITY_ANALYSIS_RESULT_UUID))); assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/results\\?resultsUuids=" + SENSITIVITY_ANALYSIS_RESULT_UUID))); assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/non-evacuated-energy/results\\?resultsUuids=" + SENSITIVITY_ANALYSIS_NON_EVACUATED_ENERGY_RESULT_UUID))); @@ -2442,9 +2438,6 @@ void testNodesInvalidation(final MockWebServer server) throws Exception { assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode3Uuid, firstRootNetworkUuid).getGlobalBuildStatus()); Pair> modificationBody = Pair.of(jsonCreateLoadInfos, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode2Uuid, NETWORK_UUID))); wireMockUtils.verifyNetworkModificationPostWithVariant(stubPostId, getModificationContextJsonString(mapper, modificationBody)); - - requests = TestUtils.getRequestsWithBodyDone(1, server); - assertEquals(1, requests.stream().filter(r -> r.getPath().matches("/v1/reports")).count()); } @Test diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationUnitTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationUnitTest.java index acbc90986..9db37d317 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationUnitTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationUnitTest.java @@ -49,7 +49,6 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.List; -import java.util.Map; import java.util.TreeSet; import java.util.UUID; import java.util.stream.Collectors; @@ -304,7 +303,7 @@ private NodeEntity insertNode(StudyEntity study, UUID nodeId, String variantId, // We can't use the method RootNetworkNodeInfoService::createNodeLinks because there is no transaction in a session private void createNodeLinks(RootNetworkEntity rootNetworkEntity, NetworkModificationNodeInfoEntity modificationNodeInfoEntity, String variantId, UUID reportUuid, BuildStatus buildStatus) { - RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = RootNetworkNodeInfoEntity.builder().variantId(variantId).modificationReports(Map.of(modificationNodeInfoEntity.getId(), reportUuid)).nodeBuildStatus(NodeBuildStatus.from(buildStatus).toEntity()).build(); + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = RootNetworkNodeInfoEntity.builder().variantId(variantId).modificationReportUuid(reportUuid).nodeBuildStatus(NodeBuildStatus.from(buildStatus).toEntity()).build(); modificationNodeInfoEntity.addRootNetworkNodeInfo(rootNetworkNodeInfoEntity); rootNetworkEntity.addRootNetworkNodeInfo(rootNetworkNodeInfoEntity); rootNetworkNodeInfoRepository.save(rootNetworkNodeInfoEntity); diff --git a/src/test/java/org/gridsuite/study/server/StudyTest.java b/src/test/java/org/gridsuite/study/server/StudyTest.java index cb5c3dae1..d54d53514 100644 --- a/src/test/java/org/gridsuite/study/server/StudyTest.java +++ b/src/test/java/org/gridsuite/study/server/StudyTest.java @@ -2197,9 +2197,6 @@ void testCutAndPasteNodeWithoutModification(final MockWebServer server) throws E cutAndPasteNode(study1Uuid, emptyNode, node1.getId(), InsertMode.BEFORE, 1, userId); - Set request = TestUtils.getRequestsDone(1, server); - assertTrue(request.stream().allMatch(r -> r.matches("/v1/reports"))); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(emptyNode.getId(), rootNetworkUuid).getGlobalBuildStatus()); assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(node1.getId(), rootNetworkUuid).getGlobalBuildStatus()); assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(emptyNodeChild.getId(), rootNetworkUuid).getGlobalBuildStatus()); @@ -2219,9 +2216,6 @@ void testCutAndPasteNodeWithModification(final MockWebServer server) throws Exce cutAndPasteNode(study1Uuid, notEmptyNode, node1.getId(), InsertMode.BEFORE, 1, userId); - Set request = TestUtils.getRequestsDone(2, server); - assertTrue(request.stream().allMatch(r -> r.matches("/v1/reports"))); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(notEmptyNode.getId(), rootNetworkUuid).getGlobalBuildStatus()); assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(node1.getId(), rootNetworkUuid).getGlobalBuildStatus()); assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(notEmptyNodeChild.getId(), rootNetworkUuid).getGlobalBuildStatus()); @@ -2312,9 +2306,6 @@ void testCutAndPasteSubtree(final MockWebServer server) throws Exception { checkSubtreeMovedMessageSent(study1Uuid, emptyNode.getId(), node1.getId()); checkElementUpdatedMessageSent(study1Uuid, userId); - var request = TestUtils.getRequestsDone(1, server); - assertTrue(request.stream().allMatch(r -> r.matches("/v1/reports"))); - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(node1.getId(), rootNetworkUuid).getGlobalBuildStatus()); assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(emptyNode.getId(), rootNetworkUuid).getGlobalBuildStatus()); assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(emptyNodeChild.getId(), rootNetworkUuid).getGlobalBuildStatus()); @@ -2487,8 +2478,6 @@ void testDuplicateSubtree(final MockWebServer server) throws Exception { // Invalidation node 3 assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(node3.getId(), firstRootNetworkUuid).getGlobalBuildStatus()); - Set requests = TestUtils.getRequestsWithBodyDone(1, server); - assertEquals(1, requests.stream().filter(r -> r.getPath().matches("/v1/reports")).count()); // add modification on node "node2" String createLoadAttributes = "{\"type\":\"" + ModificationType.LOAD_CREATION + "\",\"loadId\":\"loadId1\",\"loadName\":\"loadName1\",\"loadType\":\"UNDEFINED\",\"activePower\":\"100.0\",\"reactivePower\":\"50.0\",\"voltageLevelId\":\"idVL1\",\"busId\":\"idBus1\"}"; diff --git a/src/test/java/org/gridsuite/study/server/VoltageInitTest.java b/src/test/java/org/gridsuite/study/server/VoltageInitTest.java index 099c888ce..d1edaa67a 100644 --- a/src/test/java/org/gridsuite/study/server/VoltageInitTest.java +++ b/src/test/java/org/gridsuite/study/server/VoltageInitTest.java @@ -848,7 +848,7 @@ private NodeEntity insertNode(StudyEntity study, NodeEntity parentNode, String f // We can't use the method RootNetworkNodeInfoService::createNodeLinks because there is no transaction in a session private void createNodeLinks(RootNetworkEntity rootNetworkEntity, NetworkModificationNodeInfoEntity modificationNodeInfoEntity, String variantId, UUID reportUuid, BuildStatus buildStatus) { - RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = RootNetworkNodeInfoEntity.builder().variantId(variantId).modificationReports(Map.of(modificationNodeInfoEntity.getId(), reportUuid)).nodeBuildStatus(NodeBuildStatus.from(buildStatus).toEntity()).build(); + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = RootNetworkNodeInfoEntity.builder().variantId(variantId).modificationReportUuid(reportUuid).nodeBuildStatus(NodeBuildStatus.from(buildStatus).toEntity()).build(); modificationNodeInfoEntity.addRootNetworkNodeInfo(rootNetworkNodeInfoEntity); rootNetworkEntity.addRootNetworkNodeInfo(rootNetworkNodeInfoEntity); rootNetworkNodeInfoRepository.save(rootNetworkNodeInfoEntity); From dcd622855e109e1b29ef2f3f8fb496a8a127124f Mon Sep 17 00:00:00 2001 From: Ayoub LABIDI Date: Wed, 6 Aug 2025 22:45:00 +0200 Subject: [PATCH 2/9] Fix sonar issue Signed-off-by: Ayoub LABIDI --- .../server/service/RootNetworkNodeInfoService.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java b/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java index 2324522f9..7d609191f 100644 --- a/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java +++ b/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java @@ -96,7 +96,7 @@ public RootNetworkNodeInfoService(RootNetworkNodeInfoRepository rootNetworkNodeI public void createRootNetworkLinks(@NonNull UUID studyUuid, @NonNull RootNetworkEntity rootNetworkEntity) { // For each network modification node (nodeInfoEntity) create a link with the root network networkModificationNodeInfoRepository.findAllByNodeStudyId(studyUuid).forEach(networkModificationNodeEntity -> { - RootNetworkNodeInfoEntity newRootNetworkNodeInfoEntity = createDefaultEntity(networkModificationNodeEntity.getId()); + RootNetworkNodeInfoEntity newRootNetworkNodeInfoEntity = createDefaultEntity(); addLink(networkModificationNodeEntity, rootNetworkEntity, newRootNetworkNodeInfoEntity); }); } @@ -104,7 +104,7 @@ public void createRootNetworkLinks(@NonNull UUID studyUuid, @NonNull RootNetwork public void createNodeLinks(@NonNull StudyEntity studyEntity, @NonNull NetworkModificationNodeInfoEntity modificationNodeInfoEntity) { // For each root network create a link with the node studyEntity.getRootNetworks().forEach(rootNetworkEntity -> { - RootNetworkNodeInfoEntity newRootNetworkNodeInfoEntity = createDefaultEntity(modificationNodeInfoEntity.getId()); + RootNetworkNodeInfoEntity newRootNetworkNodeInfoEntity = createDefaultEntity(); addLink(modificationNodeInfoEntity, rootNetworkEntity, newRootNetworkNodeInfoEntity); }); } @@ -115,18 +115,17 @@ public void duplicateNodeLinks(List sourceNodeLinks, // when duplicating a rootNetworkNodeInfoEntity, we need to keep modificationsToExclude // use correspondence map to use duplicate modification uuids RootNetworkNodeInfoEntity newRootNetworkNodeInfoEntity = createDefaultEntity( - destinationNodeInfoEntity.getId(), nodeLink.getModificationsUuidsToExclude().stream().map(originToDuplicateModificationUuidMap::get).collect(Collectors.toSet()) ); addLink(destinationNodeInfoEntity, originToDuplicateRootNetworkMap.get(nodeLink.getRootNetwork()), newRootNetworkNodeInfoEntity); }); } - private static RootNetworkNodeInfoEntity createDefaultEntity(UUID nodeUuid) { - return createDefaultEntity(nodeUuid, new HashSet<>()); + private static RootNetworkNodeInfoEntity createDefaultEntity() { + return createDefaultEntity(new HashSet<>()); } - private static RootNetworkNodeInfoEntity createDefaultEntity(UUID nodeUuid, Set modificationsToExclude) { + private static RootNetworkNodeInfoEntity createDefaultEntity(Set modificationsToExclude) { return RootNetworkNodeInfoEntity.builder() .nodeBuildStatus(NodeBuildStatusEmbeddable.from(BuildStatus.NOT_BUILT)) .variantId(UUID.randomUUID().toString()) From 08bbd68f59be72d6bb456bc08aa514dfe4644f01 Mon Sep 17 00:00:00 2001 From: Joris Mancini Date: Mon, 25 Aug 2025 15:40:25 +0200 Subject: [PATCH 3/9] fix: delete modification reports when they're not needed anymore Signed-off-by: Joris Mancini --- .../NetworkModificationTreeService.java | 72 ++++++++++++++++--- .../service/RootNetworkNodeInfoService.java | 9 ++- 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java index ae7d9612e..33d0f83ed 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java @@ -873,7 +873,11 @@ public BuildInfos getBuildInfos(UUID nodeUuid, UUID rootNetworkUuid) { public InvalidateNodeInfos invalidateNode(UUID nodeUuid, UUID rootNetworkUuid) { NodeEntity nodeEntity = getNodeEntity(nodeUuid); - InvalidateNodeInfos invalidateNodeInfos = rootNetworkNodeInfoService.invalidateRootNetworkNode(nodeUuid, rootNetworkUuid, InvalidateNodeTreeParameters.ALL); + boolean hasBuiltChildren = hasAnyBuiltChildren(nodeEntity, rootNetworkUuid); + InvalidateNodeInfos invalidateNodeInfos = rootNetworkNodeInfoService.invalidateRootNetworkNode(nodeUuid, rootNetworkUuid, InvalidateNodeTreeParameters.ALL, !hasBuiltChildren); + if (!hasBuiltChildren) { + invalidateAscendantNodesReports(nodeUuid, rootNetworkUuid, invalidateNodeInfos); + } fillIndexedNodeInfosToInvalidate(nodeEntity, rootNetworkUuid, invalidateNodeInfos); @@ -882,6 +886,11 @@ public InvalidateNodeInfos invalidateNode(UUID nodeUuid, UUID rootNetworkUuid) { return invalidateNodeInfos; } + private void invalidateAscendantNodesReports(UUID nodeUuid, UUID rootNetworkUuid, InvalidateNodeInfos invalidateNodeInfos) { + List allNodesToHighestParentInBuiltBranch = getAllNodesToHighestParentInBuiltBranch(nodeUuid, rootNetworkUuid, false); + rootNetworkNodeInfoService.getRootNetworkNodes(rootNetworkUuid, allNodesToHighestParentInBuiltBranch).forEach(entity -> invalidateNodeInfos.addReportUuid(entity.getModificationReportUuid())); + } + @Transactional public InvalidateNodeInfos invalidateNodeTree(UUID nodeUuid, UUID rootNetworkUuid, InvalidateNodeTreeParameters invalidateTreeParameters) { InvalidateNodeInfos invalidateNodeInfos = new InvalidateNodeInfos(); @@ -889,12 +898,14 @@ public InvalidateNodeInfos invalidateNodeTree(UUID nodeUuid, UUID rootNetworkUui // Node status before invalidation NodeEntity nodeEntity = getNodeEntity(nodeUuid); boolean isModificationNode = nodeEntity.getType().equals(NodeType.NETWORK_MODIFICATION); - boolean isNodeBuilt = self.getNodeBuildStatus(nodeEntity.getIdNode(), rootNetworkUuid).isBuilt(); + boolean isNodeBuilt = isNodeBuilt(rootNetworkUuid, nodeEntity); boolean shouldInvalidateIndexedInfos = isNodeBuilt || hasAnyBuiltChildren(nodeEntity, rootNetworkUuid); // First node if (isModificationNode && !invalidateTreeParameters.isOnlyChildren()) { - invalidateNodeInfos = rootNetworkNodeInfoService.invalidateRootNetworkNode(nodeUuid, rootNetworkUuid, invalidateTreeParameters); + // if we enter this case node will be unbuilt anyway and its children too so we will have to remove reports too + invalidateNodeInfos = rootNetworkNodeInfoService.invalidateRootNetworkNode(nodeUuid, rootNetworkUuid, invalidateTreeParameters, false); + invalidateAscendantNodesReports(nodeUuid, rootNetworkUuid, invalidateNodeInfos); } // Invalidate indexed nodes @@ -921,7 +932,8 @@ private InvalidateNodeInfos invalidateChildrenNodes(UUID nodeUuid, UUID rootNetw .withBlockedNodeBuild(invalidateTreeParameters.withBlockedNodeBuild()) .build(); rootNetworkNodeInfoEntities.forEach(child -> - invalidateNodeInfos.add(rootNetworkNodeInfoService.invalidateRootNetworkNode(child, invalidateChildrenParameters)) + // InvalidationMode is ALL, so I know that all children will be unbuilt, so we have to remove reports + invalidateNodeInfos.add(rootNetworkNodeInfoService.invalidateRootNetworkNode(child, invalidateChildrenParameters, false)) ); return invalidateNodeInfos; @@ -949,7 +961,7 @@ private NodeEntity getSubTreeToInvalidateIndexedModifications(UUID nodeUuid, UUI while (currentNode.getParentNode() != null) { NodeEntity parentNode = currentNode.getParentNode(); if (parentNode.getType().equals(NodeType.ROOT) - || self.getNodeBuildStatus(parentNode.getIdNode(), rootNetworkUuid).isBuilt() + || isNodeBuilt(rootNetworkUuid, parentNode) || hasAnyBuiltChildren(parentNode, rootNetworkUuid, descendantsChecked)) { return currentNode; } @@ -960,13 +972,51 @@ private NodeEntity getSubTreeToInvalidateIndexedModifications(UUID nodeUuid, UUI return currentNode; } + /** + * Recursively iterate through *nodeUuid* parents until one of them match one of the following conditions :
+ * - it is of type ROOT
+ * - it is built
+ * - one of its children is built + * @param nodeUuid reference node from where the recursion will start + * @param rootNetworkUuid root network necessary to get the build status of each node + * @param withHighestParent whether the parent that belongs to a built branch should be in the set or not + * @return A set filled with IDs of all the parents of the current node that does not belong to a built branch + */ + private List getAllNodesToHighestParentInBuiltBranch(UUID nodeUuid, UUID rootNetworkUuid, boolean withHighestParent) { + List parents = new ArrayList<>(); + Set descendantsChecked = new HashSet<>(); + + NodeEntity currentNode = getNodeEntity(nodeUuid); + + boolean found = false; + while (!found || currentNode.getParentNode() != null) { + NodeEntity parentNode = currentNode.getParentNode(); + if (parentNode.getType().equals(NodeType.ROOT) + || isNodeBuilt(rootNetworkUuid, parentNode) + || hasAnyBuiltChildren(parentNode, rootNetworkUuid, descendantsChecked)) { + found = true; + if (withHighestParent) { + parents.add(parentNode.getIdNode()); + } + } else { + parents.add(parentNode.getIdNode()); + } + currentNode = parentNode; + } + + return parents; + } + // TODO Need to optimise with a only one recursive query private boolean hasAnyBuiltChildren(NodeEntity node, UUID rootNetworkUuid) { - return hasAnyBuiltChildren(node, rootNetworkUuid, new HashSet<>()); + return getChildren(node.getIdNode()) + .stream() + .map(child -> hasAnyBuiltChildren(child, rootNetworkUuid, new HashSet<>())) + .anyMatch(el -> el.equals(Boolean.TRUE)); } private boolean hasAnyBuiltChildren(NodeEntity node, UUID rootNetworkUuid, Set checkedChildren) { - if (self.getNodeBuildStatus(node.getIdNode(), rootNetworkUuid).isBuilt()) { + if (isNodeBuilt(rootNetworkUuid, node)) { return true; } checkedChildren.add(node); @@ -984,7 +1034,7 @@ && hasAnyBuiltChildren(child, rootNetworkUuid, checkedChildren)) { private void fillIndexedNodeInfosToInvalidate(NodeEntity nodeEntity, UUID rootNetworkUuid, InvalidateNodeInfos invalidateNodeInfos) { // when manually invalidating a single node, if this node does not have any built children // we need to invalidate indexed modifications up to it's last built parent, not included - if (hasAnyBuiltChildren(nodeEntity, rootNetworkUuid)) { + if (isNodeBuilt(rootNetworkUuid, nodeEntity) || hasAnyBuiltChildren(nodeEntity, rootNetworkUuid)) { return; } @@ -1106,7 +1156,7 @@ private Optional doGetParentNode(UUID nodeUuid, NodeType nodeType) { public long countBuiltNodes(UUID studyUuid, UUID rootNetworkUuid) { List nodes = nodesRepository.findAllByStudyIdAndTypeAndStashed(studyUuid, NodeType.NETWORK_MODIFICATION, false); // perform N queries, but it's fast: 25 ms for 400 nodes - return nodes.stream().filter(n -> self.getNodeBuildStatus(n.getIdNode(), rootNetworkUuid).isBuilt()).count(); + return nodes.stream().filter(n -> isNodeBuilt(rootNetworkUuid, n)).count(); } private void fillIndexedNodeInfosToInvalidate(UUID parentNodeUuid, boolean includeParentNode, InvalidateNodeInfos invalidateNodeInfos) { @@ -1142,4 +1192,8 @@ public NetworkModificationNode createNodeTree(@NonNull StudyEntity study, @NonNu return nodeInfo; } + + private boolean isNodeBuilt(UUID rootNetworkUuid, NodeEntity nodeEntity) { + return self.getNodeBuildStatus(nodeEntity.getIdNode(), rootNetworkUuid).isBuilt(); + } } diff --git a/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java b/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java index c7dba2782..a46d8c527 100644 --- a/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java +++ b/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java @@ -232,12 +232,12 @@ public void fillDeleteNodeInfo(UUID nodeUuid, DeleteNodeInfos deleteNodeInfos) { }); } - public InvalidateNodeInfos invalidateRootNetworkNode(UUID nodeUuid, UUID rootNetworUuid, InvalidateNodeTreeParameters invalidateTreeParameters) { + public InvalidateNodeInfos invalidateRootNetworkNode(UUID nodeUuid, UUID rootNetworUuid, InvalidateNodeTreeParameters invalidateTreeParameters, boolean shouldRemoveModificationReports) { RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoRepository.findByNodeInfoIdAndRootNetworkId(nodeUuid, rootNetworUuid).orElseThrow(() -> new StudyException(ROOT_NETWORK_NOT_FOUND)); - return invalidateRootNetworkNode(rootNetworkNodeInfoEntity, invalidateTreeParameters); + return invalidateRootNetworkNode(rootNetworkNodeInfoEntity, invalidateTreeParameters, shouldRemoveModificationReports); } - public InvalidateNodeInfos invalidateRootNetworkNode(RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity, InvalidateNodeTreeParameters invalidateTreeParameters) { + public InvalidateNodeInfos invalidateRootNetworkNode(RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity, InvalidateNodeTreeParameters invalidateTreeParameters, boolean shouldRemoveModificationReports) { boolean notOnlyChildrenBuildStatus = !invalidateTreeParameters.isOnlyChildrenBuildStatus(); // Always update blocked build info @@ -253,6 +253,9 @@ public InvalidateNodeInfos invalidateRootNetworkNode(RootNetworkNodeInfoEntity r InvalidateNodeInfos invalidateNodeInfos = getInvalidationComputationInfos(rootNetworkNodeInfoEntity, invalidateTreeParameters.computationsInvalidationMode()); if (notOnlyChildrenBuildStatus) { + if (shouldRemoveModificationReports) { + invalidateNodeInfos.addReportUuid(rootNetworkNodeInfoEntity.getModificationReportUuid()); + } invalidateNodeInfos.addVariantId(rootNetworkNodeInfoEntity.getVariantId()); invalidateBuildStatus(rootNetworkNodeInfoEntity, invalidateNodeInfos); } From 302b8e2598b1f1cb71ec7bd705ce2feba9802a5a Mon Sep 17 00:00:00 2001 From: Joris Mancini Date: Mon, 25 Aug 2025 16:25:48 +0200 Subject: [PATCH 4/9] fix: inverted boolean after refactoring Signed-off-by: Joris Mancini --- .../study/server/service/NetworkModificationTreeService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java index 33d0f83ed..33b921ff3 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java @@ -904,7 +904,7 @@ public InvalidateNodeInfos invalidateNodeTree(UUID nodeUuid, UUID rootNetworkUui // First node if (isModificationNode && !invalidateTreeParameters.isOnlyChildren()) { // if we enter this case node will be unbuilt anyway and its children too so we will have to remove reports too - invalidateNodeInfos = rootNetworkNodeInfoService.invalidateRootNetworkNode(nodeUuid, rootNetworkUuid, invalidateTreeParameters, false); + invalidateNodeInfos = rootNetworkNodeInfoService.invalidateRootNetworkNode(nodeUuid, rootNetworkUuid, invalidateTreeParameters, true); invalidateAscendantNodesReports(nodeUuid, rootNetworkUuid, invalidateNodeInfos); } @@ -933,7 +933,7 @@ private InvalidateNodeInfos invalidateChildrenNodes(UUID nodeUuid, UUID rootNetw .build(); rootNetworkNodeInfoEntities.forEach(child -> // InvalidationMode is ALL, so I know that all children will be unbuilt, so we have to remove reports - invalidateNodeInfos.add(rootNetworkNodeInfoService.invalidateRootNetworkNode(child, invalidateChildrenParameters, false)) + invalidateNodeInfos.add(rootNetworkNodeInfoService.invalidateRootNetworkNode(child, invalidateChildrenParameters, true)) ); return invalidateNodeInfos; From ae2f48e3d36fd950bd4b0490d3d0a3c2257baf6f Mon Sep 17 00:00:00 2001 From: Joris Mancini Date: Mon, 25 Aug 2025 16:26:08 +0200 Subject: [PATCH 5/9] fix: should check for reports even on unbuilt nodes Signed-off-by: Joris Mancini --- .../study/server/service/RootNetworkNodeInfoService.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java b/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java index a46d8c527..58907ab9e 100644 --- a/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java +++ b/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java @@ -247,7 +247,11 @@ public InvalidateNodeInfos invalidateRootNetworkNode(RootNetworkNodeInfoEntity r // No need to delete node results with a status different of "BUILT" if (!rootNetworkNodeInfoEntity.getNodeBuildStatus().toDto().isBuilt()) { - return new InvalidateNodeInfos(); + InvalidateNodeInfos invalidateNodeInfos = new InvalidateNodeInfos(); + if (shouldRemoveModificationReports) { + invalidateNodeInfos.addReportUuid(rootNetworkNodeInfoEntity.getModificationReportUuid()); + } + return invalidateNodeInfos; } InvalidateNodeInfos invalidateNodeInfos = getInvalidationComputationInfos(rootNetworkNodeInfoEntity, invalidateTreeParameters.computationsInvalidationMode()); From 304ae9b63719cf79328787e3371867e55e3f4c90 Mon Sep 17 00:00:00 2001 From: Joris Mancini Date: Mon, 25 Aug 2025 16:59:59 +0200 Subject: [PATCH 6/9] refactor: simplify utility functions Signed-off-by: Joris Mancini --- .../NetworkModificationTreeService.java | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java index 33b921ff3..521eafe57 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java @@ -887,7 +887,7 @@ public InvalidateNodeInfos invalidateNode(UUID nodeUuid, UUID rootNetworkUuid) { } private void invalidateAscendantNodesReports(UUID nodeUuid, UUID rootNetworkUuid, InvalidateNodeInfos invalidateNodeInfos) { - List allNodesToHighestParentInBuiltBranch = getAllNodesToHighestParentInBuiltBranch(nodeUuid, rootNetworkUuid, false); + List allNodesToHighestParentInBuiltBranch = getAllNodesToHighestParentInBuiltBranch(nodeUuid, rootNetworkUuid); rootNetworkNodeInfoService.getRootNetworkNodes(rootNetworkUuid, allNodesToHighestParentInBuiltBranch).forEach(entity -> invalidateNodeInfos.addReportUuid(entity.getModificationReportUuid())); } @@ -954,15 +954,13 @@ public void invalidateBlockedBuildNodeTree(UUID rootNetworkUuid, UUID nodeUuid) * @return the NodeEntity having its parent matching one of the above criteria */ private NodeEntity getSubTreeToInvalidateIndexedModifications(UUID nodeUuid, UUID rootNetworkUuid) { - Set descendantsChecked = new HashSet<>(); - NodeEntity currentNode = getNodeEntity(nodeUuid); while (currentNode.getParentNode() != null) { NodeEntity parentNode = currentNode.getParentNode(); if (parentNode.getType().equals(NodeType.ROOT) || isNodeBuilt(rootNetworkUuid, parentNode) - || hasAnyBuiltChildren(parentNode, rootNetworkUuid, descendantsChecked)) { + || hasAnyBuiltChildren(parentNode, rootNetworkUuid)) { return currentNode; } @@ -979,25 +977,19 @@ private NodeEntity getSubTreeToInvalidateIndexedModifications(UUID nodeUuid, UUI * - one of its children is built * @param nodeUuid reference node from where the recursion will start * @param rootNetworkUuid root network necessary to get the build status of each node - * @param withHighestParent whether the parent that belongs to a built branch should be in the set or not - * @return A set filled with IDs of all the parents of the current node that does not belong to a built branch + * @return A set filled with IDs of all the parents of the current node that does not belong to a built branch in the tree */ - private List getAllNodesToHighestParentInBuiltBranch(UUID nodeUuid, UUID rootNetworkUuid, boolean withHighestParent) { + private List getAllNodesToHighestParentInBuiltBranch(UUID nodeUuid, UUID rootNetworkUuid) { List parents = new ArrayList<>(); - Set descendantsChecked = new HashSet<>(); - NodeEntity currentNode = getNodeEntity(nodeUuid); - boolean found = false; + while (!found || currentNode.getParentNode() != null) { NodeEntity parentNode = currentNode.getParentNode(); if (parentNode.getType().equals(NodeType.ROOT) || isNodeBuilt(rootNetworkUuid, parentNode) - || hasAnyBuiltChildren(parentNode, rootNetworkUuid, descendantsChecked)) { + || hasAnyBuiltChildren(parentNode, rootNetworkUuid)) { found = true; - if (withHighestParent) { - parents.add(parentNode.getIdNode()); - } } else { parents.add(parentNode.getIdNode()); } @@ -1011,19 +1003,18 @@ private List getAllNodesToHighestParentInBuiltBranch(UUID nodeUuid, UUID r private boolean hasAnyBuiltChildren(NodeEntity node, UUID rootNetworkUuid) { return getChildren(node.getIdNode()) .stream() - .map(child -> hasAnyBuiltChildren(child, rootNetworkUuid, new HashSet<>())) + .map(child -> hasAnyBuiltChildrenRecursive(child, rootNetworkUuid)) .anyMatch(el -> el.equals(Boolean.TRUE)); } - private boolean hasAnyBuiltChildren(NodeEntity node, UUID rootNetworkUuid, Set checkedChildren) { + // This method should not be called directly, hasAnyBuiltChildren should be called instead + private boolean hasAnyBuiltChildrenRecursive(NodeEntity node, UUID rootNetworkUuid) { if (isNodeBuilt(rootNetworkUuid, node)) { return true; } - checkedChildren.add(node); for (NodeEntity child : getChildren(node.getIdNode())) { - if (!checkedChildren.contains(child) - && hasAnyBuiltChildren(child, rootNetworkUuid, checkedChildren)) { + if (hasAnyBuiltChildrenRecursive(child, rootNetworkUuid)) { return true; } } From 0e98e021fdaa6c1aba8c5a7379874b9798d748ce Mon Sep 17 00:00:00 2001 From: Joris Mancini Date: Tue, 26 Aug 2025 09:50:59 +0200 Subject: [PATCH 7/9] revert: modifications on hasAnyBuiltChildren method Signed-off-by: Joris Mancini --- .../service/NetworkModificationTreeService.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java index 521eafe57..38ca4e06c 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java @@ -954,13 +954,14 @@ public void invalidateBlockedBuildNodeTree(UUID rootNetworkUuid, UUID nodeUuid) * @return the NodeEntity having its parent matching one of the above criteria */ private NodeEntity getSubTreeToInvalidateIndexedModifications(UUID nodeUuid, UUID rootNetworkUuid) { + Set descendantsChecked = new HashSet<>(); NodeEntity currentNode = getNodeEntity(nodeUuid); while (currentNode.getParentNode() != null) { NodeEntity parentNode = currentNode.getParentNode(); if (parentNode.getType().equals(NodeType.ROOT) || isNodeBuilt(rootNetworkUuid, parentNode) - || hasAnyBuiltChildren(parentNode, rootNetworkUuid)) { + || hasAnyBuiltChildren(parentNode, rootNetworkUuid, descendantsChecked)) { return currentNode; } @@ -980,15 +981,16 @@ private NodeEntity getSubTreeToInvalidateIndexedModifications(UUID nodeUuid, UUI * @return A set filled with IDs of all the parents of the current node that does not belong to a built branch in the tree */ private List getAllNodesToHighestParentInBuiltBranch(UUID nodeUuid, UUID rootNetworkUuid) { - List parents = new ArrayList<>(); + Set descendantsChecked = new HashSet<>(); NodeEntity currentNode = getNodeEntity(nodeUuid); + List parents = new ArrayList<>(); boolean found = false; while (!found || currentNode.getParentNode() != null) { NodeEntity parentNode = currentNode.getParentNode(); if (parentNode.getType().equals(NodeType.ROOT) || isNodeBuilt(rootNetworkUuid, parentNode) - || hasAnyBuiltChildren(parentNode, rootNetworkUuid)) { + || hasAnyBuiltChildren(parentNode, rootNetworkUuid, descendantsChecked)) { found = true; } else { parents.add(parentNode.getIdNode()); @@ -1003,18 +1005,19 @@ private List getAllNodesToHighestParentInBuiltBranch(UUID nodeUuid, UUID r private boolean hasAnyBuiltChildren(NodeEntity node, UUID rootNetworkUuid) { return getChildren(node.getIdNode()) .stream() - .map(child -> hasAnyBuiltChildrenRecursive(child, rootNetworkUuid)) + .map(child -> hasAnyBuiltChildren(child, rootNetworkUuid, new HashSet<>())) .anyMatch(el -> el.equals(Boolean.TRUE)); } - // This method should not be called directly, hasAnyBuiltChildren should be called instead - private boolean hasAnyBuiltChildrenRecursive(NodeEntity node, UUID rootNetworkUuid) { + private boolean hasAnyBuiltChildren(NodeEntity node, UUID rootNetworkUuid, Set checkedChildren) { if (isNodeBuilt(rootNetworkUuid, node)) { return true; } + checkedChildren.add(node); for (NodeEntity child : getChildren(node.getIdNode())) { - if (hasAnyBuiltChildrenRecursive(child, rootNetworkUuid)) { + if (!checkedChildren.contains(child) + && hasAnyBuiltChildren(child, rootNetworkUuid, checkedChildren)) { return true; } } From 24200d69f974e9b55e0f7156a5845033768e144e Mon Sep 17 00:00:00 2001 From: Joris Mancini Date: Tue, 26 Aug 2025 16:25:26 +0200 Subject: [PATCH 8/9] fix: for node invalidation go after parents only if node is built Signed-off-by: Joris Mancini --- .../server/service/NetworkModificationTreeService.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java index 38ca4e06c..12737a4b1 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java @@ -873,9 +873,10 @@ public BuildInfos getBuildInfos(UUID nodeUuid, UUID rootNetworkUuid) { public InvalidateNodeInfos invalidateNode(UUID nodeUuid, UUID rootNetworkUuid) { NodeEntity nodeEntity = getNodeEntity(nodeUuid); + boolean isNodeBuilt = isNodeBuilt(rootNetworkUuid, nodeEntity); boolean hasBuiltChildren = hasAnyBuiltChildren(nodeEntity, rootNetworkUuid); InvalidateNodeInfos invalidateNodeInfos = rootNetworkNodeInfoService.invalidateRootNetworkNode(nodeUuid, rootNetworkUuid, InvalidateNodeTreeParameters.ALL, !hasBuiltChildren); - if (!hasBuiltChildren) { + if (isNodeBuilt && !hasBuiltChildren) { invalidateAscendantNodesReports(nodeUuid, rootNetworkUuid, invalidateNodeInfos); } @@ -986,7 +987,7 @@ private List getAllNodesToHighestParentInBuiltBranch(UUID nodeUuid, UUID r List parents = new ArrayList<>(); boolean found = false; - while (!found || currentNode.getParentNode() != null) { + while (!found && currentNode.getParentNode() != null) { NodeEntity parentNode = currentNode.getParentNode(); if (parentNode.getType().equals(NodeType.ROOT) || isNodeBuilt(rootNetworkUuid, parentNode) @@ -994,8 +995,8 @@ private List getAllNodesToHighestParentInBuiltBranch(UUID nodeUuid, UUID r found = true; } else { parents.add(parentNode.getIdNode()); + currentNode = parentNode; } - currentNode = parentNode; } return parents; From 769f86efb93147ddb9f85cce8896150833c5413b Mon Sep 17 00:00:00 2001 From: Ayoub LABIDI Date: Thu, 28 Aug 2025 08:59:47 +0200 Subject: [PATCH 9/9] do not delete node children reports if not necessary Signed-off-by: Ayoub LABIDI --- .../NetworkModificationTreeService.java | 12 +- .../gridsuite/study/server/LoadFlowTest.java | 2 +- .../server/ModificationIndexationTest.java | 12 +- .../study/server/NetworkModificationTest.java | 124 ++++++++++++++---- .../org/gridsuite/study/server/StudyTest.java | 11 ++ 5 files changed, 126 insertions(+), 35 deletions(-) diff --git a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java index 12737a4b1..4b0efc6db 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java @@ -932,10 +932,14 @@ private InvalidateNodeInfos invalidateChildrenNodes(UUID nodeUuid, UUID rootNetw .invalidationMode(InvalidateNodeTreeParameters.InvalidationMode.ALL) .withBlockedNodeBuild(invalidateTreeParameters.withBlockedNodeBuild()) .build(); - rootNetworkNodeInfoEntities.forEach(child -> - // InvalidationMode is ALL, so I know that all children will be unbuilt, so we have to remove reports - invalidateNodeInfos.add(rootNetworkNodeInfoService.invalidateRootNetworkNode(child, invalidateChildrenParameters, true)) - ); + rootNetworkNodeInfoEntities.forEach(child -> { + // InvalidationMode is ALL, so I know that all children will be unbuilt, + // so we have to remove reports for all children that are built or have built children + NodeEntity childNodeEntity = getNodeEntity(child.getNodeInfo().getIdNode()); + if (isNodeBuilt(rootNetworkUuid, childNodeEntity) || hasAnyBuiltChildren(childNodeEntity, rootNetworkUuid)) { + invalidateNodeInfos.add(rootNetworkNodeInfoService.invalidateRootNetworkNode(child, invalidateChildrenParameters, true)); + } + }); return invalidateNodeInfos; } diff --git a/src/test/java/org/gridsuite/study/server/LoadFlowTest.java b/src/test/java/org/gridsuite/study/server/LoadFlowTest.java index f06e5eea6..0e8f078f5 100644 --- a/src/test/java/org/gridsuite/study/server/LoadFlowTest.java +++ b/src/test/java/org/gridsuite/study/server/LoadFlowTest.java @@ -948,7 +948,7 @@ void testInvalidateNodesAfterLoadflow(final MockWebServer server) throws Excepti checkUpdateModelStatusMessagesReceived(studyUuid, NotificationService.UPDATE_TYPE_LOADFLOW_STATUS); - var requests = TestUtils.getRequestsDone(2, server); + var requests = TestUtils.getRequestsDone(3, server); assertTrue(requests.stream().anyMatch(r -> r.matches("/v1/results\\?resultsUuids=.*"))); assertTrue(requests.stream().anyMatch(r -> r.matches("/v1/reports"))); assertTrue(requests.stream().anyMatch(r -> r.matches("/v1/results/invalidate-status\\?resultUuid=.*"))); diff --git a/src/test/java/org/gridsuite/study/server/ModificationIndexationTest.java b/src/test/java/org/gridsuite/study/server/ModificationIndexationTest.java index e07605e78..e9358f0d7 100644 --- a/src/test/java/org/gridsuite/study/server/ModificationIndexationTest.java +++ b/src/test/java/org/gridsuite/study/server/ModificationIndexationTest.java @@ -93,7 +93,7 @@ void testInvalidateBuiltNodeAndItsChildren() { node3.getModificationGroupUuid() )); - SQLStatementCountValidator.assertSelectCount(16); + SQLStatementCountValidator.assertSelectCount(23); } @Test @@ -105,7 +105,7 @@ void testInvalidateNotBuiltNodeAndItsChildren() { node5.getModificationGroupUuid() )); - SQLStatementCountValidator.assertSelectCount(14); + SQLStatementCountValidator.assertSelectCount(23); } @Test @@ -116,7 +116,7 @@ void testInvalidateBuiltNodeChildrenOnly() { node5.getModificationGroupUuid() )); - SQLStatementCountValidator.assertSelectCount(7); + SQLStatementCountValidator.assertSelectCount(17); } @Test @@ -128,7 +128,7 @@ void testInvalidateNotBuiltNodeChildrenOnly() { node3.getModificationGroupUuid() )); - SQLStatementCountValidator.assertSelectCount(16); + SQLStatementCountValidator.assertSelectCount(23); } @Test @@ -137,7 +137,7 @@ void testInvalidateBuiltNodeOnlyWithBuiltChildren() { assertThat(invalidateNodeInfos.getGroupUuids()).isEmpty(); - SQLStatementCountValidator.assertSelectCount(6); + SQLStatementCountValidator.assertSelectCount(9); } @Test @@ -149,7 +149,7 @@ void testInvalidateBuiltNodeOnlyWithoutBuiltChildren() { node3.getModificationGroupUuid() )); - SQLStatementCountValidator.assertSelectCount(17); + SQLStatementCountValidator.assertSelectCount(27); } private void createStudyAndNodesWithIndexedModification() { diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java index b6d0c85d3..324ae180b 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java @@ -594,7 +594,7 @@ void testBuild() throws Exception { } @Test - void testLocalBuildValue() throws Exception { + void testLocalBuildValue(final MockWebServer server) throws Exception { StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -664,6 +664,9 @@ void testLocalBuildValue() throws Exception { //Build modification node 2, local status should be BUILT and computed one should be BUILT_WITH_ERRORS assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode2Uuid, rootNetworkUuid).getLocalBuildStatus()); assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(modificationNode2Uuid, rootNetworkUuid).getGlobalBuildStatus()); + + Set requests = TestUtils.getRequestsWithBodyDone(1, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test @@ -761,6 +764,9 @@ void testNetworkModificationSwitch(final MockWebServer server) throws Exception modificationBody = Pair.of(bodyJson, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); wireMockUtils.verifyNetworkModificationPostWithVariant(stubPostId, getModificationContextJsonString(mapper, modificationBody)); + Set requests = TestUtils.getRequestsWithBodyDone(3, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); + // modificationNode2 is still built assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode1Uuid, firstRootNetworkUuid).getGlobalBuildStatus()); @@ -769,7 +775,7 @@ void testNetworkModificationSwitch(final MockWebServer server) throws Exception } @Test - void testNetworkModificationEquipment() throws Exception { + void testNetworkModificationEquipment(final MockWebServer server) throws Exception { MvcResult mvcResult; String resultAsString; String userId = "userId"; @@ -828,10 +834,13 @@ void testNetworkModificationEquipment() throws Exception { checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(bodyJson, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid2, NETWORK_UUID))); wireMockUtils.verifyNetworkModificationPostWithVariant(stubPostId, getModificationContextJsonString(mapper, modificationBody)); + + Set requests = TestUtils.getRequestsWithBodyDone(1, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test - void testCreateGenerator() throws Exception { + void testCreateGenerator(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -921,10 +930,13 @@ void testCreateGenerator() throws Exception { .content(bodyJsonCreateBis).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isForbidden()); + + Set requests = TestUtils.getRequestsWithBodyDone(1, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test - void testCreateShuntsCompensator() throws Exception { + void testCreateShuntsCompensator(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -976,10 +988,13 @@ void testCreateShuntsCompensator() throws Exception { .content(createShuntCompensatorAttributes2).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isForbidden()); + + Set requests = TestUtils.getRequestsWithBodyDone(1, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test - void testCreateLine() throws Exception { + void testCreateLine(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -1065,10 +1080,13 @@ void testCreateLine() throws Exception { .content(createLineAttributes2).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isForbidden()); + + Set requests = TestUtils.getRequestsWithBodyDone(1, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test - void testCreateTwoWindingsTransformer() throws Exception { + void testCreateTwoWindingsTransformer(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -1137,6 +1155,9 @@ void testCreateTwoWindingsTransformer() throws Exception { .content(createTwoWindingsTransformerAttributes2).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isForbidden()); + + Set requests = TestUtils.getRequestsWithBodyDone(1, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test @@ -1186,7 +1207,7 @@ void deleteModificationRequest() throws Exception { } @Test - void testUpdateLines() throws Exception { + void testUpdateLines(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -1337,10 +1358,13 @@ void testUpdateLines() throws Exception { checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(bodyJsonCreate9, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode2Uuid, NETWORK_UUID))); wireMockUtils.verifyNetworkModificationPostWithVariant(stubPostId, getModificationContextJsonString(mapper, modificationBody)); + + Set requests = TestUtils.getRequestsWithBodyDone(9, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test - void testCreateLoad() throws Exception { + void testCreateLoad(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -1413,10 +1437,13 @@ void testCreateLoad() throws Exception { .content(createLoadAttributes2).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isForbidden()); + + Set requests = TestUtils.getRequestsWithBodyDone(3, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test - void testModifyLoad() throws Exception { + void testModifyLoad(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -1474,10 +1501,13 @@ void testModifyLoad() throws Exception { checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); wireMockUtils.verifyNetworkModificationPut(stubPutId, MODIFICATION_UUID, loadAttributesUpdated); + + Set requests = TestUtils.getRequestsWithBodyDone(3, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test - void testModifyEquipment() throws Exception { + void testModifyEquipment(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -1532,10 +1562,13 @@ void testModifyEquipment() throws Exception { checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); wireMockUtils.verifyNetworkModificationPut(stubPutId, MODIFICATION_UUID, generatorAttributesUpdated); + + Set requests = TestUtils.getRequestsWithBodyDone(3, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test - void testCreateSubstation() throws Exception { + void testCreateSubstation(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -1604,10 +1637,13 @@ void testCreateSubstation() throws Exception { .content(createSubstationAttributes2).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isForbidden()); + + Set requests = TestUtils.getRequestsWithBodyDone(3, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test - void testCreateVoltageLevel() throws Exception { + void testCreateVoltageLevel(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -1678,10 +1714,13 @@ void testCreateVoltageLevel() throws Exception { .content(createVoltageLevelAttributes2).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isForbidden()); + + Set requests = TestUtils.getRequestsWithBodyDone(3, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test - void testLineSplitWithVoltageLevel() throws Exception { + void testLineSplitWithVoltageLevel(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -1749,10 +1788,13 @@ void testLineSplitWithVoltageLevel() throws Exception { checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); wireMockUtils.verifyNetworkModificationPost(stubPostId, modificationBodyJson); wireMockUtils.verifyNetworkModificationPut(stubPutId, MODIFICATION_UUID, badBody); + + Set requests = TestUtils.getRequestsWithBodyDone(3, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test - void testLineAttachToVoltageLevel() throws Exception { + void testLineAttachToVoltageLevel(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -1789,10 +1831,13 @@ void testLineAttachToVoltageLevel() throws Exception { checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); wireMockUtils.verifyNetworkModificationPut(stubPutId, MODIFICATION_UUID, createLineAttachToVoltageLevelAttributes); + + Set requests = TestUtils.getRequestsWithBodyDone(2, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test - void testLinesAttachToSplitLines() throws Exception { + void testLinesAttachToSplitLines(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -1844,6 +1889,9 @@ void testLinesAttachToSplitLines() throws Exception { checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); wireMockUtils.verifyNetworkModificationPost(stubPostId, modificationBodyJson); wireMockUtils.verifyNetworkModificationPut(stubPutId, MODIFICATION_UUID, badBody); + + Set requests = TestUtils.getRequestsWithBodyDone(3, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @ParameterizedTest @@ -1906,7 +1954,7 @@ void testScaling(ModificationType scalingType) throws Exception { } @Test - void testDeleteVoltageLevelOnline() throws Exception { + void testDeleteVoltageLevelOnline(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -1956,10 +2004,13 @@ void testDeleteVoltageLevelOnline() throws Exception { checkEquipmentUpdatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); wireMockUtils.verifyNetworkModificationPut(stubIdPutErr, MODIFICATION_UUID, badBody); + + Set requests = TestUtils.getRequestsWithBodyDone(3, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test - void testDeleteAttachingline() throws Exception { + void testDeleteAttachingline(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -2010,10 +2061,13 @@ void testDeleteAttachingline() throws Exception { checkEquipmentUpdatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); wireMockUtils.verifyNetworkModificationPut(stubIdPutErr, MODIFICATION_UUID, badBody); + + Set requests = TestUtils.getRequestsWithBodyDone(3, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test - void testReorderModification() throws Exception { + void testReorderModification(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -2065,6 +2119,9 @@ void testReorderModification() throws Exception { "build", WireMock.equalTo("false"), "before", WireMock.equalTo(modification2.toString())), expectedBodyStr); + + Set requests = TestUtils.getRequestsWithBodyDone(2, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test @@ -2092,7 +2149,7 @@ void testReorderModificationErrorCase() throws Exception { } @Test - void testDuplicateModification() throws Exception { + void testDuplicateModification(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyUuid = studyEntity.getId(); @@ -2159,6 +2216,9 @@ void testDuplicateModification() throws Exception { wireMockUtils.verifyPutRequestWithUrlMatching(groupStubId, url, Map.of( "action", WireMock.equalTo("COPY")), expectedBody); + + Set requests = TestUtils.getRequestsWithBodyDone(1, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test @@ -2190,7 +2250,7 @@ void testDuplicateModificationErrorCase() throws Exception { } @Test - void testCutAndPasteModification() throws Exception { + void testCutAndPasteModification(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyUuid = studyEntity.getId(); @@ -2264,6 +2324,9 @@ void testCutAndPasteModification() throws Exception { .content(modificationUuidListBody) .header(USER_ID_HEADER, "userId")) .andExpect(status().isBadRequest()); + + Set requests = TestUtils.getRequestsWithBodyDone(3, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test @@ -2296,7 +2359,7 @@ void testCutAndPasteModificationErrorCase() throws Exception { } @Test - void testDeleteEquipment() throws Exception { + void testDeleteEquipment(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -2358,6 +2421,9 @@ void testDeleteEquipment() throws Exception { checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); wireMockUtils.verifyNetworkModificationPut(stubPutId, MODIFICATION_UUID, bodyJson); + + Set requests = TestUtils.getRequestsWithBodyDone(3, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } @Test @@ -2407,7 +2473,8 @@ void testNodesInvalidation(final MockWebServer server) throws Exception { checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); wireMockUtils.verifyNetworkModificationPut(stubUuid, MODIFICATION_UUID, generatorAttributesUpdated); - var requests = TestUtils.getRequestsWithBodyDone(14, server); + var requests = TestUtils.getRequestsWithBodyDone(15, server); + assertEquals(1, requests.stream().filter(r -> r.getPath().matches("/v1/reports")).count()); assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/results\\?resultsUuids=" + SECURITY_ANALYSIS_RESULT_UUID))); assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/results\\?resultsUuids=" + SENSITIVITY_ANALYSIS_RESULT_UUID))); assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/non-evacuated-energy/results\\?resultsUuids=" + SENSITIVITY_ANALYSIS_NON_EVACUATED_ENERGY_RESULT_UUID))); @@ -2442,6 +2509,9 @@ void testNodesInvalidation(final MockWebServer server) throws Exception { assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode3Uuid, firstRootNetworkUuid).getGlobalBuildStatus()); Pair> modificationBody = Pair.of(jsonCreateLoadInfos, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode2Uuid, NETWORK_UUID))); wireMockUtils.verifyNetworkModificationPostWithVariant(stubPostId, getModificationContextJsonString(mapper, modificationBody)); + + requests = TestUtils.getRequestsWithBodyDone(1, server); + assertEquals(1, requests.stream().filter(r -> r.getPath().matches("/v1/reports")).count()); } @Test @@ -2526,7 +2596,7 @@ void testRemoveLoadFlowComputationReport(final MockWebServer server) throws Exce } @Test - void testUpdateOfBuildStatus() throws Exception { + void testUpdateOfBuildStatus(final MockWebServer server) throws Exception { StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID firstRootNetworkUuid = studyTestUtils.getOneRootNetworkUuid(studyEntity.getId()); UUID studyNameUserIdUuid = studyEntity.getId(); @@ -2609,6 +2679,9 @@ void testUpdateOfBuildStatus() throws Exception { assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid, firstRootNetworkUuid).getGlobalBuildStatus()); modificationBody = Pair.of(jsonCreateLoadInfos, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid, NETWORK_UUID))); wireMockUtils.verifyNetworkModificationPostWithVariant(stubPostId, getModificationContextJsonString(mapper, modificationBody)); + + Set requests = TestUtils.getRequestsWithBodyDone(1, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } private void testBuildWithNodeUuid(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, String userId, UUID profileStubId) throws Exception { @@ -2926,7 +2999,7 @@ private NetworkModificationNode createNetworkModificationNode(UUID studyUuid, UU } @Test - void testCreateModificationWithErrors() throws Exception { + void testCreateModificationWithErrors(final MockWebServer server) throws Exception { StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); UUID firstRootNetworkUuid = studyTestUtils.getOneRootNetworkUuid(studyNameUserIdUuid); @@ -2986,6 +3059,9 @@ void testCreateModificationWithErrors() throws Exception { checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); wireMockUtils.verifyNetworkModificationPost(stubId, modificationBodyJson); + + Set requests = TestUtils.getRequestsWithBodyDone(4, server); + assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); } private void checkElementUpdatedMessageSent(UUID elementUuid, String userId) { diff --git a/src/test/java/org/gridsuite/study/server/StudyTest.java b/src/test/java/org/gridsuite/study/server/StudyTest.java index 9a2c37a57..58e0ccb0b 100644 --- a/src/test/java/org/gridsuite/study/server/StudyTest.java +++ b/src/test/java/org/gridsuite/study/server/StudyTest.java @@ -2153,6 +2153,9 @@ void testCutAndPasteNode(final MockWebServer mockWebServer) throws Exception { && nodeEntity.getParentNode().getIdNode().equals(rootNode.getId())) .map(NodeEntity::getIdNode) .collect(Collectors.toList())); + + Set request = TestUtils.getRequestsDone(7, mockWebServer); + assertTrue(request.stream().allMatch(r -> r.matches("/v1/reports"))); } @Test @@ -2223,6 +2226,9 @@ void testCutAndPasteNodeWithModification(final MockWebServer server) throws Exce cutAndPasteNode(study1Uuid, notEmptyNode, node1.getId(), InsertMode.BEFORE, 1, userId); + Set request = TestUtils.getRequestsDone(2, server); + assertTrue(request.stream().allMatch(r -> r.matches("/v1/reports"))); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(notEmptyNode.getId(), rootNetworkUuid).getGlobalBuildStatus()); assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(node1.getId(), rootNetworkUuid).getGlobalBuildStatus()); assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(notEmptyNodeChild.getId(), rootNetworkUuid).getGlobalBuildStatus()); @@ -2310,6 +2316,9 @@ void testCutAndPasteSubtree(final MockWebServer server) throws Exception { checkSubtreeMovedMessageSent(study1Uuid, emptyNode.getId(), node1.getId()); checkElementUpdatedMessageSent(study1Uuid, userId); + var request = TestUtils.getRequestsDone(1, server); + assertTrue(request.stream().allMatch(r -> r.matches("/v1/reports"))); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(node1.getId(), rootNetworkUuid).getGlobalBuildStatus()); assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(emptyNode.getId(), rootNetworkUuid).getGlobalBuildStatus()); assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(emptyNodeChild.getId(), rootNetworkUuid).getGlobalBuildStatus()); @@ -2482,6 +2491,8 @@ void testDuplicateSubtree(final MockWebServer server) throws Exception { // Invalidation node 3 assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(node3.getId(), firstRootNetworkUuid).getGlobalBuildStatus()); + Set requests = TestUtils.getRequestsWithBodyDone(1, server); + assertEquals(1, requests.stream().filter(r -> r.getPath().matches("/v1/reports")).count()); // add modification on node "node2" String createLoadAttributes = "{\"type\":\"" + ModificationType.LOAD_CREATION + "\",\"loadId\":\"loadId1\",\"loadName\":\"loadName1\",\"loadType\":\"UNDEFINED\",\"activePower\":\"100.0\",\"reactivePower\":\"50.0\",\"voltageLevelId\":\"idVL1\",\"busId\":\"idBus1\"}";