diff --git a/src/main/java/org/gridsuite/study/server/controller/SupervisionController.java b/src/main/java/org/gridsuite/study/server/controller/SupervisionController.java index d8d9d9840..db2b46458 100644 --- a/src/main/java/org/gridsuite/study/server/controller/SupervisionController.java +++ b/src/main/java/org/gridsuite/study/server/controller/SupervisionController.java @@ -181,7 +181,7 @@ public ResponseEntity invalidateAllNodesBuilds(@PathVariable("studyUuid") } @DeleteMapping(value = "/studies/{studyUuid}/invalidate") - @Operation(summary = "Invalidate built nodes and delete root node network") + @Operation(summary = "Invalidate all node tree, clean stashed elements and delete root networks") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "study has been invalidated")}) public ResponseEntity invalidateStudy(@PathVariable("studyUuid") UUID studyUuid) { supervisionService.invalidateStudy(studyUuid); 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 3a6470ae9..bf6278292 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java @@ -46,7 +46,8 @@ public class NetworkModificationService { private static final String DELIMITER = "/"; private static final String COMPOSITE_PATH = "network-composite-modifications" + DELIMITER; - private static final String GROUP_PATH = "groups" + DELIMITER + "{groupUuid}"; + private static final String GROUPS = "groups"; + private static final String GROUP_PATH = GROUPS + DELIMITER + "{groupUuid}"; private static final String CONTAINER_PATH = "containers" + DELIMITER + "{containerId}"; private static final String NETWORK_MODIFICATIONS_PATH = "network-modifications"; private static final String NETWORK_MODIFICATIONS_COUNT_PATH = "network-modifications-count"; @@ -186,6 +187,24 @@ public void deleteModifications(UUID groupUUid) { restTemplate.delete(getNetworkModificationServerURI(false) + path); } + 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) + .queryParam(QUERY_PARAM_ERROR_ON_GROUP_NOT_FOUND, false) + .toUriString(); + + restTemplate.exchange(getNetworkModificationServerURI(false) + path, + HttpMethod.DELETE, + httpEntity, + new ParameterizedTypeReference>() { }); + } + public void deleteModifications(UUID groupUuid, List modificationsUuids) { Objects.requireNonNull(groupUuid); var path = UriComponentsBuilder @@ -598,6 +617,24 @@ private String toJson(Object object) { return json; } + public void deleteStashedModificationsGroups(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 + "/stashed-modifications") + .queryParam(QUERY_PARAM_ERROR_ON_GROUP_NOT_FOUND, false) + .toUriString(); + + restTemplate.exchange(getNetworkModificationServerURI(false) + path, + HttpMethod.DELETE, + httpEntity, + new ParameterizedTypeReference>() { }); + } + public void deleteStashedModifications(UUID groupUUid) { Objects.requireNonNull(groupUUid); var path = UriComponentsBuilder.fromPath(GROUP_PATH + "/stashed-modifications") 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 fcf66c794..234d0dad1 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java @@ -479,6 +479,39 @@ public void doDeleteTree(UUID studyId) { } } + @Transactional + public void deleteAllStashedElements(UUID studyId) { + List nodes = nodesRepository.findAllByStudyId(studyId); + List stashedNodes = new ArrayList<>(); + List notStashedNodes = new ArrayList<>(); + for (NodeEntity nodeEntity : nodes) { + if (nodeEntity.isStashed()) { + stashedNodes.add(nodeEntity); + } else { + notStashedNodes.add(nodeEntity); + } + } + + // remove stashed modification on not stashed nodes + List networkModificationNodeInfos = networkModificationNodeInfoRepository + .findAllById(notStashedNodes.stream().map(NodeEntity::getIdNode).toList()); + List stashedModificationGroupUuids = networkModificationNodeInfos.stream() + .map(NetworkModificationNodeInfoEntity::getModificationGroupUuid) + .toList(); + networkModificationService.deleteStashedModificationsGroups(stashedModificationGroupUuids); + + // remove modification on stashed nodes + List networkModificationNodeInfosToDelete = networkModificationNodeInfoRepository + .findAllById(stashedNodes.stream().map(NodeEntity::getIdNode).toList()); + List modificationGroupUuidsToDelete = networkModificationNodeInfosToDelete.stream() + .map(NetworkModificationNodeInfoEntity::getModificationGroupUuid) + .toList(); + networkModificationService.deleteModificationsGroups(modificationGroupUuidsToDelete); + // remove stashed nodes + networkModificationNodeInfoRepository.deleteAllById(stashedNodes.stream().map(NodeEntity::getIdNode).toList()); + nodesRepository.deleteAll(stashedNodes); + } + @Transactional public NodeEntity createRoot(StudyEntity study) { NodeEntity node = nodesRepository.save(new NodeEntity(null, null, NodeType.ROOT, study, false, null, new ArrayList<>())); 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 ff6008954..4b099bfc6 100644 --- a/src/main/java/org/gridsuite/study/server/service/SupervisionService.java +++ b/src/main/java/org/gridsuite/study/server/service/SupervisionService.java @@ -405,6 +405,8 @@ public void invalidateStudy(UUID studyUuid) { rootNetworkService.getStudyRootNetworkIds(studyUuid).forEach(rnId -> { try { rootNetworkService.updateNetworkLoadStatus(rnId, RootNetworkLoadStatus.UNLOADING); + // remove all stashed nodes and network modifications + networkModificationTreeService.deleteAllStashedElements(studyUuid); studyService.invalidateStudyRootNetwork(studyUuid, rnId, SUPERVISION_USER, false); rootNetworkService.updateNetworkLoadStatus(rnId, RootNetworkLoadStatus.UNLOADED); } catch (Exception e) { 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 dd15ec777..158f34262 100644 --- a/src/test/java/org/gridsuite/study/server/service/NetworkModificationServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/service/NetworkModificationServiceTest.java @@ -13,11 +13,15 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; import org.springframework.web.client.RestTemplate; import java.util.List; +import java.util.Map; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; @@ -124,6 +128,32 @@ void testUpdateNetworkModificationsMetadata() { verify(restTemplate).exchange(eq(expectedUrl), eq(HttpMethod.PUT), org.mockito.ArgumentMatchers.>any(), eq(Void.class)); } + @Test + void testDeleteModificationsGroups() { + UUID firstUuid = UUID.randomUUID(); + UUID secondUuid = UUID.randomUUID(); + String expectedUrl = NETWORK_MODIFICATION_SERVER_URI + "/v1/groups?errorOnGroupNotFound=false"; + + 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(); + UUID secondUuid = UUID.randomUUID(); + String expectedUrl = NETWORK_MODIFICATION_SERVER_URI + "/v1/groups/stashed-modifications?errorOnGroupNotFound=false"; + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + networkModificationService.deleteStashedModificationsGroups(List.of(firstUuid, secondUuid)); + HttpEntity httpEntity = new HttpEntity<>("[\"" + firstUuid + "\",\"" + secondUuid + "\"]", headers); + verify(restTemplate).exchange(expectedUrl, HttpMethod.DELETE, httpEntity, new ParameterizedTypeReference>() { }); + } + @Test void testRenameRootNetworkTag() { UUID firstGroupUuid = UUID.randomUUID();