From c5f33f562f9a090def262d99e21898c2ccc9f6a0 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Fri, 11 Sep 2026 16:26:34 +0200 Subject: [PATCH 1/8] managed description in reference modifications Signed-off-by: Etienne LESOT --- pom.xml | 2 +- .../modification/server/CompositeController.java | 10 ++++++---- .../repositories/CompositeModificationRepository.java | 6 ++++++ .../repositories/NetworkModificationRepository.java | 10 ++++++++-- .../server/service/NetworkModificationService.java | 8 ++++---- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 781ac81db..5cf33840e 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ **/migration/**/* gridsuite org.gridsuite:network-modification-server - 1.9.0 + 1.10.0-SNAPSHOT 1.51.0 diff --git a/src/main/java/org/gridsuite/modification/server/CompositeController.java b/src/main/java/org/gridsuite/modification/server/CompositeController.java index 1d3147e75..ba4260b51 100644 --- a/src/main/java/org/gridsuite/modification/server/CompositeController.java +++ b/src/main/java/org/gridsuite/modification/server/CompositeController.java @@ -88,8 +88,9 @@ public ResponseEntity createNetworkCompositeModification(@Parameter(descri public ResponseEntity extractCompositeModificationToShare( @PathVariable("uuid") UUID compositeModificationUuid, @Parameter(description = "Group owning the composite modification", required = true) @RequestParam("groupUuid") UUID groupUuid, - @Parameter(description = "New name of the shared composite modification") @RequestParam(value = "name", required = false) String name) { - networkModificationService.extractCompositeModificationToShare(groupUuid, compositeModificationUuid, name); + @Parameter(description = "New name of the shared composite modification") @RequestParam(value = "name", required = false) String name, + @Parameter(description = "New name of the shared composite modification") @RequestParam(value = "description", required = false) String description) { + networkModificationService.extractCompositeModificationToShare(groupUuid, compositeModificationUuid, name, description); return ResponseEntity.ok().build(); } @@ -125,8 +126,9 @@ public ResponseEntity> duplicateCompositeModifications(@Paramete @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The composite modification has been updated")}) public ResponseEntity updateNetworkCompositeModification( @PathVariable("uuid") UUID compositeModificationUuid, - @Parameter(description = "New composite name") @RequestParam(value = "name", required = false) String name) { - networkModificationService.updateCompositeModification(compositeModificationUuid, name); + @Parameter(description = "New composite name") @RequestParam(value = "name", required = false) String name, + @Parameter(description = "New composite description") @RequestParam(value = "description", required = false) String description) { + networkModificationService.updateCompositeModification(compositeModificationUuid, name, description); return ResponseEntity.ok().build(); } diff --git a/src/main/java/org/gridsuite/modification/server/repositories/CompositeModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/CompositeModificationRepository.java index e1a94f6fc..d3367dae9 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/CompositeModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/CompositeModificationRepository.java @@ -36,6 +36,12 @@ default void renameCompositeModification(CompositeModificationEntity compositeEn compositeEntity.setMessageValues(MAPPER.writeValueAsString(compositeEntity.toModificationInfos().getMapMessageValues())); } + @SneakyThrows + default void changeDescriptionOfCompositeModification(CompositeModificationEntity compositeEntity, String description) { + compositeEntity.setDescription(description); + compositeEntity.setMessageValues(MAPPER.writeValueAsString(compositeEntity.toModificationInfos().getMapMessageValues())); + } + @SneakyThrows default void generateModificationMessage(ModificationInfos modificationInfos) { if (modificationInfos.getMessageType() == null) { diff --git a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java index 6158dfa02..882e31e93 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java @@ -191,12 +191,15 @@ public void replaceCompositeModification(@NonNull UUID compositeUuid, @NonNull S compositeModificationRepository.renameCompositeModification(compositeEntity, name); } - public void updateCompositeModification(@NonNull UUID compositeUuid, String name) { + public void updateCompositeModification(@NonNull UUID compositeUuid, String name, String description) { CompositeModificationEntity compositeEntity = compositeModificationRepository.findById(compositeUuid) .orElseThrow(() -> getModificationNotFoundException(compositeUuid.toString())); if (name != null) { compositeModificationRepository.renameCompositeModification(compositeEntity, name); } + if (description != null) { + compositeModificationRepository.changeDescriptionOfCompositeModification(compositeEntity, description); + } } private List saveModificationsNonTransactional(@NonNull UUID groupUuid, List modifications) { @@ -1332,7 +1335,7 @@ public List insertCompositeModifications( * @param name name given to the shared composite modification, null to keep the current one */ @Transactional - public void extractCompositeModificationToShare(@NonNull UUID groupUuid, @NonNull UUID modificationUuid, String name) { + public void extractCompositeModificationToShare(@NonNull UUID groupUuid, @NonNull UUID modificationUuid, String name, String description) { ModificationGroupEntity groupEntity = getModificationGroup(groupUuid); ModificationEntity modificationEntity = getModificationEntity(modificationUuid); if (!(modificationEntity instanceof CompositeModificationEntity compositeEntity)) { @@ -1362,6 +1365,9 @@ public void extractCompositeModificationToShare(@NonNull UUID groupUuid, @NonNul if (name != null) { compositeModificationRepository.renameCompositeModification(compositeEntity, name); } + if (description != null) { + compositeModificationRepository.changeDescriptionOfCompositeModification(compositeEntity, description); + } } private AbstractModificationContainerEntity getContainer(ModificationContainerInfos containerInfos) { diff --git a/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java b/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java index b97443a6c..b1271be85 100644 --- a/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java @@ -563,8 +563,8 @@ public UUID createNetworkCompositeModification(@NonNull List modificationU } @Transactional - public void extractCompositeModificationToShare(@NonNull UUID groupUuid, @NonNull UUID modificationUuid, String name) { - networkModificationRepository.extractCompositeModificationToShare(groupUuid, modificationUuid, name); + public void extractCompositeModificationToShare(@NonNull UUID groupUuid, @NonNull UUID modificationUuid, String name, String description) { + networkModificationRepository.extractCompositeModificationToShare(groupUuid, modificationUuid, name, description); } public Map duplicateCompositeModifications(List sourceModificationUuids) { @@ -572,8 +572,8 @@ public Map duplicateCompositeModifications(List sourceModifica } @Transactional - public void updateCompositeModification(@NonNull UUID compositeUuid, String name) { - networkModificationRepository.updateCompositeModification(compositeUuid, name); + public void updateCompositeModification(@NonNull UUID compositeUuid, String name, String description) { + networkModificationRepository.updateCompositeModification(compositeUuid, name, description); } @Transactional From 3a71d38a66593182111077708b802d796cea32dc Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Wed, 16 Sep 2026 08:26:28 +0200 Subject: [PATCH 2/8] to clean Signed-off-by: Etienne LESOT --- pom.xml | 2 +- .../server/dto/ModificationMetadata.java | 3 +++ .../server/entities/ModificationEntity.java | 3 ++- .../CompositeModificationRepository.java | 1 - .../server/repositories/ModificationRepository.java | 2 +- .../repositories/NetworkModificationRepository.java | 12 ++++++++++-- 6 files changed, 17 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 5cf33840e..781ac81db 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ **/migration/**/* gridsuite org.gridsuite:network-modification-server - 1.10.0-SNAPSHOT + 1.9.0 1.51.0 diff --git a/src/main/java/org/gridsuite/modification/server/dto/ModificationMetadata.java b/src/main/java/org/gridsuite/modification/server/dto/ModificationMetadata.java index 5796ed502..352bf48e6 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/ModificationMetadata.java +++ b/src/main/java/org/gridsuite/modification/server/dto/ModificationMetadata.java @@ -29,5 +29,8 @@ public class ModificationMetadata { @Schema(description = "Modification type") private ModificationType type; + + @Schema(description = "Modification description") + private String description; } diff --git a/src/main/java/org/gridsuite/modification/server/entities/ModificationEntity.java b/src/main/java/org/gridsuite/modification/server/entities/ModificationEntity.java index b21948ad3..ddad0ba1f 100644 --- a/src/main/java/org/gridsuite/modification/server/entities/ModificationEntity.java +++ b/src/main/java/org/gridsuite/modification/server/entities/ModificationEntity.java @@ -98,9 +98,10 @@ public ModificationEntity(UUID id, String type, Instant date, Boolean stashed, B this.description = description; } - public ModificationEntity(UUID id, String type) { + public ModificationEntity(UUID id, String type, String description) { this.id = id; this.type = type; + this.description = description; } protected ModificationEntity(ModificationInfos modificationInfos) { diff --git a/src/main/java/org/gridsuite/modification/server/repositories/CompositeModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/CompositeModificationRepository.java index d3367dae9..f8f678f6f 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/CompositeModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/CompositeModificationRepository.java @@ -39,7 +39,6 @@ default void renameCompositeModification(CompositeModificationEntity compositeEn @SneakyThrows default void changeDescriptionOfCompositeModification(CompositeModificationEntity compositeEntity, String description) { compositeEntity.setDescription(description); - compositeEntity.setMessageValues(MAPPER.writeValueAsString(compositeEntity.toModificationInfos().getMapMessageValues())); } @SneakyThrows diff --git a/src/main/java/org/gridsuite/modification/server/repositories/ModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/ModificationRepository.java index 6991bbec2..c250b50c6 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/ModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/ModificationRepository.java @@ -59,7 +59,7 @@ AND COALESCE(a.applicable, true) List findAllActiveModificationsByContainerId(@Param("containerId") UUID containerId, @Param("rootNetworkTag") String rootNetworkTag); - @Query(value = "SELECT new ModificationEntity(m.id, m.type) FROM ModificationEntity m WHERE m.id IN (?1)") + @Query(value = "SELECT new ModificationEntity(m.id, m.type, m.description) FROM ModificationEntity m WHERE m.id IN (?1)") List findMetadataIn(List uuids); /** diff --git a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java index e1360892f..6354c61c3 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java @@ -555,7 +555,7 @@ private ModificationInfos loadModificationReference(ModificationEntity modificat .date(modificationEntity.getDate()) .stashed(modificationEntity.getStashed()) .activated(modificationEntity.getActivated()) - .description(modificationEntity.getDescription()) + .description(referencedEntity.getDescription()) .messageType(referencedEntity.getMessageType()) .messageValues(referencedEntity.getMessageValues()) .referencedId(referencedEntity.getId()) @@ -1003,7 +1003,14 @@ public void updateNetworkModificationMetadata(@NonNull List modificationUu .findById(modificationUuid) .orElseThrow(() -> getModificationNotFoundException(modificationUuid.toString())); if (metadata.getDescription() != null) { - modificationEntity.setDescription(metadata.getDescription()); + if (modificationEntity instanceof ModificationReferenceEntity modificationReferenceEntity) { + ModificationEntity referencedModificationEntity = this.modificationRepository + .findById(modificationReferenceEntity.getReferencedId()) + .orElseThrow(() -> getModificationNotFoundException(modificationUuid.toString())); + referencedModificationEntity.setDescription(metadata.getDescription()); + } else { + modificationEntity.setDescription(metadata.getDescription()); + } } if (metadata.getActivated() != null) { updateActivated(modificationEntity, metadata.getActivated()); @@ -1162,6 +1169,7 @@ public List getModificationsMetadata(List uuids) { .map(entity -> ModificationMetadata.builder() .id(entity.getId()) .type(ModificationType.valueOf(entity.getType())) + .description(entity.getDescription()) .build()) .toList(); } From 114dfc947f349c85d72958664890c51d89818ab0 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Thu, 17 Sep 2026 07:37:38 +0200 Subject: [PATCH 3/8] add connection to directory-server Signed-off-by: Etienne LESOT --- .../server/NetworkModificationController.java | 8 ++- .../server/dto/ElementAttributes.java | 27 +++++++++ .../server/dto/ReferenceAttributes.java | 39 +++++++++++++ .../server/dto/ReferenceContainer.java | 35 ++++++++++++ .../NetworkModificationRepository.java | 39 +++++++++---- .../server/service/DirectoryService.java | 56 +++++++++++++++++++ .../service/NetworkModificationService.java | 21 +++++-- src/main/resources/application-local.yml | 2 + 8 files changed, 209 insertions(+), 18 deletions(-) create mode 100644 src/main/java/org/gridsuite/modification/server/dto/ElementAttributes.java create mode 100644 src/main/java/org/gridsuite/modification/server/dto/ReferenceAttributes.java create mode 100644 src/main/java/org/gridsuite/modification/server/dto/ReferenceContainer.java create mode 100644 src/main/java/org/gridsuite/modification/server/service/DirectoryService.java diff --git a/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java b/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java index 705233f94..dc3532693 100644 --- a/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java +++ b/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java @@ -13,6 +13,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import org.gridsuite.modification.dto.ModificationInfos; +import org.gridsuite.modification.dto.ModificationReferenceInfos; import org.gridsuite.modification.modifications.AbstractModification; import org.gridsuite.modification.server.dto.*; import org.gridsuite.modification.server.dto.catalog.LineTypeInfos; @@ -317,8 +318,13 @@ public ResponseEntity hasModificationReferences( @ApiResponse(responseCode = "200", description = "The metadata of the network modifications has been successfully updated") public ResponseEntity updateNetworkModificationMetadata( @Parameter(description = "Network modifications UUIDs") @RequestParam("uuids") List networkModificationUuids, + @Parameter(description = "User id") @RequestParam("userId") String userId, @RequestBody ModificationInfos metadata) { - networkModificationService.updateNetworkModificationMetadata(networkModificationUuids, metadata); + if (metadata instanceof ModificationReferenceInfos modificationReferenceInfos) { + networkModificationService.updateModificationReferencedMetadata(networkModificationUuids, modificationReferenceInfos, userId); + } else { + networkModificationService.updateNetworkModificationMetadata(networkModificationUuids, metadata); + } return ResponseEntity.ok().build(); } diff --git a/src/main/java/org/gridsuite/modification/server/dto/ElementAttributes.java b/src/main/java/org/gridsuite/modification/server/dto/ElementAttributes.java new file mode 100644 index 000000000..68be7ddf9 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/ElementAttributes.java @@ -0,0 +1,27 @@ +/* + 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.modification.server.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NonNull; + +import java.util.UUID; + +/** + * @author Mathieu Deharbe + */ +@Getter +@AllArgsConstructor +public class ElementAttributes { + private String elementName; + private String description; + + public static ElementAttributes createElementAttributes(String elementName, String description) { + return new ElementAttributes(elementName, description); + } +} \ No newline at end of file diff --git a/src/main/java/org/gridsuite/modification/server/dto/ReferenceAttributes.java b/src/main/java/org/gridsuite/modification/server/dto/ReferenceAttributes.java new file mode 100644 index 000000000..7b705ad2f --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/ReferenceAttributes.java @@ -0,0 +1,39 @@ +/* + 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.modification.server.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NonNull; + +import java.util.UUID; + +/** + * @author Mathieu Deharbe + */ +@Getter +@AllArgsConstructor +public class ReferenceAttributes { + public enum ReferenceType { + STUDY_NODE, + STUDY_NODE_NETWORK_MODIFICATION, + DIRECTORY_NETWORK_MODIFICATION, + } + + // id of the reference modification + @NonNull + private UUID referenceId; + // Container where the reference is used (see ReferenceType for the meaning of its ids) + @NonNull + private ReferenceContainer referenceContainer; + @NonNull + private ReferenceType referenceType; + + public static ReferenceAttributes createReferenceAttributes(UUID referenceId, UUID rootContainerId, UUID containerId, ReferenceType referenceType) { + return new ReferenceAttributes(referenceId, ReferenceContainer.builder().rootContainerId(rootContainerId).containerId(containerId).build(), referenceType); + } +} \ No newline at end of file diff --git a/src/main/java/org/gridsuite/modification/server/dto/ReferenceContainer.java b/src/main/java/org/gridsuite/modification/server/dto/ReferenceContainer.java new file mode 100644 index 000000000..0e9cdfeb8 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/ReferenceContainer.java @@ -0,0 +1,35 @@ +/* + 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.modification.server.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.Setter; +import lombok.experimental.SuperBuilder; + +import java.util.UUID; + +/** + * 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 + * + * @author Mathieu Deharbe + */ +@Getter +@Setter +@NoArgsConstructor +@SuperBuilder +public class ReferenceContainer { + @NonNull + private UUID rootContainerId; + @NonNull + private UUID containerId; +} \ No newline at end of file diff --git a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java index 27601b374..d6eed50eb 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java @@ -19,10 +19,7 @@ import org.gridsuite.modification.dto.tabular.TabularCreationInfos; import org.gridsuite.modification.dto.tabular.TabularModificationInfos; import org.gridsuite.modification.modifications.AbstractModification; -import org.gridsuite.modification.server.dto.CompositeInfos; -import org.gridsuite.modification.server.dto.ModificationContainerInfos; -import org.gridsuite.modification.server.dto.ModificationMetadata; -import org.gridsuite.modification.server.dto.ModificationReferenceData; +import org.gridsuite.modification.server.dto.*; import org.gridsuite.modification.server.elasticsearch.ModificationApplicationInfosService; import org.gridsuite.modification.server.entities.*; import org.gridsuite.modification.server.entities.equipment.modification.EquipmentModificationEntity; @@ -1003,14 +1000,7 @@ public void updateNetworkModificationMetadata(@NonNull List modificationUu .findById(modificationUuid) .orElseThrow(() -> getModificationNotFoundException(modificationUuid.toString())); if (metadata.getDescription() != null) { - if (modificationEntity instanceof ModificationReferenceEntity modificationReferenceEntity) { - ModificationEntity referencedModificationEntity = this.modificationRepository - .findById(modificationReferenceEntity.getReferencedId()) - .orElseThrow(() -> getModificationNotFoundException(modificationUuid.toString())); - referencedModificationEntity.setDescription(metadata.getDescription()); - } else { - modificationEntity.setDescription(metadata.getDescription()); - } + modificationEntity.setDescription(metadata.getDescription()); } if (metadata.getActivated() != null) { updateActivated(modificationEntity, metadata.getActivated()); @@ -1023,6 +1013,31 @@ public void updateNetworkModificationMetadata(@NonNull List modificationUu } } + @Transactional + public Map updateModificationReferencedMetadata(@NonNull List modificationUuids, @NonNull ModificationReferenceInfos metadata) { + Map modificationToBeUpdatedInDirectory = new HashMap<>(); + for (UUID modificationUuid : modificationUuids) { + ModificationEntity modificationEntity = this.modificationRepository + .findById(modificationUuid) + .orElseThrow(() -> getModificationNotFoundException(modificationUuid.toString())); + if (metadata.getDescription() != null) { + // we need to update the referenced modification contained in the modificationEntity + assert modificationEntity instanceof ModificationReferenceEntity; + ModificationReferenceEntity modificationReferenceEntity = (ModificationReferenceEntity) modificationEntity; + ModificationEntity referencedModificationEntity = this.modificationRepository + .findById(modificationReferenceEntity.getReferencedId()) + .orElseThrow(() -> getModificationNotFoundException(modificationUuid.toString())); + referencedModificationEntity.setDescription(metadata.getDescription()); + modificationToBeUpdatedInDirectory.put(referencedModificationEntity.getId(), + new ElementAttributes(null, metadata.getDescription())); + } + if (metadata.getActivated() != null) { + updateActivated(modificationEntity, metadata.getActivated()); + } + } + return modificationToBeUpdatedInDirectory; + } + // TODO remove when activation for a sub modification (composite) is implemented : no need optimized load private void updateActivated(ModificationEntity entity, boolean activated) { entity.setActivated(activated); diff --git a/src/main/java/org/gridsuite/modification/server/service/DirectoryService.java b/src/main/java/org/gridsuite/modification/server/service/DirectoryService.java new file mode 100644 index 000000000..9b887ceb2 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/service/DirectoryService.java @@ -0,0 +1,56 @@ +/** + * 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.modification.server.service; + +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; +import org.gridsuite.modification.server.dto.ElementAttributes; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestClient; +import org.springframework.web.util.UriComponentsBuilder; + +import java.util.UUID; + +/** + * @author Mathieu Deharbe + */ +@Service +public class DirectoryService { + + private static final String DIRECTORY_API_VERSION = "v1"; + private static final String DELIMITER = "/"; + public static final String HEADER_USER_ID = "userId"; + + @Setter + @Getter + private static String directoryServerBaseUri; + private final RestClient restClient; + + public DirectoryService(@Value("${gridsuite.services.directory-server.base-uri:http://directory-server/}") String directoryServerBaseUri, + RestClient restClient) { + setDirectoryServerBaseUri(directoryServerBaseUri); + this.restClient = restClient; + } + + public void updateElement(@NonNull UUID elementUuid, @NonNull ElementAttributes elementAttributes, String userId) { + var path = UriComponentsBuilder.fromPath( + DELIMITER + DIRECTORY_API_VERSION + DELIMITER + "elements/{elementUuid}") + .buildAndExpand(elementUuid) + .toUriString(); + + restClient.put() + .uri(getDirectoryServerBaseUri() + path) + .contentType(MediaType.APPLICATION_JSON) + .header(HEADER_USER_ID, userId) + .body(elementAttributes) + .retrieve() + .toBodilessEntity(); + } +} diff --git a/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java b/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java index 2174a7a56..4d811ca99 100644 --- a/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java @@ -20,10 +20,7 @@ import org.apache.commons.lang3.StringUtils; import org.gridsuite.filter.AbstractFilter; import org.gridsuite.modification.ModificationType; -import org.gridsuite.modification.dto.CompositeModificationInfos; -import org.gridsuite.modification.dto.EquipmentModificationInfos; -import org.gridsuite.modification.dto.GenerationDispatchInfos; -import org.gridsuite.modification.dto.ModificationInfos; +import org.gridsuite.modification.dto.*; import org.gridsuite.modification.error.NetworkModificationException; import org.gridsuite.modification.modifications.AbstractModification; import org.gridsuite.modification.server.dto.*; @@ -81,6 +78,8 @@ public class NetworkModificationService { private final FilterService filterService; + private final DirectoryService directoryService; + static final String NETWORK_UUID = "networkUuid.keyword"; static final String CREATED_EQUIPMENT_IDS = "createdEquipmentIds.fullascii"; static final String MODIFIED_EQUIPMENT_IDS = "modifiedEquipmentIds.fullascii"; @@ -97,7 +96,8 @@ public NetworkModificationService(NetworkStoreService networkStoreService, ModificationApplicationInfosService applicationInfosService, ElasticsearchOperations elasticsearchOperations, ModificationRepository modificationRepository, - FilterService filterService) { + FilterService filterService, + DirectoryService directoryService) { this.networkStoreService = networkStoreService; this.networkModificationRepository = networkModificationRepository; this.equipmentInfosService = equipmentInfosService; @@ -108,6 +108,7 @@ public NetworkModificationService(NetworkStoreService networkStoreService, this.elasticsearchOperations = elasticsearchOperations; this.modificationRepository = modificationRepository; this.filterService = filterService; + this.directoryService = directoryService; } public List getModificationGroups() { @@ -281,6 +282,16 @@ public void updateNetworkModificationMetadata(@NonNull List modificationUu networkModificationRepository.updateNetworkModificationMetadata(modificationUuids, metadata); } + @Transactional + public void updateModificationReferencedMetadata(@NonNull List modificationUuids, @NonNull ModificationReferenceInfos metadata, String userId) { + Map test = networkModificationRepository.updateModificationReferencedMetadata(modificationUuids, metadata); + if (!test.isEmpty()) { + test.forEach((elementUuid, elementAttributes) -> + directoryService.updateElement(elementUuid, elementAttributes, userId)); + } + + } + @Transactional public void updateRootNetworkApplicability(@NonNull List modificationUuids, @NonNull String rootNetworkTag, boolean applicable) { assertRootNetworkTagFits(rootNetworkTag); diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 3900f3887..89e4c51df 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -14,6 +14,8 @@ gridsuite: base-uri: http://localhost:5027 loadflow-server: base-uri: http://localhost:5008 + directory-server: + base-uri: http://localhost:5026 spring: rabbitmq: From 3c57b82e3dc1b3595ccb23e2213f4be0a2e5c0cc Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Thu, 17 Sep 2026 08:42:03 +0200 Subject: [PATCH 4/8] clean Signed-off-by: Etienne LESOT --- .../gridsuite/modification/server/dto/ElementAttributes.java | 5 +---- src/main/resources/application-local.yml | 2 -- .../modification/server/ModificationControllerTest.java | 2 ++ 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/gridsuite/modification/server/dto/ElementAttributes.java b/src/main/java/org/gridsuite/modification/server/dto/ElementAttributes.java index 68be7ddf9..54831242c 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/ElementAttributes.java +++ b/src/main/java/org/gridsuite/modification/server/dto/ElementAttributes.java @@ -8,9 +8,6 @@ import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.NonNull; - -import java.util.UUID; /** * @author Mathieu Deharbe @@ -24,4 +21,4 @@ public class ElementAttributes { public static ElementAttributes createElementAttributes(String elementName, String description) { return new ElementAttributes(elementName, description); } -} \ No newline at end of file +} diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 45c3a423c..65a317729 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -16,8 +16,6 @@ gridsuite: base-uri: http://localhost:5026 loadflow-server: base-uri: http://localhost:5008 - directory-server: - base-uri: http://localhost:5026 spring: rabbitmq: diff --git a/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java b/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java index c43dc5259..0d39e53f6 100644 --- a/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java +++ b/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java @@ -489,6 +489,7 @@ void testDisableNetworkModifications() throws Exception { mockMvc.perform(put(URI_NETWORK_MODIF_BASE) .queryParam("groupUuid", TEST_GROUP_ID.toString()) .queryParam("uuids", uuidString) + .queryParam("userId", "userId") .content(mapper.writeValueAsString(metadata)) .contentType(MediaType.APPLICATION_JSON) ).andExpect(status().isOk()); @@ -588,6 +589,7 @@ void updateModificationDescription() throws Exception { mockMvc.perform(put(URI_NETWORK_MODIF_BASE) .queryParam("groupUuid", TEST_GROUP_ID.toString()) .queryParam("uuids", uuidString) + .queryParam("userId", "userId") .content(mapper.writeValueAsString(metadata)) .contentType(MediaType.APPLICATION_JSON) ).andExpect(status().isOk()); From 0fca0cc3a5cf4d99cf5b4ae507cffd5cddd64220 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Thu, 17 Sep 2026 12:07:36 +0200 Subject: [PATCH 5/8] add test Signed-off-by: Etienne LESOT --- .../server/CompositeControllerTest.java | 71 +++++++++++++++++-- 1 file changed, 66 insertions(+), 5 deletions(-) diff --git a/src/test/java/org/gridsuite/modification/server/CompositeControllerTest.java b/src/test/java/org/gridsuite/modification/server/CompositeControllerTest.java index 8fbbd1601..c3b3722ce 100644 --- a/src/test/java/org/gridsuite/modification/server/CompositeControllerTest.java +++ b/src/test/java/org/gridsuite/modification/server/CompositeControllerTest.java @@ -18,11 +18,7 @@ import org.gridsuite.modification.dto.EquipmentAttributeModificationInfos; import org.gridsuite.modification.dto.ModificationInfos; import org.gridsuite.modification.dto.ModificationReferenceInfos; -import org.gridsuite.modification.server.dto.ActionType; -import org.gridsuite.modification.server.dto.CompositeInfos; -import org.gridsuite.modification.server.dto.ModificationReferenceData; -import org.gridsuite.modification.server.dto.NetworkModificationResult; -import org.gridsuite.modification.server.dto.NetworkModificationsResult; +import org.gridsuite.modification.server.dto.*; import org.gridsuite.modification.server.entities.CompositeModificationEntity; import org.gridsuite.modification.server.entities.ModificationContainerType; import org.gridsuite.modification.server.entities.ModificationEntity; @@ -31,6 +27,7 @@ import org.gridsuite.modification.server.repositories.CompositeModificationRepository; import org.gridsuite.modification.server.repositories.ModificationRepository; import org.gridsuite.modification.server.repositories.NetworkModificationRepository; +import org.gridsuite.modification.server.service.DirectoryService; import org.gridsuite.modification.server.service.ReportService; import org.gridsuite.modification.server.utils.NetworkCreation; import org.gridsuite.modification.server.utils.TestUtils; @@ -99,6 +96,9 @@ class CompositeControllerTest { @MockitoBean private NetworkStoreService networkStoreService; + @MockitoBean + private DirectoryService directoryService; + private Network network; @BeforeEach @@ -439,6 +439,67 @@ void testExtractCompositeModificationToShare() throws Exception { .andExpect(status().isNotFound()); } + @Test + void testUpdateDescriptionOfSharedModification() throws Exception { + int modificationsNumber = 2; + List modificationList = createSomeSwitchModifications(TEST_GROUP_ID, modificationsNumber); + + MvcResult mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) + .queryParam("name", "composite name") + .queryParam("description", "composite description") + .content(mapper.writeValueAsString(modificationList.stream().map(ModificationInfos::getUuid).toList())) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + UUID standaloneCompositeUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + + // the composite modification to share is inserted into the group, as a composite of its own + runRequestAsync( + mockMvc, + put(URI_COMPOSITE_NETWORK_MODIF_BASE + "/groups/" + TEST_GROUP_ID + "?action=INSERT") + .content(getJsonBodyModificationCompositeToBeInserted( + List.of(new CompositeInfos(standaloneCompositeUuid, "composite name", false, "composite description in the study")))) + .contentType(MediaType.APPLICATION_JSON), + status().isOk()); + ModificationInfos compositeInfos = networkModificationRepository.getModifications(TEST_GROUP_ID, true, true).getLast(); + assert compositeInfos instanceof CompositeModificationInfos; + assertEquals("composite description in the study", compositeInfos.getDescription()); + UUID compositeInGroupUuid = compositeInfos.getUuid(); + + mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE + "/" + compositeInGroupUuid + "/share") + .queryParam("groupUuid", TEST_GROUP_ID.toString()) + .queryParam("name", "shared composite") + .queryParam("description", "shared description")) + .andExpect(status().isOk()) + .andReturn(); + + // the composite modification is shared as it was, keeping its own uuid, and a reference to it took its place + // in the group + List newModificationList = networkModificationRepository.getModifications(TEST_GROUP_ID, false, true); + assertEquals(modificationsNumber + 1, newModificationList.size()); + + ModificationReferenceInfos reference = assertInstanceOf(ModificationReferenceInfos.class, newModificationList.getLast()); + assertEquals(compositeInGroupUuid, reference.getReferencedId()); + assertEquals("shared composite", ((CompositeModificationInfos) reference.getReferencedInfos()).getName()); + assertEquals("shared description", reference.getReferencedInfos().getDescription()); + assertEquals(ModificationReferenceInfos.Type.BASIC, reference.getReferenceType()); + + // update metadata of shared composite + ModificationReferenceInfos metadata = new ModificationReferenceInfos(); + metadata.setDescription("new shared description"); + mockMvc.perform(put(URI_NETWORK_MODIF_BASE) + .queryParam("uuids", reference.getUuid().toString()) + .queryParam("userId", "userId") + .content(mapper.writeValueAsString(metadata)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + List updatedModificationList = networkModificationRepository.getModifications(TEST_GROUP_ID, false, true); + ModificationReferenceInfos updatedReference = assertInstanceOf(ModificationReferenceInfos.class, updatedModificationList.getLast()); + assertEquals("new shared description", updatedReference.getReferencedInfos().getDescription()); + } + @Test void testExtractNestedCompositeModificationToShare() throws Exception { // The tree is group -> composite P -> composite C -> composite G, built from the deepest one up, and we had some other modifications inside the composites From d63abb65306dfa72f71e53c0299a040126d12e87 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Thu, 17 Sep 2026 13:07:38 +0200 Subject: [PATCH 6/8] add test Signed-off-by: Etienne LESOT --- .../server/service/DirectoryServiceTest.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/gridsuite/modification/server/service/DirectoryServiceTest.java b/src/test/java/org/gridsuite/modification/server/service/DirectoryServiceTest.java index 47e39a72a..a12bb248e 100644 --- a/src/test/java/org/gridsuite/modification/server/service/DirectoryServiceTest.java +++ b/src/test/java/org/gridsuite/modification/server/service/DirectoryServiceTest.java @@ -6,6 +6,7 @@ */ package org.gridsuite.modification.server.service; +import org.gridsuite.modification.server.dto.ElementAttributes; import org.gridsuite.modification.server.dto.ReferenceAttributes; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -18,7 +19,7 @@ import static org.gridsuite.modification.server.service.DirectoryService.HEADER_USER_ID; import static org.springframework.http.HttpMethod.PUT; import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; -import static org.springframework.test.web.client.response.MockRestResponseCreators.*; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; class DirectoryServiceTest { private static final String DIRECTORY_SERVER_BASE_URI = "http://directory-server-test"; @@ -60,6 +61,24 @@ void testUpdateElementReference() { directoryServer.verify(); } + @Test + void testUpdateElement() { + UUID elementUuid = UUID.randomUUID(); + String userId = "userId"; + ElementAttributes elementAttributes = ElementAttributes.createElementAttributes("name", "description"); + + String expectedUrl = DIRECTORY_SERVER_BASE_URI + "/v1/elements/" + elementUuid; + directoryServer.expect(requestTo(expectedUrl)) + .andExpect(method(PUT)) + .andExpect(header(HEADER_USER_ID, userId)) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andRespond(withSuccess()); + + directoryService.updateElement(elementUuid, elementAttributes, userId); + + directoryServer.verify(); + } + @Test void testCreateElementReference() { UUID elementUuid = UUID.randomUUID(); From cbebd0ad09afc449de94a619a1c1ab2b5c0d2456 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Thu, 17 Sep 2026 14:32:52 +0200 Subject: [PATCH 7/8] clean Signed-off-by: Etienne LESOT --- .../modification/server/dto/ModificationMetadata.java | 3 --- .../modification/server/entities/ModificationEntity.java | 3 +-- .../server/repositories/ModificationRepository.java | 2 +- .../server/repositories/NetworkModificationRepository.java | 1 - 4 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/gridsuite/modification/server/dto/ModificationMetadata.java b/src/main/java/org/gridsuite/modification/server/dto/ModificationMetadata.java index 352bf48e6..5796ed502 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/ModificationMetadata.java +++ b/src/main/java/org/gridsuite/modification/server/dto/ModificationMetadata.java @@ -29,8 +29,5 @@ public class ModificationMetadata { @Schema(description = "Modification type") private ModificationType type; - - @Schema(description = "Modification description") - private String description; } diff --git a/src/main/java/org/gridsuite/modification/server/entities/ModificationEntity.java b/src/main/java/org/gridsuite/modification/server/entities/ModificationEntity.java index ddad0ba1f..b21948ad3 100644 --- a/src/main/java/org/gridsuite/modification/server/entities/ModificationEntity.java +++ b/src/main/java/org/gridsuite/modification/server/entities/ModificationEntity.java @@ -98,10 +98,9 @@ public ModificationEntity(UUID id, String type, Instant date, Boolean stashed, B this.description = description; } - public ModificationEntity(UUID id, String type, String description) { + public ModificationEntity(UUID id, String type) { this.id = id; this.type = type; - this.description = description; } protected ModificationEntity(ModificationInfos modificationInfos) { diff --git a/src/main/java/org/gridsuite/modification/server/repositories/ModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/ModificationRepository.java index c250b50c6..6991bbec2 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/ModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/ModificationRepository.java @@ -59,7 +59,7 @@ AND COALESCE(a.applicable, true) List findAllActiveModificationsByContainerId(@Param("containerId") UUID containerId, @Param("rootNetworkTag") String rootNetworkTag); - @Query(value = "SELECT new ModificationEntity(m.id, m.type, m.description) FROM ModificationEntity m WHERE m.id IN (?1)") + @Query(value = "SELECT new ModificationEntity(m.id, m.type) FROM ModificationEntity m WHERE m.id IN (?1)") List findMetadataIn(List uuids); /** diff --git a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java index 9e34fff21..8c0f8c2fc 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java @@ -1194,7 +1194,6 @@ public List getModificationsMetadata(List uuids) { .map(entity -> ModificationMetadata.builder() .id(entity.getId()) .type(ModificationType.valueOf(entity.getType())) - .description(entity.getDescription()) .build()) .toList(); } From 52efe4694457afa2cb1e6c7597aef7e2b91b4295 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Thu, 17 Sep 2026 14:37:02 +0200 Subject: [PATCH 8/8] clean Signed-off-by: Etienne LESOT --- .../gridsuite/modification/server/dto/ReferenceAttributes.java | 1 + .../gridsuite/modification/server/dto/ReferenceContainer.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/org/gridsuite/modification/server/dto/ReferenceAttributes.java b/src/main/java/org/gridsuite/modification/server/dto/ReferenceAttributes.java index 8240fbdd1..d2cc9f19f 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/ReferenceAttributes.java +++ b/src/main/java/org/gridsuite/modification/server/dto/ReferenceAttributes.java @@ -37,3 +37,4 @@ public static ReferenceAttributes createReferenceAttributes(UUID referenceId, UU return new ReferenceAttributes(referenceId, ReferenceContainer.builder().rootContainerId(rootContainerId).containerId(containerId).build(), referenceType); } } + diff --git a/src/main/java/org/gridsuite/modification/server/dto/ReferenceContainer.java b/src/main/java/org/gridsuite/modification/server/dto/ReferenceContainer.java index 6ee038c14..c00b7ed3e 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/ReferenceContainer.java +++ b/src/main/java/org/gridsuite/modification/server/dto/ReferenceContainer.java @@ -31,3 +31,4 @@ public class ReferenceContainer { @NonNull private UUID rootContainerId; @NonNull private UUID containerId; } +