diff --git a/src/main/java/org/gridsuite/directory/server/DirectoryController.java b/src/main/java/org/gridsuite/directory/server/DirectoryController.java index f4b27f7f..c771637f 100644 --- a/src/main/java/org/gridsuite/directory/server/DirectoryController.java +++ b/src/main/java/org/gridsuite/directory/server/DirectoryController.java @@ -329,19 +329,18 @@ public ResponseEntity elementNameCandidate(@PathVariable("directoryUuid" return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(service.getDuplicateNameCandidate(directoryUuid, elementName, type, userId)); } - @PutMapping(value = "/elements/references") - @Operation(summary = "For each shared element from a list, updates one of their reference from an origin reference to a target reference") + @PutMapping(value = "/elements/{elementUuid}/references/{referenceUuid}", consumes = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Update an element reference") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "References were successfully updated"), + @ApiResponse(responseCode = "200", description = "Reference were successfully updated"), @ApiResponse(responseCode = "404", description = "At least one element was not found"), @ApiResponse(responseCode = "403", description = "Not authorized to update at least one element") }) - public ResponseEntity updateSharedElementsReferences(@RequestParam("ids") List elementUuids, - @RequestParam("originReferenceUuid") UUID originReferenceUuid, - @RequestParam("targetReferenceUuid") UUID targetReferenceUuid, - @RequestParam("targetReferenceType") ReferenceAttributes.ReferenceType targetReferenceType, - @RequestHeader("userId") String userId) { - service.updateElementsReferences(elementUuids, originReferenceUuid, targetReferenceUuid, targetReferenceType, userId); + public ResponseEntity updateElementReference(@PathVariable("elementUuid") UUID elementId, + @PathVariable("referenceUuid") UUID referenceId, + @RequestBody ReferenceAttributes referenceAttributes, + @RequestHeader("userId") String userId) { + service.updateElementReference(elementId, referenceId, referenceAttributes, userId); return ResponseEntity.ok().build(); } diff --git a/src/main/java/org/gridsuite/directory/server/DirectoryService.java b/src/main/java/org/gridsuite/directory/server/DirectoryService.java index 116d2e02..ab9cf78f 100644 --- a/src/main/java/org/gridsuite/directory/server/DirectoryService.java +++ b/src/main/java/org/gridsuite/directory/server/DirectoryService.java @@ -12,6 +12,7 @@ import org.gridsuite.directory.server.error.DirectoryException; import org.gridsuite.directory.server.repository.DirectoryElementEntity; import org.gridsuite.directory.server.repository.DirectoryElementRepository; +import org.gridsuite.directory.server.repository.ReferenceContainerEmbeddable; import org.gridsuite.directory.server.repository.ReferenceEmbeddable; import org.gridsuite.directory.server.services.*; import org.springframework.dao.DataIntegrityViolationException; @@ -41,6 +42,7 @@ public class DirectoryService { public static final String DIRECTORY = "DIRECTORY"; public static final String ELEMENT = "ELEMENT"; + public static final String REFERENCE = "REFERENCE"; private static final int ES_PAGE_MAX_SIZE = 50; static final int MAX_RETRY = 3; static final int DELAY_RETRY = 50; @@ -346,32 +348,29 @@ public void createElementReference(UUID elementUuid, ReferenceAttributes referen private ReferenceEmbeddable createReferenceEntity(ReferenceAttributes referenceAttributes) { return new ReferenceEmbeddable( referenceAttributes.getReferenceId(), + createReferencePathEntity(referenceAttributes.getReferenceContainer()), referenceAttributes.getReferenceType().name() ); } + private ReferenceContainerEmbeddable createReferencePathEntity(ReferenceContainer referenceId) { + return new ReferenceContainerEmbeddable(referenceId.getRootContainerId(), referenceId.getContainerId()); + } + @Transactional - public void updateElementsReferences(@NonNull List elementsUuids, @NonNull UUID originReferenceUuid, - @NonNull UUID targetReferenceUuid, @NonNull ReferenceAttributes.ReferenceType targetReferenceType, String userId) { - elementsUuids.forEach(elementUuid -> { - DirectoryElementEntity directoryElementEntity = getDirectoryElementEntity(elementUuid); - - directoryElementEntity.getReferences().stream() - .filter(ref -> originReferenceUuid.equals(ref.getReferenceId())) - .findFirst() - .ifPresent(ref -> { - ref.setReferenceId(targetReferenceUuid); - ref.setReferenceType(targetReferenceType.name()); - notifyDirectoryHasChanged(directoryElementEntity.getParentId() == null ? elementUuid : directoryElementEntity.getParentId(), userId, directoryElementEntity.getName()); - }); - }); + public void updateElementReference(@NonNull UUID elementId, @NonNull UUID referenceId, @NonNull ReferenceAttributes referenceAttributes, String userId) { + DirectoryElementEntity directoryElementEntity = getDirectoryElementEntity(elementId); + ReferenceEmbeddable reference = directoryElementEntity.getReference(referenceId) + .orElseThrow(() -> DirectoryException.createElementNotFound(REFERENCE, referenceAttributes.getReferenceId())); + reference.setReferenceContainer(createReferencePathEntity(referenceAttributes.getReferenceContainer())); + reference.setReferenceType(referenceAttributes.getReferenceType().name()); + notifyDirectoryHasChanged(directoryElementEntity.getParentId() == null ? elementId : directoryElementEntity.getParentId(), userId, directoryElementEntity.getName()); } @Transactional public void deleteElementReference(UUID elementUuid, UUID referenceUuid, String userId) { DirectoryElementEntity directoryElementEntity = getDirectoryElementEntity(elementUuid); directoryElementEntity.removeReference(referenceUuid); - notifyDirectoryHasChanged(directoryElementEntity.getParentId() == null ? elementUuid : directoryElementEntity.getParentId(), userId, directoryElementEntity.getName()); } diff --git a/src/main/java/org/gridsuite/directory/server/dto/ReferenceAttributes.java b/src/main/java/org/gridsuite/directory/server/dto/ReferenceAttributes.java index 597851d2..ee9d0188 100644 --- a/src/main/java/org/gridsuite/directory/server/dto/ReferenceAttributes.java +++ b/src/main/java/org/gridsuite/directory/server/dto/ReferenceAttributes.java @@ -6,11 +6,9 @@ */ package org.gridsuite.directory.server.dto; -import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.experimental.SuperBuilder; +import lombok.NonNull; import java.util.UUID; @@ -18,17 +16,15 @@ * @author Slimane Amar */ @Getter -@Setter -@NoArgsConstructor -@SuperBuilder -@JsonInclude(JsonInclude.Include.NON_NULL) +@AllArgsConstructor public class ReferenceAttributes { public enum ReferenceType { STUDY_NODE, - NETWORK_MODIFICATION, - DIRECTORY_ELEMENT + STUDY_NODE_NETWORK_MODIFICATION, + DIRECTORY_NETWORK_MODIFICATION, } - private UUID referenceId; - private ReferenceType referenceType; + @NonNull private UUID referenceId; + @NonNull private ReferenceContainer referenceContainer; + @NonNull private ReferenceType referenceType; } diff --git a/src/main/java/org/gridsuite/directory/server/dto/ReferenceContainer.java b/src/main/java/org/gridsuite/directory/server/dto/ReferenceContainer.java new file mode 100644 index 00000000..c37c7bf2 --- /dev/null +++ b/src/main/java/org/gridsuite/directory/server/dto/ReferenceContainer.java @@ -0,0 +1,34 @@ +/* + Copyright (c) 2026, RTE (http://www.rte-france.com) + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.directory.server.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.Setter; +import lombok.experimental.SuperBuilder; + +import java.util.UUID; + +/** + * @author Slimane Amar + */ +@Getter +@Setter +@NoArgsConstructor +@SuperBuilder +/** + * ReferenceContainer represents the information that makes it easy to locate the reference where it is used. + * It depends on the type of reference: + * STUDY_NODE: rootContainerId: studyId; containerId: nodeId + * STUDY_NODE_NETWORK_MODIFICATION: rootContainerId: nodeId; containerId: parentCompositeId + * DIRECTORY_NETWORK_MODIFICATION: rootContainerId: directoryId; containerId: parentCompositeId + */ +public class ReferenceContainer { + @NonNull private UUID rootContainerId; + @NonNull private UUID containerId; +} diff --git a/src/main/java/org/gridsuite/directory/server/repository/DirectoryElementEntity.java b/src/main/java/org/gridsuite/directory/server/repository/DirectoryElementEntity.java index 4b0d0e70..2588a238 100644 --- a/src/main/java/org/gridsuite/directory/server/repository/DirectoryElementEntity.java +++ b/src/main/java/org/gridsuite/directory/server/repository/DirectoryElementEntity.java @@ -126,10 +126,13 @@ public void addReference(ReferenceEmbeddable reference) { } public void removeReference(UUID referenceId) { - this.references.stream() - .filter(reference -> Objects.equals(reference.getReferenceId(), referenceId)) - .findFirst() - .ifPresent(this::removeReference); + getReference(referenceId).ifPresent(this::removeReference); + } + + public Optional getReference(UUID referenceId) { + return this.references.stream() + .filter(reference -> reference.getReferenceId().equals(referenceId)) + .findFirst(); } public void removeReference(ReferenceEmbeddable reference) { diff --git a/src/main/java/org/gridsuite/directory/server/repository/ReferenceContainerEmbeddable.java b/src/main/java/org/gridsuite/directory/server/repository/ReferenceContainerEmbeddable.java new file mode 100644 index 00000000..9389c7cf --- /dev/null +++ b/src/main/java/org/gridsuite/directory/server/repository/ReferenceContainerEmbeddable.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.directory.server.repository; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.*; +import org.gridsuite.directory.server.dto.ReferenceContainer; + +import java.util.UUID; + +/** + * @author Slimane Amar + */ +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@Builder +@Embeddable +public class ReferenceContainerEmbeddable { + @Column(name = "rootContainerId") + private UUID rootContainerId; + + @Column(name = "containerId") + @NonNull private UUID containerId; + + public ReferenceContainer toReferenceAttributes() { + return ReferenceContainer.builder() + .rootContainerId(rootContainerId) + .containerId(containerId) + .build(); + } +} diff --git a/src/main/java/org/gridsuite/directory/server/repository/ReferenceEmbeddable.java b/src/main/java/org/gridsuite/directory/server/repository/ReferenceEmbeddable.java index 9eeedc3b..ef04128f 100644 --- a/src/main/java/org/gridsuite/directory/server/repository/ReferenceEmbeddable.java +++ b/src/main/java/org/gridsuite/directory/server/repository/ReferenceEmbeddable.java @@ -8,6 +8,7 @@ import jakarta.persistence.Column; import jakarta.persistence.Embeddable; +import jakarta.persistence.Embedded; import lombok.*; import org.gridsuite.directory.server.dto.ReferenceAttributes; import org.gridsuite.directory.server.dto.ReferenceAttributes.ReferenceType; @@ -27,13 +28,13 @@ public class ReferenceEmbeddable { @Column(name = "reference_id") private UUID referenceId; + @Embedded + private ReferenceContainerEmbeddable referenceContainer; + @Column(name = "reference_type") private String referenceType; public ReferenceAttributes toReferenceAttributes() { - return ReferenceAttributes.builder() - .referenceId(referenceId) - .referenceType(ReferenceType.valueOf(referenceType)) - .build(); + return new ReferenceAttributes(referenceId, referenceContainer.toReferenceAttributes(), ReferenceType.valueOf(referenceType)); } } diff --git a/src/main/resources/db/changelog/changesets/changelog_20260907T092547Z.xml b/src/main/resources/db/changelog/changesets/changelog_20260907T092547Z.xml new file mode 100644 index 00000000..247f8f77 --- /dev/null +++ b/src/main/resources/db/changelog/changesets/changelog_20260907T092547Z.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index fafea538..67fff291 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -90,3 +90,7 @@ databaseChangeLog: - include: file: changesets/changelog_20260715T123918Z.xml relativeToChangelogFile: true + + - include: + file: changesets/changelog_20260907T092547Z.xml + relativeToChangelogFile: true diff --git a/src/test/java/org/gridsuite/directory/server/DirectoryTest.java b/src/test/java/org/gridsuite/directory/server/DirectoryTest.java index f2b7eb9e..2ac68d6f 100644 --- a/src/test/java/org/gridsuite/directory/server/DirectoryTest.java +++ b/src/test/java/org/gridsuite/directory/server/DirectoryTest.java @@ -67,6 +67,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.gridsuite.directory.server.NotificationService.*; import static org.gridsuite.directory.server.dto.ElementAttributes.toElementAttributes; +import static org.gridsuite.directory.server.dto.ReferenceAttributes.ReferenceType.STUDY_NODE; import static org.gridsuite.directory.server.services.ConsumerService.HEADER_STUDY_UUID; import static org.gridsuite.directory.server.services.ConsumerService.UPDATE_TYPE_STUDY_CREATION_FINISHED; import static org.gridsuite.directory.server.utils.DirectoryTestUtils.jsonResponse; @@ -2239,10 +2240,7 @@ void testDirectoryContentRecursive() throws Exception { // create rootDir UUID uuidNewRootDirectory = retrieveInsertAndCheckRootDirectory("rootDir", USER_ID).getElementUuid(); - List referenceAttributesList = List.of( - ReferenceAttributes.builder().referenceId(UUID.randomUUID()).referenceType(ReferenceType.STUDY_NODE).build(), - ReferenceAttributes.builder().referenceId(UUID.randomUUID()).referenceType(ReferenceType.STUDY_NODE).build() - ); + List referenceAttributesList = List.of(createElementReference(STUDY_NODE), createElementReference(STUDY_NODE)); // create modifRoot ElementAttributes rootModifAttributes = toElementAttributesWithReferences(null, "modifRoot", MODIFICATION, referenceAttributesList, USER_ID); @@ -2270,6 +2268,14 @@ void testDirectoryContentRecursive() throws Exception { assertRequestsCount(9, 0, 0, 0); } + private ReferenceAttributes createElementReference(ReferenceType referenceType) { + return new ReferenceAttributes(UUID.randomUUID(), createReferenceContainer(), referenceType); + } + + private ReferenceContainer createReferenceContainer() { + return ReferenceContainer.builder().rootContainerId(UUID.randomUUID()).containerId(UUID.randomUUID()).build(); + } + @Test void testElementsUpdateOk() throws Exception { checkRootDirectoriesList(USER_ID, List.of()); @@ -2373,8 +2379,7 @@ void testElementReferences() { testNotificationDirectory(rootAttributes.getElementUuid(), NotificationType.UPDATE_DIRECTORY, userId); // create a reference to the element - UUID referenceId = UUID.randomUUID(); - ReferenceAttributes referenceAttributes = ReferenceAttributes.builder().referenceId(referenceId).referenceType(ReferenceType.STUDY_NODE).build(); + ReferenceAttributes referenceAttributes = createElementReference(STUDY_NODE); mockMvc.perform(post(String.format("/v1/elements/%s/references", elementAttributes.getElementUuid())) .header("userId", userId) .contentType(MediaType.APPLICATION_JSON) @@ -2387,7 +2392,7 @@ void testElementReferences() { testNotificationDirectory(rootAttributes.getElementUuid(), NotificationType.UPDATE_DIRECTORY, userId); // delete the reference to the element - mockMvc.perform(delete(String.format("/v1/elements/%s/references/%s", elementAttributes.getElementUuid(), referenceId)) + mockMvc.perform(delete(String.format("/v1/elements/%s/references/%s", elementAttributes.getElementUuid(), referenceAttributes.getReferenceId())) .header("userId", userId)) .andExpect(status().isOk()); @@ -2507,13 +2512,11 @@ void testUpdateElementsReferences() { testNotificationDirectory(rootAttributes.getElementUuid(), NotificationType.UPDATE_DIRECTORY, userId); // composite1 starts out referencing a study node - UUID nodeUuid = UUID.randomUUID(); - ReferenceAttributes nodeReferenceAttributes = ReferenceAttributes.builder().referenceId(nodeUuid).referenceType(ReferenceType.STUDY_NODE).build(); - + ReferenceAttributes composite1ReferenceAttributes = createElementReference(STUDY_NODE); mockMvc.perform(post(String.format("/v1/elements/%s/references", composite1Attributes.getElementUuid())) .header("userId", userId) .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(nodeReferenceAttributes))) + .content(objectMapper.writeValueAsString(composite1ReferenceAttributes))) .andExpect(status().isOk()); testNotificationDirectory(rootAttributes.getElementUuid(), NotificationType.UPDATE_DIRECTORY, userId); @@ -2521,13 +2524,13 @@ void testUpdateElementsReferences() { ElementAttributes originModificationAttributes = directoryService.createElement( DirectoryTestUtils.toElementAttributes(null, "originModification", "ELEMENT", userId), rootAttributes.getElementUuid(), userId, false); testNotificationDirectory(rootAttributes.getElementUuid(), NotificationType.UPDATE_DIRECTORY, userId); - UUID originModificationUuid = originModificationAttributes.getElementUuid(); - ReferenceAttributes modificationReferenceAttributes = ReferenceAttributes.builder().referenceId(originModificationUuid).referenceType(ReferenceType.NETWORK_MODIFICATION).build(); + ReferenceContainer composite2ReferenceContainer = ReferenceContainer.builder().rootContainerId(UUID.randomUUID()).containerId(originModificationAttributes.getElementUuid()).build(); + ReferenceAttributes composite2ReferenceAttributes = new ReferenceAttributes(UUID.randomUUID(), composite2ReferenceContainer, ReferenceType.STUDY_NODE_NETWORK_MODIFICATION); mockMvc.perform(post(String.format("/v1/elements/%s/references", composite2Attributes.getElementUuid())) .header("userId", userId) .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(modificationReferenceAttributes))) + .content(objectMapper.writeValueAsString(composite2ReferenceAttributes))) .andExpect(status().isOk()); testNotificationDirectory(rootAttributes.getElementUuid(), NotificationType.UPDATE_DIRECTORY, userId); @@ -2537,24 +2540,22 @@ void testUpdateElementsReferences() { testNotificationDirectory(rootAttributes.getElementUuid(), NotificationType.UPDATE_DIRECTORY, userId); UUID targetModificationUuid = targetModificationAttributes.getElementUuid(); - // composite1 moves from the study node to the network-modification composite - mockMvc.perform(put("/v1/elements/references") - .header("userId", userId) - .param("ids", composite1Attributes.getElementUuid().toString()) - .param("originReferenceUuid", nodeUuid.toString()) - .param("targetReferenceUuid", targetModificationUuid.toString()) - .param("targetReferenceType", ReferenceType.NETWORK_MODIFICATION.name())) - .andExpect(status().isOk()); + // composite1 reference moves from the study node to the network-modification composite + ReferenceAttributes newComposite1ReferenceAttributes = new ReferenceAttributes(composite1ReferenceAttributes.getReferenceId(), + ReferenceContainer.builder().rootContainerId(UUID.randomUUID()).containerId(targetModificationUuid).build(), ReferenceType.STUDY_NODE_NETWORK_MODIFICATION); + mockMvc.perform(put(String.format("/v1/elements/%s/references/%s", composite1Attributes.getElementUuid(), composite1ReferenceAttributes.getReferenceId())) + .header("userId", userId) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(newComposite1ReferenceAttributes))) + .andExpect(status().isOk()); // composite2 moves from the network-modification composite to a study node - UUID targetNodeUuid = UUID.randomUUID(); - mockMvc.perform(put("/v1/elements/references") - .header("userId", userId) - .param("ids", composite2Attributes.getElementUuid().toString()) - .param("originReferenceUuid", originModificationUuid.toString()) - .param("targetReferenceUuid", targetNodeUuid.toString()) - .param("targetReferenceType", ReferenceType.STUDY_NODE.name())) - .andExpect(status().isOk()); + ReferenceAttributes newComposite2ReferenceAttributes = new ReferenceAttributes(composite2ReferenceAttributes.getReferenceId(), createReferenceContainer(), ReferenceType.STUDY_NODE); + mockMvc.perform(put(String.format("/v1/elements/%s/references/%s", composite2Attributes.getElementUuid(), composite2ReferenceAttributes.getReferenceId())) + .header("userId", userId) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(newComposite2ReferenceAttributes))) + .andExpect(status().isOk()); // one UPDATE_DIRECTORY notification per moved composite, both pointing at the same parent directory assertDirectoriesNotified(Set.of(rootAttributes.getElementUuid()), 2, userId); @@ -2565,54 +2566,26 @@ void testUpdateElementsReferences() { // composite1 now references the network-modification composite assertEquals(1, updatedComposite1.getReferences().size()); - assertEquals(targetModificationUuid, updatedComposite1.getReferences().getFirst().getReferenceId()); - assertEquals(ReferenceType.NETWORK_MODIFICATION, updatedComposite1.getReferences().getFirst().getReferenceType()); + assertEquals(ReferenceType.STUDY_NODE_NETWORK_MODIFICATION, updatedComposite1.getReferences().getFirst().getReferenceType()); + assertTrue(new MatcherJson<>(objectMapper, newComposite1ReferenceAttributes.getReferenceContainer()).matchesSafely(updatedComposite1.getReferences().getFirst().getReferenceContainer())); + assertEquals(targetModificationUuid, updatedComposite1.getReferences().getFirst().getReferenceContainer().getContainerId()); // composite2 now references the study node assertEquals(1, updatedComposite2.getReferences().size()); - assertEquals(targetNodeUuid, updatedComposite2.getReferences().getFirst().getReferenceId()); - assertEquals(ReferenceType.STUDY_NODE, updatedComposite2.getReferences().getFirst().getReferenceType()); + assertEquals(STUDY_NODE, updatedComposite2.getReferences().getFirst().getReferenceType()); + assertTrue(new MatcherJson<>(objectMapper, newComposite2ReferenceAttributes.getReferenceContainer()).matchesSafely(updatedComposite2.getReferences().getFirst().getReferenceContainer())); + assertNotEquals(originModificationAttributes.getElementUuid(), updatedComposite2.getReferences().getFirst().getReferenceContainer().getContainerId()); } @Test @SneakyThrows void testUpdateElementsReferencesElementNotFound() { - UUID unknownElementUuid = UUID.randomUUID(); - - mockMvc.perform(put("/v1/elements/references") - .header("userId", USER_ID) - .param("ids", unknownElementUuid.toString()) - .param("originReferenceUuid", UUID.randomUUID().toString()) - .param("targetReferenceUuid", UUID.randomUUID().toString()) - .param("targetReferenceType", ReferenceType.STUDY_NODE.name())) - .andExpect(status().isNotFound()); - } - - @Test - @SneakyThrows - void testUpdateElementsReferencesWithNoMatchingElements() { - String userId = "user"; - - ElementAttributes rootAttributes = directoryService.createRootDirectory(new RootDirectoryAttributes("root", userId, null, null, null, null), userId); - testNotificationDirectory(rootAttributes.getElementUuid(), NotificationType.ADD_DIRECTORY, userId); - - ElementAttributes compositeAttributes = directoryService.createElement( - DirectoryTestUtils.toElementAttributes(null, "composite", "TYPE", userId), rootAttributes.getElementUuid(), userId, false); - testNotificationDirectory(rootAttributes.getElementUuid(), NotificationType.UPDATE_DIRECTORY, userId); - - // composite has no reference matching this study node - the reference list itself must stay untouched - UUID unknownNodeUuid = UUID.randomUUID(); - UUID unknownTargetNodeUuid = UUID.randomUUID(); - mockMvc.perform(put("/v1/elements/references") - .header("userId", userId) - .param("ids", compositeAttributes.getElementUuid().toString()) - .param("originReferenceUuid", unknownNodeUuid.toString()) - .param("targetReferenceUuid", unknownTargetNodeUuid.toString()) - .param("targetReferenceType", ReferenceType.STUDY_NODE.name())) - .andExpect(status().isOk()); - assertDirectoriesNotified(Set.of(), 0, userId); + mockMvc.perform(put(String.format("/v1/elements/%s/references/%s", UUID.randomUUID(), UUID.randomUUID())) + .header("userId", USER_ID) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(createElementReference(STUDY_NODE)))) + .andExpect(status().isNotFound()); - ElementAttributes unchangedComposite = directoryService.getElementWithReferences(compositeAttributes.getElementUuid()); - assertTrue(unchangedComposite.getReferences() == null || unchangedComposite.getReferences().isEmpty()); + assertDirectoriesNotified(Set.of(), 0, USER_ID); } } diff --git a/src/test/java/org/gridsuite/directory/server/ElementAttributesTest.java b/src/test/java/org/gridsuite/directory/server/ElementAttributesTest.java index 36b0b8ba..82d3fa3f 100644 --- a/src/test/java/org/gridsuite/directory/server/ElementAttributesTest.java +++ b/src/test/java/org/gridsuite/directory/server/ElementAttributesTest.java @@ -8,12 +8,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import lombok.SneakyThrows; -import org.gridsuite.directory.server.dto.DirectoryElementStatus; -import org.gridsuite.directory.server.dto.ElementAttributes; -import org.gridsuite.directory.server.dto.ReferenceAttributes; +import org.gridsuite.directory.server.dto.*; import org.gridsuite.directory.server.dto.ReferenceAttributes.ReferenceType; -import org.gridsuite.directory.server.dto.RootDirectoryAttributes; import org.gridsuite.directory.server.repository.DirectoryElementEntity; +import org.gridsuite.directory.server.repository.ReferenceContainerEmbeddable; import org.gridsuite.directory.server.repository.ReferenceEmbeddable; import org.gridsuite.directory.server.utils.MatcherJson; import org.gridsuite.directory.server.utils.elasticsearch.DisableElasticsearch; @@ -95,9 +93,12 @@ void testElementAttributesCreation() { verifyElementAttributes(toElementAttributes(ELEMENT_UUID, "name", DIRECTORY, "userId", "description")); verifyElementAttributes(toElementAttributes(ELEMENT_UUID, "name", DIRECTORY, "userId")); - verifyElementAttributes(toElementAttributesWithReferences(new DirectoryElementEntity(ELEMENT_UUID, ELEMENT_UUID, "name", DIRECTORY, "userId", "description", + verifyElementAttributes(toElementAttributesWithReferences( + new DirectoryElementEntity(ELEMENT_UUID, ELEMENT_UUID, "name", DIRECTORY, "userId", "description", lastModificationDate, lastModificationDate, "userId", - List.of(new ReferenceEmbeddable(UUID.randomUUID(), ReferenceType.STUDY_NODE.name())), DirectoryElementStatus.CREATED), 1L)); + List.of(new ReferenceEmbeddable(UUID.randomUUID(), new ReferenceContainerEmbeddable(UUID.randomUUID(), UUID.randomUUID()), ReferenceType.STUDY_NODE.name())), + DirectoryElementStatus.CREATED), + 1L)); verifyElementAttributes(toElementAttributes(new DirectoryElementEntity(ELEMENT_UUID, ELEMENT_UUID, "name", DIRECTORY, "userId", "description", lastModificationDate, lastModificationDate, "userId", List.of(), DirectoryElementStatus.CREATED), 1L)); @@ -165,10 +166,20 @@ private String toJsonString(List references) { } return "\"references\":[" + references.stream() .map(ref -> - "{" + toJsonString("referenceId", ref.getReferenceId()) + "," + toJsonString("referenceType", ref.getReferenceType().name()) + "}") + "{" + toJsonString("referenceId", ref.getReferenceId()) + + "," + toJsonString(ref.getReferenceContainer()) + + "," + toJsonString("referenceType", ref.getReferenceType().name()) + + "}") .collect(Collectors.joining(",")) + "]"; } + private String toJsonString(ReferenceContainer referenceContainer) { + return "\"referenceContainer\":{" + + toJsonString("rootContainerId", referenceContainer.getRootContainerId()) + "," + + toJsonString("containerId", referenceContainer.getContainerId()) + + "}"; + } + private String toJsonString(String key, Object value) { if (value == null) { return (String) value;