From 61d2ea785a253fa1fa20ce8560814bf622de1593 Mon Sep 17 00:00:00 2001 From: Ayoub LABIDI Date: Sun, 17 May 2026 18:08:06 +0200 Subject: [PATCH] Handle async network modification application results Signed-off-by: Ayoub LABIDI --- .../server/controller/StudyController.java | 6 +- .../modification/ModificationReceiver.java | 20 ++ .../study/server/service/ConsumerService.java | 35 ++++ .../service/NetworkModificationService.java | 60 ++++-- .../server/service/RebuildNodeService.java | 6 +- .../study/server/service/StudyService.java | 198 +++++++++--------- src/main/resources/config/application.yaml | 7 + .../study/server/NetworkModificationTest.java | 150 ++++++++----- .../study/server/VoltageInitTest.java | 30 +-- .../gridsuite/study/server/WorkflowTest.java | 32 +++ .../ModificationToExcludeTest.java | 27 +-- .../studycontroller/NodeControllerTest.java | 25 ++- .../server/studycontroller/StudyTest.java | 7 +- .../study/server/utils/TestUtils.java | 50 +++++ 14 files changed, 435 insertions(+), 218 deletions(-) create mode 100644 src/main/java/org/gridsuite/study/server/dto/modification/ModificationReceiver.java diff --git a/src/main/java/org/gridsuite/study/server/controller/StudyController.java b/src/main/java/org/gridsuite/study/server/controller/StudyController.java index e1fdaa6b45..335a3d33a3 100644 --- a/src/main/java/org/gridsuite/study/server/controller/StudyController.java +++ b/src/main/java/org/gridsuite/study/server/controller/StudyController.java @@ -713,8 +713,9 @@ private void handleInsertCompositeNetworkModifications(UUID targetStudyUuid, UUI studyService.invalidateNodeTreeWithLF(targetStudyUuid, targetNodeUuid); try { studyService.insertCompositeNetworkModifications(targetStudyUuid, targetNodeUuid, modificationsToCopy, userId, action); - } finally { + } catch (Exception e) { studyService.unblockNodeTree(targetStudyUuid, targetNodeUuid); + throw e; } } @@ -723,8 +724,9 @@ private void handleDuplicateNetworkModifications(UUID targetStudyUuid, UUID targ studyService.invalidateNodeTreeWithLF(targetStudyUuid, targetNodeUuid); try { studyService.duplicateNetworkModifications(targetStudyUuid, targetNodeUuid, originNodeUuid, modificationsToCopyUuidList, userId); - } finally { + } catch (Exception e) { studyService.unblockNodeTree(targetStudyUuid, targetNodeUuid); + throw e; } } diff --git a/src/main/java/org/gridsuite/study/server/dto/modification/ModificationReceiver.java b/src/main/java/org/gridsuite/study/server/dto/modification/ModificationReceiver.java new file mode 100644 index 0000000000..9d94dc3e3a --- /dev/null +++ b/src/main/java/org/gridsuite/study/server/dto/modification/ModificationReceiver.java @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.study.server.dto.modification; + +import java.util.List; +import java.util.UUID; + +/** + * @author Ayoub LABIDI + */ +public record ModificationReceiver( + UUID studyUuid, + UUID nodeUuid, + UUID originNodeUuid, + List rootNetworkUuids +) { } diff --git a/src/main/java/org/gridsuite/study/server/service/ConsumerService.java b/src/main/java/org/gridsuite/study/server/service/ConsumerService.java index 8091b8aeab..e4cf6e3da0 100644 --- a/src/main/java/org/gridsuite/study/server/service/ConsumerService.java +++ b/src/main/java/org/gridsuite/study/server/service/ConsumerService.java @@ -15,7 +15,9 @@ import org.gridsuite.study.server.dto.*; import org.gridsuite.study.server.dto.caseimport.CaseImportAction; import org.gridsuite.study.server.dto.caseimport.CaseImportReceiver; +import org.gridsuite.study.server.dto.modification.ModificationReceiver; import org.gridsuite.study.server.dto.modification.NetworkModificationResult; +import org.gridsuite.study.server.dto.modification.NetworkModificationsResult; import org.gridsuite.study.server.dto.networkexport.ExportNetworkStatus; import org.gridsuite.study.server.dto.networkexport.NetworkExportReceiver; import org.gridsuite.study.server.dto.networkexport.NodeExportInfos; @@ -213,6 +215,39 @@ private void handleBuildCanceledOrFailedWorkflow(UUID studyUuid, UUID nodeUuid, } } + @Bean + public Consumer> consumeApplicationResult() { + return message -> { + String receiver = message.getHeaders().get(HEADER_RECEIVER, String.class); + if (receiver != null) { + try { + ModificationReceiver receiverObj = objectMapper.readValue( + URLDecoder.decode(receiver, StandardCharsets.UTF_8), ModificationReceiver.class); + studyService.handleApplicationResult(receiverObj, message.getPayload()); + } catch (Exception e) { + LOGGER.error(e.toString()); + } + } + }; + } + + @Bean + public Consumer> consumeApplicationFailed() { + return message -> { + String receiver = message.getHeaders().get(HEADER_RECEIVER, String.class); + if (receiver != null) { + try { + ModificationReceiver receiverObj = objectMapper.readValue( + URLDecoder.decode(receiver, StandardCharsets.UTF_8), ModificationReceiver.class); + LOGGER.warn("Modification application failed for node '{}'", receiverObj.nodeUuid()); + studyService.handleApplicationFailed(receiverObj); + } catch (Exception e) { + LOGGER.error(e.toString()); + } + } + }; + } + @Bean public Consumer> consumeCaseImportSucceeded() { return message -> { diff --git a/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java b/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java index ddb37da6fa..255fc65e1c 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java @@ -14,8 +14,8 @@ import org.gridsuite.study.server.dto.BuildInfos; import org.gridsuite.study.server.dto.NodeReceiver; import org.gridsuite.study.server.dto.modification.ModificationApplicationContext; +import org.gridsuite.study.server.dto.modification.ModificationReceiver; import org.gridsuite.study.server.dto.modification.NetworkModificationMetadata; -import org.gridsuite.study.server.dto.modification.NetworkModificationsResult; import org.gridsuite.study.server.dto.workflow.AbstractWorkflowInfos; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; @@ -134,13 +134,16 @@ public void deleteModifications(UUID groupUuid, List modificationsUuids) { restTemplate.delete(path); } - public NetworkModificationsResult createModification(UUID groupUuid, - Pair> modificationContextInfos) { + public List createModification(UUID groupUuid, ModificationReceiver receiver, + Pair> modificationContextInfos) { Objects.requireNonNull(modificationContextInfos); var uriComponentsBuilder = UriComponentsBuilder .fromUriString(getNetworkModificationServerURI(false) + NETWORK_MODIFICATIONS_PATH) .queryParam(GROUP_UUID, groupUuid); + if (receiver != null) { + uriComponentsBuilder.queryParam(QUERY_PARAM_RECEIVER, buildModificationReceiver(receiver)); + } var path = uriComponentsBuilder .buildAndExpand() @@ -150,7 +153,7 @@ public NetworkModificationsResult createModification(UUID groupUuid, headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity httpEntity = new HttpEntity<>(getModificationContextJsonString(objectMapper, modificationContextInfos), headers); - return restTemplate.exchange(path, HttpMethod.POST, httpEntity, NetworkModificationsResult.class).getBody(); + return restTemplate.exchange(path, HttpMethod.POST, httpEntity, new ParameterizedTypeReference>() { }).getBody(); } public void updateModification(String createEquipmentAttributes, UUID modificationUuid) { @@ -257,14 +260,18 @@ public void stopBuild(@NonNull UUID nodeUuid, @NonNull UUID rootNetworkUuid) { restTemplate.put(getNetworkModificationServerURI(false) + path, null); } - public NetworkModificationsResult moveModifications(UUID originGroupUuid, UUID targetGroupUuid, UUID beforeUuid, Pair, List> modificationContextInfos, boolean buildTargetNode) { + public List moveModifications(UUID originGroupUuid, UUID targetGroupUuid, UUID beforeUuid, + ModificationReceiver receiver, + Pair, List> modificationContextInfos) { var path = UriComponentsBuilder.fromPath(GROUP_PATH) .queryParam(QUERY_PARAM_ACTION, ModificationsActionType.MOVE.name()) - .queryParam("originGroupUuid", originGroupUuid) - .queryParam("build", buildTargetNode); + .queryParam("originGroupUuid", originGroupUuid); if (beforeUuid != null) { path.queryParam("before", beforeUuid); } + if (receiver != null) { + path.queryParam(QUERY_PARAM_RECEIVER, buildModificationReceiver(receiver)); + } HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); @@ -274,19 +281,23 @@ public NetworkModificationsResult moveModifications(UUID originGroupUuid, UUID t getNetworkModificationServerURI(false) + path.buildAndExpand(targetGroupUuid).toUriString(), HttpMethod.PUT, httpEntity, - NetworkModificationsResult.class).getBody(); + new ParameterizedTypeReference>() { }).getBody(); } - public NetworkModificationsResult duplicateModifications(UUID groupUuid, - Pair, List> modificationContextInfos) { - return handleModifications(groupUuid, null, ModificationsActionType.COPY, modificationContextInfos); + public List duplicateModifications(UUID groupUuid, ModificationReceiver receiver, + Pair, List> modificationContextInfos) { + return handleModifications(groupUuid, null, ModificationsActionType.COPY, receiver, modificationContextInfos); } - public NetworkModificationsResult insertCompositeModifications(UUID groupUuid, - CompositeModificationsActionType action, - Pair>, List> modificationContextInfos) { + public List insertCompositeModifications(UUID groupUuid, + CompositeModificationsActionType action, + ModificationReceiver receiver, + Pair>, List> modificationContextInfos) { var path = UriComponentsBuilder.fromPath(COMPOSITE_PATH + GROUP_PATH) .queryParam(QUERY_PARAM_ACTION, action.name()); + if (receiver != null) { + path.queryParam(QUERY_PARAM_RECEIVER, buildModificationReceiver(receiver)); + } HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); @@ -296,18 +307,22 @@ public NetworkModificationsResult insertCompositeModifications(UUID groupUuid, getNetworkModificationServerURI(false) + path.buildAndExpand(groupUuid).toUriString(), HttpMethod.PUT, httpEntity, - NetworkModificationsResult.class + new ParameterizedTypeReference>() { } ).getBody(); } - private NetworkModificationsResult handleModifications(UUID groupUuid, UUID originGroupUuid, ModificationsActionType action, - Pair, List> modificationContextInfos) { + private List handleModifications(UUID groupUuid, UUID originGroupUuid, ModificationsActionType action, + ModificationReceiver receiver, + Pair, List> modificationContextInfos) { var path = UriComponentsBuilder.fromPath(GROUP_PATH) .queryParam(QUERY_PARAM_ACTION, action.name()); if (originGroupUuid != null) { path.queryParam("originGroupUuid", originGroupUuid); } + if (receiver != null) { + path.queryParam(QUERY_PARAM_RECEIVER, buildModificationReceiver(receiver)); + } HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); @@ -317,7 +332,7 @@ private NetworkModificationsResult handleModifications(UUID groupUuid, UUID orig getNetworkModificationServerURI(false) + path.buildAndExpand(groupUuid).toUriString(), HttpMethod.PUT, httpEntity, - NetworkModificationsResult.class + new ParameterizedTypeReference>() { } ).getBody(); } @@ -341,14 +356,19 @@ public Map duplicateModificationsGroup(UUID sourceGroupUuid, UUID gr ).getBody(); } - public NetworkModificationsResult duplicateModificationsFromGroup(UUID groupUuid, UUID originGroupUuid, Pair, List> modificationContextInfos) { - return handleModifications(groupUuid, originGroupUuid, StudyConstants.ModificationsActionType.COPY, modificationContextInfos); + public List duplicateModificationsFromGroup(UUID groupUuid, UUID originGroupUuid, ModificationReceiver receiver, + Pair, List> modificationContextInfos) { + return handleModifications(groupUuid, originGroupUuid, StudyConstants.ModificationsActionType.COPY, receiver, modificationContextInfos); } private String buildReceiver(UUID nodeUuid, UUID rootNetworkUuid) { return URLEncoder.encode(toJson(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } + private String buildModificationReceiver(ModificationReceiver receiver) { + return URLEncoder.encode(toJson(receiver), StandardCharsets.UTF_8); + } + private String toJson(Object object) { String json; try { diff --git a/src/main/java/org/gridsuite/study/server/service/RebuildNodeService.java b/src/main/java/org/gridsuite/study/server/service/RebuildNodeService.java index 66f141fa12..130ceed044 100644 --- a/src/main/java/org/gridsuite/study/server/service/RebuildNodeService.java +++ b/src/main/java/org/gridsuite/study/server/service/RebuildNodeService.java @@ -36,8 +36,9 @@ private void handleCreateNetworkModification(UUID studyUuid, UUID nodeUuid, Stri studyService.invalidateNodeTreeWithLF(studyUuid, nodeUuid); try { studyService.createNetworkModification(studyUuid, nodeUuid, modificationAttributes, userId); - } finally { + } catch (Exception e) { studyService.unblockNodeTree(studyUuid, nodeUuid); + throw e; } } @@ -121,11 +122,12 @@ private void handleMoveNetworkModifications(UUID studyUuid, UUID targetNodeUuid, boolean isTargetInDifferentNodeTree = studyService.invalidateNodeTreeWhenMoveModifications(studyUuid, targetNodeUuid, originNodeUuid); try { studyService.moveNetworkModifications(studyUuid, targetNodeUuid, originNodeUuid, modificationsToCopyUuidList, null, isTargetInDifferentNodeTree, userId); - } finally { + } catch (Exception e) { studyService.unblockNodeTree(studyUuid, originNodeUuid); if (isTargetInDifferentNodeTree) { studyService.unblockNodeTree(studyUuid, targetNodeUuid); } + throw e; } } 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 7f10021924..bd9b583af3 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -74,7 +74,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -1731,28 +1730,13 @@ public void createNetworkModification(UUID studyUuid, UUID nodeUuid, String crea notificationService.emitStartModificationEquipmentNotification(studyUuid, nodeUuid, childrenUuids, NotificationService.MODIFICATIONS_CREATING_IN_PROGRESS); try { UUID groupUuid = networkModificationTreeService.getModificationGroupUuid(nodeUuid); - List studyRootNetworkEntities = getStudyRootNetworks(studyUuid); - - List modificationApplicationContexts = studyRootNetworkEntities.stream() - .map(rootNetworkEntity -> rootNetworkNodeInfoService.getNetworkModificationApplicationContext(rootNetworkEntity.getId(), nodeUuid, rootNetworkEntity.getNetworkUuid())) - .toList(); - - NetworkModificationsResult networkModificationResults = networkModificationService.createModification(groupUuid, Pair.of(createModificationAttributes, modificationApplicationContexts)); - - if (networkModificationResults != null && networkModificationResults.modificationResults() != null) { - int index = 0; - // for each NetworkModificationResult, send an impact notification - studyRootNetworkEntities are ordered in the same way as networkModificationResults - for (Optional modificationResultOpt : networkModificationResults.modificationResults()) { - if (modificationResultOpt.isPresent() && studyRootNetworkEntities.get(index) != null) { - emitNetworkModificationImpacts(studyUuid, nodeUuid, studyRootNetworkEntities.get(index).getId(), modificationResultOpt.get()); - } - index++; - } - } - } finally { + ModificationApplicationRequest appRequest = buildModificationApplicationRequest(studyUuid, nodeUuid); + networkModificationService.createModification(groupUuid, appRequest.receiver(), Pair.of(createModificationAttributes, appRequest.contexts())); + notificationService.emitElementUpdated(studyUuid, userId); + } catch (Exception e) { notificationService.emitEndModificationEquipmentNotification(studyUuid, nodeUuid, childrenUuids); + throw e; } - notificationService.emitElementUpdated(studyUuid, userId); } @Transactional @@ -2379,24 +2363,33 @@ public void moveNetworkModifications( UUID originGroupUuid = networkModificationTreeService.getModificationGroupUuid(originNodeUuid); UUID targetGroupUuid = networkModificationTreeService.getModificationGroupUuid(targetNodeUuid); - List modificationApplicationContexts = studyRootNetworkEntities.stream() - .map(rootNetworkEntity -> rootNetworkNodeInfoService.getNetworkModificationApplicationContext(rootNetworkEntity.getId(), targetNodeUuid, rootNetworkEntity.getNetworkUuid())) - .toList(); - - NetworkModificationsResult networkModificationsResult = networkModificationService.moveModifications(originGroupUuid, targetGroupUuid, beforeUuid, Pair.of(modificationUuidList, modificationApplicationContexts), isTargetInDifferentNodeTree); - rootNetworkNodeInfoService.moveModificationsToExclude(originNodeUuid, targetNodeUuid, networkModificationsResult.modificationUuids()); - - // Target node - if (isTargetInDifferentNodeTree) { - emitNetworkModificationImpactsForAllRootNetworks(networkModificationsResult.modificationResults(), studyEntity, targetNodeUuid); + List modificationApplicationContexts = isTargetInDifferentNodeTree + ? studyRootNetworkEntities.stream() + .map(rootNetworkEntity -> rootNetworkNodeInfoService.getNetworkModificationApplicationContext(rootNetworkEntity.getId(), targetNodeUuid, rootNetworkEntity.getNetworkUuid())) + .toList() + : List.of(); + + UUID originNodeForReceiver = isTargetDifferentNode ? originNodeUuid : null; + ModificationReceiver receiver = isTargetInDifferentNodeTree + ? new ModificationReceiver(studyUuid, targetNodeUuid, originNodeForReceiver, + studyRootNetworkEntities.stream().map(RootNetworkEntity::getId).toList()) + : null; + + List savedUuids = networkModificationService.moveModifications(originGroupUuid, targetGroupUuid, beforeUuid, receiver, Pair.of(modificationUuidList, modificationApplicationContexts)); + rootNetworkNodeInfoService.moveModificationsToExclude(originNodeUuid, targetNodeUuid, savedUuids); + notificationService.emitElementUpdated(studyUuid, userId); + + if (receiver == null) { + // same group reorder or same subtree move: no async apply + notificationService.emitEndModificationEquipmentNotification(studyUuid, targetNodeUuid, childrenUuids); } - } finally { + } catch (Exception e) { notificationService.emitEndModificationEquipmentNotification(studyUuid, targetNodeUuid, childrenUuids); if (isTargetDifferentNode) { notificationService.emitEndModificationEquipmentNotification(studyUuid, originNodeUuid, originNodeChildrenUuids); } + throw e; } - notificationService.emitElementUpdated(studyUuid, userId); } public void moveSubModification( @@ -2421,18 +2414,52 @@ public void moveSubModification( notificationService.emitElementUpdated(studyUuid, userId); } - private void emitNetworkModificationImpactsForAllRootNetworks(List> modificationResults, StudyEntity studyEntity, UUID impactedNode) { - int index = 0; - List rootNetworkEntities = studyEntity.getRootNetworks(); - // for each NetworkModificationResult, send an impact notification - studyRootNetworkEntities are ordered in the same way as networkModificationResults - for (Optional modificationResultOpt : modificationResults) { - if (modificationResultOpt.isPresent() && rootNetworkEntities.get(index) != null) { - emitNetworkModificationImpacts(studyEntity.getId(), impactedNode, rootNetworkEntities.get(index).getId(), modificationResultOpt.get()); + private record ModificationApplicationRequest( + List contexts, + ModificationReceiver receiver) { } + + private ModificationApplicationRequest buildModificationApplicationRequest(UUID studyUuid, UUID nodeUuid) { + List rootNetworks = getStudyRootNetworks(studyUuid); + List contexts = rootNetworks.stream() + .map(rn -> rootNetworkNodeInfoService.getNetworkModificationApplicationContext(rn.getId(), nodeUuid, rn.getNetworkUuid())) + .toList(); + ModificationReceiver receiver = new ModificationReceiver(studyUuid, nodeUuid, null, + rootNetworks.stream().map(RootNetworkEntity::getId).toList()); + return new ModificationApplicationRequest(contexts, receiver); + } + + private void emitApplicationEnd(ModificationReceiver receiver) { + UUID nodeUuid = receiver.nodeUuid(); + try { + List childrenUuids = networkModificationTreeService.getChildrenUuids(nodeUuid); + notificationService.emitEndModificationEquipmentNotification(receiver.studyUuid(), nodeUuid, childrenUuids); + if (receiver.originNodeUuid() != null) { + List originChildrenUuids = networkModificationTreeService.getChildrenUuids(receiver.originNodeUuid()); + notificationService.emitEndModificationEquipmentNotification(receiver.studyUuid(), receiver.originNodeUuid(), originChildrenUuids); } - index++; + } finally { + receiver.rootNetworkUuids().forEach(rn -> networkModificationTreeService.unblockNodeTree(rn, nodeUuid)); } } + public void handleApplicationResult(ModificationReceiver receiver, NetworkModificationsResult result) { + try { + List> modificationResults = result.modificationResults(); + List rootNetworkUuids = receiver.rootNetworkUuids(); + for (int i = 0; i < modificationResults.size(); i++) { + final int index = i; + modificationResults.get(i).ifPresent( + r -> emitNetworkModificationImpacts(receiver.studyUuid(), receiver.nodeUuid(), rootNetworkUuids.get(index), r)); + } + } finally { + emitApplicationEnd(receiver); + } + } + + public void handleApplicationFailed(ModificationReceiver receiver) { + emitApplicationEnd(receiver); + } + @Transactional public void duplicateNetworkModifications( UUID targetStudyUuid, @@ -2440,13 +2467,19 @@ public void duplicateNetworkModifications( UUID originNodeUuid, List modificationsUuids, String userId) { - duplicateModificationsOrInsertComposites(targetStudyUuid, targetNodeUuid, - (groupUuid, modificationApplicationContexts) -> { - NetworkModificationsResult networkModificationResults = networkModificationService.duplicateModifications(groupUuid, Pair.of(modificationsUuids, modificationApplicationContexts)); - copyModificationsToExclude(originNodeUuid, targetNodeUuid, modificationsUuids, networkModificationResults); - return networkModificationResults; - }, - userId); + List childrenUuids = networkModificationTreeService.getChildrenUuids(targetNodeUuid); + notificationService.emitStartModificationEquipmentNotification(targetStudyUuid, targetNodeUuid, childrenUuids, NotificationService.MODIFICATIONS_UPDATING_IN_PROGRESS); + try { + checkStudyContainsNode(targetStudyUuid, targetNodeUuid); + UUID groupUuid = networkModificationTreeService.getModificationGroupUuid(targetNodeUuid); + ModificationApplicationRequest appRequest = buildModificationApplicationRequest(targetStudyUuid, targetNodeUuid); + List savedUuids = networkModificationService.duplicateModifications(groupUuid, appRequest.receiver(), Pair.of(modificationsUuids, appRequest.contexts())); + copyModificationsToExclude(originNodeUuid, targetNodeUuid, modificationsUuids, savedUuids); + notificationService.emitElementUpdated(targetStudyUuid, userId); + } catch (Exception e) { + notificationService.emitEndModificationEquipmentNotification(targetStudyUuid, targetNodeUuid, childrenUuids); + throw e; + } } @Transactional @@ -2456,65 +2489,33 @@ public void insertCompositeNetworkModifications( List> compositesInfos, String userId, StudyConstants.CompositeModificationsActionType action) { - duplicateModificationsOrInsertComposites(targetStudyUuid, targetNodeUuid, - (groupUuid, modificationApplicationContexts) -> - networkModificationService.insertCompositeModifications(groupUuid, action, Pair.of(compositesInfos, modificationApplicationContexts)), - userId); - } - - private void duplicateModificationsOrInsertComposites( - UUID targetStudyUuid, - UUID targetNodeUuid, - BiFunction, NetworkModificationsResult> handleModifications, - String userId) { List childrenUuids = networkModificationTreeService.getChildrenUuids(targetNodeUuid); notificationService.emitStartModificationEquipmentNotification(targetStudyUuid, targetNodeUuid, childrenUuids, NotificationService.MODIFICATIONS_UPDATING_IN_PROGRESS); try { checkStudyContainsNode(targetStudyUuid, targetNodeUuid); - - List studyRootNetworkEntities = getStudyRootNetworks(targetStudyUuid); UUID groupUuid = networkModificationTreeService.getModificationGroupUuid(targetNodeUuid); - - List modificationApplicationContexts = studyRootNetworkEntities.stream() - .map(rootNetworkEntity -> rootNetworkNodeInfoService.getNetworkModificationApplicationContext(rootNetworkEntity.getId(), targetNodeUuid, rootNetworkEntity.getNetworkUuid())) - .toList(); - - NetworkModificationsResult networkModificationResults = handleModifications.apply(groupUuid, modificationApplicationContexts); - - sendImpactNotifications(targetStudyUuid, targetNodeUuid, networkModificationResults, studyRootNetworkEntities); - } finally { + ModificationApplicationRequest appRequest = buildModificationApplicationRequest(targetStudyUuid, targetNodeUuid); + networkModificationService.insertCompositeModifications(groupUuid, action, appRequest.receiver(), Pair.of(compositesInfos, appRequest.contexts())); + notificationService.emitElementUpdated(targetStudyUuid, userId); + } catch (Exception e) { notificationService.emitEndModificationEquipmentNotification(targetStudyUuid, targetNodeUuid, childrenUuids); - } - notificationService.emitElementUpdated(targetStudyUuid, userId); - } - - private void sendImpactNotifications(UUID targetStudyUuid, UUID targetNodeUuid, NetworkModificationsResult networkModificationResults, List studyRootNetworkEntities) { - if (networkModificationResults != null) { - int index = 0; - // for each NetworkModificationResult, send an impact notification - studyRootNetworkEntities are ordered in the same way as networkModificationResults - for (Optional modificationResultOpt : networkModificationResults.modificationResults()) { - if (modificationResultOpt.isPresent() && studyRootNetworkEntities.get(index) != null) { - emitNetworkModificationImpacts(targetStudyUuid, targetNodeUuid, studyRootNetworkEntities.get(index).getId(), modificationResultOpt.get()); - } - index++; - } + throw e; } } private void copyModificationsToExclude(UUID originNodeUuid, UUID targetNodeUuid, List modificationsUuids, - NetworkModificationsResult networkModificationResults) { + List savedUuids) { Map mappingModificationsUuids = new HashMap<>(); - List copyUuids = networkModificationResults.modificationUuids(); // Map root-level modifications for (int i = 0; i < modificationsUuids.size(); i++) { - mappingModificationsUuids.put(modificationsUuids.get(i), copyUuids.get(i)); + mappingModificationsUuids.put(modificationsUuids.get(i), savedUuids.get(i)); } List originalChildren = networkModificationService.findAllChildrenUuids(modificationsUuids); - List copyChildren = networkModificationService.findAllChildrenUuids(copyUuids); + List copyChildren = networkModificationService.findAllChildrenUuids(savedUuids); for (int i = 0; i < originalChildren.size(); i++) { mappingModificationsUuids.put(originalChildren.get(i), copyChildren.get(i)); } @@ -3366,27 +3367,28 @@ public void insertVoltageInitModifications(UUID studyUuid, UUID nodeUuid, UUID r } }); // duplicate the modification created by voltageInit server into the current node - NetworkModificationsResult networkModificationResults = networkModificationService.duplicateModificationsFromGroup(networkModificationTreeService.getModificationGroupUuid(nodeUuid), voltageInitModificationsGroupUuid, Pair.of(List.of(), modificationApplicationContexts)); + List savedUuids = networkModificationService.duplicateModificationsFromGroup( + networkModificationTreeService.getModificationGroupUuid(nodeUuid), voltageInitModificationsGroupUuid, + new ModificationReceiver(studyUuid, nodeUuid, null, List.of(rootNetworkUuid)), + Pair.of(List.of(), modificationApplicationContexts)); - // We expect a single voltageInit modification in the result list - if (networkModificationResults != null && networkModificationResults.modificationUuids().size() == 1) { + // We expect a single voltageInit modification, deactivate it for all other root networks synchronously + if (savedUuids.size() == 1) { for (UUID otherRootNetwork : rootNetworkToDeactivateUuids) { - rootNetworkNodeInfoService.updateModificationsToExclude(nodeUuid, otherRootNetwork, Set.of(networkModificationResults.modificationUuids().getFirst()), false); + rootNetworkNodeInfoService.updateModificationsToExclude(nodeUuid, otherRootNetwork, Set.of(savedUuids.getFirst()), false); } - // The modification was applied only on rootNetworkUuid, so the single result must be attributed to it - networkModificationResults.modificationResults().getFirst() - .ifPresent(result -> emitNetworkModificationImpacts(studyUuid, nodeUuid, rootNetworkUuid, result)); } voltageInitService.resetModificationsGroupUuid(resultUuid); // send notification voltage init result has changed notificationService.emitStudyChanged(studyUuid, nodeUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_VOLTAGE_INIT_RESULT); - } finally { - networkModificationTreeService.unblockNodeTree(rootNetworkUuid, nodeUuid); + notificationService.emitElementUpdated(studyUuid, userId); + } catch (Exception e) { notificationService.emitEndModificationEquipmentNotification(studyUuid, nodeUuid, childrenUuids); + networkModificationTreeService.unblockNodeTree(rootNetworkUuid, nodeUuid); + throw e; } - notificationService.emitElementUpdated(studyUuid, userId); } @Transactional diff --git a/src/main/resources/config/application.yaml b/src/main/resources/config/application.yaml index c1cd9ad0ac..f3ce7532d3 100644 --- a/src/main/resources/config/application.yaml +++ b/src/main/resources/config/application.yaml @@ -10,6 +10,7 @@ spring: consumeDsaDebug;consumeDsaResult;consumeDsaStopped;consumeDsaFailed;consumeDsaCancelFailed;\ consumeDmcDebug;consumeDmcResult;consumeDmcStopped;consumeDmcFailed;consumeDmcCancelFailed;\ consumeBuildResult;consumeBuildStopped;consumeBuildFailed;\ + consumeApplicationResult;consumeApplicationFailed;\ consumeCaseImportSucceeded;consumeCaseImportFailed;\ consumeSensitivityAnalysisResult;consumeSensitivityAnalysisStopped;consumeSensitivityAnalysisFailed;consumeSensitivityAnalysisCancelFailed;\ consumeShortCircuitAnalysisDebug;consumeShortCircuitAnalysisResult;consumeShortCircuitAnalysisStopped;consumeShortCircuitAnalysisFailed;consumeShortCircuitAnalysisCancelFailed;\ @@ -90,6 +91,12 @@ spring: consumeBuildFailed-in-0: destination: ${powsybl-ws.rabbitmq.destination.prefix:}build.run.dlx group: dlq + consumeApplicationResult-in-0: + destination: ${powsybl-ws.rabbitmq.destination.prefix:}modification.result + group: studyModificationResultGroup + consumeApplicationFailed-in-0: + destination: ${powsybl-ws.rabbitmq.destination.prefix:}modification.run.dlx + group: dlq consumeLoadFlowResult-in-0: destination: ${powsybl-ws.rabbitmq.destination.prefix:}loadflow.result group: studyLoadFlowResultGroup diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java index e1c9110553..8f873d0c22 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java @@ -504,7 +504,7 @@ void testLocalBuildValue() throws Exception { Map createLoadInfos = Map.of("type", ModificationType.LOAD_CREATION, "equipmentId", "loadId"); String jsonCreateLoadInfos = mapper.writeValueAsString(createLoadInfos); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); // Mark the node status as built RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoRepository.findByNodeInfoIdAndRootNetworkId(modificationNode.getId(), studyTestUtils.getOneRootNetworkUuid(studyNameUserIdUuid)).orElseThrow(() -> new StudyException(NOT_FOUND, "Root network not found")); @@ -518,12 +518,12 @@ void testLocalBuildValue() throws Exception { // Create network modification on BUILT modification node Optional networkModificationResult = createModificationResultWithElementImpact(SimpleImpactType.CREATION, IdentifiableType.LOAD, "loadId", Set.of("s1")); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); NetworkImpactsInfos expectedPayload = NetworkImpactsInfos.builder().impactedSubstationsIds(ImmutableSet.of("s1")).deletedEquipments(ImmutableSet.of()).build(); // Build first node with errors networkModificationResult.get().setApplicationStatus(NetworkModificationResult.ApplicationStatus.WITH_ERRORS); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(networkModificationResult)))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); UUID deleteModificationIndexStub = wireMockStubs.stubNetworkModificationDeleteIndex(); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(jsonCreateLoadInfos).contentType(MediaType.APPLICATION_JSON) @@ -533,6 +533,7 @@ void testLocalBuildValue() throws Exception { checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid, new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(networkModificationResult))); checkNodesBuildStatusUpdatedMessageReceived(studyNameUserIdUuid, List.of(modificationNodeUuid)); checkEquipmentMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, expectedPayload); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); @@ -542,7 +543,7 @@ void testLocalBuildValue() throws Exception { // Build second node is OK networkModificationResult.get().setApplicationStatus(NetworkModificationResult.ApplicationStatus.ALL_OK); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(networkModificationResult)))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode2Uuid) .content(jsonCreateLoadInfos).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) @@ -551,6 +552,7 @@ void testLocalBuildValue() throws Exception { checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode2Uuid, new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(networkModificationResult))); checkNodesBuildStatusUpdatedMessageReceived(studyNameUserIdUuid, List.of(modificationNode2Uuid)); checkEquipmentMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid, expectedPayload); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); @@ -690,13 +692,14 @@ void testNetworkModificationSwitch() throws Exception { .andExpect(status().isForbidden()); // update switch on first modification node - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode1Uuid) .content(bodyJson).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(bodyJson, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -713,6 +716,7 @@ void testNetworkModificationSwitch() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode2Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(bodyJson, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode2Uuid, NETWORK_UUID))); @@ -728,7 +732,7 @@ void testNetworkModificationSwitch() throws Exception { Optional networkModificationResult = createModificationResultWithElementImpact(SimpleImpactType.MODIFICATION, IdentifiableType.SWITCH, "switchId", Set.of("s1", "s2", "s3")); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(networkModificationResult)))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); UUID deleteModificationIndexStub = wireMockStubs.stubNetworkModificationDeleteIndex(); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode1Uuid) .content(bodyJson).contentType(MediaType.APPLICATION_JSON) @@ -741,6 +745,7 @@ void testNetworkModificationSwitch() throws Exception { checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid, new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(networkModificationResult))); checkEquipmentMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, expectedPayload); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); modificationBody = Pair.of(bodyJson, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -782,13 +787,14 @@ void testNetworkModificationEquipment() throws Exception { .andExpect(status().isForbidden()); //update equipment - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(bodyJson).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); Pair> modificationBody = Pair.of(bodyJson, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid, NETWORK_UUID))); wireMockStubs.verifyNetworkModificationPostWithVariant(getModificationContextJsonString(mapper, modificationBody)); @@ -804,6 +810,7 @@ void testNetworkModificationEquipment() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid2, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid2); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid2); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid2); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(bodyJson, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid2, NETWORK_UUID))); @@ -847,13 +854,14 @@ void testCreateGenerator() throws Exception { .andExpect(status().isForbidden()); // create generator on first modification node - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode1Uuid) .content(bodyJsonCreate).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(bodyJsonCreate, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -866,6 +874,7 @@ void testCreateGenerator() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode2Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(bodyJsonCreate, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode2Uuid, NETWORK_UUID))); @@ -923,13 +932,14 @@ void testCreateShuntsCompensator() throws Exception { .andExpect(status().isForbidden()); // create shuntCompensator on modification node child of root node - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode1Uuid) .content(createShuntCompensatorAttributes).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(createShuntCompensatorAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -987,13 +997,14 @@ void testCreateLine() throws Exception { .andExpect(status().isForbidden()); // create line on first modification node - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode1Uuid) .content(createLineAttributes).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(createLineAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -1006,6 +1017,7 @@ void testCreateLine() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode2Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); modificationBody = Pair.of(createLineAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode2Uuid, NETWORK_UUID))); wireMockStubs.verifyNetworkModificationPostWithVariant(getModificationContextJsonString(mapper, modificationBody)); @@ -1070,13 +1082,14 @@ void testCreateTwoWindingsTransformer() throws Exception { .andExpect(status().isForbidden()); // create 2WT on first modification node - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode1Uuid) .content(createTwoWindingsTransformerAttributes).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(createTwoWindingsTransformerAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -1089,6 +1102,7 @@ void testCreateTwoWindingsTransformer() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode2Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(createTwoWindingsTransformerAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode2Uuid, NETWORK_UUID))); @@ -1186,7 +1200,7 @@ void testUpdateLines() throws Exception { String bodyJsonCreate1 = mapper.writeValueAsString(bodyLineInfos); // change line status on root node (not allowed) - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, rootNodeUuid) .content(bodyJsonCreate1).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) @@ -1199,6 +1213,7 @@ void testUpdateLines() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(bodyJsonCreate1, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -1221,13 +1236,14 @@ void testUpdateLines() throws Exception { bodyLineInfos.put("equipmentId", "line23"); bodyLineInfos.put("action", "trip"); String bodyJsonCreate3 = mapper.writeValueAsString(bodyLineInfos); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode1Uuid) .content(bodyJsonCreate3).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(bodyJsonCreate3, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -1250,13 +1266,14 @@ void testUpdateLines() throws Exception { bodyLineInfos.put("equipmentId", "line13"); bodyLineInfos.put("action", "energiseEndOne"); String bodyJsonCreate5 = mapper.writeValueAsString(bodyLineInfos); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode1Uuid) .content(bodyJsonCreate5).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(bodyJsonCreate5, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -1279,13 +1296,14 @@ void testUpdateLines() throws Exception { bodyLineInfos.put("equipmentId", "line13"); bodyLineInfos.put("action", "switchOn"); String bodyJsonCreate7 = mapper.writeValueAsString(bodyLineInfos); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode1Uuid) .content(bodyJsonCreate7).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(bodyJsonCreate7, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -1306,13 +1324,14 @@ void testUpdateLines() throws Exception { // switch on line on second modification node String bodyJsonCreate9 = bodyJsonCreate7; - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode2Uuid) .content(bodyJsonCreate9).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode2Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(bodyJsonCreate9, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode2Uuid, NETWORK_UUID))); @@ -1345,13 +1364,14 @@ void testCreateLoad() throws Exception { .andExpect(status().isForbidden()); // create load on first modification node - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode1Uuid) .content(createLoadAttributes).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(createLoadAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -1364,6 +1384,7 @@ void testCreateLoad() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode2Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(createLoadAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode2Uuid, NETWORK_UUID))); @@ -1418,13 +1439,14 @@ void testModifyLoad() throws Exception { .andExpect(status().isForbidden()); // modify load on first modification node - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(loadModificationAttributes).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(loadModificationAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid, NETWORK_UUID))); @@ -1437,6 +1459,7 @@ void testModifyLoad() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid2, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid2); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid2); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid2); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(loadModificationAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid2, NETWORK_UUID))); @@ -1476,13 +1499,14 @@ void testModifyEquipment() throws Exception { .andExpect(status().isForbidden()); // modify generator on first modification node - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(equipmentModificationAttribute).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(equipmentModificationAttribute, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid, NETWORK_UUID))); @@ -1495,6 +1519,7 @@ void testModifyEquipment() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid2, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid2); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid2); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid2); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(equipmentModificationAttribute, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid2, NETWORK_UUID))); @@ -1537,13 +1562,14 @@ void testCreateSubstation() throws Exception { .andExpect(status().isForbidden()); // create substation on first modification node - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode1Uuid) .content(createSubstationAttributes).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(createSubstationAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -1556,6 +1582,7 @@ void testCreateSubstation() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode2Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(createSubstationAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode2Uuid, NETWORK_UUID))); @@ -1609,13 +1636,14 @@ void testCreateVoltageLevel() throws Exception { .andExpect(status().isForbidden()); // create voltage level - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode1Uuid) .content(createVoltageLevelAttributes).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(createVoltageLevelAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -1628,6 +1656,7 @@ void testCreateVoltageLevel() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode2Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(createVoltageLevelAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode2Uuid, NETWORK_UUID))); @@ -1683,13 +1712,14 @@ void testLineSplitWithVoltageLevel() throws Exception { lineSplitWoVL.setType(ModificationType.LINE_SPLIT_WITH_VOLTAGE_LEVEL); String lineSplitWoVLasJSON = mapper.writeValueAsString(lineSplitWoVL); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(lineSplitWoVLasJSON).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(lineSplitWoVLasJSON, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid, NETWORK_UUID))); @@ -1743,13 +1773,14 @@ void testLineAttachToVoltageLevel() throws Exception { String createLineAttachToVoltageLevelAttributes = "{\"type\":\"" + ModificationType.LINE_ATTACH_TO_VOLTAGE_LEVEL + "\",\"lineToAttachToId\":\"line3\",\"percent\":\"10\",\"mayNewVoltageLevelInfos\":" + createVoltageLevelAttributes + ",\"attachmentLine\":" + createLineAttributes + "}"; - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(createLineAttachToVoltageLevelAttributes).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(createLineAttachToVoltageLevelAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid, NETWORK_UUID))); @@ -1778,13 +1809,14 @@ void testLinesAttachToSplitLines() throws Exception { UUID modificationNodeUuid = modificationNode.getId(); String createLinesAttachToSplitLinesAttributes = "{\"type\":\"" + ModificationType.LINES_ATTACH_TO_SPLIT_LINES + "\",\"lineToAttachTo1Id\":\"line1\",\"lineToAttachTo2Id\":\"line2\",\"attachedLineId\":\"line3\",\"voltageLevelId\":\"vl1\",\"bbsBusId\":\"v1bbs\",\"replacingLine1Id\":\"replacingLine1Id\",\"replacingLine1Name\":\"replacingLine1Name\",\"replacingLine2Id\":\"replacingLine2Id\",\"replacingLine2Name\":\"replacingLine2Name\"}"; - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(createLinesAttachToSplitLinesAttributes).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(createLinesAttachToSplitLinesAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid, NETWORK_UUID))); @@ -1836,13 +1868,14 @@ void testScaling(ModificationType scalingType) throws Exception { NetworkModificationNode modificationNode = createNetworkModificationNode(studyNameUserIdUuid, rootNodeUuid, VARIANT_ID, "node", "userId"); UUID modificationNodeUuid = modificationNode.getId(); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(requestBody).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(requestBody, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid, NETWORK_UUID))); @@ -1892,13 +1925,14 @@ void testDeleteVoltageLevelOnline() throws Exception { UUID modificationNodeUuid = modificationNode.getId(); String createDeleteVoltageLevelOnlineAttributes = "{\"type\":\"" + ModificationType.DELETE_VOLTAGE_LEVEL_ON_LINE + "\",\"lineToAttachTo1Id\":\"line1\",\"lineToAttachTo2Id\":\"line2\",\"replacingLine1Id\":\"replacingLine1Id\",\"replacingLine1Name\":\"replacingLine1Name\"}"; - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(createDeleteVoltageLevelOnlineAttributes).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); Pair> modificationBody = Pair.of(createDeleteVoltageLevelOnlineAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid, NETWORK_UUID))); wireMockStubs.verifyNetworkModificationPostWithVariant(getModificationContextJsonString(mapper, modificationBody)); @@ -1945,13 +1979,14 @@ void testDeleteAttachingline() throws Exception { UUID modificationNodeUuid = modificationNode.getId(); String createDeleteAttachingLineAttributes = "{\"type\":\"" + ModificationType.DELETE_ATTACHING_LINE + "\",\"lineToAttachTo1Id\":\"line1\",\"lineToAttachTo2Id\":\"line2\",\"attachedLineId\":\"line3\",\"replacingLine1Id\":\"replacingLine1Id\",\"replacingLine1Name\":\"replacingLine1Name\"}"; - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(createDeleteAttachingLineAttributes).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); Pair> modificationBody = Pair.of(createDeleteAttachingLineAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid, NETWORK_UUID))); wireMockStubs.verifyNetworkModificationPostWithVariant(getModificationContextJsonString(mapper, modificationBody)); @@ -1993,7 +2028,6 @@ void testReorderModification() throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyNameUserIdUuid = studyEntity.getId(); - UUID firstRootNetworkUuid = studyTestUtils.getOneRootNetworkUuid(studyNameUserIdUuid); UUID rootNodeUuid = getRootNode(studyNameUserIdUuid).getId(); NetworkModificationNode modificationNode = createNetworkModificationNode(studyNameUserIdUuid, rootNodeUuid, UUID.randomUUID(), VARIANT_ID, "node", userId); @@ -2004,7 +2038,7 @@ void testReorderModification() throws Exception { UUID groupStubId = wireMockServer.stubFor(WireMock.any(WireMock.urlPathMatching("/v1/groups/.*")) .withQueryParam("action", WireMock.equalTo("MOVE")) .willReturn(WireMock.ok() - .withBody(mapper.writeValueAsString(new NetworkModificationsResult(Arrays.asList(modification1, modification2), List.of(Optional.empty())))) + .withBody(mapper.writeValueAsString(Arrays.asList(modification1, modification2))) .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))).getId(); // switch the 2 modifications order (modification1 is set at the end, after modification2) @@ -2016,13 +2050,12 @@ void testReorderModification() throws Exception { checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); - Pair, List> expectedBody = Pair.of(Collections.singletonList(modification1), List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid, NETWORK_UUID))); + Pair, List> expectedBody = Pair.of(Collections.singletonList(modification1), List.of()); String expectedBodyStr = mapper.writeValueAsString(expectedBody); String url = "/v1/groups/" + modificationNode.getModificationGroupUuid(); WireMockUtils.verifyPutRequest(wireMockServer, groupStubId, url, true, Map.of( "action", WireMock.equalTo("MOVE"), - "originGroupUuid", WireMock.equalTo(modificationNode.getModificationGroupUuid().toString()), - "build", WireMock.equalTo("false")), + "originGroupUuid", WireMock.equalTo(modificationNode.getModificationGroupUuid().toString())), expectedBodyStr); // switch back the 2 modifications order (modification1 is set before modification2) @@ -2037,7 +2070,6 @@ void testReorderModification() throws Exception { WireMockUtils.verifyPutRequest(wireMockServer, groupStubId, url, true, Map.of( "action", WireMock.equalTo("MOVE"), "originGroupUuid", WireMock.equalTo(modificationNode.getModificationGroupUuid().toString()), - "build", WireMock.equalTo("false"), "before", WireMock.equalTo(modification2.toString())), expectedBodyStr); } @@ -2088,7 +2120,7 @@ void testInsertComposite() throws Exception { wireMockServer.stubFor(WireMock.any(WireMock.urlPathMatching("/v1/network-composite-modifications/groups/.*")) .withQueryParam("action", WireMock.equalTo("INSERT")) .willReturn(WireMock.ok() - .withBody(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID(), UUID.randomUUID()), List.of(Optional.empty())))) + .withBody(mapper.writeValueAsString(List.of(UUID.randomUUID(), UUID.randomUUID()))) .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))).getId(); // insert 2 composite modifications in node1 @@ -2100,6 +2132,7 @@ void testInsertComposite() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyUuid, nodeUuid1, output); checkEquipmentUpdatingMessagesReceived(studyUuid, nodeUuid1); + studyTestUtils.sendApplicationResult(studyUuid, nodeUuid1); checkEquipmentUpdatingFinishedMessagesReceived(studyUuid, nodeUuid1); checkElementUpdatedMessageSent(studyUuid, userId); @@ -2135,7 +2168,7 @@ void testDuplicateModification() throws Exception { wireMockServer.stubFor(WireMock.any(WireMock.urlPathMatching("/v1/groups/.*")) .withQueryParam("action", WireMock.equalTo("COPY")) .willReturn(WireMock.ok() - .withBody(mapper.writeValueAsString(new NetworkModificationsResult(copyUuids, List.of()))) + .withBody(mapper.writeValueAsString(copyUuids)) .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); // uuids is sent as repeated params (?uuids=x&uuids=y) — match on path only, both calls return empty list @@ -2153,6 +2186,7 @@ void testDuplicateModification() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyUuid, nodeUuid1, output); checkEquipmentUpdatingMessagesReceived(studyUuid, nodeUuid1); + studyTestUtils.sendApplicationResult(studyUuid, nodeUuid1); checkEquipmentUpdatingFinishedMessagesReceived(studyUuid, nodeUuid1); checkElementUpdatedMessageSent(studyUuid, userId); @@ -2176,7 +2210,7 @@ void testDuplicateModification() throws Exception { wireMockServer.stubFor(WireMock.any(WireMock.urlPathMatching("/v1/groups/.*")) .withQueryParam("action", WireMock.equalTo("COPY")) .willReturn(WireMock.ok() - .withBody(mapper.writeValueAsString(new NetworkModificationsResult(copyUuids2, List.of(Optional.of(NetworkModificationResult.builder().build()))))) + .withBody(mapper.writeValueAsString(copyUuids2)) .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); mockMvc.perform(put("/v1/studies/{studyUuid}/nodes/{nodeUuid}?originStudyUuid={originStudyUuid}&originNodeUuid={originNodeUuid}&action=COPY", @@ -2190,6 +2224,7 @@ void testDuplicateModification() throws Exception { checkUpdateStatusMessagesReceived(studyUuid, nodeUuid1, output); checkEquipmentUpdatingMessagesReceived(studyUuid, nodeUuid1); checkElementUpdatedMessageSent(studyUuid, userId); + studyTestUtils.sendApplicationResult(studyUuid, nodeUuid1, new NetworkModificationsResult(copyUuids2, List.of(Optional.of(NetworkModificationResult.builder().build())))); checkEquipmentMessagesReceived(studyUuid, List.of(nodeUuid1), expectedPayload); checkEquipmentUpdatingFinishedMessagesReceived(studyUuid, nodeUuid1); @@ -2221,7 +2256,7 @@ void testDuplicateModificationReplicateChildExcludedUuids() throws Exception { wireMockServer.stubFor(WireMock.any(WireMock.urlPathMatching("/v1/groups/.*")) .withQueryParam("action", WireMock.equalTo("COPY")) .willReturn(WireMock.ok() - .withBody(mapper.writeValueAsString(new NetworkModificationsResult(copyUuids, List.of()))) + .withBody(mapper.writeValueAsString(copyUuids)) .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); // First call (originals) returns originalChild; second call (copies) returns copyChild @@ -2250,6 +2285,7 @@ void testDuplicateModificationReplicateChildExcludedUuids() throws Exception { checkUpdateStatusMessagesReceived(studyUuid, nodeUuid1, output); checkEquipmentUpdatingMessagesReceived(studyUuid, nodeUuid1); + studyTestUtils.sendApplicationResult(studyUuid, nodeUuid1); checkEquipmentUpdatingFinishedMessagesReceived(studyUuid, nodeUuid1); checkElementUpdatedMessageSent(studyUuid, userId); @@ -2284,7 +2320,7 @@ void testDuplicateModificationBetweenStudies() throws Exception { wireMockServer.stubFor(WireMock.any(WireMock.urlPathMatching("/v1/groups/.*")) .withQueryParam("action", WireMock.equalTo("COPY")) .willReturn(WireMock.ok() - .withBody(mapper.writeValueAsString(new NetworkModificationsResult(copyUuids, List.of()))) + .withBody(mapper.writeValueAsString(copyUuids)) .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); // uuids is sent as repeated params — match on path only @@ -2302,6 +2338,7 @@ void testDuplicateModificationBetweenStudies() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyEntity1.getId(), node1.getId(), output); checkEquipmentUpdatingMessagesReceived(studyEntity1.getId(), node1.getId()); + studyTestUtils.sendApplicationResult(studyEntity1.getId(), node1.getId()); checkEquipmentUpdatingFinishedMessagesReceived(studyEntity1.getId(), node1.getId()); checkElementUpdatedMessageSent(studyEntity1.getId(), userId); @@ -2372,7 +2409,7 @@ void testCutAndPasteModification() throws Exception { UUID groupStubId = wireMockServer.stubFor(WireMock.any(WireMock.urlPathMatching("/v1/groups/.*")) .withQueryParam("action", WireMock.equalTo("MOVE")) .willReturn(WireMock.ok() - .withBody(mapper.writeValueAsString(new NetworkModificationsResult(Arrays.asList(modification1, modification2), List.of(Optional.empty())))) + .withBody(mapper.writeValueAsString(Arrays.asList(modification1, modification2))) .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))).getId(); // move 2 modifications within node 1 @@ -2386,13 +2423,12 @@ void testCutAndPasteModification() throws Exception { checkEquipmentUpdatingMessagesReceived(studyUuid, nodeUuid1); checkEquipmentUpdatingFinishedMessagesReceived(studyUuid, nodeUuid1); - Pair, List> expectedBody = Pair.of(List.of(modification1, modification2), List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, node1.getId(), NETWORK_UUID))); + Pair, List> expectedBody = Pair.of(List.of(modification1, modification2), List.of()); String expectedBodyStr = mapper.writeValueAsString(expectedBody); String url = "/v1/groups/" + node1.getModificationGroupUuid(); WireMockUtils.verifyPutRequest(wireMockServer, groupStubId, url, true, Map.of( "action", WireMock.equalTo("MOVE"), - "originGroupUuid", WireMock.equalTo(node1.getModificationGroupUuid().toString()), - "build", WireMock.equalTo("false")), + "originGroupUuid", WireMock.equalTo(node1.getModificationGroupUuid().toString())), expectedBodyStr); // move 2 modifications from node1 to node2 @@ -2406,18 +2442,17 @@ void testCutAndPasteModification() throws Exception { checkUpdateStatusMessagesReceived(studyUuid, nodeUuid2, output); checkEquipmentUpdatingMessagesReceived(studyUuid, nodeUuid2); checkEquipmentUpdatingMessagesReceived(studyUuid, nodeUuid1); + studyTestUtils.sendApplicationResult(studyUuid, nodeUuid2, nodeUuid1); checkEquipmentUpdatingFinishedMessagesReceived(studyUuid, nodeUuid2); checkEquipmentUpdatingFinishedMessagesReceived(studyUuid, nodeUuid1); checkElementUpdatedMessageSent(studyUuid, userId); - checkElementUpdatedMessageSent(studyUuid, userId); expectedBody = Pair.of(List.of(modification1, modification2), List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, node2.getId(), NETWORK_UUID))); expectedBodyStr = mapper.writeValueAsString(expectedBody); url = "/v1/groups/" + node2.getModificationGroupUuid(); WireMockUtils.verifyPutRequest(wireMockServer, groupStubId, url, true, Map.of( "action", WireMock.equalTo("MOVE"), - "originGroupUuid", WireMock.equalTo(node1.getModificationGroupUuid().toString()), - "build", WireMock.equalTo("true")), + "originGroupUuid", WireMock.equalTo(node1.getModificationGroupUuid().toString())), expectedBodyStr); // move modification without defining originNodeUuid @@ -2486,13 +2521,14 @@ void testDeleteEquipment() throws Exception { .andExpect(status().isForbidden()); // delete equipment on first modification node - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode1Uuid) .content(bodyJson).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(bodyJson, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -2505,6 +2541,7 @@ void testDeleteEquipment() throws Exception { .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode2Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); modificationBody = Pair.of(bodyJson, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode2Uuid, NETWORK_UUID))); @@ -2599,7 +2636,7 @@ void testNodesInvalidation() throws Exception { when(rootNetworkNodeInfoService.isLoadflowDone(modificationNode2Uuid, firstRootNetworkUuid)).thenReturn(true); Map createLoadInfos = Map.of("type", ModificationType.LOAD_CREATION, "equipmentId", "loadId"); String jsonCreateLoadInfos = mapper.writeValueAsString(createLoadInfos); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode2Uuid) .content(jsonCreateLoadInfos).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) @@ -2608,6 +2645,7 @@ void testNodesInvalidation() throws Exception { checkNodesInvalidationMessagesReceived(studyNameUserIdUuid, List.of(modificationNode2Uuid, modificationNode3Uuid)); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode2Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode3Uuid, firstRootNetworkUuid).getGlobalBuildStatus()); @@ -2656,7 +2694,7 @@ void testRemoveLoadFlowComputationReport() throws Exception { String bodyJson = mapper.writeValueAsString(body); // add this modification to the node => invalidate the LF - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); UUID deleteModificationIndexStub = wireMockStubs.stubNetworkModificationDeleteIndex(); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNode1Uuid) .content(bodyJson).contentType(MediaType.APPLICATION_JSON) @@ -2665,6 +2703,7 @@ void testRemoveLoadFlowComputationReport() throws Exception { checkNodesBuildStatusUpdatedMessageReceived(studyNameUserIdUuid, List.of(modificationNode1Uuid)); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNode1Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); Pair> modificationBody = Pair.of(bodyJson, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNode1Uuid, NETWORK_UUID))); @@ -2708,13 +2747,14 @@ void testUpdateOfBuildStatus() throws Exception { String jsonCreateLoadInfos = mapper.writeValueAsString(createLoadInfos); // Create network modification on NOT_BUILT modification node - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(jsonCreateLoadInfos).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid, firstRootNetworkUuid).getGlobalBuildStatus()); @@ -2729,7 +2769,7 @@ void testUpdateOfBuildStatus() throws Exception { // Create network modification on BUILT modification node Optional networkModificationResult = createModificationResultWithElementImpact(SimpleImpactType.CREATION, IdentifiableType.LOAD, "loadId", Set.of("s1")); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(networkModificationResult)))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(jsonCreateLoadInfos).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) @@ -2738,6 +2778,7 @@ void testUpdateOfBuildStatus() throws Exception { checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid, new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(networkModificationResult))); checkEquipmentMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, expectedPayload); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid, firstRootNetworkUuid).getGlobalBuildStatus()); @@ -2746,7 +2787,7 @@ void testUpdateOfBuildStatus() throws Exception { // Built with warnings networkModificationResult.get().setApplicationStatus(NetworkModificationResult.ApplicationStatus.WITH_WARNINGS); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(networkModificationResult)))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(jsonCreateLoadInfos).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) @@ -2754,6 +2795,7 @@ void testUpdateOfBuildStatus() throws Exception { checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid, new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(networkModificationResult))); checkNodesBuildStatusUpdatedMessageReceived(studyNameUserIdUuid, List.of(modificationNodeUuid)); checkEquipmentMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, expectedPayload); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); @@ -2763,7 +2805,7 @@ void testUpdateOfBuildStatus() throws Exception { // Built with errors networkModificationResult.get().setApplicationStatus(NetworkModificationResult.ApplicationStatus.WITH_ERRORS); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(networkModificationResult)))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(jsonCreateLoadInfos).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) @@ -2771,6 +2813,7 @@ void testUpdateOfBuildStatus() throws Exception { checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid, new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(networkModificationResult))); checkNodesBuildStatusUpdatedMessageReceived(studyNameUserIdUuid, List.of(modificationNodeUuid)); checkEquipmentMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, expectedPayload); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); @@ -3106,13 +3149,14 @@ void testCreateModificationWithErrors() throws Exception { String jsonCreateLoadInfos = mapper.writeValueAsString(createLoadInfos); // Create network modification on first modification node - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, studyNameUserIdUuid, modificationNodeUuid) .content(jsonCreateLoadInfos).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid, output); checkEquipmentCreatingMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); + studyTestUtils.sendApplicationResult(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); String modificationBodyJson = getModificationContextJsonString(mapper, Pair.of(jsonCreateLoadInfos, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, modificationNodeUuid, NETWORK_UUID)))); diff --git a/src/test/java/org/gridsuite/study/server/VoltageInitTest.java b/src/test/java/org/gridsuite/study/server/VoltageInitTest.java index 50e2c5e3ed..cac2e29b01 100644 --- a/src/test/java/org/gridsuite/study/server/VoltageInitTest.java +++ b/src/test/java/org/gridsuite/study/server/VoltageInitTest.java @@ -30,7 +30,6 @@ import org.gridsuite.study.server.dto.RootNetworkNodeInfo; import org.gridsuite.study.server.dto.impacts.SimpleElementImpact.SimpleImpactType; import org.gridsuite.study.server.dto.modification.ModificationApplicationContext; -import org.gridsuite.study.server.dto.modification.NetworkModificationResult; import org.gridsuite.study.server.dto.modification.NetworkModificationsResult; import org.gridsuite.study.server.dto.voltageinit.parameters.*; import org.gridsuite.study.server.networkmodificationtree.dto.*; @@ -337,10 +336,7 @@ public MockResponse dispatch(RecordedRequest request) { } else if (path.matches("/v1/results/" + VOLTAGE_INIT_RESULT_UUID + "/modifications-group-uuid")) { return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), "\"" + MODIFICATIONS_GROUP_UUID + "\""); } else if (path.matches("/v1/groups/.*" + "\\?action=COPY.*")) { - Optional networkModificationResult = - createModificationResultWithElementImpact(SimpleImpactType.MODIFICATION, - IdentifiableType.GENERATOR, "genId", Set.of("s1")); - return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), objectMapper.writeValueAsString(new NetworkModificationsResult(List.of(VOLTAGE_INIT_MODIFICATION_UUID), List.of(networkModificationResult)))); + return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), objectMapper.writeValueAsString(List.of(VOLTAGE_INIT_MODIFICATION_UUID))); } else if (path.matches("/v1/groups/" + MODIFICATIONS_GROUP_UUID + "/network-modifications\\?errorOnGroupNotFound=false&onlyStashed=false&onlyMetadata=.*")) { return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), objectMapper.writeValueAsString(VOLTAGE_INIT_PREVIEW_MODIFICATION_LIST)); } else if (path.matches("/v1/results/" + VOLTAGE_INIT_RESULT_UUID + "/stop.*") @@ -730,14 +726,13 @@ void testInsertVoltageInitModifications(final MockWebServer server) throws Excep // clone and insert again voltage-init modification to modificationNode3Uuid, with LF result -> node is invalidated when(loadFlowService.getLoadFlowStatus(any())).thenReturn(LoadFlowStatus.CONVERGED); - when(networkModificationService.duplicateModificationsFromGroup(any(), any(), any())).thenReturn(null); + doReturn(List.of()).when(networkModificationService).duplicateModificationsFromGroup(any(), any(), any(), any()); mockMvc.perform(post("/v1/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/network-modifications/voltage-init", studyNameUserIdUuid, firstRootNetworkUuid, modificationNode3Uuid) .header("userId", "userId")).andExpect(status().isOk()); - assertTrue(TestUtils.getRequestsDone(7, server).stream().allMatch(r -> + assertTrue(TestUtils.getRequestsDone(6, server).stream().allMatch(r -> r.matches("/v1/results/" + VOLTAGE_INIT_RESULT_UUID + "/modifications-group-uuid") || r.matches("/v1/results/" + VOLTAGE_INIT_RESULT_UUID + "/status") || r.matches("/v1/results\\?resultsUuids=" + VOLTAGE_INIT_RESULT_UUID) || - r.matches("/v1/groups/.*\\?action=COPY.*") || r.matches("/v1/network-modifications/index\\?networkUuid=.*&groupUuids=.*") || r.matches("/v1/reports") )); @@ -858,10 +853,13 @@ void testInsertVoltageInitModificationsWithTwoRootNetworks(final MockWebServer s )); checkEquipmentUpdatingMessagesReceived(studyUuid, nodeUuid); checkUpdateModelsStatusMessagesReceived(studyUuid, firstRootNetworkUuid); - checkEquipmentMessagesReceived(studyUuid, nodeUuid, NetworkImpactsInfos.builder().impactedSubstationsIds(ImmutableSet.of("s1")).build()); checkUpdateModelStatusMessagesReceived(studyUuid, firstRootNetworkUuid, NotificationService.UPDATE_TYPE_VOLTAGE_INIT_RESULT); // results only for 1st root network - checkElementUpdatedMessageSent(studyUuid, "userId"); + studyTestUtils.sendApplicationResult(studyUuid, nodeUuid, firstRootNetworkUuid, null, + new NetworkModificationsResult(List.of(VOLTAGE_INIT_MODIFICATION_UUID), + List.of(createModificationResultWithElementImpact(SimpleImpactType.MODIFICATION, IdentifiableType.GENERATOR, "genId", Set.of("s1"))))); + checkEquipmentMessagesReceived(studyUuid, nodeUuid, NetworkImpactsInfos.builder().impactedSubstationsIds(ImmutableSet.of("s1")).build()); checkEquipmentUpdatingFinishedMessagesReceived(studyUuid, nodeUuid); + checkElementUpdatedMessageSent(studyUuid, "userId"); ModificationApplicationContext ctx1 = rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, nodeUuid, NETWORK_UUID); ModificationApplicationContext ctx2 = rootNetworkNodeInfoService.getNetworkModificationApplicationContext(secondRootNetworkUuid, nodeUuid, SECOND_NETWORK_UUID); @@ -904,18 +902,24 @@ private void createNodeLinks(RootNetworkEntity rootNetworkEntity, NetworkModific } private void checkInsertVoltageInitModifications(UUID studyUuid, UUID modificationNodeUuid, UUID rootNetworkUuid, boolean isBuildNode) throws Exception { - NodeBuildStatus nodeBuildStatus = networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid, rootNetworkUuid); - assertTrue(isBuildNode ? nodeBuildStatus.isBuilt() : nodeBuildStatus.isNotBuilt()); checkEquipmentUpdatingMessagesReceived(studyUuid, modificationNodeUuid); if (!isBuildNode) { checkUpdateModelStatusMessagesReceived(studyUuid, rootNetworkUuid, NotificationService.NODE_BUILD_STATUS_UPDATED); } checkUpdateModelsStatusMessagesReceived(studyUuid, rootNetworkUuid); + checkUpdateModelStatusMessagesReceived(studyUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_VOLTAGE_INIT_RESULT); + // Simulate broker result from network-modification-server + studyTestUtils.sendApplicationResult(studyUuid, modificationNodeUuid, rootNetworkUuid, null, + new NetworkModificationsResult(List.of(VOLTAGE_INIT_MODIFICATION_UUID), + isBuildNode + ? List.of(createModificationResultWithElementImpact(SimpleImpactType.MODIFICATION, IdentifiableType.GENERATOR, "genId", Set.of("s1"))) + : List.of(Optional.empty()))); if (isBuildNode) { checkEquipmentMessagesReceived(studyUuid, modificationNodeUuid, NetworkImpactsInfos.builder().impactedSubstationsIds(ImmutableSet.of("s1")).build()); } - checkUpdateModelStatusMessagesReceived(studyUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_VOLTAGE_INIT_RESULT); checkEquipmentUpdatingFinishedMessagesReceived(studyUuid, modificationNodeUuid); + NodeBuildStatus nodeBuildStatus = networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid, rootNetworkUuid); + assertTrue(isBuildNode ? nodeBuildStatus.isBuilt() : nodeBuildStatus.isNotBuilt()); checkElementUpdatedMessageSent(studyUuid, "userId"); } diff --git a/src/test/java/org/gridsuite/study/server/WorkflowTest.java b/src/test/java/org/gridsuite/study/server/WorkflowTest.java index 9a370ab460..373b51a9ea 100644 --- a/src/test/java/org/gridsuite/study/server/WorkflowTest.java +++ b/src/test/java/org/gridsuite/study/server/WorkflowTest.java @@ -9,7 +9,9 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.gridsuite.study.server.dto.NodeReceiver; +import org.gridsuite.study.server.dto.modification.ModificationReceiver; import org.gridsuite.study.server.dto.modification.NetworkModificationResult; +import org.gridsuite.study.server.dto.modification.NetworkModificationsResult; import org.gridsuite.study.server.dto.workflow.RerunLoadFlowInfos; import org.gridsuite.study.server.dto.workflow.WorkflowType; import org.gridsuite.study.server.notification.NotificationService; @@ -25,7 +27,9 @@ import org.springframework.test.context.bean.override.mockito.MockitoBean; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.UUID; import static org.gridsuite.study.server.StudyConstants.*; @@ -110,4 +114,32 @@ void testConsumeBuildFailedInRerunLoadFlowWorkflow() throws JsonProcessingExcept verify(notificationService, times(1)).emitNodeBuildFailed(studyUuid, nodeUuid, rootNetworkUuid, errorMessage); verify(studyService, times(1)).deleteLoadflowResult(studyUuid, nodeUuid, rootNetworkUuid, loadflowResultUuid); } + + @Test + void testConsumeApplicationResult() throws JsonProcessingException { + NetworkModificationsResult result = new NetworkModificationsResult( + List.of(UUID.randomUUID()), List.of(Optional.empty())); + ModificationReceiver receiver = new ModificationReceiver(studyUuid, nodeUuid, null, List.of(rootNetworkUuid)); + + Map headers = new HashMap<>(); + headers.put(HEADER_RECEIVER, objectMapper.writeValueAsString(receiver)); + MessageHeaders messageHeaders = new MessageHeaders(headers); + + consumerService.consumeApplicationResult().accept(MessageBuilder.createMessage(result, messageHeaders)); + + verify(studyService, times(1)).handleApplicationResult(receiver, result); + } + + @Test + void testConsumeApplicationFailed() throws JsonProcessingException { + ModificationReceiver receiver = new ModificationReceiver(studyUuid, nodeUuid, null, List.of(rootNetworkUuid)); + + Map headers = new HashMap<>(); + headers.put(HEADER_RECEIVER, objectMapper.writeValueAsString(receiver)); + MessageHeaders messageHeaders = new MessageHeaders(headers); + + consumerService.consumeApplicationFailed().accept(MessageBuilder.createMessage("", messageHeaders)); + + verify(studyService, times(1)).handleApplicationFailed(receiver); + } } diff --git a/src/test/java/org/gridsuite/study/server/rootnetworks/ModificationToExcludeTest.java b/src/test/java/org/gridsuite/study/server/rootnetworks/ModificationToExcludeTest.java index 7b47cf868a..6528f2bef8 100644 --- a/src/test/java/org/gridsuite/study/server/rootnetworks/ModificationToExcludeTest.java +++ b/src/test/java/org/gridsuite/study/server/rootnetworks/ModificationToExcludeTest.java @@ -11,8 +11,6 @@ import org.gridsuite.study.server.ContextConfigurationWithTestChannel; import org.gridsuite.study.server.error.StudyException; import org.gridsuite.study.server.dto.*; -import org.gridsuite.study.server.dto.modification.NetworkModificationResult; -import org.gridsuite.study.server.dto.modification.NetworkModificationsResult; import org.gridsuite.study.server.networkmodificationtree.dto.ExcludedNetworkModifications; import org.gridsuite.study.server.networkmodificationtree.dto.InsertMode; import org.gridsuite.study.server.networkmodificationtree.dto.NetworkModificationNode; @@ -521,14 +519,11 @@ void testDuplicateModificationBetweenStudiesWithCommonRootNetworkTag() { List modifications = List.of(MODIFICATION_TO_EXCLUDE_1, MODIFICATION_TO_EXCLUDE_2); Mockito.doReturn( - new NetworkModificationsResult( - modifications.stream() - .map(ORIGIN_TO_DUPLICATE_MODIFICATION_UUID_MAP::get) - .toList(), - List.of() - ) - ).when(networkModificationService) - .duplicateModifications(any(), any()); + modifications.stream() + .map(ORIGIN_TO_DUPLICATE_MODIFICATION_UUID_MAP::get) + .toList() + ).when(networkModificationService) + .duplicateModifications(any(), any(), any()); // -------- EXECUTE -------- studyService.duplicateNetworkModifications( study2.getId(), @@ -601,8 +596,8 @@ void testDuplicateModificationWithModificationsToExclude() { // mock duplicateModificationsGroup to return a mapping between origin modification uuid and their duplicate uuid List modificationsToDuplicate = List.of(MODIFICATION_NEVER_EXCLUDED, MODIFICATION_TO_EXCLUDE_1, MODIFICATION_TO_EXCLUDE_2); Mockito.doReturn( - new NetworkModificationsResult(modificationsToDuplicate.stream().map(ORIGIN_TO_DUPLICATE_MODIFICATION_UUID_MAP::get).toList(), List.of()) - ).when(networkModificationService).duplicateModifications(any(), any()); + modificationsToDuplicate.stream().map(ORIGIN_TO_DUPLICATE_MODIFICATION_UUID_MAP::get).toList() + ).when(networkModificationService).duplicateModifications(any(), any(), any()); // duplicate (excluded) modification uuids for RH1 Set modificationUuidsToDuplicate1 = Sets.intersection(MODIFICATIONS_TO_EXCLUDE_RN_1, new HashSet<>(modificationsToDuplicate)); @@ -782,7 +777,7 @@ void testMoveExcludedModification() { rootNetworkNodeInfoRepository.save(rootNetwork0NodeInfo1Entity); // try to execute modification move - if modification move fails, they should not be moved from a node to another in exludedModifications - Mockito.doThrow(new RuntimeException()).when(networkModificationService).moveModifications(any(), any(), any(), any(), eq(true)); + Mockito.doThrow(new RuntimeException()).when(networkModificationService).moveModifications(any(), any(), any(), any(), any()); List modificationsToMove = List.of(MODIFICATIONS_TO_EXCLUDE_RN_1.stream().findFirst().orElseThrow()); assertThrows(RuntimeException.class, () -> studyService.moveNetworkModifications(studyUuid, firstNodeUuid, firstNodeUuid, modificationsToMove, null, false, USER_ID)); @@ -797,11 +792,7 @@ void testMoveExcludedModification() { assertThat(expectedExcludedModifications).usingRecursiveComparison().isEqualTo(excludedModifications); // if it returned OK, then they should be moved from one node to another's excluded modifications - Mockito.doReturn(new NetworkModificationsResult(modificationsToMove, List.of(Optional.of(NetworkModificationResult.builder() - .applicationStatus(NetworkModificationResult.ApplicationStatus.ALL_OK) - .lastGroupApplicationStatus(NetworkModificationResult.ApplicationStatus.ALL_OK) - .networkImpacts(List.of()) - .build())))).when(networkModificationService).moveModifications(any(), any(), any(), any(), eq(true)); + Mockito.doReturn(modificationsToMove).when(networkModificationService).moveModifications(any(), any(), any(), any(), any()); studyService.moveNetworkModifications(studyUuid, secondNodeUuid, firstNodeUuid, modificationsToMove, null, true, USER_ID); // assert origin node still have all excluded modifications, except the moved one diff --git a/src/test/java/org/gridsuite/study/server/studycontroller/NodeControllerTest.java b/src/test/java/org/gridsuite/study/server/studycontroller/NodeControllerTest.java index b0744d0959..607664ed2e 100644 --- a/src/test/java/org/gridsuite/study/server/studycontroller/NodeControllerTest.java +++ b/src/test/java/org/gridsuite/study/server/studycontroller/NodeControllerTest.java @@ -13,7 +13,6 @@ import org.gridsuite.study.server.dto.RootNetworkNodeInfo; import org.gridsuite.study.server.dto.modification.ModificationApplicationContext; import org.gridsuite.study.server.dto.modification.ModificationType; -import org.gridsuite.study.server.dto.modification.NetworkModificationsResult; import org.gridsuite.study.server.networkmodificationtree.dto.*; import org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity; import org.gridsuite.study.server.notification.NotificationService; @@ -67,13 +66,14 @@ void testCutAndPasteNode() throws Exception { // add modification on node "node1" String createTwoWindingsTransformerAttributes = "{\"type\":\"" + ModificationType.TWO_WINDINGS_TRANSFORMER_CREATION + "\",\"equipmentId\":\"2wtId\",\"equipmentName\":\"2wtName\",\"seriesResistance\":\"10\",\"seriesReactance\":\"10\",\"magnetizingConductance\":\"100\",\"magnetizingSusceptance\":\"100\",\"ratedVoltage1\":\"480\",\"ratedVoltage2\":\"380\",\"voltageLevelId1\":\"CHOO5P6\",\"busOrBusbarSectionId1\":\"CHOO5P6_1\",\"voltageLevelId2\":\"CHOO5P6\",\"busOrBusbarSectionId2\":\"CHOO5P6_1\"}"; - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, study1Uuid, node1.getId(), firstRootNetworkUuid) .content(createTwoWindingsTransformerAttributes).contentType(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); checkUpdateModelsStatusMessagesReceived(study1Uuid, node1.getId()); checkEquipmentCreatingMessagesReceived(study1Uuid, node1.getId()); + studyTestUtils.sendApplicationResult(study1Uuid, node1.getId()); checkEquipmentUpdatingFinishedMessagesReceived(study1Uuid, node1.getId()); checkElementUpdatedMessageSent(study1Uuid, userId); Pair> modificationBody = Pair.of(createTwoWindingsTransformerAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, node1.getId(), NETWORK_UUID))); @@ -81,7 +81,7 @@ void testCutAndPasteNode() throws Exception { // 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\"}"; - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, study1Uuid, node2.getId(), firstRootNetworkUuid) .contentType(MediaType.APPLICATION_JSON) .content(createLoadAttributes) @@ -89,6 +89,7 @@ void testCutAndPasteNode() throws Exception { .andExpect(status().isOk()); checkUpdateModelsStatusMessagesReceived(study1Uuid, node2.getId()); checkEquipmentCreatingMessagesReceived(study1Uuid, node2.getId()); + studyTestUtils.sendApplicationResult(study1Uuid, node2.getId()); checkEquipmentUpdatingFinishedMessagesReceived(study1Uuid, node2.getId()); checkElementUpdatedMessageSent(study1Uuid, userId); modificationBody = Pair.of(createLoadAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, node2.getId(), NETWORK_UUID))); @@ -480,7 +481,7 @@ void testDuplicateNode() throws Exception { // add modification on node "node1" String createTwoWindingsTransformerAttributes = "{\"type\":\"" + ModificationType.TWO_WINDINGS_TRANSFORMER_CREATION + "\",\"equipmentId\":\"2wtId\",\"equipmentName\":\"2wtName\",\"seriesResistance\":\"10\",\"seriesReactance\":\"10\",\"magnetizingConductance\":\"100\",\"magnetizingSusceptance\":\"100\",\"ratedVoltage1\":\"480\",\"ratedVoltage2\":\"380\",\"voltageLevelId1\":\"CHOO5P6\",\"busOrBusbarSectionId1\":\"CHOO5P6_1\",\"voltageLevelId2\":\"CHOO5P6\",\"busOrBusbarSectionId2\":\"CHOO5P6_1\"}"; - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, study1Uuid, node1.getId(), firstRootNetworkUuid) .contentType(MediaType.APPLICATION_JSON) .content(createTwoWindingsTransformerAttributes) @@ -488,6 +489,7 @@ void testDuplicateNode() throws Exception { .andExpect(status().isOk()); checkUpdateModelsStatusMessagesReceived(study1Uuid, node1.getId()); checkEquipmentCreatingMessagesReceived(study1Uuid, node1.getId()); + studyTestUtils.sendApplicationResult(study1Uuid, node1.getId()); checkEquipmentUpdatingFinishedMessagesReceived(study1Uuid, node1.getId()); checkElementUpdatedMessageSent(study1Uuid, userId); Pair> modificationBody = Pair.of(createTwoWindingsTransformerAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, node1.getId(), NETWORK_UUID))); @@ -495,7 +497,7 @@ void testDuplicateNode() throws Exception { // 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\"}"; - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, study1Uuid, node2.getId(), firstRootNetworkUuid) .contentType(MediaType.APPLICATION_JSON) .content(createLoadAttributes) @@ -503,6 +505,7 @@ void testDuplicateNode() throws Exception { .andExpect(status().isOk()); checkUpdateModelsStatusMessagesReceived(study1Uuid, node2.getId()); checkEquipmentCreatingMessagesReceived(study1Uuid, node2.getId()); + studyTestUtils.sendApplicationResult(study1Uuid, node2.getId()); checkEquipmentUpdatingFinishedMessagesReceived(study1Uuid, node2.getId()); checkElementUpdatedMessageSent(study1Uuid, userId); modificationBody = Pair.of(createLoadAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, node2.getId(), NETWORK_UUID))); @@ -608,7 +611,7 @@ void testDuplicateSubtree() throws Exception { UUID deleteModificationIndexStub = wireMockStubs.stubNetworkModificationDeleteIndex(); UUID stubDeleteReportsId = wireMockServer.stubFor(WireMock.delete(WireMock.urlPathEqualTo("/v1/reports")) .willReturn(WireMock.ok())).getId(); - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, study1Uuid, node1.getId(), firstRootNetworkUuid) .contentType(MediaType.APPLICATION_JSON) .content(createTwoWindingsTransformerAttributes) @@ -618,6 +621,7 @@ void testDuplicateSubtree() throws Exception { checkNodeBuildStatusUpdatedMessageReceived(study1Uuid, List.of(node3.getId())); checkUpdateModelsStatusMessagesReceived(study1Uuid, node1.getId()); checkEquipmentCreatingMessagesReceived(study1Uuid, node1.getId()); + studyTestUtils.sendApplicationResult(study1Uuid, node1.getId()); checkEquipmentUpdatingFinishedMessagesReceived(study1Uuid, node1.getId()); checkElementUpdatedMessageSent(study1Uuid, userId); Pair> modificationBody = Pair.of(createTwoWindingsTransformerAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, node1.getId(), NETWORK_UUID))); @@ -631,7 +635,7 @@ void testDuplicateSubtree() throws Exception { // 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\"}"; - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, study1Uuid, node2.getId(), firstRootNetworkUuid) .contentType(MediaType.APPLICATION_JSON) .content(createLoadAttributes) @@ -639,6 +643,7 @@ void testDuplicateSubtree() throws Exception { .andExpect(status().isOk()); checkUpdateModelsStatusMessagesReceived(study1Uuid, node2.getId()); checkEquipmentCreatingMessagesReceived(study1Uuid, node2.getId()); + studyTestUtils.sendApplicationResult(study1Uuid, node2.getId()); checkEquipmentUpdatingFinishedMessagesReceived(study1Uuid, node2.getId()); checkElementUpdatedMessageSent(study1Uuid, userId); modificationBody = Pair.of(createLoadAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, node2.getId(), NETWORK_UUID))); @@ -750,7 +755,7 @@ void testDuplicateNodeBetweenStudies() throws Exception { NetworkModificationNode study2Node2 = createNetworkModificationNode(study2Uuid, study2ModificationNodeUuid, VARIANT_ID_2, "node2", userId); // add modification on study 1 node "node1" - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); String createTwoWindingsTransformerAttributes = "{\"type\":\"" + ModificationType.TWO_WINDINGS_TRANSFORMER_CREATION + "\",\"equipmentId\":\"2wtId\",\"equipmentName\":\"2wtName\",\"seriesResistance\":\"10\",\"seriesReactance\":\"10\",\"magnetizingConductance\":\"100\",\"magnetizingSusceptance\":\"100\",\"ratedVoltage1\":\"480\",\"ratedVoltage2\":\"380\",\"voltageLevelId1\":\"CHOO5P6\",\"busOrBusbarSectionId1\":\"CHOO5P6_1\",\"voltageLevelId2\":\"CHOO5P6\",\"busOrBusbarSectionId2\":\"CHOO5P6_1\"}"; mockMvc.perform(post(URI_NETWORK_MODIF, study1Uuid, node1.getId(), firstRootNetworkUuid) .contentType(MediaType.APPLICATION_JSON) @@ -759,13 +764,14 @@ void testDuplicateNodeBetweenStudies() throws Exception { .andExpect(status().isOk()); checkUpdateModelsStatusMessagesReceived(study1Uuid, node1.getId()); checkEquipmentCreatingMessagesReceived(study1Uuid, node1.getId()); + studyTestUtils.sendApplicationResult(study1Uuid, node1.getId()); checkEquipmentUpdatingFinishedMessagesReceived(study1Uuid, node1.getId()); checkElementUpdatedMessageSent(study1Uuid, userId); Pair> modificationBody = Pair.of(createTwoWindingsTransformerAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, node1.getId(), NETWORK_UUID))); wireMockStubs.verifyNetworkModificationPostWithVariant(getModificationContextJsonString(mapper, modificationBody)); // add modification on node "node2" - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); String createLoadAttributes = "{\"type\":\"" + ModificationType.LOAD_CREATION + "\",\"loadId\":\"loadId1\",\"loadName\":\"loadName1\",\"loadType\":\"UNDEFINED\",\"activePower\":\"100.0\",\"reactivePower\":\"50.0\",\"voltageLevelId\":\"idVL1\",\"busId\":\"idBus1\"}"; mockMvc.perform(post(URI_NETWORK_MODIF, study1Uuid, node2.getId(), firstRootNetworkUuid) .contentType(MediaType.APPLICATION_JSON) @@ -774,6 +780,7 @@ void testDuplicateNodeBetweenStudies() throws Exception { .andExpect(status().isOk()); checkUpdateModelsStatusMessagesReceived(study1Uuid, node2.getId()); checkEquipmentCreatingMessagesReceived(study1Uuid, node2.getId()); + studyTestUtils.sendApplicationResult(study1Uuid, node2.getId()); checkEquipmentUpdatingFinishedMessagesReceived(study1Uuid, node2.getId()); checkElementUpdatedMessageSent(study1Uuid, userId); modificationBody = Pair.of(createLoadAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(firstRootNetworkUuid, node2.getId(), NETWORK_UUID))); diff --git a/src/test/java/org/gridsuite/study/server/studycontroller/StudyTest.java b/src/test/java/org/gridsuite/study/server/studycontroller/StudyTest.java index d8e80caf05..35cafd377b 100644 --- a/src/test/java/org/gridsuite/study/server/studycontroller/StudyTest.java +++ b/src/test/java/org/gridsuite/study/server/studycontroller/StudyTest.java @@ -15,7 +15,6 @@ import org.gridsuite.study.server.dto.*; import org.gridsuite.study.server.dto.modification.ModificationApplicationContext; import org.gridsuite.study.server.dto.modification.ModificationType; -import org.gridsuite.study.server.dto.modification.NetworkModificationsResult; import org.gridsuite.study.server.dto.networkexport.NetworkExportReceiver; import org.gridsuite.study.server.dto.networkexport.PermissionType; import org.gridsuite.study.server.networkmodificationtree.dto.*; @@ -922,7 +921,7 @@ private void testDuplicateStudy(UUID study1Uuid, UUID rootNetworkUuid, String us // add modification on node "node1" String createTwoWindingsTransformerAttributes = "{\"type\":\"" + ModificationType.TWO_WINDINGS_TRANSFORMER_CREATION + "\",\"equipmentId\":\"2wtId\",\"equipmentName\":\"2wtName\",\"seriesResistance\":\"10\",\"seriesReactance\":\"10\",\"magnetizingConductance\":\"100\",\"magnetizingSusceptance\":\"100\",\"ratedVoltage1\":\"480\",\"ratedVoltage2\":\"380\",\"voltageLevelId1\":\"CHOO5P6\",\"busOrBusbarSectionId1\":\"CHOO5P6_1\",\"voltageLevelId2\":\"CHOO5P6\",\"busOrBusbarSectionId2\":\"CHOO5P6_1\"}"; - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, study1Uuid, node1.getId(), rootNetworkUuid) .contentType(MediaType.APPLICATION_JSON) .content(createTwoWindingsTransformerAttributes) @@ -930,6 +929,7 @@ private void testDuplicateStudy(UUID study1Uuid, UUID rootNetworkUuid, String us .andExpect(status().isOk()); checkUpdateModelsStatusMessagesReceived(study1Uuid, node1.getId()); checkEquipmentCreatingMessagesReceived(study1Uuid, node1.getId()); + studyTestUtils.sendApplicationResult(study1Uuid, node1.getId()); checkEquipmentUpdatingFinishedMessagesReceived(study1Uuid, node1.getId()); checkElementUpdatedMessageSent(study1Uuid, userId); Pair> modificationBody = Pair.of(createTwoWindingsTransformerAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(rootNetworkUuid, node1.getId(), NETWORK_UUID))); @@ -938,7 +938,7 @@ private void testDuplicateStudy(UUID study1Uuid, UUID rootNetworkUuid, String us // 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\"}"; - wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty())))); + wireMockStubs.stubNetworkModificationPost(mapper.writeValueAsString(List.of(UUID.randomUUID()))); mockMvc.perform(post(URI_NETWORK_MODIF, study1Uuid, node2.getId(), rootNetworkUuid) .contentType(MediaType.APPLICATION_JSON) .content(createLoadAttributes) @@ -946,6 +946,7 @@ private void testDuplicateStudy(UUID study1Uuid, UUID rootNetworkUuid, String us .andExpect(status().isOk()); checkUpdateStatusMessagesReceived(study1Uuid, node2.getId(), output); checkEquipmentCreatingMessagesReceived(study1Uuid, node2.getId()); + studyTestUtils.sendApplicationResult(study1Uuid, node2.getId()); checkEquipmentUpdatingFinishedMessagesReceived(study1Uuid, node2.getId()); checkElementUpdatedMessageSent(study1Uuid, userId); modificationBody = Pair.of(createLoadAttributes, List.of(rootNetworkNodeInfoService.getNetworkModificationApplicationContext(rootNetworkUuid, node2.getId(), NETWORK_UUID))); diff --git a/src/test/java/org/gridsuite/study/server/utils/TestUtils.java b/src/test/java/org/gridsuite/study/server/utils/TestUtils.java index 98b9e7ff1f..aa4a9dd198 100644 --- a/src/test/java/org/gridsuite/study/server/utils/TestUtils.java +++ b/src/test/java/org/gridsuite/study/server/utils/TestUtils.java @@ -6,6 +6,8 @@ */ package org.gridsuite.study.server.utils; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; import com.google.common.io.ByteStreams; @@ -19,6 +21,8 @@ import org.gridsuite.study.server.error.StudyBusinessErrorCode; import org.gridsuite.study.server.error.StudyException; import org.gridsuite.study.server.networkmodificationtree.dto.NetworkModificationNode; +import org.gridsuite.study.server.dto.modification.ModificationReceiver; +import org.gridsuite.study.server.dto.modification.NetworkModificationsResult; import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; @@ -28,12 +32,16 @@ import org.gridsuite.study.server.utils.assertions.Assertions; import org.junit.platform.commons.util.StringUtils; import org.mockito.stubbing.Answer; +import org.springframework.cloud.stream.binder.test.InputDestination; import org.springframework.cloud.stream.binder.test.OutputDestination; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.IOException; +import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.CompletableFuture; @@ -42,6 +50,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import static org.gridsuite.study.server.StudyConstants.HEADER_RECEIVER; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; @@ -90,15 +99,56 @@ public final class TestUtils { }"""; private final RootNetworkRepository rootNetworkRepository; + private InputDestination input; + private ObjectMapper objectMapper; public TestUtils(RootNetworkRepository rootNetworkRepository) { this.rootNetworkRepository = rootNetworkRepository; } + @Autowired + void setObjectMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Autowired(required = false) + void setInput(InputDestination input) { + this.input = input; + } + public UUID getOneRootNetworkUuid(UUID studyUuid) { return getOneRootNetwork(studyUuid).getId(); } + public void sendApplicationResult(UUID studyUuid, UUID nodeUuid) { + sendApplicationResult(studyUuid, nodeUuid, (UUID) null); + } + + public void sendApplicationResult(UUID studyUuid, UUID nodeUuid, UUID originNodeUuid) { + sendApplicationResult(studyUuid, nodeUuid, originNodeUuid, new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.empty()))); + } + + public void sendApplicationResult(UUID studyUuid, UUID nodeUuid, NetworkModificationsResult result) { + sendApplicationResult(studyUuid, nodeUuid, null, result); + } + + public void sendApplicationResult(UUID studyUuid, UUID nodeUuid, UUID originNodeUuid, NetworkModificationsResult result) { + sendApplicationResult(studyUuid, nodeUuid, getOneRootNetworkUuid(studyUuid), originNodeUuid, result); + } + + public void sendApplicationResult(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, UUID originNodeUuid, NetworkModificationsResult result) { + Objects.requireNonNull(input, "InputDestination is not available - ensure @ContextConfigurationWithTestChannel is on the test class"); + ModificationReceiver receiver = new ModificationReceiver(studyUuid, nodeUuid, originNodeUuid, List.of(rootNetworkUuid)); + try { + String receiverEncoded = URLEncoder.encode(objectMapper.writeValueAsString(receiver), StandardCharsets.UTF_8); + input.send(MessageBuilder.withPayload(result) + .setHeader(HEADER_RECEIVER, receiverEncoded) + .build(), "modification.result"); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + public RootNetworkEntity getOneRootNetwork(UUID studyUuid) { return rootNetworkRepository.findAllWithInfosByStudyId(studyUuid).get(0); }