From 94a3630d67028c75f11a55d73c25993a6c520c6c Mon Sep 17 00:00:00 2001 From: Florent MILLOT <75525996+flomillot@users.noreply.github.com> Date: Mon, 19 Oct 2026 17:41:02 +0200 Subject: [PATCH 01/11] Delete network modifications without their group Signed-off-by: Florent MILLOT <75525996+flomillot@users.noreply.github.com> --- .../study/server/service/NetworkModificationService.java | 5 ++--- .../org/gridsuite/study/server/service/StudyService.java | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) 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 2e98cab54c..a975e51949 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java @@ -216,12 +216,11 @@ public void deleteModificationsGroups(List groupUuids) { new ParameterizedTypeReference>() { }); } - public void deleteModifications(UUID groupUuid, List modificationsUuids) { - Objects.requireNonNull(groupUuid); + public void deleteModifications(List modificationsUuids) { + Objects.requireNonNull(modificationsUuids); var path = UriComponentsBuilder .fromUriString(getNetworkModificationServerURI(false) + NETWORK_MODIFICATIONS_PATH) .queryParam(UUIDS, modificationsUuids) - .queryParam(GROUP_UUID, groupUuid) .buildAndExpand() .toUriString(); restTemplate.delete(path); 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 91c3c2fbde..6ea21b9121 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -1587,10 +1587,8 @@ public void deleteNetworkModifications(UUID studyUuid, UUID nodeUuid, List if (!networkModificationTreeService.getStudyUuidForNodeId(nodeUuid).equals(studyUuid)) { throw new StudyException(NOT_ALLOWED); } - UUID groupId = networkModificationTreeService.getModificationGroupUuid(nodeUuid); - List referencesToBeDeleted = networkModificationService.getModificationReferences(modificationsUuids); - networkModificationService.deleteModifications(groupId, modificationsUuids); + networkModificationService.deleteModifications(modificationsUuids); // if there are unstashed references modifications in the deleted netmods, those references have to be removed from directory server removeReferences(referencesToBeDeleted, userId); } finally { From 7c2708873c0a39ffc5010b2f5d49fa8ec1113d15 Mon Sep 17 00:00:00 2001 From: Florent MILLOT <75525996+flomillot@users.noreply.github.com> Date: Mon, 19 Oct 2026 17:41:31 +0200 Subject: [PATCH 02/11] Delete modification references instead of stashing them Stashing a node deletes its modification references, restoring a node or a modification no longer links them back, and deleting stashed modifications no longer unlinks references. Signed-off-by: Florent MILLOT <75525996+flomillot@users.noreply.github.com> --- .../service/NetworkModificationService.java | 16 +++++--------- .../NetworkModificationTreeService.java | 13 ++++------- .../study/server/service/StudyService.java | 7 ++---- .../study/server/NetworkModificationTest.java | 22 ------------------- .../NetworkModificationServiceTest.java | 11 ++++++++++ 5 files changed, 22 insertions(+), 47 deletions(-) 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 a975e51949..1515b09600 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java @@ -288,15 +288,13 @@ public void updateModificationsMetadata(UUID groupUUid, List modifications restTemplate.exchange(path, HttpMethod.PUT, userIdEntity(userId, metadata), Void.class); } - public void restoreModifications(UUID groupUUid, List modificationsUuids, UUID studyUuid, UUID nodeUuid, String userId) { + public void restoreModifications(UUID groupUUid, List modificationsUuids, String userId) { Objects.requireNonNull(groupUUid); Objects.requireNonNull(modificationsUuids); var path = UriComponentsBuilder .fromUriString(getNetworkModificationServerURI(false) + NETWORK_MODIFICATIONS_PATH) .queryParam(UUIDS, modificationsUuids) .queryParam(GROUP_UUID, groupUUid) - .queryParam(QUERY_PARAM_STUDY_ROOT_CONTAINER_UUID, studyUuid) - .queryParam(QUERY_PARAM_NODE_CONTAINER_UUID, nodeUuid) .queryParam(QUERY_PARAM_STASHED, false) .buildAndExpand() .toUriString(); @@ -641,20 +639,16 @@ public void deleteStashedModificationsFromGroups(List groupUuids, String u new ParameterizedTypeReference>() { }); } - public void restoreElementReferences(UUID groupUUid, UUID studyUuid, UUID newNodeUuid, String userId) { - Objects.requireNonNull(groupUUid); + public void deleteModificationReferences(UUID groupUuid, String userId) { + Objects.requireNonNull(groupUuid); var path = UriComponentsBuilder.fromPath(GROUP_PATH + "/references") - .queryParam(QUERY_PARAM_NODE_CONTAINER_UUID, newNodeUuid) - .queryParam(QUERY_PARAM_STUDY_ROOT_CONTAINER_UUID, studyUuid) - .buildAndExpand(groupUUid) + .buildAndExpand(groupUuid) .toUriString(); HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); headers.set(HEADER_USER_ID, userId); - HttpEntity httpEntity = new HttpEntity<>(headers); - restTemplate.exchange(getNetworkModificationServerURI(false) + path, HttpMethod.PUT, httpEntity, Void.class); + restTemplate.exchange(getNetworkModificationServerURI(false) + path, HttpMethod.DELETE, new HttpEntity<>(headers), Void.class); } public void verifyModifications(UUID groupUuid, Set modificationUuids) { 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 c8303b920a..9bae351bf2 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java @@ -69,7 +69,6 @@ public class NetworkModificationTreeService { private final UserAdminService userAdminService; private final StudyServerExecutionService studyServerExecutionService; - private final DirectoryService directoryService; public NetworkModificationTreeService(NodeRepository nodesRepository, RootNodeInfoRepository rootNodeInfoRepository, @@ -82,8 +81,7 @@ public NetworkModificationTreeService(NodeRepository nodesRepository, NetworkService networkStoreService, ReportService reportService, UserAdminService userAdminService, - StudyServerExecutionService studyServerExecutionService, - DirectoryService directoryService) { + StudyServerExecutionService studyServerExecutionService) { this.nodesRepository = nodesRepository; this.networkModificationNodeInfoRepository = networkModificationNodeInfoRepository; this.networkModificationService = networkModificationService; @@ -96,7 +94,6 @@ public NetworkModificationTreeService(NodeRepository nodesRepository, this.reportService = reportService; this.userAdminService = userAdminService; this.studyServerExecutionService = studyServerExecutionService; - this.directoryService = directoryService; } private NetworkModificationNodeInfoEntity createNetworkModificationNode(StudyEntity study, NodeEntity parentNode, NetworkModificationNode networkModificationNode) { @@ -338,6 +335,7 @@ private void stashNode(UUID nodeId, boolean stashChildren, List stashedNod NodeEntity nodeToStash = nodeToStashInfo.getNode(); UUID modificationGroupUuid = nodeToStashInfo.getModificationGroupUuid(); networkModificationService.deleteStashedModificationsFromGroups(List.of(modificationGroupUuid), userId); + networkModificationService.deleteModificationReferences(modificationGroupUuid, userId); if (!stashChildren) { insertNodesToParent(nodeToStash.getParentNode(), nodeToStashInfo.getColumnPosition(), getChildren(nodeId)); } else { @@ -872,7 +870,7 @@ public List> getStashedNodes(UUID studyUuid) { } @Transactional - public void restoreNode(UUID studyId, List nodeIds, UUID anchorNodeId, String userId) { + public void restoreNode(UUID studyId, List nodeIds, UUID anchorNodeId) { for (UUID nodeId : nodeIds) { NodeEntity nodeToRestore = getNodeEntity(nodeId); NodeEntity anchorNode = getNodeEntity(anchorNodeId); @@ -887,10 +885,7 @@ public void restoreNode(UUID studyId, List nodeIds, UUID anchorNodeId, Str nodeToRestore.setStashed(false); nodeToRestore.setStashDate(null); modificationNodeToRestore.setColumnPosition(getNextColumnPosition(anchorNodeId)); - NodeEntity newNode = nodesRepository.save(nodeToRestore); - // restore the references pointing from directory server to netmod-server - List modificationsReferences = networkModificationService.getModificationReferences(getModificationGroupUuid(newNode.getIdNode())); - directoryService.createElementsReferences(modificationsReferences, studyId, newNode.getIdNode(), userId); + nodesRepository.save(nodeToRestore); if (hasChildren(nodeId)) { restoreNodeChildren(studyId, nodeId); notificationService.emitSubtreeInserted(studyId, nodeId, anchorNodeId); 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 6ea21b9121..6aba9a7e48 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -1587,10 +1587,7 @@ public void deleteNetworkModifications(UUID studyUuid, UUID nodeUuid, List if (!networkModificationTreeService.getStudyUuidForNodeId(nodeUuid).equals(studyUuid)) { throw new StudyException(NOT_ALLOWED); } - List referencesToBeDeleted = networkModificationService.getModificationReferences(modificationsUuids); networkModificationService.deleteModifications(modificationsUuids); - // if there are unstashed references modifications in the deleted netmods, those references have to be removed from directory server - removeReferences(referencesToBeDeleted, userId); } finally { notificationService.emitModificationsDeleted(studyUuid, nodeUuid, childrenUuids); } @@ -1679,7 +1676,7 @@ public void restoreNetworkModifications(UUID studyUuid, UUID nodeUuid, List> getStashedNodes(UUID studyId) { public void restoreNodes(UUID studyId, List nodeIds, UUID anchorNodeId, String userId) { networkModificationTreeService.assertIsRootOrConstructionNode(anchorNodeId); - networkModificationTreeService.restoreNode(studyId, nodeIds, anchorNodeId, userId); + networkModificationTreeService.restoreNode(studyId, nodeIds, anchorNodeId); notificationService.emitElementUpdated(studyId, userId); } diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java index 8993b84bf9..25775fa759 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java @@ -1149,19 +1149,6 @@ void deleteModificationRequest() throws Exception { String userId = "userId"; UUID modificationUuid = UUID.randomUUID(); - // stubs the checks and updates of referenced modifications - List stubbedReferences = List.of(new ModificationReference(modificationUuid, modificationUuid, null)); - UUID referencesStubId = wireMockServer.stubFor(WireMock.get(WireMock.urlPathEqualTo("/v1/references")) - .withQueryParam("uuids", equalTo(modificationUuid.toString())) - .willReturn(WireMock.ok() - .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .withBody(mapper.writeValueAsString(stubbedReferences))) - ).getId(); - UUID removeReferencesStubId = wireMockServer.stubFor(WireMock.delete(urlPathMatching( - "/v1/elements/" + modificationUuid + "/references/.*")) - .willReturn(WireMock.ok()) - ).getId(); - UUID stubId = wireMockServer.stubFor(WireMock.delete(urlPathMatching("/v1/network-modifications")).willReturn(WireMock.ok())).getId(); StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); @@ -1187,15 +1174,7 @@ void deleteModificationRequest() throws Exception { .queryParam("uuids", modificationUuid.toString()) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); - WireMockUtils.verifyGetRequest(wireMockServer, referencesStubId, "/v1/references", Map.of("uuids", equalTo(modificationUuid.toString()))); WireMockUtils.verifyDeleteRequest(wireMockServer, stubId, "/v1/network-modifications", false, Map.of("uuids", equalTo(modificationUuid.toString()))); - WireMockUtils.verifyDeleteRequest( - wireMockServer, - removeReferencesStubId, - "/v1/elements/" + modificationUuid + "/references/.*", - true, - Map.of() - ); checkEquipmentDeletingFinishedMessagesReceived(studyUuid, modificationNode.getId()); stubId = wireMockServer.stubFor(WireMock.delete(urlPathMatching("/v1/network-modifications.*")) @@ -1205,7 +1184,6 @@ void deleteModificationRequest() throws Exception { .queryParam("uuids", modificationUuid.toString()) .header(USER_ID_HEADER, "userId")) .andExpect(status().isInternalServerError()); - WireMockUtils.verifyGetRequest(wireMockServer, referencesStubId, "/v1/references", Map.of("uuids", equalTo(modificationUuid.toString()))); WireMockUtils.verifyDeleteRequest(wireMockServer, stubId, "/v1/network-modifications", false, Map.of("uuids", equalTo(modificationUuid.toString()))); checkEquipmentDeletingFinishedMessagesReceived(studyUuid, modificationNode.getId()); } diff --git a/src/test/java/org/gridsuite/study/server/service/NetworkModificationServiceTest.java b/src/test/java/org/gridsuite/study/server/service/NetworkModificationServiceTest.java index a2219d3440..f85ef8d102 100644 --- a/src/test/java/org/gridsuite/study/server/service/NetworkModificationServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/service/NetworkModificationServiceTest.java @@ -196,6 +196,17 @@ void testGetReferencesFromGroup() { assertThat(networkModificationService.getModificationReferences(groupUuid)).isEqualTo(expected); } + @Test + void testDeleteModificationReferences() { + UUID groupUuid = UUID.randomUUID(); + String expectedUrl = NETWORK_MODIFICATION_SERVER_URI + "/v1/groups/" + groupUuid + "/references"; + + networkModificationService.deleteModificationReferences(groupUuid, "userId"); + + verify(restTemplate).exchange(eq(expectedUrl), eq(HttpMethod.DELETE), + argThat((HttpEntity entity) -> "userId".equals(entity.getHeaders().getFirst(HEADER_USER_ID))), eq(Void.class)); + } + @Test void testRenameRootNetworkTag() { UUID firstGroupUuid = UUID.randomUUID(); From 28c60e3b521bef447534985db183cb99135a2b0f Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Tue, 20 Oct 2026 15:29:33 +0200 Subject: [PATCH 03/11] Check the deleted modifications belong to the node The network-modification-server now deletes modifications by id wherever they sit, so the study server verifies them against the node group first. Signed-off-by: Florent MILLOT --- .../org/gridsuite/study/server/service/StudyService.java | 1 + .../org/gridsuite/study/server/NetworkModificationTest.java | 6 ++++++ 2 files changed, 7 insertions(+) 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 6ea21b9121..9482b28323 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -1587,6 +1587,7 @@ public void deleteNetworkModifications(UUID studyUuid, UUID nodeUuid, List if (!networkModificationTreeService.getStudyUuidForNodeId(nodeUuid).equals(studyUuid)) { throw new StudyException(NOT_ALLOWED); } + networkModificationService.verifyModifications(networkModificationTreeService.getModificationGroupUuid(nodeUuid), new HashSet<>(modificationsUuids)); List referencesToBeDeleted = networkModificationService.getModificationReferences(modificationsUuids); networkModificationService.deleteModifications(modificationsUuids); // if there are unstashed references modifications in the deleted netmods, those references have to be removed from directory server diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java index 8993b84bf9..01f9871a48 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java @@ -1163,6 +1163,8 @@ void deleteModificationRequest() throws Exception { ).getId(); UUID stubId = wireMockServer.stubFor(WireMock.delete(urlPathMatching("/v1/network-modifications")).willReturn(WireMock.ok())).getId(); + UUID verifyStubId = wireMockServer.stubFor(WireMock.get(urlPathMatching("/v1/containers/.*/network-modifications/verify")) + .willReturn(WireMock.ok())).getId(); StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyUuid = studyEntity.getId(); @@ -1187,6 +1189,8 @@ void deleteModificationRequest() throws Exception { .queryParam("uuids", modificationUuid.toString()) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); + WireMockUtils.verifyGetRequest(wireMockServer, verifyStubId, "/v1/containers/" + modificationNode.getModificationGroupUuid() + "/network-modifications/verify", + Map.of("uuids", equalTo(modificationUuid.toString()))); WireMockUtils.verifyGetRequest(wireMockServer, referencesStubId, "/v1/references", Map.of("uuids", equalTo(modificationUuid.toString()))); WireMockUtils.verifyDeleteRequest(wireMockServer, stubId, "/v1/network-modifications", false, Map.of("uuids", equalTo(modificationUuid.toString()))); WireMockUtils.verifyDeleteRequest( @@ -1205,6 +1209,8 @@ void deleteModificationRequest() throws Exception { .queryParam("uuids", modificationUuid.toString()) .header(USER_ID_HEADER, "userId")) .andExpect(status().isInternalServerError()); + WireMockUtils.verifyGetRequest(wireMockServer, verifyStubId, "/v1/containers/" + modificationNode.getModificationGroupUuid() + "/network-modifications/verify", + Map.of("uuids", equalTo(modificationUuid.toString()))); WireMockUtils.verifyGetRequest(wireMockServer, referencesStubId, "/v1/references", Map.of("uuids", equalTo(modificationUuid.toString()))); WireMockUtils.verifyDeleteRequest(wireMockServer, stubId, "/v1/network-modifications", false, Map.of("uuids", equalTo(modificationUuid.toString()))); checkEquipmentDeletingFinishedMessagesReceived(studyUuid, modificationNode.getId()); From a0accce67e31eceb0ca422a04e376e921a3f7db4 Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Tue, 20 Oct 2026 16:14:17 +0200 Subject: [PATCH 04/11] Revert "Check the deleted modifications belong to the node" This reverts commit 28c60e3b. Signed-off-by: Florent MILLOT --- .../org/gridsuite/study/server/service/StudyService.java | 1 - .../org/gridsuite/study/server/NetworkModificationTest.java | 6 ------ 2 files changed, 7 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 9482b28323..6ea21b9121 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -1587,7 +1587,6 @@ public void deleteNetworkModifications(UUID studyUuid, UUID nodeUuid, List if (!networkModificationTreeService.getStudyUuidForNodeId(nodeUuid).equals(studyUuid)) { throw new StudyException(NOT_ALLOWED); } - networkModificationService.verifyModifications(networkModificationTreeService.getModificationGroupUuid(nodeUuid), new HashSet<>(modificationsUuids)); List referencesToBeDeleted = networkModificationService.getModificationReferences(modificationsUuids); networkModificationService.deleteModifications(modificationsUuids); // if there are unstashed references modifications in the deleted netmods, those references have to be removed from directory server diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java index 01f9871a48..8993b84bf9 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java @@ -1163,8 +1163,6 @@ void deleteModificationRequest() throws Exception { ).getId(); UUID stubId = wireMockServer.stubFor(WireMock.delete(urlPathMatching("/v1/network-modifications")).willReturn(WireMock.ok())).getId(); - UUID verifyStubId = wireMockServer.stubFor(WireMock.get(urlPathMatching("/v1/containers/.*/network-modifications/verify")) - .willReturn(WireMock.ok())).getId(); StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyUuid = studyEntity.getId(); @@ -1189,8 +1187,6 @@ void deleteModificationRequest() throws Exception { .queryParam("uuids", modificationUuid.toString()) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); - WireMockUtils.verifyGetRequest(wireMockServer, verifyStubId, "/v1/containers/" + modificationNode.getModificationGroupUuid() + "/network-modifications/verify", - Map.of("uuids", equalTo(modificationUuid.toString()))); WireMockUtils.verifyGetRequest(wireMockServer, referencesStubId, "/v1/references", Map.of("uuids", equalTo(modificationUuid.toString()))); WireMockUtils.verifyDeleteRequest(wireMockServer, stubId, "/v1/network-modifications", false, Map.of("uuids", equalTo(modificationUuid.toString()))); WireMockUtils.verifyDeleteRequest( @@ -1209,8 +1205,6 @@ void deleteModificationRequest() throws Exception { .queryParam("uuids", modificationUuid.toString()) .header(USER_ID_HEADER, "userId")) .andExpect(status().isInternalServerError()); - WireMockUtils.verifyGetRequest(wireMockServer, verifyStubId, "/v1/containers/" + modificationNode.getModificationGroupUuid() + "/network-modifications/verify", - Map.of("uuids", equalTo(modificationUuid.toString()))); WireMockUtils.verifyGetRequest(wireMockServer, referencesStubId, "/v1/references", Map.of("uuids", equalTo(modificationUuid.toString()))); WireMockUtils.verifyDeleteRequest(wireMockServer, stubId, "/v1/network-modifications", false, Map.of("uuids", equalTo(modificationUuid.toString()))); checkEquipmentDeletingFinishedMessagesReceived(studyUuid, modificationNode.getId()); From 4ee40d85dc7687781ac174918e140812bf1e77fa Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Wed, 21 Oct 2026 10:32:15 +0200 Subject: [PATCH 05/11] Let network-modification-server unlink the deleted references Signed-off-by: Florent MILLOT --- .../server/service/DirectoryService.java | 23 ------------------- .../service/NetworkModificationService.java | 12 ++++++---- .../study/server/service/StudyService.java | 18 +++------------ .../study/server/NetworkModificationTest.java | 22 ------------------ 4 files changed, 11 insertions(+), 64 deletions(-) diff --git a/src/main/java/org/gridsuite/study/server/service/DirectoryService.java b/src/main/java/org/gridsuite/study/server/service/DirectoryService.java index ca4a2f80e6..62316dc8a5 100644 --- a/src/main/java/org/gridsuite/study/server/service/DirectoryService.java +++ b/src/main/java/org/gridsuite/study/server/service/DirectoryService.java @@ -137,29 +137,6 @@ public void createElementReference(@NonNull UUID elementUuid, @NonNull Reference restTemplate.exchange(getDirectoryServerServerBaseUri() + path, HttpMethod.POST, requestEntity, ElementAttributes.class); } - /** - * remove reference from the shared modification in directory server - * @param referenceUuid uuid of the composite or group where the 'Modification reference' is located - * @param userId id of the user who caused the unreferencing - * @param sharedElementUuid uuid of the referenced shared element in the directory-server - */ - public void removeElementReference(UUID sharedElementUuid, UUID referenceUuid, String userId) { - Objects.requireNonNull(referenceUuid); - Objects.requireNonNull(sharedElementUuid); - - var path = UriComponentsBuilder.fromPath( - DELIMITER + DIRECTORY_API_VERSION + DELIMITER + "elements/{elementUuid}/references/{referenceUuid}") - .buildAndExpand(sharedElementUuid, referenceUuid) - .toUriString(); - - HttpHeaders headers = new HttpHeaders(); - headers.set(HEADER_USER_ID, userId); - headers.setContentType(MediaType.APPLICATION_JSON); - - HttpEntity requestEntity = new HttpEntity<>(headers); - restTemplate.exchange(getDirectoryServerServerBaseUri() + path, HttpMethod.DELETE, requestEntity, ElementAttributes.class); - } - public void createElement(UUID directoryUuid, String description, UUID elementUuid, String elementName, String type, String userId) { UriComponentsBuilder pathBuilder = UriComponentsBuilder.fromPath(DELIMITER + DIRECTORY_API_VERSION + "/directories/{directoryUuid}/elements"); ElementAttributes elementAttributes = new ElementAttributes(elementUuid, elementName, type, userId, 0, description); 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 a975e51949..e5189b60fd 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java @@ -190,13 +190,15 @@ public Integer getModificationsCount(UUID groupUUid, boolean stashedModification return restTemplate.exchange(getNetworkModificationServerURI(false) + path, HttpMethod.GET, null, Integer.class).getBody(); } - public void deleteModifications(UUID groupUUid) { + public void deleteModifications(UUID groupUUid, String userId) { Objects.requireNonNull(groupUUid); var path = UriComponentsBuilder.fromPath(GROUP_PATH) .buildAndExpand(groupUUid) .toUriString(); - restTemplate.delete(getNetworkModificationServerURI(false) + path); + HttpHeaders headers = new HttpHeaders(); + headers.set(HEADER_USER_ID, userId); + restTemplate.exchange(getNetworkModificationServerURI(false) + path, HttpMethod.DELETE, new HttpEntity<>(headers), Void.class); } public void deleteModificationsGroups(List groupUuids) { @@ -216,14 +218,16 @@ public void deleteModificationsGroups(List groupUuids) { new ParameterizedTypeReference>() { }); } - public void deleteModifications(List modificationsUuids) { + public void deleteModifications(List modificationsUuids, String userId) { Objects.requireNonNull(modificationsUuids); var path = UriComponentsBuilder .fromUriString(getNetworkModificationServerURI(false) + NETWORK_MODIFICATIONS_PATH) .queryParam(UUIDS, modificationsUuids) .buildAndExpand() .toUriString(); - restTemplate.delete(path); + HttpHeaders headers = new HttpHeaders(); + headers.set(HEADER_USER_ID, userId); + restTemplate.exchange(path, HttpMethod.DELETE, new HttpEntity<>(headers), Void.class); } public NetworkModificationsResult createModification(UUID groupUuid, 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 6ea21b9121..b6f7ce16ed 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -656,11 +656,8 @@ public void deleteStudyIfNotCreationInProgress(UUID studyUuid, String userId) { } private void deleteModificationsFromGroup(Pair groupUuidNodeUuid, String userId) { - // fetch the references data in order to remove those references from directory-server - List referencesToBeDeleted = networkModificationService.getModificationReferences(groupUuidNodeUuid.getFirst()); - removeReferences(referencesToBeDeleted, userId); - - networkModificationService.deleteModifications(groupUuidNodeUuid.getFirst()); + // network-modification-server unlinks the deleted references from directory-server + networkModificationService.deleteModifications(groupUuidNodeUuid.getFirst(), userId); } @Transactional @@ -1587,22 +1584,13 @@ public void deleteNetworkModifications(UUID studyUuid, UUID nodeUuid, List if (!networkModificationTreeService.getStudyUuidForNodeId(nodeUuid).equals(studyUuid)) { throw new StudyException(NOT_ALLOWED); } - List referencesToBeDeleted = networkModificationService.getModificationReferences(modificationsUuids); - networkModificationService.deleteModifications(modificationsUuids); - // if there are unstashed references modifications in the deleted netmods, those references have to be removed from directory server - removeReferences(referencesToBeDeleted, userId); + networkModificationService.deleteModifications(modificationsUuids, userId); } finally { notificationService.emitModificationsDeleted(studyUuid, nodeUuid, childrenUuids); } notificationService.emitElementUpdated(studyUuid, userId); } - private void removeReferences(List references, String userId) { - references.forEach(reference -> - directoryService.removeElementReference(reference.referencedId(), reference.modificationUuid(), userId) - ); - } - @Transactional public void stashNetworkModifications(UUID studyUuid, UUID nodeUuid, List modificationsUuids, String userId) { List childrenUuids = networkModificationTreeService.getChildrenUuids(nodeUuid); diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java index 8993b84bf9..25775fa759 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java @@ -1149,19 +1149,6 @@ void deleteModificationRequest() throws Exception { String userId = "userId"; UUID modificationUuid = UUID.randomUUID(); - // stubs the checks and updates of referenced modifications - List stubbedReferences = List.of(new ModificationReference(modificationUuid, modificationUuid, null)); - UUID referencesStubId = wireMockServer.stubFor(WireMock.get(WireMock.urlPathEqualTo("/v1/references")) - .withQueryParam("uuids", equalTo(modificationUuid.toString())) - .willReturn(WireMock.ok() - .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .withBody(mapper.writeValueAsString(stubbedReferences))) - ).getId(); - UUID removeReferencesStubId = wireMockServer.stubFor(WireMock.delete(urlPathMatching( - "/v1/elements/" + modificationUuid + "/references/.*")) - .willReturn(WireMock.ok()) - ).getId(); - UUID stubId = wireMockServer.stubFor(WireMock.delete(urlPathMatching("/v1/network-modifications")).willReturn(WireMock.ok())).getId(); StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); @@ -1187,15 +1174,7 @@ void deleteModificationRequest() throws Exception { .queryParam("uuids", modificationUuid.toString()) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); - WireMockUtils.verifyGetRequest(wireMockServer, referencesStubId, "/v1/references", Map.of("uuids", equalTo(modificationUuid.toString()))); WireMockUtils.verifyDeleteRequest(wireMockServer, stubId, "/v1/network-modifications", false, Map.of("uuids", equalTo(modificationUuid.toString()))); - WireMockUtils.verifyDeleteRequest( - wireMockServer, - removeReferencesStubId, - "/v1/elements/" + modificationUuid + "/references/.*", - true, - Map.of() - ); checkEquipmentDeletingFinishedMessagesReceived(studyUuid, modificationNode.getId()); stubId = wireMockServer.stubFor(WireMock.delete(urlPathMatching("/v1/network-modifications.*")) @@ -1205,7 +1184,6 @@ void deleteModificationRequest() throws Exception { .queryParam("uuids", modificationUuid.toString()) .header(USER_ID_HEADER, "userId")) .andExpect(status().isInternalServerError()); - WireMockUtils.verifyGetRequest(wireMockServer, referencesStubId, "/v1/references", Map.of("uuids", equalTo(modificationUuid.toString()))); WireMockUtils.verifyDeleteRequest(wireMockServer, stubId, "/v1/network-modifications", false, Map.of("uuids", equalTo(modificationUuid.toString()))); checkEquipmentDeletingFinishedMessagesReceived(studyUuid, modificationNode.getId()); } From 8450222aee1e7f3cf0a87a1db3ab9de7c1141aea Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Wed, 21 Oct 2026 15:16:42 +0200 Subject: [PATCH 06/11] Remove obsolete comment on reference unlinking Signed-off-by: Florent MILLOT --- .../java/org/gridsuite/study/server/service/StudyService.java | 1 - 1 file changed, 1 deletion(-) 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 bac8093a97..29a41e915f 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -656,7 +656,6 @@ public void deleteStudyIfNotCreationInProgress(UUID studyUuid, String userId) { } private void deleteModificationsFromGroup(Pair groupUuidNodeUuid, String userId) { - // network-modification-server unlinks the deleted references from directory-server networkModificationService.deleteModifications(groupUuidNodeUuid.getFirst(), userId); } From eb8f69a612fbe4829f5d4643d49fb322fb4fb2c7 Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Fri, 23 Oct 2026 09:33:44 +0200 Subject: [PATCH 07/11] Check that the user is forwarded when deleting modifications Signed-off-by: Florent MILLOT --- .../org/gridsuite/study/server/NetworkModificationTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java index 9eb6e83d5b..eea7d6f366 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java @@ -1150,7 +1150,10 @@ void deleteModificationRequest() throws Exception { String userId = "userId"; UUID modificationUuid = UUID.randomUUID(); - UUID stubId = wireMockServer.stubFor(WireMock.delete(urlPathMatching("/v1/network-modifications")).willReturn(WireMock.ok())).getId(); + // the user is forwarded for network-modification-server to unlink the deleted references + UUID stubId = wireMockServer.stubFor(WireMock.delete(urlPathMatching("/v1/network-modifications")) + .withHeader(USER_ID_HEADER, equalTo(userId)) + .willReturn(WireMock.ok())).getId(); StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); UUID studyUuid = studyEntity.getId(); From c790a20320b534e688e508e01e195c9cad85249e Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Fri, 23 Oct 2026 10:04:08 +0200 Subject: [PATCH 08/11] Remove the unused deletion of modification groups Signed-off-by: Florent MILLOT --- .../NetworkModificationRestService.java | 17 ----------------- .../NetworkModificationServiceTest.java | 13 ------------- 2 files changed, 30 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 116777484c..5566579afa 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 @@ -210,23 +210,6 @@ public void deleteModifications(UUID groupUUid, String userId) { restTemplate.exchange(getNetworkModificationServerURI(false) + path, HttpMethod.DELETE, new HttpEntity<>(headers), Void.class); } - public void deleteModificationsGroups(List groupUuids) { - Objects.requireNonNull(groupUuids); - if (groupUuids.isEmpty()) { - return; - } - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - HttpEntity httpEntity = new HttpEntity<>(toJson(groupUuids), headers); - var path = UriComponentsBuilder.fromPath(GROUPS) - .toUriString(); - - restTemplate.exchange(getNetworkModificationServerURI(false) + path, - HttpMethod.DELETE, - httpEntity, - new ParameterizedTypeReference>() { }); - } - public void deleteModifications(List modificationsUuids, String userId) { Objects.requireNonNull(modificationsUuids); var path = UriComponentsBuilder 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 867a054224..1b657df155 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 @@ -135,19 +135,6 @@ void testUnshareModificationReference() { verify(restTemplate).exchange(expectedUrl, HttpMethod.PUT, new HttpEntity<>(headers), Void.class); } - @Test - void testDeleteModificationsGroups() { - UUID firstUuid = UUID.randomUUID(); - UUID secondUuid = UUID.randomUUID(); - String expectedUrl = NETWORK_MODIFICATION_SERVER_URI + "/v1/groups"; - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - networkModificationService.deleteModificationsGroups(List.of(firstUuid, secondUuid)); - HttpEntity httpEntity = new HttpEntity<>("[\"" + firstUuid + "\",\"" + secondUuid + "\"]", headers); - verify(restTemplate).exchange(expectedUrl, HttpMethod.DELETE, httpEntity, new ParameterizedTypeReference>() { }); - } - @Test void testDeleteStashedModificationsGroups() { UUID firstUuid = UUID.randomUUID(); From 67d61bc1136e70d0095c6bc1f0114f8daa61379e Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Fri, 23 Oct 2026 12:48:06 +0200 Subject: [PATCH 09/11] Stop expecting study-server to read the references when deleting a study Signed-off-by: Florent MILLOT --- .../study/server/studycontroller/StudyTest.java | 6 ------ .../study/server/utils/wiremock/WireMockStubs.java | 11 ----------- 2 files changed, 17 deletions(-) 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 c20f4ceaa1..17e04ba5d4 100644 --- a/src/test/java/org/gridsuite/study/server/studycontroller/StudyTest.java +++ b/src/test/java/org/gridsuite/study/server/studycontroller/StudyTest.java @@ -246,14 +246,12 @@ void testDeleteStudy() throws Exception { UUID stubUuid = wireMockStubs.stubNetworkModificationDeleteGroup(); UUID stubDeleteCaseId = wireMockStubs.caseServer.stubDeleteCase(CASE_UUID_STRING); DeleteStudyStubs deleteStudyStubs = setupDeleteStudyStubs(); - UUID stubReferencesUuid = wireMockStubs.stubGetAllReferencesDataFromGroup(); mockMvc.perform(delete("/v1/studies/{studyUuid}", studyUuid).header(USER_ID_HEADER, "userId")) .andExpect(status().isOk()); assertTrue(studyRepository.findById(studyUuid).isEmpty()); - wireMockStubs.verifyGetReferencesDataFromGroup(stubReferencesUuid); wireMockStubs.verifyNetworkModificationDeleteGroup(stubUuid); wireMockStubs.caseServer.verifyDeleteCase(stubDeleteCaseId, CASE_UUID_STRING); deleteStudyStubs.verify(wireMockStubs, computationServerStubs, 10); // voltageInit, loadFlow, securityAnalysis, sensitivityAnalysis, stateEstimation, pccMin, dynamic, shortCircuit @@ -282,13 +280,11 @@ void testDeleteStudyWithError(final CapturedOutput capturedOutput) throws Except }).when(caseService).deleteCase(any()); UUID stubUuid = wireMockStubs.stubNetworkModificationDeleteGroup(); DeleteStudyStubs deleteStudyStubs = setupDeleteStudyStubs(); - UUID stubReferencesUuid = wireMockStubs.stubGetAllReferencesDataFromGroup(); mockMvc.perform(delete("/v1/studies/{studyUuid}", studyUuid).header(USER_ID_HEADER, "userId")) .andExpectAll(status().isOk()); assertTrue(capturedOutput.getOut().contains(StudyServerExecutionService.class.getName() + " - " + CompletionException.class.getName() + ": " + InterruptedException.class.getName())); - wireMockStubs.verifyGetReferencesDataFromGroup(stubReferencesUuid); wireMockStubs.verifyNetworkModificationDeleteGroup(stubUuid); deleteStudyStubs.verify(wireMockStubs, computationServerStubs, 3); // loadflow, security, sensitivity, stateEstimation, shortCircuit, pccMin } @@ -299,7 +295,6 @@ void testDeleteStudyWithNonExistingCase() throws Exception { UUID nonExistingCaseUuid = UUID.randomUUID(); UUID stubUuid = wireMockStubs.stubNetworkModificationDeleteGroup(); - UUID stubReferencesUuid = wireMockStubs.stubGetAllReferencesDataFromGroup(); // Changing the study case uuid with a non-existing case StudyEntity studyEntity = studyRepository.findById(studyUuid).orElse(null); @@ -316,7 +311,6 @@ void testDeleteStudyWithNonExistingCase() throws Exception { assertTrue(studyRepository.findById(studyUuid).isEmpty()); - wireMockStubs.verifyGetReferencesDataFromGroup(stubReferencesUuid); wireMockStubs.verifyNetworkModificationDeleteGroup(stubUuid); wireMockStubs.caseServer.verifyDeleteCase(stubDeleteCaseId, nonExistingCaseUuid.toString()); deleteStudyStubs.verify(wireMockStubs, computationServerStubs, 10); diff --git a/src/test/java/org/gridsuite/study/server/utils/wiremock/WireMockStubs.java b/src/test/java/org/gridsuite/study/server/utils/wiremock/WireMockStubs.java index a6d12c4a35..65869df50b 100644 --- a/src/test/java/org/gridsuite/study/server/utils/wiremock/WireMockStubs.java +++ b/src/test/java/org/gridsuite/study/server/utils/wiremock/WireMockStubs.java @@ -247,17 +247,6 @@ public UUID stubNetworkModificationDeleteGroup() { ).getId(); } - public UUID stubGetAllReferencesDataFromGroup() { - return wireMock.stubFor(WireMock.get(WireMock.urlPathMatching(URI_NETWORK_MODIFICATION_CONTAINERS + DELIMITER + ".*/references")) - .willReturn(WireMock.ok() - .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .withBody("[]"))).getId(); - } - - public void verifyGetReferencesDataFromGroup(UUID getReferencesUuid) { - verifyGetRequest(wireMock, getReferencesUuid, URI_NETWORK_MODIFICATION_CONTAINERS + DELIMITER + ".*/references", true, Map.of(), 1); - } - public UUID stubNetworkModificationDeleteIndex() { return wireMock.stubFor(WireMock.delete(WireMock.urlPathMatching(URI_NETWORK_MODIFICATION + DELIMITER + "index.*")) .willReturn(WireMock.ok()) From bae56d8c3f79fd64418224549167372241f80cb6 Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Fri, 23 Oct 2026 17:25:04 +0200 Subject: [PATCH 10/11] Require the modifications to delete, and clarify the deletion methods Signed-off-by: Florent MILLOT --- .../study/server/controller/StudyController.java | 2 +- .../gridsuite/study/server/service/StudyService.java | 11 +++-------- .../NetworkModificationRestService.java | 12 ++++-------- 3 files changed, 8 insertions(+), 17 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 5f834ae1f4..6a66ce0ef1 100644 --- a/src/main/java/org/gridsuite/study/server/controller/StudyController.java +++ b/src/main/java/org/gridsuite/study/server/controller/StudyController.java @@ -1032,7 +1032,7 @@ public ResponseEntity updateNetworkModification(@Parameter(description = " @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The network modifications was deleted"), @ApiResponse(responseCode = "404", description = "The study/node is not found")}) public ResponseEntity deleteNetworkModifications(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "Node UUID") @PathVariable("nodeUuid") UUID nodeUuid, - @Parameter(description = "Network modification UUIDs") @RequestParam(name = "uuids", required = false) List networkModificationUuids, + @Parameter(description = "Network modification UUIDs") @RequestParam(name = "uuids") List networkModificationUuids, @RequestHeader(HEADER_USER_ID) String userId) { studyService.assertIsNodeNotReadOnly(nodeUuid); studyService.deleteNetworkModifications(studyUuid, nodeUuid, networkModificationUuids, userId); 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 8dc5251a46..a3fc4cae22 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -657,18 +657,13 @@ public void deleteStudyIfNotCreationInProgress(UUID studyUuid, String userId) { // delete all distant resources linked to nodes studyServerExecutionService.runAsync(() -> deleteStudyInfos.getModificationGroupUuidsNodeUuids().stream() .filter(Objects::nonNull) - .forEach(groupUuidNodeUuid -> deleteModificationsFromGroup(groupUuidNodeUuid, userId))); + .forEach(groupUuidNodeUuid -> networkModificationRestService.deleteModificationsByGroup(groupUuidNodeUuid.getFirst(), userId))); LOGGER.trace("Delete study '{}' : {} seconds", studyUuid, TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime.get())); } } - private void deleteModificationsFromGroup(Pair groupUuidNodeUuid, String userId) { - // network-modification-server unlinks the deleted references from directory-server - networkModificationRestService.deleteModifications(groupUuidNodeUuid.getFirst(), userId); - } - @Transactional public CreatedStudyBasicInfos insertStudy(UUID studyUuid, String userId, NetworkInfos networkInfos, CaseInfos caseInfos, ComputationParameterUUIDs computationParameterUUIDs, UUID networkVisualizationParametersUuid, @@ -1549,7 +1544,7 @@ public void deleteNetworkModifications(UUID studyUuid, UUID nodeUuid, List if (!networkModificationTreeService.getStudyUuidForNodeId(nodeUuid).equals(studyUuid)) { throw new StudyException(NOT_ALLOWED); } - networkModificationRestService.deleteModifications(modificationsUuids, userId); + networkModificationRestService.deleteModificationsByUuids(modificationsUuids, userId); } finally { notificationService.emitModificationsDeleted(studyUuid, nodeUuid, childrenUuids); } @@ -1698,7 +1693,7 @@ private void deleteNodesInfos(DeleteNodeInfos deleteNodeInfos, String userId) { .mapToObj(index -> Pair.of(modificationGroupUuids.get(index), removedNodeUuids.get(index))) .toList(); futures.add(studyServerExecutionService.runAsync(() -> modificationGroupUuidsNodeUuids.forEach( - groupUuidNodeUuid -> deleteModificationsFromGroup(groupUuidNodeUuid, userId)) + groupUuidNodeUuid -> networkModificationRestService.deleteModificationsByGroup(groupUuidNodeUuid.getFirst(), userId)) )); futures.add(studyServerExecutionService.runAsync(() -> deleteNodeInfos.getRemovedNodeUuids().forEach(dynamicSimulationEventService::deleteEventsByNodeId))); futures.addAll(rootNetworkNodeInfoService.getRemoteDeletions(deleteNodeInfos)); 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 dbaaa590cf..771ee155c2 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 @@ -199,27 +199,23 @@ public Integer getModificationsCount(UUID groupUUid, boolean stashedModification return restTemplate.exchange(getNetworkModificationServerURI(false) + path, HttpMethod.GET, null, Integer.class).getBody(); } - public void deleteModifications(UUID groupUUid, String userId) { + public void deleteModificationsByGroup(UUID groupUUid, String userId) { Objects.requireNonNull(groupUUid); var path = UriComponentsBuilder.fromPath(GROUP_PATH) .buildAndExpand(groupUUid) .toUriString(); - HttpHeaders headers = new HttpHeaders(); - headers.set(HEADER_USER_ID, userId); - restTemplate.exchange(getNetworkModificationServerURI(false) + path, HttpMethod.DELETE, new HttpEntity<>(headers), Void.class); + restTemplate.exchange(getNetworkModificationServerURI(false) + path, HttpMethod.DELETE, userIdEntity(userId), Void.class); } - public void deleteModifications(List modificationsUuids, String userId) { + public void deleteModificationsByUuids(List modificationsUuids, String userId) { Objects.requireNonNull(modificationsUuids); var path = UriComponentsBuilder .fromUriString(getNetworkModificationServerURI(false) + NETWORK_MODIFICATIONS_PATH) .queryParam(UUIDS, modificationsUuids) .buildAndExpand() .toUriString(); - HttpHeaders headers = new HttpHeaders(); - headers.set(HEADER_USER_ID, userId); - restTemplate.exchange(path, HttpMethod.DELETE, new HttpEntity<>(headers), Void.class); + restTemplate.exchange(path, HttpMethod.DELETE, userIdEntity(userId), Void.class); } public NetworkModificationsResult createModification(UUID groupUuid, From 20330a6f370d590d8a2b0a7dcb3408f76431132a Mon Sep 17 00:00:00 2001 From: Florent MILLOT <75525996+flomillot@users.noreply.github.com> Date: Wed, 28 Oct 2026 11:11:00 +0100 Subject: [PATCH 11/11] Send the user when deleting voltage init results Signed-off-by: Florent MILLOT <75525996+flomillot@users.noreply.github.com> --- .../service/RootNetworkNodeInfoService.java | 3 ++- .../server/service/SupervisionService.java | 4 ++-- .../common/AbstractComputationRestService.java | 17 +++++++++++++++++ .../voltageinit/VoltageInitRestService.java | 8 ++++---- .../service/voltageinit/VoltageInitService.java | 2 +- .../server/rootnetworks/RootNetworkTest.java | 3 ++- 6 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java b/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java index 1a569a9cba..c5921cf0f1 100644 --- a/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java +++ b/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java @@ -58,6 +58,7 @@ import static org.gridsuite.study.server.dto.ComputationType.*; import static org.gridsuite.study.server.dto.InvalidateNodeTreeParameters.ComputationsInvalidationMode; import static org.gridsuite.study.server.error.StudyBusinessErrorCode.*; +import static org.gridsuite.study.server.service.SupervisionService.SUPERVISION_USER; /** * @author Slimane amar @@ -547,7 +548,7 @@ public List> getRemoteDeletions(RemoteDeletionInfos infos) studyServerExecutionService.runAsync(() -> sensitivityAnalysisRestService.deleteSensitivityAnalysisResults(infos.getSensitivityAnalysisResultUuids())), studyServerExecutionService.runAsync(() -> shortCircuitRestService.deleteShortCircuitAnalysisResults(infos.getShortCircuitAnalysisResultUuids())), studyServerExecutionService.runAsync(() -> shortCircuitRestService.deleteShortCircuitAnalysisResults(infos.getOneBusShortCircuitAnalysisResultUuids())), - studyServerExecutionService.runAsync(() -> voltageInitRestService.deleteVoltageInitResults(infos.getVoltageInitResultUuids())), + studyServerExecutionService.runAsync(() -> voltageInitRestService.deleteVoltageInitResults(infos.getVoltageInitResultUuids(), SUPERVISION_USER)), studyServerExecutionService.runAsync(() -> dynamicSimulationRestService.deleteResults(infos.getDynamicSimulationResultUuids())), studyServerExecutionService.runAsync(() -> dynamicSecurityAnalysisRestService.deleteResults(infos.getDynamicSecurityAnalysisResultUuids())), studyServerExecutionService.runAsync(() -> dynamicMarginCalculationRestService.deleteResults(infos.getDynamicMarginCalculationResultUuids())), diff --git a/src/main/java/org/gridsuite/study/server/service/SupervisionService.java b/src/main/java/org/gridsuite/study/server/service/SupervisionService.java index b0434d0f37..212d55eccd 100644 --- a/src/main/java/org/gridsuite/study/server/service/SupervisionService.java +++ b/src/main/java/org/gridsuite/study/server/service/SupervisionService.java @@ -107,7 +107,7 @@ public class SupervisionService { private final NetworkModificationRestService networkModificationService; - private static final String SUPERVISION_USER = "Supervision"; + public static final String SUPERVISION_USER = "Supervision"; public SupervisionService(StudyService studyService, NetworkModificationTreeService networkModificationTreeService, LoadFlowService loadFlowService, @@ -354,7 +354,7 @@ private Integer deleteVoltageInitResults() { }); reportService.deleteReports(reportsToDelete); } - voltageInitService.deleteAllVoltageInitResults(); + voltageInitService.deleteAllVoltageInitResults(SUPERVISION_USER); LOGGER.trace(DELETION_LOG_MESSAGE, ComputationType.VOLTAGE_INITIALIZATION, TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime.get())); return rootNetworkNodeInfoEntities.size(); } diff --git a/src/main/java/org/gridsuite/study/server/service/common/AbstractComputationRestService.java b/src/main/java/org/gridsuite/study/server/service/common/AbstractComputationRestService.java index 3415fee941..0989aac2c1 100644 --- a/src/main/java/org/gridsuite/study/server/service/common/AbstractComputationRestService.java +++ b/src/main/java/org/gridsuite/study/server/service/common/AbstractComputationRestService.java @@ -2,6 +2,8 @@ import org.gridsuite.study.server.service.client.AbstractRestClient; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; @@ -9,6 +11,7 @@ import java.util.List; import java.util.UUID; +import static org.gridsuite.study.server.StudyConstants.HEADER_USER_ID; import static org.gridsuite.study.server.StudyConstants.QUERY_PARAM_RESULTS_UUIDS; public abstract class AbstractComputationRestService extends AbstractRestClient { @@ -35,4 +38,18 @@ public static void deleteCalculationResults(List resultsUuids, UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath(path).queryParam(QUERY_PARAM_RESULTS_UUIDS, resultsUuids); restTemplate.delete(serverBaseUri + uriComponentsBuilder.build().toUriString()); } + + public static void deleteCalculationResults(List resultsUuids, + String path, + RestTemplate restTemplate, + String serverBaseUri, + String userId) { + if (resultsUuids != null && resultsUuids.isEmpty()) { + return; + } + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath(path).queryParam(QUERY_PARAM_RESULTS_UUIDS, resultsUuids); + HttpHeaders headers = new HttpHeaders(); + headers.set(HEADER_USER_ID, userId); + restTemplate.exchange(serverBaseUri + uriComponentsBuilder.build().toUriString(), HttpMethod.DELETE, new HttpEntity<>(headers), Void.class); + } } diff --git a/src/main/java/org/gridsuite/study/server/service/voltageinit/VoltageInitRestService.java b/src/main/java/org/gridsuite/study/server/service/voltageinit/VoltageInitRestService.java index c479a40597..dc0b2e96ea 100644 --- a/src/main/java/org/gridsuite/study/server/service/voltageinit/VoltageInitRestService.java +++ b/src/main/java/org/gridsuite/study/server/service/voltageinit/VoltageInitRestService.java @@ -208,12 +208,12 @@ public void stopVoltageInit(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, restTemplate.exchange(baseUri + path, HttpMethod.PUT, new HttpEntity<>(headers), Void.class); } - public void deleteVoltageInitResults(List resultsUuids) { - deleteCalculationResults(resultsUuids, DELIMITER + VOLTAGE_INIT_API_VERSION + "/results", restTemplate, baseUri); + public void deleteVoltageInitResults(List resultsUuids, String userId) { + deleteCalculationResults(resultsUuids, DELIMITER + VOLTAGE_INIT_API_VERSION + "/results", restTemplate, baseUri, userId); } - public void deleteAllVoltageInitResults() { - deleteVoltageInitResults(null); + public void deleteAllVoltageInitResults(String userId) { + deleteVoltageInitResults(null, userId); } public Integer getVoltageInitResultsCount() { diff --git a/src/main/java/org/gridsuite/study/server/service/voltageinit/VoltageInitService.java b/src/main/java/org/gridsuite/study/server/service/voltageinit/VoltageInitService.java index e77dffa548..9eac728729 100644 --- a/src/main/java/org/gridsuite/study/server/service/voltageinit/VoltageInitService.java +++ b/src/main/java/org/gridsuite/study/server/service/voltageinit/VoltageInitService.java @@ -81,7 +81,7 @@ public UUID runVoltageInit(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, private UUID handleVoltageInitRequest(StudyEntity studyEntity, UUID nodeUuid, UUID rootNetworkUuid, boolean debug, String userId) { UUID prevResultUuid = rootNetworkNodeInfoService.getComputationResultUuid(nodeUuid, rootNetworkUuid, VOLTAGE_INITIALIZATION); if (prevResultUuid != null) { - voltageInitRestService.deleteVoltageInitResults(List.of(prevResultUuid)); + voltageInitRestService.deleteVoltageInitResults(List.of(prevResultUuid), userId); } UUID networkUuid = rootNetworkService.getNetworkUuid(rootNetworkUuid); diff --git a/src/test/java/org/gridsuite/study/server/rootnetworks/RootNetworkTest.java b/src/test/java/org/gridsuite/study/server/rootnetworks/RootNetworkTest.java index 92c86fb6f7..10298d79d2 100644 --- a/src/test/java/org/gridsuite/study/server/rootnetworks/RootNetworkTest.java +++ b/src/test/java/org/gridsuite/study/server/rootnetworks/RootNetworkTest.java @@ -66,6 +66,7 @@ import static org.gridsuite.study.server.StudyConstants.*; import static org.gridsuite.study.server.error.StudyBusinessErrorCode.MAXIMUM_ROOT_NETWORK_BY_STUDY_REACHED; import static org.gridsuite.study.server.error.StudyBusinessErrorCode.NOT_FOUND; +import static org.gridsuite.study.server.service.SupervisionService.SUPERVISION_USER; import static org.gridsuite.study.server.utils.TestUtils.createModificationNodeInfo; import static org.gridsuite.study.server.utils.TestUtils.synchronizeStudyServerExecutionService; import static org.gridsuite.study.server.utils.wiremock.WireMockUtils.verifyPostRequest; @@ -583,7 +584,7 @@ void testDeleteRootNetwork() throws Exception { verify(stateEstimationService, times(1)).deleteStateEstimationResults(List.of(STATE_ESTIMATION_RESULT_UUID)); verify(pccMinService, times(1)).deletePccMinResults(List.of(PCC_MIN_RESULT_UUID)); verify(sensitivityAnalysisService, times(1)).deleteSensitivityAnalysisResults(List.of(SENSITIVITY_ANALYSIS_RESULT_UUID)); - verify(voltageInitService, times(1)).deleteVoltageInitResults(List.of(VOLTAGE_INIT_RESULT_UUID)); + verify(voltageInitService, times(1)).deleteVoltageInitResults(List.of(VOLTAGE_INIT_RESULT_UUID), SUPERVISION_USER); } @Test