From cf98b2fbca2b831eee06a45a6d4fd8e64772b12a Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Wed, 21 Oct 2026 16:13:45 +0200 Subject: [PATCH 01/14] unsharing of all the references in a study Signed-off-by: Mathieu DEHARBE --- .../server/controller/StudyController.java | 10 +++++++++ .../study/server/service/StudyService.java | 22 +++++++++++++++++++ 2 files changed, 32 insertions(+) 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 d432cb71e3..605c07bec3 100644 --- a/src/main/java/org/gridsuite/study/server/controller/StudyController.java +++ b/src/main/java/org/gridsuite/study/server/controller/StudyController.java @@ -319,6 +319,16 @@ public ResponseEntity unshareModificationReference( return ResponseEntity.ok().build(); } + @PutMapping(value = "/studies/{studyUuid}/unshare") + @Operation(summary = "Unshare all the reference modifications and copy the referenced composites in their place") + @ApiResponse(responseCode = "200", description = "All the reference modifications from the study have been replaced by a copy of its referenced composite") + public ResponseEntity unshareAllReferencesInStudy( + @PathVariable("studyUuid") UUID studyUuid, + @RequestHeader(HEADER_USER_ID) String userId) { + studyService.unshareAllReferencesInStudy(studyUuid, userId); + return ResponseEntity.ok().build(); + } + @PostMapping(value = "/studies/{studyUuid}/root-networks/{rootNetworkUuid}/network", params = {"caseUuid"}) @Operation(summary = "recreate study network of a study from an existing case") @ApiResponses(value = { 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 62a1e12ab8..a3a2e9dfbc 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -316,6 +316,28 @@ public void unshareModificationReference( notificationService.emitModificationsUpdated(studyUuid, nodeUuid, Optional.empty(), List.of(modificationUuid)); } + public void unshareAllReferencesInStudy( + @NonNull final UUID studyUuid, + String userId) { + // get the modification references of the whole study + List modificationsReference = new ArrayList<>(); + List nodes = networkModificationTreeService.getAllNodes(studyUuid).stream().map(NodeEntity::getIdNode).toList(); + List nodesAffected = new ArrayList<>(); + nodes.forEach(nodeUuid -> { + UUID groupUuid = networkModificationTreeService.getModificationGroupUuid(nodeUuid); + List modificationReferences = networkModificationRestService.getModificationReferences(groupUuid); + if (!modificationReferences.isEmpty()) { + modificationsReference.addAll(modificationReferences); + nodesAffected.add(nodeUuid); + } + } + ); + modificationsReference.forEach(modificationReference -> + networkModificationRestService.unshareModificationReference(modificationReference.modificationUuid(), userId) + ); + notificationService.emitNodesChanged(studyUuid, nodesAffected); + } + @Transactional public void deleteRootNetworks(UUID studyUuid, List rootNetworksUuids, String userId) { assertIsStudyExist(studyUuid); From e7d6cc893ff11bfc33cf0204cd03ec2c0426c278 Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Thu, 22 Oct 2026 14:31:16 +0200 Subject: [PATCH 02/14] improvements Signed-off-by: Mathieu DEHARBE --- .../gridsuite/study/server/error/StudyBusinessErrorCode.java | 1 + .../study/server/service/NetworkModificationTreeService.java | 2 +- .../org/gridsuite/study/server/service/StudyService.java | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/gridsuite/study/server/error/StudyBusinessErrorCode.java b/src/main/java/org/gridsuite/study/server/error/StudyBusinessErrorCode.java index 27b61a4ce7..11510cbc07 100644 --- a/src/main/java/org/gridsuite/study/server/error/StudyBusinessErrorCode.java +++ b/src/main/java/org/gridsuite/study/server/error/StudyBusinessErrorCode.java @@ -13,6 +13,7 @@ */ public enum StudyBusinessErrorCode implements BusinessErrorCode { NOT_FOUND("study.notFound"), + NODE_NOT_FOUND("study.nodeNotFound"), COMPUTATION_RUNNING("study.computationRunning"), LOADFLOW_ERROR("study.loadflowError"), NOT_ALLOWED("study.notAllowed"), diff --git a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java index 7407cc0d7a..901ca4bd80 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java @@ -659,7 +659,7 @@ public RootNodeInfoEntity getRootNodeInfoEntity(UUID nodeId) { } public NetworkModificationNodeInfoEntity getNetworkModificationNodeInfoEntity(UUID nodeId) { - return networkModificationNodeInfoRepository.findById(nodeId).orElseThrow(() -> new StudyException(NOT_FOUND, "Node not found")); + return networkModificationNodeInfoRepository.findById(nodeId).orElseThrow(() -> new StudyException(NODE_NOT_FOUND, "Node not found")); } private AbstractNodeInfoEntity getNodeInfoEntity(UUID nodeUuid) { 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 b0793f0a31..91898e84b6 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -321,7 +321,10 @@ public void unshareAllReferencesInStudy( String userId) { // get the modification references of the whole study List modificationsReference = new ArrayList<>(); - List nodes = networkModificationTreeService.getAllNodes(studyUuid).stream().map(NodeEntity::getIdNode).toList(); + List nodes = networkModificationTreeService.getAllNodes(studyUuid) + .stream() + .filter(node -> node.getType().equals(NodeType.NETWORK_MODIFICATION)) + .map(NodeEntity::getIdNode).toList(); List nodesAffected = new ArrayList<>(); nodes.forEach(nodeUuid -> { UUID groupUuid = networkModificationTreeService.getModificationGroupUuid(nodeUuid); From e689eaaff86393e9380fa9761965299095eb8aa8 Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Thu, 22 Oct 2026 16:10:50 +0200 Subject: [PATCH 03/14] activity handling Signed-off-by: Mathieu DEHARBE --- .../server/controller/StudyController.java | 2 +- .../server/nodeactivity/NodeActivityType.java | 1 + .../study/server/service/StudyService.java | 108 +++++++++--------- 3 files changed, 59 insertions(+), 52 deletions(-) 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 605c07bec3..8cf5bec292 100644 --- a/src/main/java/org/gridsuite/study/server/controller/StudyController.java +++ b/src/main/java/org/gridsuite/study/server/controller/StudyController.java @@ -315,7 +315,7 @@ public ResponseEntity unshareModificationReference( @RequestHeader(HEADER_USER_ID) String userId) { studyService.assertIsStudyAndNodeExist(studyUuid, nodeUuid); studyService.assertIsNodeNotReadOnly(nodeUuid); - studyService.unshareModificationReference(studyUuid, nodeUuid, modificationUuid, userId); + studyService.unshareModificationReferences(studyUuid, userId, Map.of(nodeUuid, List.of(modificationUuid))); return ResponseEntity.ok().build(); } diff --git a/src/main/java/org/gridsuite/study/server/nodeactivity/NodeActivityType.java b/src/main/java/org/gridsuite/study/server/nodeactivity/NodeActivityType.java index 9b71186861..870e821bc2 100644 --- a/src/main/java/org/gridsuite/study/server/nodeactivity/NodeActivityType.java +++ b/src/main/java/org/gridsuite/study/server/nodeactivity/NodeActivityType.java @@ -28,6 +28,7 @@ public enum NodeActivityType { REIMPORT_CASE(UPDATING, true, false, false), EDIT_TREE(UPDATING, true, true, true), EDIT_MODIFICATIONS(UPDATING, true, true, true), + UNSHARE_MODIFICATIONS(UPDATING, false, true, true), DELETE_NODES(DELETING, true, true, true), EDIT_EVENTS(UPDATING, false, true, true); 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 91898e84b6..9c184e1b89 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -38,6 +38,7 @@ import org.gridsuite.study.server.networkmodificationtree.entities.NetworkModificationNodeType; import org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity; import org.gridsuite.study.server.networkmodificationtree.entities.NodeType; +import org.gridsuite.study.server.nodeactivity.NodeActivityRunnerService; import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.notification.dto.NetworkImpactsInfos; import org.gridsuite.study.server.repository.*; @@ -84,6 +85,7 @@ import static org.gridsuite.study.server.StudyConstants.CURRENT_LIMIT_VIOLATIONS_INFOS; import static org.gridsuite.study.server.dto.ComputationType.*; import static org.gridsuite.study.server.error.StudyBusinessErrorCode.*; +import static org.gridsuite.study.server.nodeactivity.NodeActivityType.UNSHARE_MODIFICATIONS; /** * @author Abdelsalem Hedhili @@ -124,6 +126,7 @@ public class StudyService { private final RootNetworkService rootNetworkService; private final RootNetworkNodeInfoService rootNetworkNodeInfoService; private final DirectoryService directoryService; + private final NodeActivityRunnerService nodeActivityRunnerService; private final ComputationParametersService computationParametersService; private final LoadFlowRestService loadflowRestService; @@ -166,40 +169,41 @@ public enum ReportType { @Autowired public StudyService( - StudyRepository studyRepository, - StudyCreationRequestRepository studyCreationRequestRepository, - NetworkService networkStoreService, - NetworkModificationRestService networkModificationRestService, - ReportService reportService, - UserAdminService userAdminService, - StudyInfosService studyInfosService, - EquipmentInfosService equipmentInfosService, - NetworkModificationTreeService networkModificationTreeService, - ObjectMapper objectMapper, - StudyServerExecutionService studyServerExecutionService, - NotificationService notificationService, - LoadFlowRestService loadflowRestService, - LoadFlowService loadFlowService, - ShortCircuitRestService shortCircuitService, - SingleLineDiagramService singleLineDiagramService, - NetworkConversionService networkConversionService, - GeoDataService geoDataService, - NetworkMapService networkMapService, - SecurityAnalysisRestService securityAnalysisRestService, - ActionsService actionsService, - CaseService caseService, - DynamicMappingService dynamicMappingService, - VoltageInitRestService voltageInitService, - DynamicSimulationEventService dynamicSimulationEventService, - StudyConfigService studyConfigService, - NadConfigService nadConfigService, - FilterService filterService, - @Lazy StudyService studyService, - RootNetworkService rootNetworkService, - RootNetworkNodeInfoService rootNetworkNodeInfoService, - DirectoryService directoryService, - ComputationParametersService computationParametersService, - WorkspaceService workspaceService, NodeRepository nodeRepository) { + StudyRepository studyRepository, + StudyCreationRequestRepository studyCreationRequestRepository, + NetworkService networkStoreService, + NetworkModificationRestService networkModificationRestService, + ReportService reportService, + UserAdminService userAdminService, + StudyInfosService studyInfosService, + EquipmentInfosService equipmentInfosService, + NetworkModificationTreeService networkModificationTreeService, + ObjectMapper objectMapper, + StudyServerExecutionService studyServerExecutionService, + NotificationService notificationService, + LoadFlowRestService loadflowRestService, + LoadFlowService loadFlowService, + ShortCircuitRestService shortCircuitService, + SingleLineDiagramService singleLineDiagramService, + NetworkConversionService networkConversionService, + GeoDataService geoDataService, + NetworkMapService networkMapService, + SecurityAnalysisRestService securityAnalysisRestService, + ActionsService actionsService, + CaseService caseService, + DynamicMappingService dynamicMappingService, + VoltageInitRestService voltageInitService, + DynamicSimulationEventService dynamicSimulationEventService, + StudyConfigService studyConfigService, + NadConfigService nadConfigService, + FilterService filterService, + @Lazy StudyService studyService, + RootNetworkService rootNetworkService, + RootNetworkNodeInfoService rootNetworkNodeInfoService, + DirectoryService directoryService, + ComputationParametersService computationParametersService, + WorkspaceService workspaceService, NodeRepository nodeRepository, + NodeActivityRunnerService nodeActivityRunnerService) { this.studyRepository = studyRepository; this.studyCreationRequestRepository = studyCreationRequestRepository; this.networkStoreService = networkStoreService; @@ -235,6 +239,7 @@ public StudyService( this.computationParametersService = computationParametersService; this.workspaceService = workspaceService; this.nodeRepository = nodeRepository; + this.nodeActivityRunnerService = nodeActivityRunnerService; } private CreatedStudyBasicInfos toStudyInfos(UUID studyUuid) { @@ -307,38 +312,39 @@ public void assertIsRootNetworkAndNodeInStudy(@NonNull final UUID studyUuid, @No } } - public void unshareModificationReference( - @NonNull final UUID studyUuid, - @NonNull final UUID nodeUuid, - @NonNull final UUID modificationUuid, - String userId) { - networkModificationRestService.unshareModificationReference(modificationUuid, userId); - notificationService.emitModificationsUpdated(studyUuid, nodeUuid, Optional.empty(), List.of(modificationUuid)); - } - public void unshareAllReferencesInStudy( @NonNull final UUID studyUuid, String userId) { // get the modification references of the whole study - List modificationsReference = new ArrayList<>(); + // TODO : may be improved after integration of 5387 ticket List nodes = networkModificationTreeService.getAllNodes(studyUuid) .stream() .filter(node -> node.getType().equals(NodeType.NETWORK_MODIFICATION)) .map(NodeEntity::getIdNode).toList(); - List nodesAffected = new ArrayList<>(); + Map> referencesAffectedByNode = new HashMap<>(); nodes.forEach(nodeUuid -> { UUID groupUuid = networkModificationTreeService.getModificationGroupUuid(nodeUuid); - List modificationReferences = networkModificationRestService.getModificationReferences(groupUuid); + List modificationReferences = networkModificationRestService.getModificationReferences(groupUuid) + .stream().map(ModificationReference::modificationUuid).toList(); if (!modificationReferences.isEmpty()) { - modificationsReference.addAll(modificationReferences); - nodesAffected.add(nodeUuid); + referencesAffectedByNode.put(nodeUuid, modificationReferences); } } ); - modificationsReference.forEach(modificationReference -> - networkModificationRestService.unshareModificationReference(modificationReference.modificationUuid(), userId) + + nodeActivityRunnerService.runWith(UNSHARE_MODIFICATIONS, studyUuid, referencesAffectedByNode.keySet().stream().toList(), + () -> unshareModificationReferences(studyUuid, userId, referencesAffectedByNode)); + } + + public void unshareModificationReferences(@NonNull UUID studyUuid, String userId, Map> referencesAffectedByNode) { + referencesAffectedByNode.forEach((nodeUuid, modificationReferenceUuids) -> { + modificationReferenceUuids.forEach(modificationReferenceUuid -> { + networkModificationRestService.unshareModificationReference(modificationReferenceUuid, userId); + }); + notificationService.emitModificationsUpdated(studyUuid, nodeUuid, Optional.empty(), modificationReferenceUuids); + } ); - notificationService.emitNodesChanged(studyUuid, nodesAffected); + // notificationService.emitNodesChanged(studyUuid, referencesAffectedByNode.keySet()); // TODO : probablement pas utile, mais tester pour icone "partagé" ajoutée par Maissa en 5387 } @Transactional From bb6849d373d2d6b0501dc204687dea87f1aa42f8 Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Thu, 22 Oct 2026 16:37:10 +0200 Subject: [PATCH 04/14] activity handling Signed-off-by: Mathieu DEHARBE --- .../java/org/gridsuite/study/server/StudyServiceTest.java | 4 ++-- .../study/server/nodeactivity/NodeActivityRulesTest.java | 4 ++-- .../studycontroller/StudyControllerRebuildNodeTest.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/java/org/gridsuite/study/server/StudyServiceTest.java b/src/test/java/org/gridsuite/study/server/StudyServiceTest.java index 319c7609dd..d5d6839d14 100644 --- a/src/test/java/org/gridsuite/study/server/StudyServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/StudyServiceTest.java @@ -275,7 +275,7 @@ void testUnshareModificationReference() { UUID modificationUuid = UUID.randomUUID(); String userId = "userId"; - studyService.unshareModificationReference(studyUuid, nodeUuid, modificationUuid, userId); + studyService.unshareModificationReferences(studyUuid, userId, Map.of(nodeUuid, List.of(modificationUuid))); // the reference is replaced remotely by a copy of the shared composite, then the front is notified verify(networkModificationService, times(1)).unshareModificationReference(modificationUuid, userId); @@ -293,7 +293,7 @@ void testUnshareModificationReferenceDoesNotNotifyWhenRemoteCallFails() { .when(networkModificationService).unshareModificationReference(modificationUuid, userId); assertThrows(RuntimeException.class, - () -> studyService.unshareModificationReference(studyUuid, nodeUuid, modificationUuid, userId)); + () -> studyService.unshareModificationReferences(studyUuid, userId, Map.of(nodeUuid, List.of(modificationUuid)))); verify(notificationService, never()).emitModificationsUpdated(any(), any(), any(), any()); } diff --git a/src/test/java/org/gridsuite/study/server/nodeactivity/NodeActivityRulesTest.java b/src/test/java/org/gridsuite/study/server/nodeactivity/NodeActivityRulesTest.java index 835f665c65..211826f05b 100644 --- a/src/test/java/org/gridsuite/study/server/nodeactivity/NodeActivityRulesTest.java +++ b/src/test/java/org/gridsuite/study/server/nodeactivity/NodeActivityRulesTest.java @@ -76,7 +76,7 @@ private static boolean hasConflict(NodeActivityEntity activity, List touchOnlyTheirNode = List.of(BUILD, UNBUILD, COMPUTE, EDIT_EVENTS); + List touchOnlyTheirNode = List.of(BUILD, UNBUILD, COMPUTE, EDIT_EVENTS, UNSHARE_MODIFICATIONS); List invalidateTheirChildren = List.of(UNBUILD_CHILDREN, UNBUILD_ALL, COMPUTE_AND_UNBUILD_CHILDREN, REIMPORT_CASE, EDIT_TREE, EDIT_MODIFICATIONS, DELETE_NODES); @@ -92,7 +92,7 @@ void affectsAllRootNetworksIsClassified() { List oneRootNetwork = List.of(BUILD, UNBUILD, UNBUILD_CHILDREN, COMPUTE, COMPUTE_AND_UNBUILD_CHILDREN, REIMPORT_CASE); List allRootNetworks = List.of(UNBUILD_ALL, EDIT_TREE, EDIT_MODIFICATIONS, - DELETE_NODES, EDIT_EVENTS); + DELETE_NODES, EDIT_EVENTS, UNSHARE_MODIFICATIONS); assertThat(oneRootNetwork).noneMatch(NodeActivityType::affectsAllRootNetworks); assertThat(allRootNetworks).allMatch(NodeActivityType::affectsAllRootNetworks); diff --git a/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java b/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java index 8ad6975e6d..e759ddf6f1 100644 --- a/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java +++ b/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java @@ -153,7 +153,7 @@ void testUnshareModificationReference() { ResponseEntity response = studyController.unshareModificationReference(modificationUuid, studyUuid, nodeUuid, userId); Assertions.assertEquals(HttpStatus.OK, response.getStatusCode()); - verify(studyService, times(1)).unshareModificationReference(studyUuid, nodeUuid, modificationUuid, userId); + verify(studyService, times(1)).unshareModificationReferences(studyUuid, userId, Map.of(nodeUuid, List.of(modificationUuid))); verify(studyService, times(1)).assertIsStudyAndNodeExist(studyUuid, nodeUuid); verify(studyService, times(1)).assertIsNodeNotReadOnly(nodeUuid); } From 0a7b8c46ba640b14506a480789ba828d9e8e625e Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Thu, 22 Oct 2026 16:46:26 +0200 Subject: [PATCH 05/14] corrects TUs Signed-off-by: Mathieu DEHARBE --- .../gridsuite/study/server/error/StudyExceptionHandler.java | 1 + .../gridsuite/study/server/NetworkModificationTreeTest.java | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/gridsuite/study/server/error/StudyExceptionHandler.java b/src/main/java/org/gridsuite/study/server/error/StudyExceptionHandler.java index 9f636478a5..a729bb8e5b 100644 --- a/src/main/java/org/gridsuite/study/server/error/StudyExceptionHandler.java +++ b/src/main/java/org/gridsuite/study/server/error/StudyExceptionHandler.java @@ -33,6 +33,7 @@ protected StudyExceptionHandler(ServerNameProvider serverNameProvider) { protected HttpStatus mapStatus(StudyBusinessErrorCode studyBusinessErrorCode) { return switch (studyBusinessErrorCode) { case NOT_FOUND, + NODE_NOT_FOUND, NO_VOLTAGE_INIT_RESULTS_FOR_NODE -> HttpStatus.NOT_FOUND; case COMPUTATION_RUNNING, diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java index cb00a4dc97..0753b7a545 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java @@ -90,7 +90,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.gridsuite.study.server.StudyConstants.HEADER_USER_ID; -import static org.gridsuite.study.server.error.StudyBusinessErrorCode.NOT_FOUND; +import static org.gridsuite.study.server.error.StudyBusinessErrorCode.NODE_NOT_FOUND; import static org.gridsuite.study.server.notification.NotificationService.*; import static org.gridsuite.study.server.service.NetworkModificationTreeService.ROOT_NODE_NAME; import static org.gridsuite.study.server.utils.TestUtils.checkUpdateStatusMessagesReceived; @@ -808,7 +808,7 @@ void testNodeModificationInfos() throws Exception { RootNode root = getRootNode(rootStudyId, firstRootNetworkUuid); UUID rootId = root.getId(); - RootNodeInfoEntity rootInfos = rootNodeInfoRepository.findById(rootId).orElseThrow(() -> new StudyException(NOT_FOUND, "Node not found")); + RootNodeInfoEntity rootInfos = rootNodeInfoRepository.findById(rootId).orElseThrow(() -> new StudyException(NODE_NOT_FOUND, "Node not found")); assertEquals(rootId, rootInfos.getId()); List children = root.getChildren(); @@ -816,7 +816,7 @@ void testNodeModificationInfos() throws Exception { NetworkModificationNode n1 = (NetworkModificationNode) (children.stream().filter(c -> c.getName().equals("n1")).findFirst().orElseThrow()); NetworkModificationNodeInfoEntity n1Infos = networkModificationTreeService.getNetworkModificationNodeInfoEntity(n1.getId()); RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoRepository.findByNodeInfoIdAndRootNetworkId(n1.getId(), - firstRootNetworkUuid).orElseThrow(() -> new StudyException(NOT_FOUND, "Root network not found")); + firstRootNetworkUuid).orElseThrow(() -> new StudyException(NODE_NOT_FOUND, "Root network not found")); assertEquals("n1", n1.getName()); assertEquals("zzz", n1.getDescription()); From 9192c8f556c4243d532b6c15e8dc93c7c87200ce Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Thu, 22 Oct 2026 17:17:14 +0200 Subject: [PATCH 06/14] more TUs Signed-off-by: Mathieu DEHARBE --- .../study/server/StudyServiceTest.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/test/java/org/gridsuite/study/server/StudyServiceTest.java b/src/test/java/org/gridsuite/study/server/StudyServiceTest.java index dac1303cae..c8ccbf5c30 100644 --- a/src/test/java/org/gridsuite/study/server/StudyServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/StudyServiceTest.java @@ -7,6 +7,7 @@ package org.gridsuite.study.server; import org.gridsuite.study.server.dto.ComputationType; +import org.gridsuite.study.server.dto.ModificationReference; import org.gridsuite.study.server.dto.QuotaState; import org.gridsuite.study.server.dto.QuotaType; import org.gridsuite.study.server.error.StudyException; @@ -14,6 +15,8 @@ import org.gridsuite.study.server.networkmodificationtree.dto.NodeBuildStatus; import org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity; import org.gridsuite.study.server.networkmodificationtree.entities.NodeType; +import org.gridsuite.study.server.nodeactivity.NodeActivityRunnerService; +import org.gridsuite.study.server.nodeactivity.NodeActivityType; import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.networkmodificationtree.NodeRepository; import org.gridsuite.study.server.service.NetworkModificationTreeService; @@ -58,6 +61,8 @@ class StudyServiceTest { private NotificationService notificationService; @MockitoBean private RootNetworkService rootNetworkService; + @MockitoBean + private NodeActivityRunnerService nodeActivityRunnerService; @AfterEach void resetOperationQuotasFlag() { @@ -282,6 +287,50 @@ void testUnshareModificationReference() { verify(notificationService, times(1)).emitModificationsUpdated(studyUuid, nodeUuid, Optional.empty(), List.of(modificationUuid)); } + @Test + void testUnshareAllReferencesInStudy() { + UUID studyUuid = UUID.randomUUID(); + String userId = "userId"; + + doReturn(List.of()).when(networkModificationTreeService).getAllNodes(studyUuid); + + studyService.unshareAllReferencesInStudy(studyUuid, userId); + + verify(networkModificationTreeService, times(1)).getAllNodes(studyUuid); + } + + @Test + void testUnshareAllReferencesInStudyWithReferences() { + UUID studyUuid = UUID.randomUUID(); + UUID nodeUuid = UUID.randomUUID(); + UUID modificationUuid = UUID.randomUUID(); + String userId = "userId"; + + NodeEntity nodeEntity = new NodeEntity(nodeUuid, null, NodeType.NETWORK_MODIFICATION, null, false, null, List.of()); + doReturn(List.of(nodeEntity)).when(networkModificationTreeService).getAllNodes(studyUuid); + + UUID groupUuid = UUID.randomUUID(); + doReturn(groupUuid).when(networkModificationTreeService).getModificationGroupUuid(nodeUuid); + + ModificationReference modificationReference = new ModificationReference(modificationUuid, UUID.randomUUID(), null); + doReturn(List.of(modificationReference)).when(networkModificationService).getModificationReferences(groupUuid); + + // Mock nodeActivityRunnerService to bypass database checks + doAnswer(invocation -> { + Runnable runnable = invocation.getArgument(3); + runnable.run(); + return null; + }).when(nodeActivityRunnerService).runWith(any(), any(), any(), (Runnable)any()); + + studyService.unshareAllReferencesInStudy(studyUuid, userId); + + verify(networkModificationTreeService, times(1)).getAllNodes(studyUuid); + verify(networkModificationTreeService, times(1)).getModificationGroupUuid(nodeUuid); + verify(networkModificationService, times(1)).getModificationReferences(groupUuid); + verify(networkModificationService, times(1)).unshareModificationReference(modificationUuid, userId); + verify(notificationService, times(1)).emitModificationsUpdated(studyUuid, nodeUuid, Optional.empty(), List.of(modificationUuid)); + } + @Test void testUnshareModificationReferenceDoesNotNotifyWhenRemoteCallFails() { UUID studyUuid = UUID.randomUUID(); From 21586c4d8556dae1b49382e9003920d0336fac74 Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Thu, 22 Oct 2026 17:19:26 +0200 Subject: [PATCH 07/14] sonar Signed-off-by: Mathieu DEHARBE --- src/test/java/org/gridsuite/study/server/StudyServiceTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/org/gridsuite/study/server/StudyServiceTest.java b/src/test/java/org/gridsuite/study/server/StudyServiceTest.java index c8ccbf5c30..c772816d40 100644 --- a/src/test/java/org/gridsuite/study/server/StudyServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/StudyServiceTest.java @@ -16,7 +16,6 @@ import org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity; import org.gridsuite.study.server.networkmodificationtree.entities.NodeType; import org.gridsuite.study.server.nodeactivity.NodeActivityRunnerService; -import org.gridsuite.study.server.nodeactivity.NodeActivityType; import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.networkmodificationtree.NodeRepository; import org.gridsuite.study.server.service.NetworkModificationTreeService; @@ -320,7 +319,7 @@ void testUnshareAllReferencesInStudyWithReferences() { Runnable runnable = invocation.getArgument(3); runnable.run(); return null; - }).when(nodeActivityRunnerService).runWith(any(), any(), any(), (Runnable)any()); + }).when(nodeActivityRunnerService).runWith(any(), any(), any(), (Runnable) any()); studyService.unshareAllReferencesInStudy(studyUuid, userId); From ef18bf5b15bdcac347a1cbe4766512a8f2f8b845 Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Mon, 26 Oct 2026 11:17:36 +0100 Subject: [PATCH 08/14] post merge conflicts / refactos Signed-off-by: Mathieu DEHARBE --- .../server/controller/StudyController.java | 5 +- .../study/server/service/StudyService.java | 42 +--------------- .../NetworkModificationService.java | 49 ++++++++++++++++--- .../study/server/StudyServiceTest.java | 15 +++--- .../StudyControllerRebuildNodeTest.java | 3 +- 5 files changed, 51 insertions(+), 63 deletions(-) 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 241b6cfa93..2bf47c6159 100644 --- a/src/main/java/org/gridsuite/study/server/controller/StudyController.java +++ b/src/main/java/org/gridsuite/study/server/controller/StudyController.java @@ -314,8 +314,7 @@ public ResponseEntity unshareModificationReference( @RequestHeader(HEADER_USER_ID) String userId) { studyService.assertIsStudyAndNodeExist(studyUuid, nodeUuid); studyService.assertIsNodeNotReadOnly(nodeUuid); - networkModificationActivityRunnerService.runWith(studyUuid, nodeUuid, userId, - () -> networkModificationService.unshareModificationReference(studyUuid, nodeUuid, modificationUuid, userId)); + networkModificationService.unshareModificationReferences(studyUuid, Map.of(nodeUuid, List.of(modificationUuid)), userId); return ResponseEntity.ok().build(); } @@ -325,7 +324,7 @@ public ResponseEntity unshareModificationReference( public ResponseEntity unshareAllReferencesInStudy( @PathVariable("studyUuid") UUID studyUuid, @RequestHeader(HEADER_USER_ID) String userId) { - studyService.unshareAllReferencesInStudy(studyUuid, userId); + networkModificationService.unshareAllReferencesInStudy(studyUuid, userId); return ResponseEntity.ok().build(); } 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 db286ae91f..459890f0e8 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -37,7 +37,6 @@ import org.gridsuite.study.server.networkmodificationtree.entities.NetworkModificationNodeType; import org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity; import org.gridsuite.study.server.networkmodificationtree.entities.NodeType; -import org.gridsuite.study.server.nodeactivity.NodeActivityRunnerService; import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.*; import org.gridsuite.study.server.repository.networkmodificationtree.NodeRepository; @@ -83,7 +82,6 @@ import static org.gridsuite.study.server.StudyConstants.CURRENT_LIMIT_VIOLATIONS_INFOS; import static org.gridsuite.study.server.dto.ComputationType.*; import static org.gridsuite.study.server.error.StudyBusinessErrorCode.*; -import static org.gridsuite.study.server.nodeactivity.NodeActivityType.UNSHARE_MODIFICATIONS; /** * @author Abdelsalem Hedhili @@ -124,7 +122,6 @@ public class StudyService { private final RootNetworkService rootNetworkService; private final RootNetworkNodeInfoService rootNetworkNodeInfoService; private final DirectoryService directoryService; - private final NodeActivityRunnerService nodeActivityRunnerService; private final ComputationParametersService computationParametersService; private final LoadFlowRestService loadflowRestService; @@ -200,8 +197,7 @@ public StudyService( RootNetworkNodeInfoService rootNetworkNodeInfoService, DirectoryService directoryService, ComputationParametersService computationParametersService, - WorkspaceService workspaceService, NodeRepository nodeRepository, - NodeActivityRunnerService nodeActivityRunnerService) { + WorkspaceService workspaceService, NodeRepository nodeRepository) { this.studyRepository = studyRepository; this.studyCreationRequestRepository = studyCreationRequestRepository; this.networkStoreService = networkStoreService; @@ -237,7 +233,6 @@ public StudyService( this.computationParametersService = computationParametersService; this.workspaceService = workspaceService; this.nodeRepository = nodeRepository; - this.nodeActivityRunnerService = nodeActivityRunnerService; } private CreatedStudyBasicInfos toStudyInfos(UUID studyUuid) { @@ -310,41 +305,6 @@ public void assertIsRootNetworkAndNodeInStudy(@NonNull final UUID studyUuid, @No } } - public void unshareAllReferencesInStudy( - @NonNull final UUID studyUuid, - String userId) { - // get the modification references of the whole study - // TODO : may be improved after integration of 5387 ticket - List nodes = networkModificationTreeService.getAllNodes(studyUuid) - .stream() - .filter(node -> node.getType().equals(NodeType.NETWORK_MODIFICATION)) - .map(NodeEntity::getIdNode).toList(); - Map> referencesAffectedByNode = new HashMap<>(); - nodes.forEach(nodeUuid -> { - UUID groupUuid = networkModificationTreeService.getModificationGroupUuid(nodeUuid); - List modificationReferences = networkModificationRestService.getModificationReferences(groupUuid) - .stream().map(ModificationReference::modificationUuid).toList(); - if (!modificationReferences.isEmpty()) { - referencesAffectedByNode.put(nodeUuid, modificationReferences); - } - } - ); - - nodeActivityRunnerService.runWith(UNSHARE_MODIFICATIONS, studyUuid, referencesAffectedByNode.keySet().stream().toList(), - () -> unshareModificationReferences(studyUuid, userId, referencesAffectedByNode)); - } - - public void unshareModificationReferences(@NonNull UUID studyUuid, String userId, Map> referencesAffectedByNode) { - referencesAffectedByNode.forEach((nodeUuid, modificationReferenceUuids) -> { - modificationReferenceUuids.forEach(modificationReferenceUuid -> { - networkModificationRestService.unshareModificationReference(modificationReferenceUuid, userId); - }); - notificationService.emitModificationsUpdated(studyUuid, nodeUuid, Optional.empty(), modificationReferenceUuids); - } - ); - // notificationService.emitNodesChanged(studyUuid, referencesAffectedByNode.keySet()); // TODO : probablement pas utile, mais tester pour icone "partagé" ajoutée par Maissa en 5387 - } - @Transactional public void deleteRootNetworks(UUID studyUuid, List rootNetworksUuids, String userId) { assertIsStudyExist(studyUuid); diff --git a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java index 8a47e497e5..da6fa17b7c 100644 --- a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java @@ -14,6 +14,9 @@ import org.gridsuite.study.server.dto.networkexport.PermissionType; import org.gridsuite.study.server.error.StudyException; import org.gridsuite.study.server.networkmodificationtree.dto.NodeBuildStatus; +import org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity; +import org.gridsuite.study.server.networkmodificationtree.entities.NodeType; +import org.gridsuite.study.server.nodeactivity.NodeActivityRunnerService; import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; import org.gridsuite.study.server.service.DirectoryService; @@ -30,6 +33,7 @@ import static org.gridsuite.study.server.error.StudyBusinessErrorCode.NOT_ALLOWED; import static org.gridsuite.study.server.error.StudyBusinessErrorCode.NOT_FOUND; +import static org.gridsuite.study.server.nodeactivity.NodeActivityType.UNSHARE_MODIFICATIONS; /** * @author Slimane amar @@ -42,19 +46,22 @@ public class NetworkModificationService { private final NetworkModificationRestService networkModificationRestService; private final NotificationService notificationService; private final DirectoryService directoryService; + private final NodeActivityRunnerService nodeActivityRunnerService; public NetworkModificationService(NetworkModificationTreeService networkModificationTreeService, RootNetworkService rootNetworkService, RootNetworkNodeInfoService rootNetworkNodeInfoService, NetworkModificationRestService networkModificationRestService, NotificationService notificationService, - DirectoryService directoryService) { + DirectoryService directoryService, + NodeActivityRunnerService nodeActivityRunnerService) { this.networkModificationTreeService = networkModificationTreeService; this.rootNetworkService = rootNetworkService; this.rootNetworkNodeInfoService = rootNetworkNodeInfoService; this.networkModificationRestService = networkModificationRestService; this.notificationService = notificationService; this.directoryService = directoryService; + this.nodeActivityRunnerService = nodeActivityRunnerService; } public void updateNetworkModificationNameAndDescription(UUID studyUuid, UUID nodeUuid, UUID networkModificationUuid, String metadata) { @@ -342,13 +349,39 @@ public NodeBuildStatus getNodeBuildStatus(UUID nodeUuid, UUID rootNetworkUuid) { return networkModificationTreeService.getNodeBuildStatus(nodeUuid, rootNetworkUuid); } - public void unshareModificationReference( - @NonNull final UUID studyUuid, - @NonNull final UUID nodeUuid, - @NonNull final UUID modificationUuid, - String userId) { - networkModificationRestService.unshareModificationReference(modificationUuid, userId); - notificationService.emitModificationsUpdated(studyUuid, nodeUuid, Optional.empty(), List.of(modificationUuid)); + public void unshareAllReferencesInStudy( + @NonNull final UUID studyUuid, + String userId) { + // get the modification references of the whole study + // TODO : may be improved after integration of 5387 ticket + List nodes = networkModificationTreeService.getAllNodes(studyUuid) + .stream() + .filter(node -> node.getType().equals(NodeType.NETWORK_MODIFICATION)) + .map(NodeEntity::getIdNode).toList(); + Map> referencesAffectedByNode = new HashMap<>(); + nodes.forEach(nodeUuid -> { + UUID groupUuid = networkModificationTreeService.getModificationGroupUuid(nodeUuid); + List modificationReferences = networkModificationRestService.getModificationReferences(groupUuid) + .stream().map(ModificationReference::modificationUuid).toList(); + if (!modificationReferences.isEmpty()) { + referencesAffectedByNode.put(nodeUuid, modificationReferences); + } + } + ); + + nodeActivityRunnerService.runWith(UNSHARE_MODIFICATIONS, studyUuid, referencesAffectedByNode.keySet().stream().toList(), + () -> unshareModificationReferences(studyUuid, referencesAffectedByNode, userId)); + } + + public void unshareModificationReferences(@NonNull UUID studyUuid, Map> referencesAffectedByNode, String userId) { + referencesAffectedByNode.forEach((nodeUuid, modificationReferenceUuids) -> { + modificationReferenceUuids.forEach(modificationReferenceUuid -> + networkModificationRestService.unshareModificationReference(modificationReferenceUuid, userId) + ); + notificationService.emitModificationsUpdated(studyUuid, nodeUuid, Optional.empty(), modificationReferenceUuids); + } + ); + // notificationService.emitNodesChanged(studyUuid, referencesAffectedByNode.keySet()); // TODO : probablement pas utile, mais tester pour icone "partagé" ajoutée par Maissa en 5387 } @Transactional(readOnly = true) diff --git a/src/test/java/org/gridsuite/study/server/StudyServiceTest.java b/src/test/java/org/gridsuite/study/server/StudyServiceTest.java index e033b1ba1b..1c52190984 100644 --- a/src/test/java/org/gridsuite/study/server/StudyServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/StudyServiceTest.java @@ -282,8 +282,7 @@ void testUnshareModificationReference() { UUID modificationUuid = UUID.randomUUID(); String userId = "userId"; - // studyService.unshareModificationReferences(studyUuid, userId, Map.of(nodeUuid, List.of(modificationUuid))); - networkModificationService.unshareModificationReference(studyUuid, nodeUuid, modificationUuid, userId); + networkModificationService.unshareModificationReferences(studyUuid, Map.of(nodeUuid, List.of(modificationUuid)), userId); // the reference is replaced remotely by a copy of the shared composite, then the front is notified verify(networkModificationRestService, times(1)).unshareModificationReference(modificationUuid, userId); @@ -297,7 +296,7 @@ void testUnshareAllReferencesInStudy() { doReturn(List.of()).when(networkModificationTreeService).getAllNodes(studyUuid); - studyService.unshareAllReferencesInStudy(studyUuid, userId); + networkModificationService.unshareAllReferencesInStudy(studyUuid, userId); verify(networkModificationTreeService, times(1)).getAllNodes(studyUuid); } @@ -316,7 +315,7 @@ void testUnshareAllReferencesInStudyWithReferences() { doReturn(groupUuid).when(networkModificationTreeService).getModificationGroupUuid(nodeUuid); ModificationReference modificationReference = new ModificationReference(modificationUuid, UUID.randomUUID(), null); - doReturn(List.of(modificationReference)).when(networkModificationService).getModificationReferences(groupUuid); + doReturn(List.of(modificationReference)).when(networkModificationRestService).getModificationReferences(groupUuid); // Mock nodeActivityRunnerService to bypass database checks doAnswer(invocation -> { @@ -325,12 +324,11 @@ void testUnshareAllReferencesInStudyWithReferences() { return null; }).when(nodeActivityRunnerService).runWith(any(), any(), any(), (Runnable) any()); - studyService.unshareAllReferencesInStudy(studyUuid, userId); + networkModificationService.unshareAllReferencesInStudy(studyUuid, userId); verify(networkModificationTreeService, times(1)).getAllNodes(studyUuid); verify(networkModificationTreeService, times(1)).getModificationGroupUuid(nodeUuid); - verify(networkModificationService, times(1)).getModificationReferences(groupUuid); - verify(networkModificationService, times(1)).unshareModificationReference(modificationUuid, userId); + verify(networkModificationRestService, times(1)).getModificationReferences(groupUuid); verify(notificationService, times(1)).emitModificationsUpdated(studyUuid, nodeUuid, Optional.empty(), List.of(modificationUuid)); } @@ -346,9 +344,8 @@ void testUnshareModificationReferenceDoesNotNotifyWhenRemoteCallFails() { assertThrows(RuntimeException.class, // () -> studyService.unshareModificationReferences(studyUuid, userId, Map.of(nodeUuid, List.of(modificationUuid)))); - () -> networkModificationService.unshareModificationReference(studyUuid, nodeUuid, modificationUuid, userId)); + () -> networkModificationService.unshareModificationReferences(studyUuid, Map.of(nodeUuid, List.of(modificationUuid)), userId)); verify(notificationService, never()).emitModificationsUpdated(any(), any(), any(), any()); } - } diff --git a/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java b/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java index 1a92a55ea6..a818322cc5 100644 --- a/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java +++ b/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java @@ -170,8 +170,7 @@ void testUnshareModificationReference() { ResponseEntity response = studyController.unshareModificationReference(modificationUuid, studyUuid, nodeUuid, userId); Assertions.assertEquals(HttpStatus.OK, response.getStatusCode()); - // verify(studyService, times(1)).unshareModificationReferences(studyUuid, userId, Map.of(nodeUuid, List.of(modificationUuid))); - verify(networkModificationService, times(1)).unshareModificationReference(studyUuid, nodeUuid, modificationUuid, userId); + verify(networkModificationService, times(1)).unshareModificationReferences(studyUuid, Map.of(nodeUuid, List.of(modificationUuid)), userId); verify(studyService, times(1)).assertIsStudyAndNodeExist(studyUuid, nodeUuid); verify(studyService, times(1)).assertIsNodeNotReadOnly(nodeUuid); } From 4a1e592d82c5fae789f1d85b736f7c346b68b757 Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Mon, 26 Oct 2026 13:31:05 +0100 Subject: [PATCH 09/14] cleaning Signed-off-by: Mathieu DEHARBE --- .../org/gridsuite/study/server/controller/StudyController.java | 3 ++- .../networkmodification/NetworkModificationService.java | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) 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 2bf47c6159..c4020e860f 100644 --- a/src/main/java/org/gridsuite/study/server/controller/StudyController.java +++ b/src/main/java/org/gridsuite/study/server/controller/StudyController.java @@ -314,7 +314,8 @@ public ResponseEntity unshareModificationReference( @RequestHeader(HEADER_USER_ID) String userId) { studyService.assertIsStudyAndNodeExist(studyUuid, nodeUuid); studyService.assertIsNodeNotReadOnly(nodeUuid); - networkModificationService.unshareModificationReferences(studyUuid, Map.of(nodeUuid, List.of(modificationUuid)), userId); + networkModificationActivityRunnerService.runWith(studyUuid, nodeUuid, userId, + () -> networkModificationService.unshareModificationReferences(studyUuid, Map.of(nodeUuid, List.of(modificationUuid)), userId)); return ResponseEntity.ok().build(); } diff --git a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java index da6fa17b7c..88f394e801 100644 --- a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java @@ -353,7 +353,6 @@ public void unshareAllReferencesInStudy( @NonNull final UUID studyUuid, String userId) { // get the modification references of the whole study - // TODO : may be improved after integration of 5387 ticket List nodes = networkModificationTreeService.getAllNodes(studyUuid) .stream() .filter(node -> node.getType().equals(NodeType.NETWORK_MODIFICATION)) @@ -381,7 +380,6 @@ public void unshareModificationReferences(@NonNull UUID studyUuid, Map Date: Mon, 26 Oct 2026 13:34:27 +0100 Subject: [PATCH 10/14] ignore read only nodes Signed-off-by: Mathieu DEHARBE --- .../networkmodification/NetworkModificationService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java index 88f394e801..e281effb52 100644 --- a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java @@ -356,7 +356,9 @@ public void unshareAllReferencesInStudy( List nodes = networkModificationTreeService.getAllNodes(studyUuid) .stream() .filter(node -> node.getType().equals(NodeType.NETWORK_MODIFICATION)) - .map(NodeEntity::getIdNode).toList(); + .map(NodeEntity::getIdNode) + .filter(idNode -> !networkModificationTreeService.isReadOnly(idNode)) + .toList(); Map> referencesAffectedByNode = new HashMap<>(); nodes.forEach(nodeUuid -> { UUID groupUuid = networkModificationTreeService.getModificationGroupUuid(nodeUuid); From 3422e4f34a718d81d1b7121cc59a96e29c75040a Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Mon, 26 Oct 2026 13:55:43 +0100 Subject: [PATCH 11/14] various Signed-off-by: Mathieu DEHARBE --- .../study/server/service/StudyService.java | 68 +++++++++---------- .../NetworkModificationService.java | 7 +- 2 files changed, 38 insertions(+), 37 deletions(-) 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 459890f0e8..c2af64fb9d 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -164,40 +164,40 @@ public enum ReportType { @Autowired public StudyService( - StudyRepository studyRepository, - StudyCreationRequestRepository studyCreationRequestRepository, - NetworkService networkStoreService, - NetworkModificationRestService networkModificationRestService, - ReportService reportService, - UserAdminService userAdminService, - StudyInfosService studyInfosService, - EquipmentInfosService equipmentInfosService, - NetworkModificationTreeService networkModificationTreeService, - ObjectMapper objectMapper, - StudyServerExecutionService studyServerExecutionService, - NotificationService notificationService, - LoadFlowRestService loadflowRestService, - LoadFlowService loadFlowService, - ShortCircuitRestService shortCircuitService, - SingleLineDiagramService singleLineDiagramService, - NetworkConversionService networkConversionService, - GeoDataService geoDataService, - NetworkMapService networkMapService, - SecurityAnalysisRestService securityAnalysisRestService, - ActionsService actionsService, - CaseService caseService, - DynamicMappingService dynamicMappingService, - VoltageInitRestService voltageInitService, - DynamicSimulationEventService dynamicSimulationEventService, - StudyConfigService studyConfigService, - NadConfigService nadConfigService, - FilterService filterService, - @Lazy StudyService studyService, - RootNetworkService rootNetworkService, - RootNetworkNodeInfoService rootNetworkNodeInfoService, - DirectoryService directoryService, - ComputationParametersService computationParametersService, - WorkspaceService workspaceService, NodeRepository nodeRepository) { + StudyRepository studyRepository, + StudyCreationRequestRepository studyCreationRequestRepository, + NetworkService networkStoreService, + NetworkModificationRestService networkModificationRestService, + ReportService reportService, + UserAdminService userAdminService, + StudyInfosService studyInfosService, + EquipmentInfosService equipmentInfosService, + NetworkModificationTreeService networkModificationTreeService, + ObjectMapper objectMapper, + StudyServerExecutionService studyServerExecutionService, + NotificationService notificationService, + LoadFlowRestService loadflowRestService, + LoadFlowService loadFlowService, + ShortCircuitRestService shortCircuitService, + SingleLineDiagramService singleLineDiagramService, + NetworkConversionService networkConversionService, + GeoDataService geoDataService, + NetworkMapService networkMapService, + SecurityAnalysisRestService securityAnalysisRestService, + ActionsService actionsService, + CaseService caseService, + DynamicMappingService dynamicMappingService, + VoltageInitRestService voltageInitService, + DynamicSimulationEventService dynamicSimulationEventService, + StudyConfigService studyConfigService, + NadConfigService nadConfigService, + FilterService filterService, + @Lazy StudyService studyService, + RootNetworkService rootNetworkService, + RootNetworkNodeInfoService rootNetworkNodeInfoService, + DirectoryService directoryService, + ComputationParametersService computationParametersService, + WorkspaceService workspaceService, NodeRepository nodeRepository) { this.studyRepository = studyRepository; this.studyCreationRequestRepository = studyCreationRequestRepository; this.networkStoreService = networkStoreService; diff --git a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java index e281effb52..be855fa832 100644 --- a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java @@ -352,12 +352,12 @@ public NodeBuildStatus getNodeBuildStatus(UUID nodeUuid, UUID rootNetworkUuid) { public void unshareAllReferencesInStudy( @NonNull final UUID studyUuid, String userId) { - // get the modification references of the whole study + // get the modification references of the whole study sorted by their node List nodes = networkModificationTreeService.getAllNodes(studyUuid) .stream() .filter(node -> node.getType().equals(NodeType.NETWORK_MODIFICATION)) .map(NodeEntity::getIdNode) - .filter(idNode -> !networkModificationTreeService.isReadOnly(idNode)) + .filter(idNode -> !Boolean.TRUE.equals(networkModificationTreeService.isReadOnly(idNode))) .toList(); Map> referencesAffectedByNode = new HashMap<>(); nodes.forEach(nodeUuid -> { @@ -379,9 +379,10 @@ public void unshareModificationReferences(@NonNull UUID studyUuid, Map networkModificationRestService.unshareModificationReference(modificationReferenceUuid, userId) ); - notificationService.emitModificationsUpdated(studyUuid, nodeUuid, Optional.empty(), modificationReferenceUuids); + notificationService.emitSharedModificationsUpdated(studyUuid, nodeUuid, modificationReferenceUuids); } ); + notificationService.emitNodesChanged(studyUuid, referencesAffectedByNode.keySet()); } @Transactional(readOnly = true) From 37c3a7e638454412949765f13feb9c0047cb83d9 Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Mon, 26 Oct 2026 15:54:43 +0100 Subject: [PATCH 12/14] various cleanings Signed-off-by: Mathieu DEHARBE --- .../NetworkModificationRestService.java | 5 +++-- .../NetworkModificationService.java | 8 ++------ .../org/gridsuite/study/server/StudyServiceTest.java | 10 ++++------ .../NetworkModificationServiceTest.java | 4 ++-- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationRestService.java b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationRestService.java index 81bf63fabc..3d86be9280 100644 --- a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationRestService.java +++ b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationRestService.java @@ -149,8 +149,9 @@ public void updateNetworkModification(UUID networkModificationUuid, String modif restTemplate.exchange(getNetworkModificationServerURI(false) + path, HttpMethod.PUT, new HttpEntity<>(modificationInfos, headers), Void.class); } - public void unshareModificationReference(UUID modificationReferenceUuid, String userId) { - String path = UriComponentsBuilder.fromPath(NETWORK_MODIFICATIONS_PATH + "/{uuid}/unshare").buildAndExpand(modificationReferenceUuid).toUriString(); + public void unshareModificationReferences(List modificationReferenceUuids, String userId) { + String path = UriComponentsBuilder.fromPath(NETWORK_MODIFICATIONS_PATH + "/unshare") + .queryParam(UUIDS, modificationReferenceUuids).build().toUriString(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.set(HEADER_USER_ID, userId); diff --git a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java index be855fa832..ee2b3cf996 100644 --- a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java @@ -357,7 +357,6 @@ public void unshareAllReferencesInStudy( .stream() .filter(node -> node.getType().equals(NodeType.NETWORK_MODIFICATION)) .map(NodeEntity::getIdNode) - .filter(idNode -> !Boolean.TRUE.equals(networkModificationTreeService.isReadOnly(idNode))) .toList(); Map> referencesAffectedByNode = new HashMap<>(); nodes.forEach(nodeUuid -> { @@ -376,13 +375,10 @@ public void unshareAllReferencesInStudy( public void unshareModificationReferences(@NonNull UUID studyUuid, Map> referencesAffectedByNode, String userId) { referencesAffectedByNode.forEach((nodeUuid, modificationReferenceUuids) -> { - modificationReferenceUuids.forEach(modificationReferenceUuid -> - networkModificationRestService.unshareModificationReference(modificationReferenceUuid, userId) - ); - notificationService.emitSharedModificationsUpdated(studyUuid, nodeUuid, modificationReferenceUuids); + networkModificationRestService.unshareModificationReferences(modificationReferenceUuids, userId); + notificationService.emitModificationsUpdated(studyUuid, nodeUuid, modificationReferenceUuids); } ); - notificationService.emitNodesChanged(studyUuid, referencesAffectedByNode.keySet()); } @Transactional(readOnly = true) diff --git a/src/test/java/org/gridsuite/study/server/StudyServiceTest.java b/src/test/java/org/gridsuite/study/server/StudyServiceTest.java index 1c52190984..b8714bac7c 100644 --- a/src/test/java/org/gridsuite/study/server/StudyServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/StudyServiceTest.java @@ -35,7 +35,6 @@ import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.UUID; import static org.gridsuite.study.server.error.StudyBusinessErrorCode.MAX_OPERATION_TYPE_EXCEEDED; @@ -285,8 +284,8 @@ void testUnshareModificationReference() { networkModificationService.unshareModificationReferences(studyUuid, Map.of(nodeUuid, List.of(modificationUuid)), userId); // the reference is replaced remotely by a copy of the shared composite, then the front is notified - verify(networkModificationRestService, times(1)).unshareModificationReference(modificationUuid, userId); - verify(notificationService, times(1)).emitModificationsUpdated(studyUuid, nodeUuid, Optional.empty(), List.of(modificationUuid)); + verify(networkModificationRestService, times(1)).unshareModificationReferences(List.of(modificationUuid), userId); + verify(notificationService, times(1)).emitModificationsUpdated(studyUuid, nodeUuid, List.of(modificationUuid)); } @Test @@ -329,7 +328,7 @@ void testUnshareAllReferencesInStudyWithReferences() { verify(networkModificationTreeService, times(1)).getAllNodes(studyUuid); verify(networkModificationTreeService, times(1)).getModificationGroupUuid(nodeUuid); verify(networkModificationRestService, times(1)).getModificationReferences(groupUuid); - verify(notificationService, times(1)).emitModificationsUpdated(studyUuid, nodeUuid, Optional.empty(), List.of(modificationUuid)); + verify(notificationService, times(1)).emitModificationsUpdated(studyUuid, nodeUuid, List.of(modificationUuid)); } @Test @@ -340,10 +339,9 @@ void testUnshareModificationReferenceDoesNotNotifyWhenRemoteCallFails() { String userId = "userId"; doThrow(new RuntimeException("network modification server error")) - .when(networkModificationRestService).unshareModificationReference(modificationUuid, userId); + .when(networkModificationRestService).unshareModificationReferences(List.of(modificationUuid), userId); assertThrows(RuntimeException.class, - // () -> studyService.unshareModificationReferences(studyUuid, userId, Map.of(nodeUuid, List.of(modificationUuid)))); () -> networkModificationService.unshareModificationReferences(studyUuid, Map.of(nodeUuid, List.of(modificationUuid)), userId)); verify(notificationService, never()).emitModificationsUpdated(any(), any(), any(), any()); diff --git a/src/test/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationServiceTest.java b/src/test/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationServiceTest.java index 35a46baf81..f867e70f89 100644 --- a/src/test/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationServiceTest.java @@ -126,9 +126,9 @@ void testUpdateNetworkModificationsMetadata() { @Test void testUnshareModificationReference() { UUID modificationReferenceUuid = UUID.randomUUID(); - String expectedUrl = NETWORK_MODIFICATION_SERVER_URI + "/v1/network-modifications/" + modificationReferenceUuid + "/unshare"; + String expectedUrl = NETWORK_MODIFICATION_SERVER_URI + "/v1/network-modifications/unshare?uuids=" + modificationReferenceUuid; - networkModificationService.unshareModificationReference(modificationReferenceUuid, USER_ID); + networkModificationService.unshareModificationReferences(List.of(modificationReferenceUuid), USER_ID); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); From 82104f231b442d79f4846524e8670500e3a2f12d Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Tue, 27 Oct 2026 15:18:31 +0100 Subject: [PATCH 13/14] Maissa patch (quite) Signed-off-by: Mathieu DEHARBE --- .../server/controller/StudyController.java | 3 +- .../NetworkModificationTreeService.java | 4 ++ .../NetworkModificationRestService.java | 8 +--- .../NetworkModificationService.java | 42 +++++++++---------- .../server/NetworkModificationTreeTest.java | 3 +- .../study/server/StudyServiceTest.java | 26 +++++++++--- .../NetworkModificationServiceTest.java | 4 +- .../StudyControllerRebuildNodeTest.java | 9 ++++ 8 files changed, 61 insertions(+), 38 deletions(-) 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 c4020e860f..aa2520c9e1 100644 --- a/src/main/java/org/gridsuite/study/server/controller/StudyController.java +++ b/src/main/java/org/gridsuite/study/server/controller/StudyController.java @@ -321,10 +321,11 @@ public ResponseEntity unshareModificationReference( @PutMapping(value = "/studies/{studyUuid}/unshare") @Operation(summary = "Unshare all the reference modifications and copy the referenced composites in their place") - @ApiResponse(responseCode = "200", description = "All the reference modifications from the study have been replaced by a copy of its referenced composite") + @ApiResponse(responseCode = "200", description = "All the reference modifications from the study have been replaced by copies of their referenced composites") public ResponseEntity unshareAllReferencesInStudy( @PathVariable("studyUuid") UUID studyUuid, @RequestHeader(HEADER_USER_ID) String userId) { + studyService.assertIsStudyExist(studyUuid); networkModificationService.unshareAllReferencesInStudy(studyUuid, userId); return ResponseEntity.ok().build(); } diff --git a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java index 9428d33702..42781d7928 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java @@ -999,6 +999,10 @@ public List getAllNodes(UUID studyUuid) { return nodesRepository.findAllByStudyId(studyUuid); } + public List getAllNotStashedNetworkModificationNodes(UUID studyUuid) { + return nodesRepository.findAllByStudyIdAndTypeAndStashed(studyUuid, NodeType.NETWORK_MODIFICATION, false); + } + /** * Gets or generates a modification report UUID for a node. *

diff --git a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationRestService.java b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationRestService.java index 3d86be9280..0f6abbf08f 100644 --- a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationRestService.java +++ b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationRestService.java @@ -150,12 +150,8 @@ public void updateNetworkModification(UUID networkModificationUuid, String modif } public void unshareModificationReferences(List modificationReferenceUuids, String userId) { - String path = UriComponentsBuilder.fromPath(NETWORK_MODIFICATIONS_PATH + "/unshare") - .queryParam(UUIDS, modificationReferenceUuids).build().toUriString(); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - headers.set(HEADER_USER_ID, userId); - restTemplate.exchange(getNetworkModificationServerURI(false) + path, HttpMethod.PUT, new HttpEntity<>(headers), Void.class); + String path = UriComponentsBuilder.fromPath(NETWORK_MODIFICATIONS_PATH + "/unshare").build().toUriString(); + restTemplate.exchange(getNetworkModificationServerURI(false) + path, HttpMethod.PUT, userIdEntity(userId, modificationReferenceUuids), Void.class); } public void updateNetworkModificationsMetadata(List networkModificationUuids, String metadata, String userId) { diff --git a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java index ee2b3cf996..1cd65fe1e2 100644 --- a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationService.java @@ -15,7 +15,6 @@ import org.gridsuite.study.server.error.StudyException; import org.gridsuite.study.server.networkmodificationtree.dto.NodeBuildStatus; import org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity; -import org.gridsuite.study.server.networkmodificationtree.entities.NodeType; import org.gridsuite.study.server.nodeactivity.NodeActivityRunnerService; import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; @@ -352,33 +351,32 @@ public NodeBuildStatus getNodeBuildStatus(UUID nodeUuid, UUID rootNetworkUuid) { public void unshareAllReferencesInStudy( @NonNull final UUID studyUuid, String userId) { - // get the modification references of the whole study sorted by their node - List nodes = networkModificationTreeService.getAllNodes(studyUuid) - .stream() - .filter(node -> node.getType().equals(NodeType.NETWORK_MODIFICATION)) - .map(NodeEntity::getIdNode) - .toList(); + // get the modification references of the whole study grouped by their node Map> referencesAffectedByNode = new HashMap<>(); - nodes.forEach(nodeUuid -> { - UUID groupUuid = networkModificationTreeService.getModificationGroupUuid(nodeUuid); - List modificationReferences = networkModificationRestService.getModificationReferences(groupUuid) - .stream().map(ModificationReference::modificationUuid).toList(); - if (!modificationReferences.isEmpty()) { - referencesAffectedByNode.put(nodeUuid, modificationReferences); - } - } - ); + networkModificationTreeService.getAllNotStashedNetworkModificationNodes(studyUuid).stream() + .map(NodeEntity::getIdNode) + .forEach(nodeUuid -> { + UUID groupUuid = networkModificationTreeService.getModificationGroupUuid(nodeUuid); + List modificationReferences = networkModificationRestService.getModificationReferences(groupUuid) + .stream().map(ModificationReference::modificationUuid).toList(); + if (!modificationReferences.isEmpty()) { + referencesAffectedByNode.put(nodeUuid, modificationReferences); + } + }); + if (referencesAffectedByNode.isEmpty()) { + return; + } - nodeActivityRunnerService.runWith(UNSHARE_MODIFICATIONS, studyUuid, referencesAffectedByNode.keySet().stream().toList(), + nodeActivityRunnerService.runWith(UNSHARE_MODIFICATIONS, studyUuid, new ArrayList<>(referencesAffectedByNode.keySet()), () -> unshareModificationReferences(studyUuid, referencesAffectedByNode, userId)); } public void unshareModificationReferences(@NonNull UUID studyUuid, Map> referencesAffectedByNode, String userId) { - referencesAffectedByNode.forEach((nodeUuid, modificationReferenceUuids) -> { - networkModificationRestService.unshareModificationReferences(modificationReferenceUuids, userId); - notificationService.emitModificationsUpdated(studyUuid, nodeUuid, modificationReferenceUuids); - } - ); + // a single remote call for all the references, then every affected node is notified + List allModificationReferenceUuids = referencesAffectedByNode.values().stream().flatMap(List::stream).toList(); + networkModificationRestService.unshareModificationReferences(allModificationReferenceUuids, userId); + referencesAffectedByNode.forEach((nodeUuid, modificationReferenceUuids) -> + notificationService.emitModificationsUpdated(studyUuid, nodeUuid, modificationReferenceUuids)); } @Transactional(readOnly = true) diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java index bb12467dc2..fc8bf49833 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java @@ -91,6 +91,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.gridsuite.study.server.StudyConstants.HEADER_USER_ID; import static org.gridsuite.study.server.error.StudyBusinessErrorCode.NODE_NOT_FOUND; +import static org.gridsuite.study.server.error.StudyBusinessErrorCode.NOT_FOUND; import static org.gridsuite.study.server.notification.NotificationService.*; import static org.gridsuite.study.server.service.NetworkModificationTreeService.ROOT_NODE_NAME; import static org.gridsuite.study.server.utils.TestUtils.checkUpdateStatusMessagesReceived; @@ -824,7 +825,7 @@ void testNodeModificationInfos() throws Exception { NetworkModificationNode n1 = (NetworkModificationNode) (children.stream().filter(c -> c.getName().equals("n1")).findFirst().orElseThrow()); NetworkModificationNodeInfoEntity n1Infos = networkModificationTreeService.getNetworkModificationNodeInfoEntity(n1.getId()); RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoRepository.findByNodeInfoIdAndRootNetworkId(n1.getId(), - firstRootNetworkUuid).orElseThrow(() -> new StudyException(NODE_NOT_FOUND, "Root network not found")); + firstRootNetworkUuid).orElseThrow(() -> new StudyException(NOT_FOUND, "Root network not found")); assertEquals("n1", n1.getName()); assertEquals("zzz", n1.getDescription()); diff --git a/src/test/java/org/gridsuite/study/server/StudyServiceTest.java b/src/test/java/org/gridsuite/study/server/StudyServiceTest.java index b8714bac7c..dfacc74e43 100644 --- a/src/test/java/org/gridsuite/study/server/StudyServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/StudyServiceTest.java @@ -38,6 +38,7 @@ import java.util.UUID; import static org.gridsuite.study.server.error.StudyBusinessErrorCode.MAX_OPERATION_TYPE_EXCEEDED; +import static org.gridsuite.study.server.nodeactivity.NodeActivityType.UNSHARE_MODIFICATIONS; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.*; @@ -293,11 +294,14 @@ void testUnshareAllReferencesInStudy() { UUID studyUuid = UUID.randomUUID(); String userId = "userId"; - doReturn(List.of()).when(networkModificationTreeService).getAllNodes(studyUuid); + doReturn(List.of()).when(networkModificationTreeService).getAllNotStashedNetworkModificationNodes(studyUuid); networkModificationService.unshareAllReferencesInStudy(studyUuid, userId); - verify(networkModificationTreeService, times(1)).getAllNodes(studyUuid); + verify(networkModificationTreeService, times(1)).getAllNotStashedNetworkModificationNodes(studyUuid); + verify(nodeActivityRunnerService, never()).runWith(any(), any(), any(), (Runnable) any()); + verify(networkModificationRestService, never()).unshareModificationReferences(any(), any()); + verify(notificationService, never()).emitModificationsUpdated(any(), any(), any()); } @Test @@ -307,11 +311,17 @@ void testUnshareAllReferencesInStudyWithReferences() { UUID modificationUuid = UUID.randomUUID(); String userId = "userId"; - NodeEntity nodeEntity = new NodeEntity(nodeUuid, null, NodeType.NETWORK_MODIFICATION, null, false, null, List.of()); - doReturn(List.of(nodeEntity)).when(networkModificationTreeService).getAllNodes(studyUuid); + UUID nodeWithoutReferenceUuid = UUID.randomUUID(); + doReturn(List.of( + new NodeEntity(nodeUuid, null, NodeType.NETWORK_MODIFICATION, null, false, null, List.of()), + new NodeEntity(nodeWithoutReferenceUuid, null, NodeType.NETWORK_MODIFICATION, null, false, null, List.of()) + )).when(networkModificationTreeService).getAllNotStashedNetworkModificationNodes(studyUuid); UUID groupUuid = UUID.randomUUID(); doReturn(groupUuid).when(networkModificationTreeService).getModificationGroupUuid(nodeUuid); + UUID groupWithoutReferenceUuid = UUID.randomUUID(); + doReturn(groupWithoutReferenceUuid).when(networkModificationTreeService).getModificationGroupUuid(nodeWithoutReferenceUuid); + doReturn(List.of()).when(networkModificationRestService).getModificationReferences(groupWithoutReferenceUuid); ModificationReference modificationReference = new ModificationReference(modificationUuid, UUID.randomUUID(), null); doReturn(List.of(modificationReference)).when(networkModificationRestService).getModificationReferences(groupUuid); @@ -325,10 +335,14 @@ void testUnshareAllReferencesInStudyWithReferences() { networkModificationService.unshareAllReferencesInStudy(studyUuid, userId); - verify(networkModificationTreeService, times(1)).getAllNodes(studyUuid); + verify(networkModificationTreeService, times(1)).getAllNotStashedNetworkModificationNodes(studyUuid); verify(networkModificationTreeService, times(1)).getModificationGroupUuid(nodeUuid); verify(networkModificationRestService, times(1)).getModificationReferences(groupUuid); + // only the node having references is held by the activity + verify(nodeActivityRunnerService, times(1)).runWith(eq(UNSHARE_MODIFICATIONS), eq(studyUuid), eq(List.of(nodeUuid)), (Runnable) any()); + verify(networkModificationRestService, times(1)).unshareModificationReferences(List.of(modificationUuid), userId); verify(notificationService, times(1)).emitModificationsUpdated(studyUuid, nodeUuid, List.of(modificationUuid)); + verify(notificationService, never()).emitModificationsUpdated(eq(studyUuid), eq(nodeWithoutReferenceUuid), any()); } @Test @@ -344,6 +358,6 @@ void testUnshareModificationReferenceDoesNotNotifyWhenRemoteCallFails() { assertThrows(RuntimeException.class, () -> networkModificationService.unshareModificationReferences(studyUuid, Map.of(nodeUuid, List.of(modificationUuid)), userId)); - verify(notificationService, never()).emitModificationsUpdated(any(), any(), any(), any()); + verify(notificationService, never()).emitModificationsUpdated(any(), any(), any()); } } diff --git a/src/test/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationServiceTest.java b/src/test/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationServiceTest.java index f867e70f89..b17a06f982 100644 --- a/src/test/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationServiceTest.java @@ -126,14 +126,14 @@ void testUpdateNetworkModificationsMetadata() { @Test void testUnshareModificationReference() { UUID modificationReferenceUuid = UUID.randomUUID(); - String expectedUrl = NETWORK_MODIFICATION_SERVER_URI + "/v1/network-modifications/unshare?uuids=" + modificationReferenceUuid; + String expectedUrl = NETWORK_MODIFICATION_SERVER_URI + "/v1/network-modifications/unshare"; networkModificationService.unshareModificationReferences(List.of(modificationReferenceUuid), USER_ID); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.set(HEADER_USER_ID, USER_ID); - verify(restTemplate).exchange(expectedUrl, HttpMethod.PUT, new HttpEntity<>(headers), Void.class); + verify(restTemplate).exchange(expectedUrl, HttpMethod.PUT, new HttpEntity<>(List.of(modificationReferenceUuid), headers), Void.class); } @Test diff --git a/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java b/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java index a818322cc5..302b0d80e4 100644 --- a/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java +++ b/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java @@ -174,4 +174,13 @@ void testUnshareModificationReference() { verify(studyService, times(1)).assertIsStudyAndNodeExist(studyUuid, nodeUuid); verify(studyService, times(1)).assertIsNodeNotReadOnly(nodeUuid); } + + @Test + void testUnshareAllReferencesInStudy() { + ResponseEntity response = studyController.unshareAllReferencesInStudy(studyUuid, userId); + + Assertions.assertEquals(HttpStatus.OK, response.getStatusCode()); + verify(studyService, times(1)).assertIsStudyExist(studyUuid); + verify(networkModificationService, times(1)).unshareAllReferencesInStudy(studyUuid, userId); + } } From 5f027d36ea12942bafaa49de55bc524fe9e1b6bc Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Tue, 27 Oct 2026 15:22:16 +0100 Subject: [PATCH 14/14] Maissa patch (Arename unshareAllModificationReferencesquite) Signed-off-by: Mathieu DEHARBE --- .../org/gridsuite/study/server/controller/StudyController.java | 2 +- .../server/studycontroller/StudyControllerRebuildNodeTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 aa2520c9e1..ec08f357e7 100644 --- a/src/main/java/org/gridsuite/study/server/controller/StudyController.java +++ b/src/main/java/org/gridsuite/study/server/controller/StudyController.java @@ -322,7 +322,7 @@ public ResponseEntity unshareModificationReference( @PutMapping(value = "/studies/{studyUuid}/unshare") @Operation(summary = "Unshare all the reference modifications and copy the referenced composites in their place") @ApiResponse(responseCode = "200", description = "All the reference modifications from the study have been replaced by copies of their referenced composites") - public ResponseEntity unshareAllReferencesInStudy( + public ResponseEntity unshareAllModificationReferences( @PathVariable("studyUuid") UUID studyUuid, @RequestHeader(HEADER_USER_ID) String userId) { studyService.assertIsStudyExist(studyUuid); diff --git a/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java b/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java index 302b0d80e4..09b7d7e5f8 100644 --- a/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java +++ b/src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java @@ -177,7 +177,7 @@ void testUnshareModificationReference() { @Test void testUnshareAllReferencesInStudy() { - ResponseEntity response = studyController.unshareAllReferencesInStudy(studyUuid, userId); + ResponseEntity response = studyController.unshareAllModificationReferences(studyUuid, userId); Assertions.assertEquals(HttpStatus.OK, response.getStatusCode()); verify(studyService, times(1)).assertIsStudyExist(studyUuid);