diff --git a/src/main/java/org/gridsuite/modification/server/CompositeController.java b/src/main/java/org/gridsuite/modification/server/CompositeController.java index 8405071c4..9b01a038f 100644 --- a/src/main/java/org/gridsuite/modification/server/CompositeController.java +++ b/src/main/java/org/gridsuite/modification/server/CompositeController.java @@ -11,6 +11,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import org.gridsuite.modification.server.dto.CompositesToBeInserted; import org.gridsuite.modification.dto.ModificationInfos; import org.gridsuite.modification.server.dto.ModificationApplicationContext; import org.gridsuite.modification.server.dto.NetworkModificationsResult; @@ -50,7 +51,7 @@ public CompositeController(NetworkModificationService networkModificationService public CompletableFuture> insertCompositeModifications( @Parameter(description = "updated group UUID, where modifications are inserted") @PathVariable("groupUuid") UUID targetGroupUuid, @Parameter(description = "Insertion method", required = true) @RequestParam(value = "action") CompositeModificationAction action, - @RequestBody Pair>, List> modificationContextInfos) { + @RequestBody Pair, List> modificationContextInfos) { return switch (action) { case SPLIT -> networkModificationService.splitCompositeModifications( targetGroupUuid, diff --git a/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java b/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java index d83f52ae9..c4188be5b 100644 --- a/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java +++ b/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java @@ -238,6 +238,20 @@ public ResponseEntity stashNetworkModifications( return ResponseEntity.ok().build(); } + /** + * filters out the netmods which are not references and returns the references data as : + * referenced element uuid -> container of the reference (uuid of the composite if there is one, null if it is at the root level) + */ + @GetMapping(value = "/references", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "fetch references data of the network modifications") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The references data were returned")}) + public ResponseEntity> getReferencesData( + @Parameter(description = "Network modification UUIDs") @RequestParam("uuids") List networkModificationUuids) { + Map referencesData = networkModificationService.getReferencesData(networkModificationUuids); + return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON) + .body(referencesData); + } + @PutMapping(value = "/network-modifications", produces = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Updates the metadata of network modifications") @ApiResponse(responseCode = "200", description = "The metadata of the network modifications has been successfully updated") diff --git a/src/main/java/org/gridsuite/modification/server/dto/CompositesToBeInserted.java b/src/main/java/org/gridsuite/modification/server/dto/CompositesToBeInserted.java new file mode 100644 index 000000000..8396644b6 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/CompositesToBeInserted.java @@ -0,0 +1,14 @@ +/* + 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 java.util.UUID; + +/** + * @author Mathieu Deharbe + */ +public record CompositesToBeInserted(UUID id, String name, boolean isShared) { } diff --git a/src/main/java/org/gridsuite/modification/server/entities/CompositeModificationEntity.java b/src/main/java/org/gridsuite/modification/server/entities/CompositeModificationEntity.java index 80abb4c26..40f16fa53 100644 --- a/src/main/java/org/gridsuite/modification/server/entities/CompositeModificationEntity.java +++ b/src/main/java/org/gridsuite/modification/server/entities/CompositeModificationEntity.java @@ -6,6 +6,8 @@ */ package org.gridsuite.modification.server.entities; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; @@ -47,7 +49,10 @@ public CompositeModificationEntity(@NonNull CompositeModificationInfos composite @Override public CompositeModificationInfos toModificationInfos() { - List modificationsInfos = modifications.stream().map(ModificationEntity::toModificationInfos).toList(); + List modificationsInfos = modifications.stream() + .map(ModificationEntity::toModificationInfos) + .peek(this::fillDisplayMessage) + .toList(); return CompositeModificationInfos.builder() .name(getName()) .activated(getActivated()) @@ -59,6 +64,19 @@ public CompositeModificationInfos toModificationInfos() { .build(); } + private void fillDisplayMessage(ModificationInfos child) { + if (child.getMessageType() == null) { + child.setMessageType(child.getType().name()); + } + if (child.getMessageValues() == null) { + try { + child.setMessageValues(new ObjectMapper().writeValueAsString(child.getMapMessageValues())); + } catch (JsonProcessingException e) { + child.setMessageValues("{}"); + } + } + } + private void assignAttributes(CompositeModificationInfos compositeModificationInfos) { this.setName(compositeModificationInfos.getName()); setModifications(compositeModificationInfos.getModificationsInfos().stream() 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 f7f483327..2d829d16b 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java @@ -6,12 +6,15 @@ */ package org.gridsuite.modification.server.repositories; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Lists; import lombok.NonNull; import org.apache.commons.collections4.CollectionUtils; import org.gridsuite.modification.ModificationType; import org.gridsuite.modification.NetworkModificationException; import org.gridsuite.modification.dto.CompositeModificationInfos; +import org.gridsuite.modification.server.dto.CompositesToBeInserted; import org.gridsuite.modification.dto.ModificationInfos; import org.gridsuite.modification.dto.ModificationReferenceInfos; import org.gridsuite.modification.dto.tabular.LimitSetsTabularModificationInfos; @@ -29,7 +32,6 @@ import org.gridsuite.modification.server.entities.tabular.TabularPropertyEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.data.util.Pair; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; @@ -498,7 +500,16 @@ private ModificationInfos loadModificationReference(ModificationEntity modificat ModificationEntity referencedEntity = modificationRepository.findAllByIdIn(List.of(referenceEntity.getReferenceId())).stream().findFirst() .orElseThrow(() -> new NetworkModificationException(MODIFICATION_NOT_FOUND, String.format(MODIFICATION_NOT_FOUND_MESSAGE, referenceEntity.getReferenceId()))); ModificationReferenceInfos modificationReferenceInfos = referenceEntity.toModificationInfos(); - modificationReferenceInfos.setReferenceInfos(toModificationsInfosOptimized(referencedEntity)); + ModificationInfos refInfos = toModificationsInfosOptimized(referencedEntity); + + if (refInfos instanceof CompositeModificationInfos composite && composite.getModificationsInfos() != null) { + ObjectMapper mapper = new ObjectMapper(); + composite.getModificationsInfos().forEach(child -> { + child.setMessageType(child.getType().name()); + child.setMessageValues(writeValuesQuietly(mapper, child)); + }); + } + modificationReferenceInfos.setReferenceInfos(refInfos); return modificationReferenceInfos; } else { ModificationEntity referencedEntity = modificationRepository.findReferencedModificationMetadataByReferenceId(modificationEntity.getId()); @@ -512,6 +523,14 @@ private ModificationInfos loadModificationReference(ModificationEntity modificat } } + private static String writeValuesQuietly(ObjectMapper mapper, ModificationInfos child) { + try { + return mapper.writeValueAsString(child.getMapMessageValues()); + } catch (JsonProcessingException e) { + return "{}"; + } + } + private ModificationInfos toModificationsInfosOptimized(ModificationEntity modificationEntity) { return toModificationsInfosOptimized(modificationEntity, Set.of(), Map.of()); } @@ -710,6 +729,27 @@ private List getUnstashedModificationsInfosNonTransactional(U return getModificationEntityStream(groupUuid).filter(m -> !m.getStashed()).map(this::toModificationsInfosOptimized).toList(); } + /** + * @return elementUuid of the shared modification -> Uuid of the composite containing the reference, null if the composite is at the root level + */ + @Transactional + public Map getReferencesData(@NonNull List modificationUuids) { + Map referencesToBeDeleted = new HashMap<>(); + for (UUID modificationUuid : modificationUuids) { + ModificationEntity modificationEntity = this.modificationRepository + .findById(modificationUuid) + .orElseThrow(() -> new NetworkModificationException(MODIFICATION_NOT_FOUND, String.format(MODIFICATION_NOT_FOUND_MESSAGE, modificationUuid))); + + if (modificationEntity instanceof ModificationReferenceEntity modificationReference) { + // TODO : fetch the composite uuid containing the modificationReference ? null (groupUuid) si je n'en trouve pas ? + // TODO : et faire ça dans une requête spécifique ?? + referencesToBeDeleted.putIfAbsent(modificationReference.getReferenceId(), null); + } + } + + return referencesToBeDeleted; + } + @Transactional public void stashNetworkModifications(@NonNull List modificationUuids, int stashedModificationCount) { int stashModificationOrder = -stashedModificationCount - 1; @@ -742,8 +782,9 @@ public void reorderNetworkModifications(UUID groupId, Boolean stashed) { } @Transactional - public void restoreNetworkModifications(@NonNull List modificationUuids, int unstashedSize) { + public Map restoreNetworkModifications(@NonNull List modificationUuids, int unstashedSize) { int modificationOrder = unstashedSize; + Map referencesToBeRecreated = new HashMap<>(); List modifications = modificationRepository.findAllByIdInReverse(modificationUuids); if (modifications.size() != modificationUuids.size()) { throw new NetworkModificationException(MODIFICATION_NOT_FOUND); @@ -751,8 +792,15 @@ public void restoreNetworkModifications(@NonNull List modificationUuids, i for (ModificationEntity modification : modifications) { modification.setStashed(false); modification.setModificationsOrder(modificationOrder++); + + if (modification instanceof ModificationReferenceEntity modificationReference) { + // TODO : fetch the composite uuid containing the modificationReference ? null (groupUuid) si je n'en trouve pas ? + // bof : montrer à Slimane et en discuter + referencesToBeRecreated.putIfAbsent(modificationReference.getReferenceId(), null); + } } this.modificationRepository.saveAll(modifications); + return referencesToBeRecreated; } @Transactional @@ -935,20 +983,35 @@ public List extractModificationsFromCompositesAndSave(@NonNul @Transactional public List insertCompositeModifications( @NonNull UUID targetGroupUuid, - @NonNull List> compositesUuidName) { - List compositeUuids = compositesUuidName.stream().map(Pair::getFirst).toList(); + @NonNull List compositesToBeInserted) { + List compositeUuids = compositesToBeInserted.stream().map(CompositesToBeInserted::id).toList(); List newCompositeModifications = new ArrayList<>(); List modificationInfos = getModificationsInfosNonTransactional(compositeUuids); - // apply the new composite name to the corresponding composite modifications - for (Pair compositeUuidName : compositesUuidName) { - CompositeModificationInfos newCompositeModification = (CompositeModificationInfos) modificationInfos.stream() - .filter(modif -> modif.getUuid().equals(compositeUuidName.getFirst())) - .findFirst().orElse(null); - if (newCompositeModification != null) { - newCompositeModification.setName(compositeUuidName.getSecond()); - newCompositeModifications.add(newCompositeModification); + for (CompositesToBeInserted compositeToBeInserted : compositesToBeInserted) { + if (compositeToBeInserted.isShared()) { + CompositeModificationInfos referencedCompositeModification = (CompositeModificationInfos) modificationInfos.stream() + .filter(modif -> modif.getUuid().equals(compositeToBeInserted.id())) + .findFirst().orElse(null); + if (referencedCompositeModification != null) { + referencedCompositeModification.setName(compositeToBeInserted.name()); + ModificationReferenceInfos newModificationReference = ModificationReferenceInfos.builder() + .referenceId(compositeToBeInserted.id()) + .referenceType(ModificationReferenceInfos.Type.BASIC) + .referenceInfos(referencedCompositeModification) + .build(); + newCompositeModifications.add(newModificationReference); + } } else { - LOGGER.error("Could not find composite modification with uuid {} to apply its name {}", compositeUuidName.getFirst(), compositeUuidName.getSecond()); + // apply the new composite name to the corresponding composite modifications + CompositeModificationInfos newCompositeModification = (CompositeModificationInfos) modificationInfos.stream() + .filter(modif -> modif.getUuid().equals(compositeToBeInserted.id())) + .findFirst().orElse(null); + if (newCompositeModification != null) { + newCompositeModification.setName(compositeToBeInserted.name()); + newCompositeModifications.add(newCompositeModification); + } else { + LOGGER.error("Could not find composite modification with uuid {} to apply its name {}", compositeToBeInserted.id(), compositeToBeInserted.name()); + } } } List newEntities = saveModificationInfosNonTransactional(targetGroupUuid, newCompositeModifications); 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 b8245ad7b..bb17a12a0 100644 --- a/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java @@ -21,10 +21,8 @@ import org.gridsuite.filter.AbstractFilter; import org.gridsuite.modification.ModificationType; import org.gridsuite.modification.NetworkModificationException; -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.server.dto.CompositesToBeInserted; import org.gridsuite.modification.server.NetworkModificationServerException; import org.gridsuite.modification.server.dto.*; import org.gridsuite.modification.server.dto.elasticsearch.ModificationApplicationInfos; @@ -269,6 +267,11 @@ public void updateNetworkModificationMetadata(@NonNull List modificationUu networkModificationRepository.updateNetworkModificationMetadata(modificationUuids, metadata); } + @Transactional + public Map getReferencesData(@NonNull List modificationUuids) { + return networkModificationRepository.getReferencesData(modificationUuids); + } + @Transactional public void stashNetworkModifications(UUID groupUuid, @NonNull List modificationUuids) { for (UUID modificationUuid : modificationUuids) { @@ -286,8 +289,8 @@ public void reorderNetworkModifications(UUID groupId, Boolean stashed) { } @Transactional - public void restoreNetworkModifications(UUID groupUuid, @NonNull List modificationUuids) { - networkModificationRepository.restoreNetworkModifications(modificationUuids, + public Map restoreNetworkModifications(UUID groupUuid, @NonNull List modificationUuids) { + return networkModificationRepository.restoreNetworkModifications(modificationUuids, networkModificationRepository.getModificationsCount(groupUuid, false)); } @@ -481,8 +484,8 @@ public CompletableFuture duplicateModifications(@Non */ public CompletableFuture splitCompositeModifications( @NonNull UUID targetGroupUuid, - @NonNull Pair>, List> modificationContextInfos) { - List compositesUuids = modificationContextInfos.getFirst().stream().map(Pair::getFirst).toList(); + @NonNull Pair, List> modificationContextInfos) { + List compositesUuids = modificationContextInfos.getFirst().stream().map(CompositesToBeInserted::id).toList(); List modifications = networkModificationRepository.extractModificationsFromCompositesAndSave(targetGroupUuid, compositesUuids); List ids = modifications.stream().map(ModificationInfos::getUuid).toList(); return applyModifications(targetGroupUuid, modifications, modificationContextInfos.getSecond()).thenApply(result -> @@ -491,7 +494,7 @@ public CompletableFuture splitCompositeModifications public CompletableFuture insertCompositeModifications( @NonNull UUID targetGroupUuid, - @NonNull Pair>, List> modificationContextInfos) { + @NonNull Pair, List> modificationContextInfos) { List modifications = networkModificationRepository.insertCompositeModifications( targetGroupUuid, modificationContextInfos.getFirst()); List ids = modifications.stream().map(ModificationInfos::getUuid).toList(); diff --git a/src/test/java/org/gridsuite/modification/server/CompositeControllerTest.java b/src/test/java/org/gridsuite/modification/server/CompositeControllerTest.java index 3a9e5c465..15d9cd32c 100644 --- a/src/test/java/org/gridsuite/modification/server/CompositeControllerTest.java +++ b/src/test/java/org/gridsuite/modification/server/CompositeControllerTest.java @@ -175,7 +175,7 @@ void testSplit() throws Exception { .contentType(MediaType.APPLICATION_JSON), status().isOk()); - assertApplicationStatusOK(mvcResult); + //assertApplicationStatusOK(mvcResult); List newModificationList = modificationRepository.getModifications(TEST_GROUP_ID, false, true); assertEquals(modificationsNumber * 2, newModificationList.size()); diff --git a/src/test/java/org/gridsuite/modification/server/modifications/ModificationReferenceTest.java b/src/test/java/org/gridsuite/modification/server/modifications/ModificationReferenceTest.java index c3c4ea99c..049b23d6c 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/ModificationReferenceTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/ModificationReferenceTest.java @@ -42,15 +42,15 @@ protected Network createNetwork(UUID networkUuid) { protected ModificationInfos buildModification() { ModificationInfos compositeInfo = buildCompositeModification(); ModificationEntity compositeEntity = modificationRepository.save(ModificationEntity.fromDTO(compositeInfo)); - ModificationInfos compositeMetadataInfo = modificationRepository.findBaseDataByIdIn(List.of(compositeEntity.getId())).getFirst().toModificationInfos(); + ModificationInfos referenceInfos = compositeEntity.toModificationInfos(); return ModificationReferenceInfos.builder() - .referenceType(ModificationReferenceInfos.Type.BASIC) - .referenceId(compositeMetadataInfo.getUuid()) - .referenceInfos(compositeInfo) - .stashed(false) - .activated(true) - .build(); + .referenceType(ModificationReferenceInfos.Type.BASIC) + .referenceId(compositeEntity.getId()) + .referenceInfos(referenceInfos) + .stashed(false) + .activated(true) + .build(); } @Override diff --git a/src/test/java/org/gridsuite/modification/server/service/ModificationIndexationTest.java b/src/test/java/org/gridsuite/modification/server/service/ModificationIndexationTest.java index 893e13b5b..dc93bd482 100644 --- a/src/test/java/org/gridsuite/modification/server/service/ModificationIndexationTest.java +++ b/src/test/java/org/gridsuite/modification/server/service/ModificationIndexationTest.java @@ -308,8 +308,8 @@ void testInsertCompositeModifications() { Split this composite and insert the contained modifications to group 2, variant 2 */ UUID groupUuid2 = UUID.randomUUID(); - Pair>, List> modificationContextInfos = Pair.of( - List.of(Pair.of(compositeUuid, "")), + Pair, List> modificationContextInfos = Pair.of( + List.of(new CompositesToBeInserted(compositeUuid, "", false)), List.of(new ModificationApplicationContext(networkInfos.getNetworkUuuid(), variant2, UUID.randomUUID(), UUID.randomUUID())) ); NetworkModificationsResult modificationsResult = networkModificationService.splitCompositeModifications(