diff --git a/src/main/java/org/gridsuite/study/server/controller/NetworkModificationController.java b/src/main/java/org/gridsuite/study/server/controller/NetworkModificationController.java index 22fb1a9f7..8eab18c11 100644 --- a/src/main/java/org/gridsuite/study/server/controller/NetworkModificationController.java +++ b/src/main/java/org/gridsuite/study/server/controller/NetworkModificationController.java @@ -47,6 +47,11 @@ public ResponseEntity getNetworkModificationsFromComposite(@RequestParam return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(networkModificationService.getNetworkModificationsFromComposite(compositeModificationUuids, onlyMetadata)); } + @GetMapping(value = "/network-composite-modifications/{uuid}/contains-shared-modification") + public ResponseEntity containsSharedModification(@PathVariable UUID uuid) { + return ResponseEntity.ok().body(networkModificationService.containsSharedModification(uuid)); + } + @GetMapping(value = "/network-modifications/{uuid}") public ResponseEntity getNetworkModification(@PathVariable UUID uuid) { return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(networkModificationService.getNetworkModification(uuid)); 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..26f70f9f7 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java @@ -114,6 +114,12 @@ public String getNetworkModificationsFromComposite(List compositeModificat return restTemplate.getForObject(getNetworkModificationServerURI(false) + path, String.class); } + public Boolean containsSharedModification(UUID compositeModificationUuid) { + String path = UriComponentsBuilder.fromPath(COMPOSITE_PATH + "{uuid}" + DELIMITER + "contains-shared-modification") + .buildAndExpand(compositeModificationUuid).toUriString(); + return restTemplate.getForObject(getNetworkModificationServerURI(false) + path, Boolean.class); + } + public String getNetworkModification(UUID networkModificationUuid) { String path = UriComponentsBuilder.fromPath(NETWORK_MODIFICATIONS_PATH + "/{uuid}").buildAndExpand(networkModificationUuid).toUriString(); return restTemplate.getForObject(getNetworkModificationServerURI(false) + path, String.class); @@ -502,23 +508,26 @@ public NetworkModificationsResult insertCompositeModifications(UUID groupUuid, } /** - * Asks the network modification server to take a composite modification out of its group, replacing it in the group + * Asks the network modification server to take a composite modification out of its container, replacing it there * by a reference to it, so that it can be stored as an element in the directory server. The composite modification * keeps its own uuid. + * + * @return the container the composite modification has been taken out of, now containing the reference to it : + * either the group of the node or a parent composite */ - public void extractCompositeModificationToShare(@NonNull UUID groupUuid, @NonNull UUID modificationUuid, @NonNull String name) { + public ModificationContainerInfos extractCompositeModificationToShare(@NonNull UUID groupUuid, @NonNull UUID modificationUuid, @NonNull String name) { String path = UriComponentsBuilder.fromPath(COMPOSITE_PATH + "{modificationUuid}" + DELIMITER + "share") .queryParam(QUERY_PARAM_NAME, name) .queryParam(QUERY_PARAM_GROUP_UUID, groupUuid) .buildAndExpand(modificationUuid) .toUriString(); - restTemplate.exchange( + return restTemplate.exchange( getNetworkModificationServerURI(false) + path, HttpMethod.POST, null, - Void.class - ); + ModificationContainerInfos.class + ).getBody(); } public UUID assembleModificationsIntoComposite(@NonNull List modificationsUuids) { 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 cdac0ea36..5c5aaebd4 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -2080,10 +2080,15 @@ public void shareCompositeNetworkModification( List childrenUuids = networkModificationTreeService.getChildrenUuids(nodeUuid); try { // the applied modifications are left unchanged : the node does not need to be rebuilt - networkModificationService.extractCompositeModificationToShare(groupUuid, modificationUuid, name); + ModificationContainerInfos container = networkModificationService.extractCompositeModificationToShare(groupUuid, modificationUuid, name); // the composite modification keeps its uuid when extracted, so it is shared under that same uuid directoryService.createElement(parentDirectoryUuid, description, modificationUuid, name, DirectoryService.MODIFICATION, userId); - directoryService.createsReferencesToSharedComposites(List.of(modificationUuid), userId, nodeUuid, ReferenceAttributes.ReferenceType.STUDY_NODE); + // the new reference left behind belongs to the parent composite if any, to the node otherwise + if (container != null && ModificationContainerType.COMPOSITE.equals(container.type())) { + directoryService.createsReferencesToSharedComposites(List.of(modificationUuid), userId, container.id(), ReferenceAttributes.ReferenceType.NETWORK_MODIFICATION); + } else { + directoryService.createsReferencesToSharedComposites(List.of(modificationUuid), userId, nodeUuid, ReferenceAttributes.ReferenceType.STUDY_NODE); + } } finally { notificationService.emitModificationsUpdated(studyUuid, nodeUuid, childrenUuids); } diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java index ee7fe8763..4eeaa9b31 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java @@ -2190,8 +2190,31 @@ void testShareCompositeModification() throws Exception { UUID rootNodeUuid = getRootNode(studyUuid).getId(); NetworkModificationNode node1 = createNetworkModificationNode(studyUuid, rootNodeUuid, UUID.randomUUID(), VARIANT_ID, "Node 1", userId); - UUID nodeUuid1 = node1.getId(); + // the composite modification is taken out of the node group : the reference left behind belongs to the node + testShareCompositeModificationFromContainer(studyUuid, node1, userId, + new ModificationContainerInfos(node1.getModificationGroupUuid(), ModificationContainerType.GROUP), + new ReferenceAttributes(node1.getId(), STUDY_NODE)); + } + + @Test + void testShareNestedCompositeModification() throws Exception { + String userId = "userId"; + StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); + UUID studyUuid = studyEntity.getId(); + UUID rootNodeUuid = getRootNode(studyUuid).getId(); + NetworkModificationNode node1 = createNetworkModificationNode(studyUuid, rootNodeUuid, + UUID.randomUUID(), VARIANT_ID, "Node 1", userId); + UUID parentCompositeUuid = UUID.randomUUID(); + + // the composite modification is taken out of a parent composite : the reference left behind belongs to it + testShareCompositeModificationFromContainer(studyUuid, node1, userId, + new ModificationContainerInfos(parentCompositeUuid, ModificationContainerType.COMPOSITE), + new ReferenceAttributes(parentCompositeUuid, NETWORK_MODIFICATION)); + } + + private void testShareCompositeModificationFromContainer(UUID studyUuid, NetworkModificationNode node, String userId, + ModificationContainerInfos formerContainer, ReferenceAttributes expectedReference) throws Exception { UUID compositeUuid = UUID.randomUUID(); UUID directoryUuid = UUID.randomUUID(); String compositeName = "sharedComposite"; @@ -2203,31 +2226,33 @@ void testShareCompositeModification() throws Exception { "/v1/directories/" + directoryUuid + "/elements/" + compositeName + "/types/MODIFICATION")) .willReturn(WireMock.aResponse().withStatus(HttpStatus.NO_CONTENT.value()))); - // the composite modification is taken out of the node group, then stored as an element of the directory + // the composite modification is taken out of its container, then stored as an element of the directory wireMockServer.stubFor(WireMock.post(WireMock.urlPathEqualTo( "/v1/network-composite-modifications/" + compositeUuid + "/share")) - .willReturn(WireMock.ok())); + .willReturn(WireMock.ok() + .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .withBody(mapper.writeValueAsString(formerContainer)))); wireMockServer.stubFor(WireMock.post(WireMock.urlPathEqualTo("/v1/directories/" + directoryUuid + "/elements")) .willReturn(WireMock.ok().withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); wireMockServer.stubFor(WireMock.post(WireMock.urlPathEqualTo("/v1/elements/" + compositeUuid + "/references")) .willReturn(WireMock.ok().withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); mockMvc.perform(post("/v1/studies/{studyUuid}/nodes/{nodeUuid}/network-modifications/{modificationUuid}/share", - studyUuid, nodeUuid1, compositeUuid) + studyUuid, node.getId(), compositeUuid) .queryParam("name", compositeName) .queryParam("description", "description") .queryParam("parentDirectoryUuid", directoryUuid.toString()) .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()); - checkEquipmentUpdatingFinishedMessagesReceived(studyUuid, nodeUuid1); + checkEquipmentUpdatingFinishedMessagesReceived(studyUuid, node.getId()); checkElementUpdatedMessageSent(studyUuid, userId); verifyDirectoryWriteChecks(directoryUuid, compositeName); WireMockUtilsCriteria.verifyPostRequest( wireMockServer, "/v1/network-composite-modifications/" + compositeUuid + "/share", - Map.of("groupUuid", WireMock.equalTo(node1.getModificationGroupUuid().toString()), + Map.of("groupUuid", WireMock.equalTo(node.getModificationGroupUuid().toString()), "name", WireMock.equalTo(compositeName))); WireMockUtilsCriteria.verifyPostRequest( wireMockServer, @@ -2237,7 +2262,7 @@ void testShareCompositeModification() throws Exception { wireMockServer, "/v1/elements/" + compositeUuid + "/references", Map.of(), - mapper.writeValueAsString(new ReferenceAttributes(nodeUuid1, STUDY_NODE))); + mapper.writeValueAsString(expectedReference)); } @Test diff --git a/src/test/java/org/gridsuite/study/server/controller/NetworkModificationControllerTest.java b/src/test/java/org/gridsuite/study/server/controller/NetworkModificationControllerTest.java index e7675e7ed..ef5fc3dcf 100644 --- a/src/test/java/org/gridsuite/study/server/controller/NetworkModificationControllerTest.java +++ b/src/test/java/org/gridsuite/study/server/controller/NetworkModificationControllerTest.java @@ -100,6 +100,18 @@ void testGetNetworkModificationsFromComposite() throws Exception { verify(networkModificationService).getNetworkModificationsFromComposite(List.of(firstUuid, secondUuid), false); } + @Test + void testContainsSharedModification() throws Exception { + UUID compositeUuid = UUID.randomUUID(); + when(networkModificationService.containsSharedModification(compositeUuid)).thenReturn(true); + + mockMvc.perform(get(BASE_URL + "/network-composite-modifications/{uuid}/contains-shared-modification", compositeUuid)) + .andExpect(status().isOk()) + .andExpect(content().string("true")); + + verify(networkModificationService).containsSharedModification(compositeUuid); + } + @Test void testGetNetworkModification() throws Exception { UUID modificationUuid = UUID.randomUUID(); 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..90f983241 100644 --- a/src/test/java/org/gridsuite/study/server/service/NetworkModificationServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/service/NetworkModificationServiceTest.java @@ -85,6 +85,15 @@ void testGetNetworkModificationsFromComposite() { assertThat(networkModificationService.getNetworkModificationsFromComposite(List.of(firstUuid, secondUuid), false)).isEqualTo(RESPONSE); } + @Test + void testContainsSharedModification() { + UUID compositeUuid = UUID.randomUUID(); + String expectedUrl = NETWORK_MODIFICATION_SERVER_URI + "/v1/network-composite-modifications/" + compositeUuid + "/contains-shared-modification"; + when(restTemplate.getForObject(expectedUrl, Boolean.class)).thenReturn(true); + + assertThat(networkModificationService.containsSharedModification(compositeUuid)).isTrue(); + } + @Test void testGetNetworkModification() { UUID modificationUuid = UUID.randomUUID();