diff --git a/src/main/java/org/gridsuite/modification/server/CompositeController.java b/src/main/java/org/gridsuite/modification/server/CompositeController.java new file mode 100644 index 000000000..09684bb02 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/CompositeController.java @@ -0,0 +1,99 @@ +/** + * 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; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +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.dto.ModificationInfos; +import org.gridsuite.modification.server.dto.ModificationApplicationContext; +import org.gridsuite.modification.server.dto.NetworkModificationsResult; +import org.gridsuite.modification.server.service.NetworkModificationService; +import org.springframework.data.util.Pair; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +/** + * @author Mathieu Deharbe + */ +@RestController +@RequestMapping(value = "/" + NetworkModificationApi.API_VERSION + "/network-composite-modifications") +@Tag(name = "network-modification-server - Composite modifications") +public class CompositeController { + + public enum CompositeModificationAction { + SPLIT, // the network modifications contained into the composite modifications are extracted and inserted one by one + INSERT // the composite modifications are fully inserted as composite modifications + } + + private final NetworkModificationService networkModificationService; + + public CompositeController(NetworkModificationService networkModificationService) { + this.networkModificationService = networkModificationService; + } + + @PutMapping(value = "/groups/{groupUuid}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Insert a list of composite network modifications passed in body at the end of a group") + @ApiResponse(responseCode = "200", description = "The composite modification list has been added to the group.") + 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) { + return switch (action) { + case SPLIT -> + networkModificationService.splitCompositeModifications(targetGroupUuid, modificationContextInfos) + .thenApply(ResponseEntity.ok()::body); + case INSERT -> + networkModificationService.insertCompositeModifications( + targetGroupUuid, + modificationContextInfos + ).thenApply(ResponseEntity.ok()::body); + }; + } + + @PostMapping(value = "", consumes = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Create a network composite modification") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The composite modification has been created")}) + public ResponseEntity createNetworkCompositeModification(@RequestBody List modificationUuids) { + return ResponseEntity.ok().body(networkModificationService.createNetworkCompositeModification(modificationUuids)); + } + + @GetMapping(value = "/network-modifications", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Get the list of all the network modifications inside a list of composite modifications") + @ApiResponse(responseCode = "200", description = "List of modifications inside the composite modifications") + public ResponseEntity> getNetworkModificationsFromComposite(@Parameter(description = "Composite modifications uuids list") @RequestParam("uuids") List compositeModificationUuids, + @Parameter(description = "Only metadata") @RequestParam(name = "onlyMetadata", required = false, defaultValue = "true") Boolean onlyMetadata) { + return ResponseEntity.ok() + .contentType(MediaType.APPLICATION_JSON) + .body(networkModificationService.getNetworkModificationsFromComposite(compositeModificationUuids, onlyMetadata) + ); + } + + @PostMapping(value = "/duplication", consumes = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Duplicate some composite modifications") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The duplicated modifications uuids mapped with their source uuid")}) + public ResponseEntity> duplicateCompositeModifications(@Parameter(description = "source modifications uuids list to duplicate") @RequestBody List sourceModificationUuids) { + return ResponseEntity.ok().body(networkModificationService.duplicateCompositeModifications(sourceModificationUuids)); + } + + @PutMapping(value = "/{uuid}", consumes = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Update a network composite modification") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The composite modification has been updated")}) + public ResponseEntity updateNetworkCompositeModification(@PathVariable("uuid") UUID compositeModificationUuid, + @RequestBody List modificationUuids) { + networkModificationService.updateCompositeModification(compositeModificationUuid, modificationUuids); + return ResponseEntity.ok().build(); + } +} diff --git a/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java b/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java index 19e548f57..c41b4e7fa 100644 --- a/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java +++ b/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java @@ -13,7 +13,6 @@ 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.ModificationsToCopyInfos; import org.gridsuite.modification.server.dto.*; import org.gridsuite.modification.server.dto.catalog.LineTypeInfos; import org.gridsuite.modification.server.service.LineTypesCatalogService; @@ -38,8 +37,6 @@ public class NetworkModificationController { private enum GroupModificationAction { MOVE, COPY, - SPLIT_COMPOSITE, // the network modifications contained into the composite modifications are extracted and inserted one by one - INSERT_COMPOSITE // the composite modifications are fully inserted as composite modifications } private final NetworkModificationService networkModificationService; @@ -97,7 +94,7 @@ public ResponseEntity> duplicateGroup(@RequestParam("groupUuid") } @PutMapping(value = "/groups/{groupUuid}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "For a list of network modifications passed in body, Move them before another one or at the end of the list, or Duplicate them at the end of the list, or Insert them (composite) at the end of the list") + @Operation(summary = "For a list of network modifications passed in body, Move them before another one or at the end of the list, or Duplicate them at the end of the list") @ApiResponse(responseCode = "200", description = "The modification list of the group has been updated.") public CompletableFuture> handleNetworkModifications( @Parameter(description = "updated group UUID, where modifications are pasted") @PathVariable("groupUuid") UUID targetGroupUuid, @@ -105,16 +102,12 @@ public CompletableFuture> handleNetwo @Parameter(description = "the modification Uuid to move before (MOVE option, empty means moving at the end)") @RequestParam(value = "before", required = false) UUID beforeModificationUuid, @Parameter(description = "origin group UUID, where modifications are copied or cut") @RequestParam(value = "originGroupUuid", required = false) UUID originGroupUuid, @Parameter(description = "modifications can be applied (default is true)") @RequestParam(value = "build", required = false, defaultValue = "true") Boolean canApply, - @RequestBody Pair, List> modificationContextInfos) { - List modificationsUuids = modificationContextInfos.getFirst().stream().map(ModificationsToCopyInfos::getUuid).toList(); + @RequestBody Pair, List> modificationContextInfos) { return switch (action) { case COPY -> - networkModificationService.duplicateModifications(targetGroupUuid, originGroupUuid, modificationsUuids, modificationContextInfos.getSecond()).thenApply(ResponseEntity.ok()::body); - case SPLIT_COMPOSITE -> - networkModificationService.splitCompositeModifications(targetGroupUuid, modificationsUuids, modificationContextInfos.getSecond()).thenApply(ResponseEntity.ok()::body); - case INSERT_COMPOSITE -> - networkModificationService.insertCompositeModificationsIntoGroup( + networkModificationService.duplicateModifications( targetGroupUuid, + originGroupUuid, modificationContextInfos.getFirst(), modificationContextInfos.getSecond() ).thenApply(ResponseEntity.ok()::body); @@ -124,7 +117,14 @@ public CompletableFuture> handleNetwo if (sourceGroupUuid.equals(targetGroupUuid)) { applyModifications = false; } - yield networkModificationService.moveModifications(targetGroupUuid, sourceGroupUuid, beforeModificationUuid, modificationsUuids, modificationContextInfos.getSecond(), applyModifications).thenApply(ResponseEntity.ok()::body); + yield networkModificationService.moveModifications( + targetGroupUuid, + sourceGroupUuid, + beforeModificationUuid, + modificationContextInfos.getFirst(), + modificationContextInfos.getSecond(), + applyModifications + ).thenApply(ResponseEntity.ok()::body); } }; } @@ -246,40 +246,6 @@ public ResponseEntity deleteLineTypesCatalog() { return ResponseEntity.ok().build(); } - @PostMapping(value = "/network-composite-modifications", consumes = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Create a network composite modification") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The composite modification has been created")}) - public ResponseEntity createNetworkCompositeModification(@RequestBody List modificationUuids) { - return ResponseEntity.ok().body(networkModificationService.createNetworkCompositeModification(modificationUuids)); - } - - @GetMapping(value = "/network-composite-modifications/network-modifications", produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Get the list of all the network modifications inside a list of composite modifications") - @ApiResponse(responseCode = "200", description = "List of modifications inside the composite modifications") - public ResponseEntity> getNetworkModificationsFromComposite(@Parameter(description = "Composite modifications uuids list") @RequestParam("uuids") List compositeModificationUuids, - @Parameter(description = "Only metadata") @RequestParam(name = "onlyMetadata", required = false, defaultValue = "true") Boolean onlyMetadata) { - return ResponseEntity.ok() - .contentType(MediaType.APPLICATION_JSON) - .body(networkModificationService.getNetworkModificationsFromComposite(compositeModificationUuids, onlyMetadata) - ); - } - - @PostMapping(value = "/network-composite-modifications/duplication", consumes = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Duplicate some composite modifications") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The duplicated modifications uuids mapped with their source uuid")}) - public ResponseEntity> duplicateCompositeModifications(@Parameter(description = "source modifications uuids list to duplicate") @RequestBody List sourceModificationUuids) { - return ResponseEntity.ok().body(networkModificationService.duplicateCompositeModifications(sourceModificationUuids)); - } - - @PutMapping(value = "/network-composite-modifications/{uuid}", consumes = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Update a network composite modification") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The composite modification has been updated")}) - public ResponseEntity updateNetworkCompositeModification(@PathVariable("uuid") UUID compositeModificationUuid, - @RequestBody List modificationUuids) { - networkModificationService.updateCompositeModification(compositeModificationUuid, modificationUuids); - return ResponseEntity.ok().build(); - } - @PutMapping(value = "/network-modifications", produces = MediaType.APPLICATION_JSON_VALUE, params = "stashed") @Operation(summary = "stash or unstash network modifications") @ApiResponse(responseCode = "200", description = "The network modifications were stashed") 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 538e248f4..28f83566e 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java @@ -19,6 +19,9 @@ import org.gridsuite.modification.server.entities.equipment.modification.EquipmentModificationEntity; import org.gridsuite.modification.server.entities.tabular.TabularModificationsEntity; 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; @@ -64,6 +67,8 @@ public class NetworkModificationRepository { private static final String MODIFICATION_NOT_FOUND_MESSAGE = "Modification (%s) not found"; + private static final Logger LOGGER = LoggerFactory.getLogger(NetworkModificationRepository.class); + public NetworkModificationRepository(ModificationGroupRepository modificationGroupRepository, ModificationRepository modificationRepository, GeneratorCreationRepository generatorCreationRepository, @@ -139,15 +144,6 @@ public UUID createNetworkCompositeModification(@NonNull List modificationU return modificationRepository.save(compositeEntity).getId(); } - public CompositeModificationInfos cloneCompositeModification(@NonNull ModificationsToCopyInfos compositeModification) { - CompositeModificationInfos newCompositeInfos = CompositeModificationInfos.builder().modifications(List.of()).build(); - List copiedModifications = getCompositeModificationsInfosNonTransactional(List.of(compositeModification.getUuid())).stream() - .toList(); - newCompositeInfos.setModifications(copiedModifications); - newCompositeInfos.setName(compositeModification.getCompositeName()); - return newCompositeInfos; - } - public void updateCompositeModification(@NonNull UUID compositeUuid, @NonNull List modificationUuids) { ModificationEntity modificationEntity = modificationRepository.findById(compositeUuid) .orElseThrow(() -> new NetworkModificationException(MODIFICATION_NOT_FOUND, String.format(MODIFICATION_NOT_FOUND_MESSAGE, compositeUuid))); @@ -789,13 +785,23 @@ public List saveCompositeModifications(@NonNull UUID targetGr } @Transactional - public List insertCompositeModificationsIntoGroup( + public List insertCompositeModifications( @NonNull UUID targetGroupUuid, - @NonNull List compositeModifications) { + @NonNull List> compositesUuidName) { + List compositeUuids = compositesUuidName.stream().map(Pair::getFirst).toList(); List newCompositeModifications = new ArrayList<>(); - for (ModificationsToCopyInfos compositeModification : compositeModifications) { - CompositeModificationInfos newCompositeModification = cloneCompositeModification(compositeModification); - newCompositeModifications.add(newCompositeModification); + 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); + } else { + LOGGER.error("Could not find composite modification with uuid {} to apply its name {}", compositeUuidName.getFirst(), compositeUuidName.getSecond()); + } } List newEntities = saveModificationInfosNonTransactional(targetGroupUuid, newCompositeModifications); return newEntities.stream().map(ModificationEntity::toModificationInfos).toList(); 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 cc7e82672..22a239789 100644 --- a/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java @@ -23,7 +23,6 @@ import org.gridsuite.modification.dto.EquipmentModificationInfos; import org.gridsuite.modification.dto.GenerationDispatchInfos; import org.gridsuite.modification.dto.ModificationInfos; -import org.gridsuite.modification.dto.ModificationsToCopyInfos; import org.gridsuite.modification.server.NetworkModificationServerException; import org.gridsuite.modification.server.dto.*; import org.gridsuite.modification.server.dto.elasticsearch.ModificationApplicationInfos; @@ -40,6 +39,7 @@ import org.springframework.data.elasticsearch.client.elc.Queries; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.util.Pair; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -420,21 +420,23 @@ public CompletableFuture duplicateModifications(@Non /** * all their network modifications are extracted from the composite modifications and inserted into the group */ - public CompletableFuture splitCompositeModifications(@NonNull UUID targetGroupUuid, @NonNull List compositeModificationsUuids, @NonNull List applicationContexts) { - List modifications = networkModificationRepository.saveCompositeModifications(targetGroupUuid, compositeModificationsUuids); + public CompletableFuture splitCompositeModifications( + @NonNull UUID targetGroupUuid, + @NonNull Pair>, List> modificationContextInfos) { + List modificationsUuids = modificationContextInfos.getFirst().stream().map(Pair::getFirst).toList(); + List modifications = networkModificationRepository.saveCompositeModifications(targetGroupUuid, modificationsUuids); List ids = modifications.stream().map(ModificationInfos::getUuid).toList(); - return applyModifications(targetGroupUuid, modifications, applicationContexts).thenApply(result -> + return applyModifications(targetGroupUuid, modifications, modificationContextInfos.getSecond()).thenApply(result -> new NetworkModificationsResult(ids, result)); } - public CompletableFuture insertCompositeModificationsIntoGroup( + public CompletableFuture insertCompositeModifications( @NonNull UUID targetGroupUuid, - @NonNull List compositeModifications, - @NonNull List applicationContexts) { - List modifications = networkModificationRepository.insertCompositeModificationsIntoGroup( - targetGroupUuid, compositeModifications); + @NonNull Pair>, List> modificationContextInfos) { + List modifications = networkModificationRepository.insertCompositeModifications( + targetGroupUuid, modificationContextInfos.getFirst()); List ids = modifications.stream().map(ModificationInfos::getUuid).toList(); - return applyModifications(targetGroupUuid, modifications, applicationContexts).thenApply(result -> + return applyModifications(targetGroupUuid, modifications, modificationContextInfos.getSecond()).thenApply(result -> new NetworkModificationsResult(ids, result)); } diff --git a/src/test/java/org/gridsuite/modification/server/CompositeControllerTest.java b/src/test/java/org/gridsuite/modification/server/CompositeControllerTest.java new file mode 100644 index 000000000..b85d25742 --- /dev/null +++ b/src/test/java/org/gridsuite/modification/server/CompositeControllerTest.java @@ -0,0 +1,368 @@ +/** + * 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; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.powsybl.iidm.network.IdentifiableType; +import com.powsybl.iidm.network.Network; +import com.powsybl.network.store.client.NetworkStoreService; +import com.powsybl.network.store.client.PreloadingStrategy; +import org.gridsuite.modification.NetworkModificationException; +import org.gridsuite.modification.dto.CompositeModificationInfos; +import org.gridsuite.modification.dto.EquipmentAttributeModificationInfos; +import org.gridsuite.modification.dto.ModificationInfos; +import org.gridsuite.modification.server.dto.NetworkModificationResult; +import org.gridsuite.modification.server.dto.NetworkModificationsResult; +import org.gridsuite.modification.server.repositories.NetworkModificationRepository; +import org.gridsuite.modification.server.service.ReportService; +import org.gridsuite.modification.server.utils.NetworkCreation; +import org.gridsuite.modification.server.utils.TestUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.stubbing.Answer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.util.Pair; +import org.springframework.http.MediaType; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static org.gridsuite.modification.ModificationType.COMPOSITE_MODIFICATION; +import static org.gridsuite.modification.server.utils.NetworkCreation.VARIANT_ID; +import static org.gridsuite.modification.server.utils.TestUtils.runRequestAsync; +import static org.gridsuite.modification.server.utils.assertions.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * @author Mathieu Deharbe + */ +@AutoConfigureMockMvc +@SpringBootTest +class CompositeControllerTest { + private static final UUID TEST_NETWORK_ID = UUID.fromString("7928181c-7977-4592-ba19-88027e4254e4"); + private static final UUID TEST_GROUP_ID = UUID.randomUUID(); + private static final UUID TEST_GROUP2_ID = UUID.randomUUID(); + private static final String URI_COMPOSITE_NETWORK_MODIF_BASE = "/v1/network-composite-modifications"; + private static final String URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT = "/v1/network-composite-modifications/"; + private static final String URI_NETWORK_MODIF_BASE = "/v1/network-modifications"; + + @Autowired + private MockMvc mockMvc; + + private ObjectWriter objectWriter; + + @Autowired + private NetworkModificationRepository modificationRepository; + + @MockitoBean + private ReportService reportService; + + @Autowired + private ObjectMapper mapper; + + @MockitoBean + private NetworkStoreService networkStoreService; + + private Network network; + + @BeforeEach + void setUp() { + objectWriter = mapper.writer().withDefaultPrettyPrinter(); + network = NetworkCreation.create(TEST_NETWORK_ID, true); + when(networkStoreService.getNetwork(eq(TEST_NETWORK_ID), nullable(PreloadingStrategy.class))).then((Answer) invocation -> network); + modificationRepository.deleteAll(); + } + + @AfterEach + void tearOff() { + // clean DB + modificationRepository.deleteAll(); + } + + @Test + void testSplit() throws Exception { + // Insert some switch modifications in the group + int modificationsNumber = 2; + List modificationList = createSomeSwitchModifications(TEST_GROUP_ID, modificationsNumber); + assertEquals(modificationsNumber, modificationRepository.getModifications(TEST_GROUP_ID, true, true).size()); + + // Create a composite modification with the switch modification + List modificationUuids = modificationList.stream().map(ModificationInfos::getUuid).toList(); + MvcResult mvcResult; + mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) + .content(mapper.writeValueAsString(modificationUuids)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn(); + ModificationInfos compositeModificationInfos = CompositeModificationInfos.builder() + .modifications(modificationList) + .build(); + UUID compositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + assertThat(modificationRepository.getModificationInfo(compositeModificationUuid)).recursivelyEquals(compositeModificationInfos); + + List modificationInfosList = modificationRepository.getModifications(TEST_GROUP_ID, true, true); + assertEquals(modificationsNumber, modificationInfosList.size()); + + // get the composite modification (metadata only) + mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + "/network-modifications?uuids={id}", compositeModificationUuid)) + .andExpect(status().isOk()).andReturn(); + List compositeModificationContent = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + assertEquals(modificationsNumber, compositeModificationContent.size()); + for (int i = 0; i < modificationUuids.size(); i++) { + assertEquals(modificationInfosList.get(i).getMessageValues(), compositeModificationContent.get(i).getMessageValues()); + } + assertNotNull(compositeModificationContent.getFirst().getMessageType()); + assertNotNull(compositeModificationContent.getFirst().getMessageValues()); + assertNull(((EquipmentAttributeModificationInfos) compositeModificationContent.getFirst()).getEquipmentAttributeName()); + assertNull(((EquipmentAttributeModificationInfos) compositeModificationContent.getFirst()).getEquipmentAttributeValue()); + + // create another composite modification + List otherModificationList = createSomeSwitchModifications(TEST_GROUP2_ID, modificationsNumber); + List otherModificationUuids = otherModificationList.stream().map(ModificationInfos::getUuid).toList(); + mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) + .content(mapper.writeValueAsString(otherModificationUuids)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn(); + ModificationInfos otherCompositeModificationInfos = CompositeModificationInfos.builder() + .modifications(otherModificationList) + .build(); + UUID otherCompositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + assertThat(modificationRepository.getModificationInfo(otherCompositeModificationUuid)).recursivelyEquals(otherCompositeModificationInfos); + + // get both composite modifications + mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + "/network-modifications?uuids=" + compositeModificationUuid + "&uuids=" + otherCompositeModificationUuid)) + .andExpect(status().isOk()).andReturn(); + List compositeModificationsContent = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + assertEquals(modificationsNumber * 2, compositeModificationsContent.size()); + + // get the composite modification (complete data) + mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + "/network-modifications?uuids={id}&onlyMetadata=false", compositeModificationUuid)) + .andExpect(status().isOk()).andReturn(); + compositeModificationContent = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + checkCompositeModificationContent(compositeModificationContent); + + // Insert the composite modification in the group + final String bodyJson = getJsonBodyModificationCompositeInfos( + List.of(Pair.of(compositeModificationUuid, "random name"))); + mvcResult = runRequestAsync( + mockMvc, + put(URI_COMPOSITE_NETWORK_MODIF_BASE + "/groups/" + TEST_GROUP_ID + "?action=SPLIT") + .content(bodyJson) + .contentType(MediaType.APPLICATION_JSON), + status().isOk()); + + assertApplicationStatusOK(mvcResult); + + List newModificationList = modificationRepository.getModifications(TEST_GROUP_ID, false, true); + assertEquals(modificationsNumber * 2, newModificationList.size()); + List newModificationUuidList = newModificationList.stream().map(ModificationInfos::getUuid).toList(); + assertEquals(modificationUuids.getFirst(), newModificationUuidList.getFirst()); + assertThat(modificationList.getFirst()).recursivelyEquals(newModificationList.get(modificationsNumber)); + } + + @Test + void testInsert() throws Exception { + // Insert some switch modifications in the group + int modificationsNumber = 2; + List modificationList = createSomeSwitchModifications(TEST_GROUP_ID, modificationsNumber); + + // Create a composite modification with the switch modification + List modificationUuids = modificationList.stream().map(ModificationInfos::getUuid).toList(); + MvcResult mvcResult; + mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) + .content(mapper.writeValueAsString(modificationUuids)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn(); + UUID compositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + + List modificationInfosList = modificationRepository.getModifications(TEST_GROUP_ID, true, true); + assertEquals(modificationsNumber, modificationInfosList.size()); + + // Insert the composite modification in the group + final String bodyJson = getJsonBodyModificationCompositeInfos( + List.of(Pair.of(compositeModificationUuid, "random name"))); + + // insert the same composite modification inside as a complete composite, not split into regular network modifications + mvcResult = runRequestAsync( + mockMvc, + put(URI_COMPOSITE_NETWORK_MODIF_BASE + "/groups/" + TEST_GROUP_ID + "?action=INSERT") + .content(bodyJson).contentType(MediaType.APPLICATION_JSON), status().isOk() + ); + assertApplicationStatusOK(mvcResult); + List newModificationList = modificationRepository.getModifications(TEST_GROUP_ID, false, true); + assertEquals(modificationsNumber + 1, newModificationList.size()); + CompositeModificationInfos insertedComposite = (CompositeModificationInfos) newModificationList.stream().filter(modificationInfos -> + modificationInfos.getType().equals(COMPOSITE_MODIFICATION)).findFirst().orElseThrow(); + assertNotNull(insertedComposite); + checkCompositeModificationContent(insertedComposite.getModifications()); + } + + private static void checkCompositeModificationContent(List compositeModificationContent) { + assertEquals("open", ((EquipmentAttributeModificationInfos) compositeModificationContent.getFirst()).getEquipmentAttributeName()); + assertEquals(Boolean.TRUE, ((EquipmentAttributeModificationInfos) compositeModificationContent.getFirst()).getEquipmentAttributeValue()); + assertEquals(IdentifiableType.SWITCH, ((EquipmentAttributeModificationInfos) compositeModificationContent.getFirst()).getEquipmentType()); + assertEquals("v1b1", ((EquipmentAttributeModificationInfos) compositeModificationContent.getFirst()).getEquipmentId()); + } + + private List createSomeSwitchModifications(UUID groupId, int number) throws Exception { + List openStates = List.of(true, false); + EquipmentAttributeModificationInfos switchStatusModificationInfos = EquipmentAttributeModificationInfos.builder() + .equipmentType(IdentifiableType.SWITCH) + .equipmentAttributeName("open") + .equipmentId("v1b1") + .build(); + MvcResult mvcResult; + for (int i = 0; i < number; i++) { + switchStatusModificationInfos.setEquipmentAttributeValue(openStates.get(i % 2)); + String bodyJson = TestUtils.getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, VARIANT_ID); + mvcResult = runRequestAsync(mockMvc, post(URI_NETWORK_MODIF_BASE + "?groupUuid=" + groupId).content(bodyJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); + assertApplicationStatusOK(mvcResult); + } + var modificationList = modificationRepository.getModifications(groupId, false, true); + assertEquals(number, modificationList.size()); + return modificationList; + } + + private String getJsonBodyModificationCompositeInfos(List> modifs) throws JsonProcessingException { + return TestUtils.getJsonBodyModificationCompositeInfos(modifs, TEST_NETWORK_ID, VARIANT_ID); + } + + private void assertApplicationStatusOK(MvcResult mvcResult) throws Exception { + NetworkModificationsResult networkModificationsResult = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + assertEquals(1, networkModificationsResult.modificationResults().size()); + assertTrue(networkModificationsResult.modificationResults().getFirst().isPresent()); + assertNotEquals(NetworkModificationResult.ApplicationStatus.WITH_ERRORS, networkModificationsResult.modificationResults().getFirst().get().getApplicationStatus()); + } + + @Test + void testDuplicateCompositeModification() throws Exception { + // Create a composite modification with the modification + List modificationList = createSomeSwitchModifications(TEST_GROUP_ID, 1); + List modificationUuidList = modificationList.stream().map(ModificationInfos::getUuid).toList(); + MvcResult mvcResult; + mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) + .content(mapper.writeValueAsString(modificationUuidList)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn(); + UUID compositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + + // Duplicate it without group ownership + mvcResult = mockMvc.perform( + post(URI_COMPOSITE_NETWORK_MODIF_BASE + "/duplication") + .content(objectWriter.writeValueAsString(List.of(compositeModificationUuid))) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn(); + + Map returnedMap = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + assertEquals(1, returnedMap.size()); + Map.Entry returnedIds = returnedMap.entrySet().stream().findFirst().get(); + UUID returnedSourceId = returnedIds.getKey(); + UUID returnedNewId = returnedIds.getValue(); + assertNotEquals(returnedSourceId, returnedNewId); + assertEquals(compositeModificationUuid, returnedSourceId); + + ModificationInfos sourceModificationInfos = modificationRepository.getModificationInfo(compositeModificationUuid); + ModificationInfos newModificationInfos = modificationRepository.getModificationInfo(returnedNewId); + // compare duplicate with the source (same data except uuid) + assertThat(sourceModificationInfos).recursivelyEquals(newModificationInfos); + // source group has not changed + List groupModifications = modificationRepository.getModifications(TEST_GROUP_ID, true, true, false); + assertEquals(1, groupModifications.size()); + assertEquals(modificationUuidList.getFirst(), groupModifications.getFirst().getUuid()); + + // now delete the duplicate modification + mockMvc.perform(delete(URI_NETWORK_MODIF_BASE) + .queryParam("uuids", returnedNewId.toString())) + .andExpect(status().isOk()); + + // source group has not changed + groupModifications = modificationRepository.getModifications(TEST_GROUP_ID, true, true, false); + assertEquals(1, groupModifications.size()); + assertEquals(modificationUuidList.getFirst(), groupModifications.getFirst().getUuid()); + // duplicate has been deleted + assertEquals("MODIFICATION_NOT_FOUND : " + returnedNewId, assertThrows(NetworkModificationException.class, () + -> modificationRepository.getModificationInfo(returnedNewId)).getMessage()); + } + + @Test + void testUpdateNetworkCompositeModification() throws Exception { + // Insert some switch modifications in the group + int modificationsNumber = 3; + List modificationList = createSomeSwitchModifications(TEST_GROUP_ID, modificationsNumber); + assertEquals(modificationsNumber, modificationRepository.getModifications(TEST_GROUP_ID, true, true).size()); + + // Create a composite modification with the switch modifications + List modificationUuids = modificationList.stream().map(ModificationInfos::getUuid).toList(); + MvcResult mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) + .content(mapper.writeValueAsString(modificationUuids)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn(); + UUID compositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + + // Create new modifications to use in the update + int newModificationsNumber = 2; + List newModificationList = createSomeSwitchModifications(TEST_GROUP2_ID, newModificationsNumber); + List newModificationUuids = newModificationList.stream().map(ModificationInfos::getUuid).toList(); + + // Update the composite modification with the new modifications + mockMvc.perform(put(URI_COMPOSITE_NETWORK_MODIF_BASE + "/" + compositeModificationUuid) + .content(mapper.writeValueAsString(newModificationUuids)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + // Get the composite modification content and verify it has been updated + mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + "/network-modifications?uuids={id}&onlyMetadata=false", compositeModificationUuid)) + .andExpect(status().isOk()).andReturn(); + List updatedCompositeContent = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + + assertEquals(newModificationsNumber, updatedCompositeContent.size()); + } + + @Test + void testUpdateNetworkCompositeModificationWithNonexistentUuid() throws Exception { + // Try to update a composite modification that doesn't exist + UUID nonExistentUuid = UUID.randomUUID(); + List modificationUuids = List.of(UUID.randomUUID()); + + mockMvc.perform(put(URI_COMPOSITE_NETWORK_MODIF_BASE + "/" + nonExistentUuid) + .content(mapper.writeValueAsString(modificationUuids)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNotFound()); + } + + @Test + void testUpdateNetworkCompositeModificationWithEmptyList() throws Exception { + // Create a composite modification with some modifications + List modificationList = createSomeSwitchModifications(TEST_GROUP_ID, 2); + List modificationUuids = modificationList.stream().map(ModificationInfos::getUuid).toList(); + + MvcResult mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) + .content(mapper.writeValueAsString(modificationUuids)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn(); + UUID compositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + + // Update the composite with an empty list of modifications + mockMvc.perform(put(URI_COMPOSITE_NETWORK_MODIF_BASE + "/" + compositeModificationUuid) + .content(mapper.writeValueAsString(Collections.emptyList())).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + // Verify that the composite now contains no modifications + mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + "/network-modifications?uuids={id}&onlyMetadata=false", compositeModificationUuid)) + .andExpect(status().isOk()).andReturn(); + List updatedCompositeContent = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + + assertTrue(updatedCompositeContent.isEmpty()); + } +} diff --git a/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java b/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java index 9b5d2ca2f..02bfb5273 100644 --- a/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java +++ b/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java @@ -71,8 +71,7 @@ import static org.gridsuite.modification.server.elasticsearch.EquipmentInfosService.getIndexedEquipmentTypes; import static org.gridsuite.modification.server.impacts.TestImpactUtils.*; import static org.gridsuite.modification.server.report.NetworkModificationServerReportResourceBundle.ERROR_MESSAGE_KEY; -import static org.gridsuite.modification.server.utils.TestUtils.assertLogMessage; -import static org.gridsuite.modification.server.utils.TestUtils.runRequestAsync; +import static org.gridsuite.modification.server.utils.TestUtils.*; import static org.gridsuite.modification.server.utils.assertions.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -104,8 +103,6 @@ class ModificationControllerTest { private static final UUID TEST_REPORT_ID = UUID.randomUUID(); private static final String URI_NETWORK_MODIF_BASE = "/v1/network-modifications"; - private static final String URI_COMPOSITE_NETWORK_MODIF_BASE = "/v1/network-composite-modifications"; - private static final String URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT = "/v1/network-composite-modifications/"; private static final String URI_LINE_CATALOG = URI_NETWORK_MODIF_BASE + "/catalog/line_types"; private static final String LINE_TYPES_CATALOG_JSON_FILE_1 = "/lines-catalog.json.gz"; private static final String LINE_TYPES_CATALOG_JSON_FILE_2 = "/line_types_catalog_2.json.gz"; @@ -191,14 +188,6 @@ private void assertApplicationStatusOK(MvcResult mvcResult) throws Exception { assertNotEquals(NetworkModificationResult.ApplicationStatus.WITH_ERRORS, networkModificationsResult.modificationResults().get(0).get().getApplicationStatus()); } - private String getJsonBody(ModificationInfos modificationInfos, UUID networkUuid, String variantId) throws JsonProcessingException { - return TestUtils.getJsonBody(modificationInfos, networkUuid, variantId); - } - - private String getJsonBodyModificationsToCopyInfos(List modifs, String variantId) throws JsonProcessingException { - return TestUtils.getJsonBodyModificationsToCopyInfos(modifs, TEST_NETWORK_ID, variantId); - } - private String getJsonBody(List uuids, String variantId) throws JsonProcessingException { return TestUtils.getJsonBody(uuids, TEST_NETWORK_ID, variantId); } @@ -222,7 +211,7 @@ void testEquipmentIdNonNull() { @Test void testNetworkNotFound() throws Exception { - String body = getJsonBody(LoadCreationInfos.builder().equipmentId("id").build(), NOT_FOUND_NETWORK_ID, NetworkCreation.VARIANT_ID); + String body = TestUtils.getJsonBody(LoadCreationInfos.builder().equipmentId("id").build(), NOT_FOUND_NETWORK_ID, NetworkCreation.VARIANT_ID); MvcResult mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(body).contentType(MediaType.APPLICATION_JSON), status().isNotFound()); @@ -251,7 +240,7 @@ void testNetworkModificationsToExport() throws Exception { .equipmentId("v1b1") .build(); - String switchJson = getJsonBody(switchStatusModification, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String switchJson = TestUtils.getJsonBody(switchStatusModification, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); //creating modifications associated to default group mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI) @@ -268,7 +257,7 @@ void testNetworkModificationsToExport() throws Exception { .equipmentAttributeName("v1load") .equipmentId("v1load") .build(); - String loadModificationInfosJson = getJsonBody(loadModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String loadModificationInfosJson = TestUtils.getJsonBody(loadModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(loadModificationInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); @@ -278,7 +267,7 @@ void testNetworkModificationsToExport() throws Exception { .identifiableType(IdentifiableType.VOLTAGE_LEVEL) .build(); - String customJson = getJsonBody(byFormulaModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String customJson = TestUtils.getJsonBody(byFormulaModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI) .content(customJson) @@ -334,7 +323,7 @@ void testModificationGroups() throws Exception { .equipmentAttributeValue(true) .equipmentId("v1b1") .build(); - String switchStatusModificationInfosJson = getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String switchStatusModificationInfosJson = TestUtils.getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); // no groups mvcResult = mockMvc.perform(get("/v1/groups")).andExpectAll(status().isOk(), content().contentType(MediaType.APPLICATION_JSON)).andReturn(); @@ -393,7 +382,7 @@ void testRestoreNetworkModifications() throws Exception { .equipmentId("v1b1") .stashed(true) .build(); - String switchStatusModificationInfosJson = getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String switchStatusModificationInfosJson = TestUtils.getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(switchStatusModificationInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); testElementModificationImpact(mapper, mvcResult.getResponse().getContentAsString(), Set.of("s1")); @@ -420,7 +409,7 @@ void testStashNetworkModifications() throws Exception { .equipmentId("v1b1") .stashed(true) .build(); - String switchStatusModificationInfosJson = getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String switchStatusModificationInfosJson = TestUtils.getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(switchStatusModificationInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); testElementModificationImpact(mapper, mvcResult.getResponse().getContentAsString(), Set.of("s1")); @@ -447,7 +436,7 @@ void testDisableNetworkModifications() throws Exception { .stashed(false) .activated(true) .build(); - String switchStatusModificationInfosJson = getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String switchStatusModificationInfosJson = TestUtils.getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(switchStatusModificationInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); testElementModificationImpact(mapper, mvcResult.getResponse().getContentAsString(), Set.of("s1")); @@ -480,7 +469,7 @@ void updateModificationDescription() throws Exception { .stashed(false) .description("old description") .build(); - String updateModificationDescriptionJson = getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String updateModificationDescriptionJson = TestUtils.getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(updateModificationDescriptionJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); testElementModificationImpact(mapper, mvcResult.getResponse().getContentAsString(), Set.of("s1")); @@ -513,7 +502,7 @@ void testDeleteModification() throws Exception { .equipmentAttributeValue(true) .equipmentId("v1b1") .build(); - String switchStatusModificationInfosJson = getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String switchStatusModificationInfosJson = TestUtils.getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(switchStatusModificationInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); testElementModificationImpact(mapper, mvcResult.getResponse().getContentAsString(), Set.of("s1")); @@ -569,7 +558,7 @@ void testNetworkModificationsWithErrorOnNetworkFlush() throws Exception { GroovyScriptInfos groovyScriptInfos = GroovyScriptInfos.builder() .script("network.getGenerator('idGenerator').targetP=10\nnetwork.getGenerator('idGenerator').targetP=20\n") .build(); - String groovyScriptInfosJson = getJsonBody(groovyScriptInfos, TEST_NETWORK_WITH_FLUSH_ERROR_ID, NetworkCreation.VARIANT_ID); + String groovyScriptInfosJson = TestUtils.getJsonBody(groovyScriptInfos, TEST_NETWORK_WITH_FLUSH_ERROR_ID, NetworkCreation.VARIANT_ID); runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(groovyScriptInfosJson).contentType(MediaType.APPLICATION_JSON), status().is5xxServerError()); assertEquals(1, modificationRepository.getModifications(TEST_GROUP_ID, true, false).size()); @@ -580,7 +569,7 @@ void testMultipleModificationsWithError() throws Exception { GroovyScriptInfos groovyScriptInfos = GroovyScriptInfos.builder() .script("network.getGenerator('idGenerator').targetP=10\nnetwork.getGenerator('idGenerator').targetP=20\n") .build(); - String groovyScriptInfosJson = getJsonBody(groovyScriptInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String groovyScriptInfosJson = TestUtils.getJsonBody(groovyScriptInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); // apply groovy script without error MvcResult mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(groovyScriptInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); @@ -588,7 +577,7 @@ void testMultipleModificationsWithError() throws Exception { // apply groovy script with error on the second groovyScriptInfos.setScript("network.getGenerator('there is no generator').targetP=30\nnetwork.getGenerator('idGenerator').targetP=40\n"); - groovyScriptInfosJson = getJsonBody(groovyScriptInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + groovyScriptInfosJson = TestUtils.getJsonBody(groovyScriptInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); mockMvc.perform(post(NETWORK_MODIFICATION_URI).content(groovyScriptInfosJson).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); assertNotNull(network.getGenerator("idGenerator")); @@ -609,7 +598,7 @@ private List createSomeSwitchModifications(UUID groupId, int MvcResult mvcResult; for (int i = 0; i < number; i++) { switchStatusModificationInfos.setEquipmentAttributeValue(openStates.get(i % 2)); - String bodyJson = getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String bodyJson = TestUtils.getJsonBody(switchStatusModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(URI_NETWORK_MODIF_BASE + "?groupUuid=" + groupId).content(bodyJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); } @@ -623,7 +612,7 @@ private ModificationInfos createDeletionModification(UUID groupId, IdentifiableT .equipmentType(equipmentType) .equipmentId(equipmentName) .build(); - String bodyJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String bodyJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); MvcResult mvcResult = runRequestAsync(mockMvc, post(URI_NETWORK_MODIF_BASE + "?groupUuid=" + groupId).content(bodyJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); @@ -643,15 +632,13 @@ void testCopyModification() throws Exception { List badModificationUuidList = List.of(UUID.randomUUID(), UUID.randomUUID()); duplicateModificationUuidList.addAll(badModificationUuidList); - List duplicateModificationList = duplicateModificationUuidList.stream().map( - uuid -> ModificationsToCopyInfos.builder().uuid(uuid).build()).toList(); - String bodyJson = getJsonBodyModificationsToCopyInfos(duplicateModificationList, NetworkCreation.VARIANT_ID); + String bodyJson = getJsonBody(duplicateModificationUuidList, NetworkCreation.VARIANT_ID); MvcResult mvcResult = runRequestAsync(mockMvc, put("/v1/groups/" + TEST_GROUP_ID + "?action=COPY").content(bodyJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); var newModificationList = modificationRepository.getModifications(TEST_GROUP_ID, false, true); - List newModificationUuidList = newModificationList.stream().map(ModificationInfos::getUuid).collect(Collectors.toList()); + List newModificationUuidList = newModificationList.stream().map(ModificationInfos::getUuid).toList(); // now 5 modifications: first 0-1-2 are still the same, last 3-4 are new (duplicates of 0-1) assertEquals(5, newModificationList.size()); assertEquals(modificationUuidList, newModificationUuidList.subList(0, 3)); @@ -675,14 +662,12 @@ void testCopyModification() throws Exception { // Duplicate the same modifications, and append them at the end of this new group modification list. duplicateModificationUuidList = new ArrayList<>(modificationUuidList.subList(0, 2)); - duplicateModificationList = duplicateModificationUuidList.stream().map( - uuid -> ModificationsToCopyInfos.builder().uuid(uuid).build()).toList(); - bodyJson = getJsonBodyModificationsToCopyInfos(duplicateModificationList, NetworkCreation.VARIANT_ID); + bodyJson = getJsonBody(duplicateModificationUuidList, NetworkCreation.VARIANT_ID); mvcResult = runRequestAsync(mockMvc, put("/v1/groups/" + otherGroupId + "?action=COPY").content(bodyJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); var newModificationListOtherGroup = modificationRepository.getModifications(otherGroupId, false, true); - List newModificationUuidListOtherGroup = newModificationListOtherGroup.stream().map(ModificationInfos::getUuid).collect(Collectors.toList()); + List newModificationUuidListOtherGroup = newModificationListOtherGroup.stream().map(ModificationInfos::getUuid).toList(); // now 3 modifications in new group: first 0 is still the same, last 1-2 are new (duplicates of 0-1 from first group) assertEquals(3, newModificationListOtherGroup.size()); assertEquals(modificationUuidListOtherGroup, newModificationUuidListOtherGroup.subList(0, 1)); @@ -706,9 +691,7 @@ void testCopyModification() throws Exception { } // Duplicate modifications from a group and from a list : illegal operation - duplicateModificationList = duplicateModificationUuidList.stream().map( - uuid -> ModificationsToCopyInfos.builder().uuid(uuid).build()).toList(); - bodyJson = getJsonBodyModificationsToCopyInfos(duplicateModificationList, NetworkCreation.VARIANT_ID); + bodyJson = getJsonBody(duplicateModificationUuidList, NetworkCreation.VARIANT_ID); mvcResult = mockMvc.perform( put("/v1/groups/" + otherGroupId + "?action=COPY" + "&originGroupUuid=" + TEST_GROUP_ID) .content(bodyJson) @@ -731,15 +714,13 @@ void testCopyModificationOld() throws Exception { List duplicateModificationUuidList = new ArrayList<>(modificationUuidList.subList(0, 2)); List badModificationUuidList = List.of(UUID.randomUUID(), UUID.randomUUID()); duplicateModificationUuidList.addAll(badModificationUuidList); - List duplicateModificationList = duplicateModificationUuidList.stream().map( - uuid -> ModificationsToCopyInfos.builder().uuid(uuid).build()).toList(); - String bodyJson = getJsonBodyModificationsToCopyInfos(duplicateModificationList, NetworkCreation.VARIANT_ID); + String bodyJson = getJsonBody(duplicateModificationUuidList, NetworkCreation.VARIANT_ID); String url = "/v1/groups/" + TEST_GROUP_ID + "?action=COPY"; MvcResult mvcResult = runRequestAsync(mockMvc, put(url).content(bodyJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); var newModificationList = modificationRepository.getModifications(TEST_GROUP_ID, false, true); - List newModificationUuidList = newModificationList.stream().map(ModificationInfos::getUuid).collect(Collectors.toList()); + List newModificationUuidList = newModificationList.stream().map(ModificationInfos::getUuid).toList(); // now 5 modifications: first 0-1-2 are still the same, last 3-4 are new (duplicates of 0-1) assertEquals(5, newModificationList.size()); assertEquals(modificationUuidList, newModificationUuidList.subList(0, 3)); @@ -765,15 +746,12 @@ void testCopyModificationOld() throws Exception { // Duplicate the same modifications, and append them at the end of this new group modification list. duplicateModificationUuidList = new ArrayList<>(modificationUuidList.subList(0, 2)); String copyUrl = "/v1/groups/" + otherGroupId + "?action=COPY"; - duplicateModificationList = duplicateModificationUuidList.stream().map( - uuid -> ModificationsToCopyInfos.builder().uuid(uuid).build()).toList(); - bodyJson = getJsonBodyModificationsToCopyInfos(duplicateModificationList, NetworkCreation.VARIANT_ID); - + bodyJson = getJsonBody(duplicateModificationUuidList, NetworkCreation.VARIANT_ID); mvcResult = runRequestAsync(mockMvc, put(copyUrl).content(bodyJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); var newModificationListOtherGroup = modificationRepository.getModifications(otherGroupId, false, true); - List newModificationUuidListOtherGroup = newModificationListOtherGroup.stream().map(ModificationInfos::getUuid).collect(Collectors.toList()); + List newModificationUuidListOtherGroup = newModificationListOtherGroup.stream().map(ModificationInfos::getUuid).toList(); // now 3 modifications in new group: first 0 is still the same, last 1-2 are new (duplicates of 0-1 from first group) assertEquals(3, newModificationListOtherGroup.size()); assertEquals(modificationUuidListOtherGroup, newModificationUuidListOtherGroup.subList(0, 1)); @@ -805,16 +783,14 @@ void testCopyModificationWithUnexistingId() throws Exception { // Try to copy an unexisting Modification List duplicateModificationUuidList = List.of(UUID.randomUUID()); - List duplicateModificationList = duplicateModificationUuidList.stream().map( - uuid -> ModificationsToCopyInfos.builder().uuid(uuid).build()).toList(); - String bodyJson = getJsonBodyModificationsToCopyInfos(duplicateModificationList, NetworkCreation.VARIANT_ID); + String bodyJson = getJsonBody(duplicateModificationUuidList, NetworkCreation.VARIANT_ID); String url = "/v1/groups/" + TEST_GROUP_ID + "?action=COPY" + "&before=" + modificationUuidList.get(0); mockMvc.perform(put(url).content(bodyJson) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); var newModificationList = modificationRepository.getModifications(TEST_GROUP_ID, true, true); - List newModificationUuidList = newModificationList.stream().map(ModificationInfos::getUuid).collect(Collectors.toList()); + List newModificationUuidList = newModificationList.stream().map(ModificationInfos::getUuid).toList(); // we still have the same and only modification assertEquals(newModificationUuidList, modificationUuidList); } @@ -823,7 +799,7 @@ void testCopyModificationWithUnexistingId() throws Exception { void createGeneratorWithStartup() throws Exception { // create and build generator without startup GeneratorCreationInfos generatorCreationInfos = ModificationCreation.getCreationGenerator("v2", "idGenerator1", "nameGenerator1", "1B", "v2load", "LOAD", "v1"); - String generatorCreationInfosJson = getJsonBody(generatorCreationInfos, TEST_NETWORK_ID, null); + String generatorCreationInfosJson = TestUtils.getJsonBody(generatorCreationInfos, TEST_NETWORK_ID, null); MvcResult mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(generatorCreationInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); @@ -832,7 +808,7 @@ void createGeneratorWithStartup() throws Exception { // same for bus breaker GeneratorCreationInfos generatorCreationInfosBusBreaker = ModificationCreation.getCreationGenerator("v1", "idGenerator2", "nameGenerator2", "bus1", "idGenerator1", "GENERATOR", "v1"); - generatorCreationInfosJson = getJsonBody(generatorCreationInfosBusBreaker, TEST_NETWORK_BUS_BREAKER_ID, null); + generatorCreationInfosJson = TestUtils.getJsonBody(generatorCreationInfosBusBreaker, TEST_NETWORK_BUS_BREAKER_ID, null); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(generatorCreationInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); @@ -842,7 +818,7 @@ void createGeneratorWithStartup() throws Exception { // create and build generator with startup generatorCreationInfos.setEquipmentId("idGenerator21"); generatorCreationInfos.setMarginalCost(8.); - generatorCreationInfosJson = getJsonBody(generatorCreationInfos, TEST_NETWORK_ID, null); + generatorCreationInfosJson = TestUtils.getJsonBody(generatorCreationInfos, TEST_NETWORK_ID, null); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(generatorCreationInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); @@ -856,7 +832,7 @@ void createGeneratorWithStartup() throws Exception { // same for bus breaker generatorCreationInfosBusBreaker.setEquipmentId("idGenerator3"); generatorCreationInfosBusBreaker.setPlannedOutageRate(80.); - generatorCreationInfosJson = getJsonBody(generatorCreationInfosBusBreaker, TEST_NETWORK_BUS_BREAKER_ID, null); + generatorCreationInfosJson = TestUtils.getJsonBody(generatorCreationInfosBusBreaker, TEST_NETWORK_BUS_BREAKER_ID, null); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(generatorCreationInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); @@ -876,9 +852,7 @@ void testMoveModificationInSameGroup() throws Exception { // swap modifications: move [1] before [0] List movingModificationUuidList = List.of(modificationUuidList.get(1)); - List movingModificationList = movingModificationUuidList.stream().map( - uuid -> ModificationsToCopyInfos.builder().uuid(uuid).build()).toList(); - String bodyJson = getJsonBodyModificationsToCopyInfos(movingModificationList, NetworkCreation.VARIANT_ID); + String bodyJson = getJsonBody(movingModificationUuidList, NetworkCreation.VARIANT_ID); String url = "/v1/groups/" + TEST_GROUP_ID + "?action=MOVE" + "&before=" + modificationUuidList.get(0); mockMvc.perform(put(url).content(bodyJson) .contentType(MediaType.APPLICATION_JSON)) @@ -891,208 +865,6 @@ void testMoveModificationInSameGroup() throws Exception { assertEquals(modificationUuidList, newModificationUuidList); } - @Test - void testNetworkCompositeModification() throws Exception { - // Insert some switch modifications in the group - int modificationsNumber = 2; - List modificationList = createSomeSwitchModifications(TEST_GROUP_ID, modificationsNumber); - assertEquals(modificationsNumber, modificationRepository.getModifications(TEST_GROUP_ID, true, true).size()); - - // Create a composite modification with the switch modification - List modificationUuids = modificationList.stream().map(ModificationInfos::getUuid).toList(); - MvcResult mvcResult; - mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) - .content(mapper.writeValueAsString(modificationUuids)).contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andReturn(); - ModificationInfos compositeModificationInfos = CompositeModificationInfos.builder() - .modifications(modificationList) - .build(); - UUID compositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - assertThat(modificationRepository.getModificationInfo(compositeModificationUuid)).recursivelyEquals(compositeModificationInfos); - - List modificationInfosList = modificationRepository.getModifications(TEST_GROUP_ID, true, true); - assertEquals(modificationsNumber, modificationInfosList.size()); - - // get the composite modification (metadata only) - mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + "/network-modifications?uuids={id}", compositeModificationUuid)) - .andExpect(status().isOk()).andReturn(); - List compositeModificationContent = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - assertEquals(modificationsNumber, compositeModificationContent.size()); - for (int i = 0; i < modificationUuids.size(); i++) { - assertEquals(modificationInfosList.get(i).getMessageValues(), compositeModificationContent.get(i).getMessageValues()); - } - assertNotNull(compositeModificationContent.get(0).getMessageType()); - assertNotNull(compositeModificationContent.get(0).getMessageValues()); - assertNull(((EquipmentAttributeModificationInfos) compositeModificationContent.get(0)).getEquipmentAttributeName()); - assertNull(((EquipmentAttributeModificationInfos) compositeModificationContent.get(0)).getEquipmentAttributeValue()); - assertNull(((EquipmentAttributeModificationInfos) compositeModificationContent.get(0)).getEquipmentType()); - assertNull(((EquipmentAttributeModificationInfos) compositeModificationContent.get(0)).getEquipmentId()); - - // create another composite modification - List otherModificationList = createSomeSwitchModifications(TEST_GROUP2_ID, modificationsNumber); - List otherModificationUuids = otherModificationList.stream().map(ModificationInfos::getUuid).toList(); - mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) - .content(mapper.writeValueAsString(otherModificationUuids)).contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andReturn(); - ModificationInfos otherCompositeModificationInfos = CompositeModificationInfos.builder() - .modifications(otherModificationList) - .build(); - UUID otherCompositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - assertThat(modificationRepository.getModificationInfo(otherCompositeModificationUuid)).recursivelyEquals(otherCompositeModificationInfos); - - // get both composite modifications - mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + "/network-modifications?uuids=" + compositeModificationUuid + "&uuids=" + otherCompositeModificationUuid)) - .andExpect(status().isOk()).andReturn(); - List compositeModificationsContent = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - assertEquals(modificationsNumber * 2, compositeModificationsContent.size()); - - // get the composite modification (complete data) - mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + "/network-modifications?uuids={id}&onlyMetadata=false", compositeModificationUuid)) - .andExpect(status().isOk()).andReturn(); - compositeModificationContent = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - checkCompositeModificationContent(compositeModificationContent); - - // Insert the composite modification in the group - final String bodyJson = getJsonBodyModificationsToCopyInfos( - List.of(ModificationsToCopyInfos.builder().uuid(compositeModificationUuid).compositeName("random name").build()), - NetworkCreation.VARIANT_ID); - mvcResult = runRequestAsync(mockMvc, put("/v1/groups/" + TEST_GROUP_ID + "?action=SPLIT_COMPOSITE").content(bodyJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); - - assertApplicationStatusOK(mvcResult); - - List newModificationList = modificationRepository.getModifications(TEST_GROUP_ID, false, true); - assertEquals(modificationsNumber * 2, newModificationList.size()); - List newModificationUuidList = newModificationList.stream().map(ModificationInfos::getUuid).toList(); - assertEquals(modificationUuids.get(0), newModificationUuidList.get(0)); - assertThat(modificationList.get(0)).recursivelyEquals(newModificationList.get(modificationsNumber)); - - // insert the same composite modification inside the same group but this time as a complete composite, not split into regular network modifications - mvcResult = runRequestAsync( - mockMvc, - put("/v1/groups/" + TEST_GROUP_ID + "?action=INSERT_COMPOSITE") - .content(bodyJson).contentType(MediaType.APPLICATION_JSON), status().isOk() - ); - assertApplicationStatusOK(mvcResult); - newModificationList = modificationRepository.getModifications(TEST_GROUP_ID, false, true); - assertEquals(modificationsNumber * 2 + 1, newModificationList.size()); - CompositeModificationInfos insertedComposite = (CompositeModificationInfos) newModificationList.stream().filter(modificationInfos -> - modificationInfos.getType().equals(COMPOSITE_MODIFICATION)).findFirst().orElseThrow(); - assertNotNull(insertedComposite); - checkCompositeModificationContent(insertedComposite.getModifications()); - } - - @Test - void testNetworkCompositeModificationWithMissingInfo() throws Exception { - // Insert some switch modifications in the group - int modificationsNumber = 2; - List modificationList = createSomeSwitchModifications(TEST_GROUP_ID, modificationsNumber); - assertEquals(modificationsNumber, modificationRepository.getModifications(TEST_GROUP_ID, true, true).size()); - - // Create a composite modification with the switch modifications - List modificationUuids = modificationList.stream().map(ModificationInfos::getUuid).toList(); - MvcResult mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) - .content(mapper.writeValueAsString(modificationUuids)).contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andReturn(); - UUID compositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - - // Create another composite modification - List otherModificationList = createSomeSwitchModifications(TEST_GROUP2_ID, modificationsNumber); - List otherModificationUuids = otherModificationList.stream().map(ModificationInfos::getUuid).toList(); - mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) - .content(mapper.writeValueAsString(otherModificationUuids)).contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andReturn(); - UUID otherCompositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - - UUID nonExistingUuid1 = UUID.randomUUID(); - UUID nonExistingUuid2 = UUID.randomUUID(); - - // Test with mixed existing/non-existing UUIDs - mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + "/network-modifications-with-missing-info") - .param("uuids", compositeModificationUuid.toString()) - .param("uuids", nonExistingUuid1.toString()) - .param("uuids", otherCompositeModificationUuid.toString()) - .param("uuids", nonExistingUuid2.toString())) - .andExpect(status().isOk()) - .andReturn(); - - NetworkModificationsWithMissingInfo result = mapper.readValue( - mvcResult.getResponse().getContentAsString(), - new TypeReference<>() { }); - - // Verify network modifications are returned for existing composite modifications - assertEquals(modificationsNumber * 2, result.networkModifications().size()); - assertNotNull(((EquipmentAttributeModificationInfos) result.networkModifications().get(0)).getEquipmentAttributeName()); - assertNotNull(((EquipmentAttributeModificationInfos) result.networkModifications().get(0)).getEquipmentAttributeValue()); - - // Verify missing UUIDs are reported - assertEquals(2, result.missingCompositeModifications().size()); - assertTrue(result.missingCompositeModifications().contains(nonExistingUuid1)); - assertTrue(result.missingCompositeModifications().contains(nonExistingUuid2)); - } - - private static void checkCompositeModificationContent(List compositeModificationContent) { - assertEquals("open", ((EquipmentAttributeModificationInfos) compositeModificationContent.getFirst()).getEquipmentAttributeName()); - assertEquals(Boolean.TRUE, ((EquipmentAttributeModificationInfos) compositeModificationContent.getFirst()).getEquipmentAttributeValue()); - assertEquals(IdentifiableType.SWITCH, ((EquipmentAttributeModificationInfos) compositeModificationContent.getFirst()).getEquipmentType()); - assertEquals("v1b1", ((EquipmentAttributeModificationInfos) compositeModificationContent.getFirst()).getEquipmentId()); - } - - /** - * TODO : Remove this test after the final integration of root networks - * Need to use tne new test with modificationContextInfos DTO (see above) - */ - @Test - void testNetworkCompositeModificationOld() throws Exception { - // Insert some switch modifications in the group - int modificationsNumber = 2; - List modificationList = createSomeSwitchModifications(TEST_GROUP_ID, modificationsNumber); - assertEquals(modificationsNumber, modificationRepository.getModifications(TEST_GROUP_ID, true, true).size()); - - // Create a composite modification with the switch modification - List modificationUuids = modificationList.stream().map(ModificationInfos::getUuid).toList(); - MvcResult mvcResult; - mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) - .content(mapper.writeValueAsString(modificationUuids)).contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andReturn(); - ModificationInfos compositeModificationInfos = CompositeModificationInfos.builder() - .modifications(modificationList) - .build(); - UUID compositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - assertThat(modificationRepository.getModificationInfo(compositeModificationUuid)).recursivelyEquals(compositeModificationInfos); - assertEquals(modificationsNumber, modificationRepository.getModifications(TEST_GROUP_ID, true, true).size()); - - // get the composite modification (metadata only) - mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + "/network-modifications?uuids={id}", compositeModificationUuid)) - .andExpect(status().isOk()).andReturn(); - List compositeModificationContent = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - assertEquals(modificationsNumber, compositeModificationContent.size()); - assertNotNull(compositeModificationContent.get(0).getMessageType()); - assertNotNull(compositeModificationContent.get(0).getMessageValues()); - assertNull(((EquipmentAttributeModificationInfos) compositeModificationContent.get(0)).getEquipmentAttributeName()); - assertNull(((EquipmentAttributeModificationInfos) compositeModificationContent.get(0)).getEquipmentAttributeValue()); - assertNull(((EquipmentAttributeModificationInfos) compositeModificationContent.get(0)).getEquipmentType()); - assertNull(((EquipmentAttributeModificationInfos) compositeModificationContent.get(0)).getEquipmentId()); - - // get the composite modification (complete data) - mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + "/network-modifications?uuids={id}&onlyMetadata=false", compositeModificationUuid)) - .andExpect(status().isOk()).andReturn(); - compositeModificationContent = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - checkCompositeModificationContent(compositeModificationContent); - final String bodyJson = getJsonBodyModificationsToCopyInfos( - List.of(ModificationsToCopyInfos.builder().uuid(compositeModificationUuid).build()), - NetworkCreation.VARIANT_ID); - // Insert the composite modification in the group - mvcResult = runRequestAsync(mockMvc, put("/v1/groups/" + TEST_GROUP_ID + "?action=SPLIT_COMPOSITE").content(bodyJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); - - assertApplicationStatusOK(mvcResult); - - List newModificationList = modificationRepository.getModifications(TEST_GROUP_ID, false, true); - assertEquals(modificationsNumber * 2, newModificationList.size()); - List newModificationUuidList = newModificationList.stream().map(ModificationInfos::getUuid).toList(); - assertEquals(modificationUuids.get(0), newModificationUuidList.get(0)); - assertThat(modificationList.get(0)).recursivelyEquals(newModificationList.get(modificationsNumber)); - } - @Test void testMoveModificationBetweenTwoGroups() throws Exception { String substationS3 = network.getLoad("v5load").getTerminal().getVoltageLevel().getSubstation().get().getId(); @@ -1110,9 +882,7 @@ void testMoveModificationBetweenTwoGroups() throws Exception { // cut origin[0] and append to destination List movingModificationUuidList = List.of(originSingleModification); - List movingModificationList = movingModificationUuidList.stream().map( - uuid -> ModificationsToCopyInfos.builder().uuid(uuid).build()).toList(); - String bodyJson = getJsonBodyModificationsToCopyInfos(movingModificationList, NetworkCreation.VARIANT_ID); + String bodyJson = getJsonBody(movingModificationUuidList, NetworkCreation.VARIANT_ID); String url = "/v1/groups/" + TEST_GROUP_ID + "?action=MOVE" + "&originGroupUuid=" + TEST_GROUP2_ID + "&build=true"; MvcResult mvcResult = runRequestAsync(mockMvc, put(url).content(bodyJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); @@ -1150,8 +920,8 @@ void testMoveModificationWithUnexistingId() throws Exception { stream().map(ModificationInfos::getUuid).collect(Collectors.toList()); // try to move an unexisting modification before [0]: no error, no change - List movingModificationList = List.of(ModificationsToCopyInfos.builder().uuid(UUID.randomUUID()).build()); - String bodyJson = getJsonBodyModificationsToCopyInfos(movingModificationList, NetworkCreation.VARIANT_ID); + List movingModificationUuidList = List.of(UUID.randomUUID()); + String bodyJson = getJsonBody(movingModificationUuidList, NetworkCreation.VARIANT_ID); String url = "/v1/groups/" + TEST_GROUP_ID + "?action=MOVE" + "&originGroupUuid=" + TEST_GROUP_ID + "&before=" + modificationUuidList.get(0); mockMvc.perform(put(url).content(bodyJson) @@ -1159,7 +929,7 @@ void testMoveModificationWithUnexistingId() throws Exception { .andExpect(status().isOk()); var newModificationUuidList = modificationRepository.getModifications(TEST_GROUP_ID, true, true). - stream().map(ModificationInfos::getUuid).collect(Collectors.toList()); + stream().map(ModificationInfos::getUuid).toList(); assertNotNull(newModificationUuidList); // nothing has changed in modification group assertEquals(modificationUuidList, newModificationUuidList); @@ -1169,7 +939,7 @@ void testMoveModificationWithUnexistingId() throws Exception { void testDuplicateModificationGroup() throws Exception { MvcResult mvcResult; VoltageLevelCreationInfos vl1 = ModificationCreation.getCreationVoltageLevel("s1", "vl1Id", "vl1Name"); - String bodyJson = getJsonBody(vl1, TEST_NETWORK_BUS_BREAKER_ID, null); + String bodyJson = TestUtils.getJsonBody(vl1, TEST_NETWORK_BUS_BREAKER_ID, null); runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(bodyJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); // create new line in voltage levels with node/breaker topology @@ -1199,7 +969,7 @@ void testDuplicateModificationGroup() throws Exception { ) ) .build(); - bodyJson = getJsonBody(lineCreationInfos, TEST_NETWORK_BUS_BREAKER_ID, null); + bodyJson = TestUtils.getJsonBody(lineCreationInfos, TEST_NETWORK_BUS_BREAKER_ID, null); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(bodyJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); @@ -1218,7 +988,7 @@ void testDuplicateModificationGroup() throws Exception { LineAttachToVoltageLevelInfos lineAttachToVL = new LineAttachToVoltageLevelInfos("line3", 10.0, "AttPointId", "attPointName", null, null, "v4", "1.A", attachmentLine, "nl1", "NewLine1", "nl2", "NewLine2"); - String bodyJson2 = getJsonBody(lineAttachToVL, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String bodyJson2 = TestUtils.getJsonBody(lineAttachToVL, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(bodyJson2).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); @@ -1227,12 +997,12 @@ void testDuplicateModificationGroup() throws Exception { //create a lineSplit LineSplitWithVoltageLevelInfos lineSplitWoVL = new LineSplitWithVoltageLevelInfos("line1", 10.0, null, "v4", "1.A", "nl11", "NewLine11", "nl12", "NewLine12"); - bodyJson2 = getJsonBody(lineSplitWoVL, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + bodyJson2 = TestUtils.getJsonBody(lineSplitWoVL, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(bodyJson2).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); //create a generator GeneratorCreationInfos generatorCreationInfos = ModificationCreation.getCreationGenerator("v2", "idGenerator1", "nameGenerator1", "1B", "v2load", "LOAD", "v1"); - bodyJson2 = getJsonBody(generatorCreationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + bodyJson2 = TestUtils.getJsonBody(generatorCreationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(bodyJson2).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); testNetworkModificationsCount(TEST_GROUP_ID, 5); @@ -1269,7 +1039,7 @@ void testDuplicateModificationGroup() throws Exception { void replaceTeePointByVoltageLevelOnLineDuplicateModificationGroupTest() throws Exception { LinesAttachToSplitLinesInfos linesAttachToSplitLinesInfos = new LinesAttachToSplitLinesInfos("l1", "l2", "l3", "v4", "bbs4", "nl1", "NewLine1", "nl2", "NewLine2"); - String body = getJsonBody(linesAttachToSplitLinesInfos, TEST_NETWORK_WITH_TEE_POINT_ID, null); + String body = TestUtils.getJsonBody(linesAttachToSplitLinesInfos, TEST_NETWORK_WITH_TEE_POINT_ID, null); MvcResult mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(body).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); @@ -1298,7 +1068,7 @@ void testGroupDuplication() throws Exception { .connectionDirection(ConnectablePosition.Direction.BOTTOM) .connectionName("bottom") .build(); - String loadCreationInfosJson = getJsonBody(loadCreationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String loadCreationInfosJson = TestUtils.getJsonBody(loadCreationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); MvcResult mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(loadCreationInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); assertNotNull(network.getLoad("idLoad1")); // load was created @@ -1326,7 +1096,7 @@ void testTombstonedEquipmentInfos() throws Exception { .equipmentType(IdentifiableType.LOAD) .equipmentId("v1load") .build(); - String equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); + String equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); // delete load mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); @@ -1339,7 +1109,7 @@ void testTombstonedEquipmentInfos() throws Exception { // Only the modification should be added in the database but the load cannot be deleted equipmentDeletionInfos.setEquipmentType(IdentifiableType.LOAD); equipmentDeletionInfos.setEquipmentId("v3load"); - equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VARIANT_NOT_EXISTING_ID); + equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VARIANT_NOT_EXISTING_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); Optional networkModificationsResult = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); assertTrue(networkModificationsResult.isPresent()); @@ -1352,7 +1122,7 @@ void testTombstonedEquipmentInfos() throws Exception { // delete shunt compensator equipmentDeletionInfos.setEquipmentType(IdentifiableType.SHUNT_COMPENSATOR); equipmentDeletionInfos.setEquipmentId("v2shunt"); - equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); + equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); testConnectableDeletionImpacts(mvcResult.getResponse().getContentAsString(), IdentifiableType.SHUNT_COMPENSATOR, "v2shunt", "v2bshunt", "v2dshunt", "s1"); @@ -1361,7 +1131,7 @@ void testTombstonedEquipmentInfos() throws Exception { // delete generator equipmentDeletionInfos.setEquipmentType(IdentifiableType.GENERATOR); equipmentDeletionInfos.setEquipmentId("idGenerator"); - equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); + equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); testConnectableDeletionImpacts(mvcResult.getResponse().getContentAsString(), IdentifiableType.GENERATOR, "idGenerator", "v2bgenerator", "v2dgenerator", "s1"); @@ -1370,7 +1140,7 @@ void testTombstonedEquipmentInfos() throws Exception { // delete line equipmentDeletionInfos.setEquipmentType(IdentifiableType.LINE); equipmentDeletionInfos.setEquipmentId("line2"); - equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); + equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); testBranchDeletionImpacts(mvcResult.getResponse().getContentAsString(), IdentifiableType.LINE, "line2", "v1bl2", "v1dl2", "s1", "v3bl2", "v3dl2", "s2"); @@ -1379,7 +1149,7 @@ void testTombstonedEquipmentInfos() throws Exception { // delete two windings transformer equipmentDeletionInfos.setEquipmentType(IdentifiableType.TWO_WINDINGS_TRANSFORMER); equipmentDeletionInfos.setEquipmentId("trf1"); - equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); + equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); testBranchDeletionImpacts(mvcResult.getResponse().getContentAsString(), IdentifiableType.TWO_WINDINGS_TRANSFORMER, "trf1", "v1btrf1", "v1dtrf1", "s1", "v2btrf1", "v2dtrf1", "s1"); @@ -1388,7 +1158,7 @@ void testTombstonedEquipmentInfos() throws Exception { // delete three windings transformer equipmentDeletionInfos.setEquipmentType(IdentifiableType.THREE_WINDINGS_TRANSFORMER); equipmentDeletionInfos.setEquipmentId("trf6"); - equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); + equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); test3WTDeletionImpacts(mvcResult.getResponse().getContentAsString(), "trf6", "v1btrf6", "v1dtrf6", "v2btrf6", "v2dtrf6", "v4btrf6", "v4dtrf6", "s1"); @@ -1397,7 +1167,7 @@ void testTombstonedEquipmentInfos() throws Exception { // delete static var compensator equipmentDeletionInfos.setEquipmentType(IdentifiableType.STATIC_VAR_COMPENSATOR); equipmentDeletionInfos.setEquipmentId("v3Compensator"); - equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); + equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); testConnectableDeletionImpacts(mvcResult.getResponse().getContentAsString(), IdentifiableType.STATIC_VAR_COMPENSATOR, "v3Compensator", "v3bCompensator", "v3dCompensator", "s2"); @@ -1406,7 +1176,7 @@ void testTombstonedEquipmentInfos() throws Exception { // delete battery equipmentDeletionInfos.setEquipmentType(IdentifiableType.BATTERY); equipmentDeletionInfos.setEquipmentId("v3Battery"); - equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); + equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); testConnectableDeletionImpacts(mvcResult.getResponse().getContentAsString(), IdentifiableType.BATTERY, "v3Battery", "v3bBattery", "v3dBattery", "s2"); @@ -1415,7 +1185,7 @@ void testTombstonedEquipmentInfos() throws Exception { // delete dangling line equipmentDeletionInfos.setEquipmentType(IdentifiableType.DANGLING_LINE); equipmentDeletionInfos.setEquipmentId("v2Dangling"); - equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); + equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); testConnectableDeletionImpacts(mvcResult.getResponse().getContentAsString(), IdentifiableType.DANGLING_LINE, "v2Dangling", "v2bdangling", "v2ddangling", "s1"); @@ -1424,7 +1194,7 @@ void testTombstonedEquipmentInfos() throws Exception { // delete hvdc line => also delete converter stations equipmentDeletionInfos.setEquipmentType(IdentifiableType.HVDC_LINE); equipmentDeletionInfos.setEquipmentId("hvdcLine"); - equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); + equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); List expectedImpacts = createMultipleDeletionImpacts( @@ -1442,7 +1212,7 @@ void testTombstonedEquipmentInfos() throws Exception { // delete voltage level equipmentDeletionInfos.setEquipmentType(IdentifiableType.VOLTAGE_LEVEL); equipmentDeletionInfos.setEquipmentId("v5"); - equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); + equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); expectedImpacts = createMultipleDeletionImpacts( @@ -1459,7 +1229,7 @@ void testTombstonedEquipmentInfos() throws Exception { // delete substation equipmentDeletionInfos.setEquipmentType(IdentifiableType.SUBSTATION); equipmentDeletionInfos.setEquipmentId("s3"); - equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); + equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); expectedImpacts = createMultipleDeletionImpacts( @@ -1477,7 +1247,7 @@ void testTombstonedEquipmentInfos() throws Exception { // delete substation with lines equipmentDeletionInfos.setEquipmentType(IdentifiableType.SUBSTATION); equipmentDeletionInfos.setEquipmentId("s2"); - equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); + equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, VariantManagerConstants.INITIAL_VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); expectedImpacts = new ArrayList<>(); @@ -1934,7 +1704,7 @@ void testDeleteStashedNetworkModifications() throws Exception { .equipmentAttributeName("v1load") .equipmentId("v1load") .build(); - String loadModificationInfosJson = getJsonBody(loadModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); + String loadModificationInfosJson = TestUtils.getJsonBody(loadModificationInfos, TEST_NETWORK_ID, NetworkCreation.VARIANT_ID); mvcResult = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(loadModificationInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult); @@ -1959,133 +1729,17 @@ void testGetModificationsCount() throws Exception { mvcResult = mockMvc.perform(get("/v1/groups/{groupUuid}/network-modifications-count", TEST_GROUP_ID) .queryParam("stashed", "false")) .andExpect(status().isOk()).andReturn(); - assertEquals(3, Integer.valueOf(mvcResult.getResponse().getContentAsString()).intValue()); + assertEquals(3, Integer.parseInt(mvcResult.getResponse().getContentAsString())); mvcResult = mockMvc.perform(get("/v1/groups/{groupUuid}/network-modifications-count", TEST_GROUP_ID) .queryParam("stashed", "true")) .andExpect(status().isOk()).andReturn(); - assertEquals(0, Integer.valueOf(mvcResult.getResponse().getContentAsString()).intValue()); + assertEquals(0, Integer.parseInt(mvcResult.getResponse().getContentAsString())); //Test for stashed parameter default value mvcResult = mockMvc.perform(get("/v1/groups/{groupUuid}/network-modifications-count", TEST_GROUP_ID)) .andExpect(status().isOk()).andReturn(); - assertEquals(3, Integer.valueOf(mvcResult.getResponse().getContentAsString()).intValue()); - } - - @Test - void testDuplicateCompositeModification() throws Exception { - // Create a composite modification with the modification - List modificationList = createSomeSwitchModifications(TEST_GROUP_ID, 1); - List modificationUuidList = modificationList.stream().map(ModificationInfos::getUuid).toList(); - MvcResult mvcResult; - mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) - .content(mapper.writeValueAsString(modificationUuidList)).contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andReturn(); - UUID compositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - - // Duplicate it without group ownership - mvcResult = mockMvc.perform( - post(URI_COMPOSITE_NETWORK_MODIF_BASE + "/duplication") - .content(objectWriter.writeValueAsString(List.of(compositeModificationUuid))) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andReturn(); - - Map returnedMap = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - assertEquals(1, returnedMap.size()); - Map.Entry returnedIds = returnedMap.entrySet().stream().findFirst().get(); - UUID returnedSourceId = returnedIds.getKey(); - UUID returnedNewId = returnedIds.getValue(); - assertNotEquals(returnedSourceId, returnedNewId); - assertEquals(compositeModificationUuid, returnedSourceId); - - ModificationInfos sourceModificationInfos = modificationRepository.getModificationInfo(compositeModificationUuid); - ModificationInfos newModificationInfos = modificationRepository.getModificationInfo(returnedNewId); - // compare duplicate with the source (same data except uuid) - assertThat(sourceModificationInfos).recursivelyEquals(newModificationInfos); - // source group has not changed - List groupModifications = modificationRepository.getModifications(TEST_GROUP_ID, true, true, false); - assertEquals(1, groupModifications.size()); - assertEquals(modificationUuidList.get(0), groupModifications.get(0).getUuid()); - - // now delete the duplicate modification - mockMvc.perform(delete(URI_NETWORK_MODIF_BASE) - .queryParam("uuids", returnedNewId.toString())) - .andExpect(status().isOk()); - - // source group has not changed - groupModifications = modificationRepository.getModifications(TEST_GROUP_ID, true, true, false); - assertEquals(1, groupModifications.size()); - assertEquals(modificationUuidList.get(0), groupModifications.get(0).getUuid()); - // duplicate has been deleted - assertEquals("MODIFICATION_NOT_FOUND : " + returnedNewId, assertThrows(NetworkModificationException.class, () - -> modificationRepository.getModificationInfo(returnedNewId)).getMessage()); - } - - @Test - void testUpdateNetworkCompositeModification() throws Exception { - // Insert some switch modifications in the group - int modificationsNumber = 3; - List modificationList = createSomeSwitchModifications(TEST_GROUP_ID, modificationsNumber); - assertEquals(modificationsNumber, modificationRepository.getModifications(TEST_GROUP_ID, true, true).size()); - - // Create a composite modification with the switch modifications - List modificationUuids = modificationList.stream().map(ModificationInfos::getUuid).toList(); - MvcResult mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) - .content(mapper.writeValueAsString(modificationUuids)).contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andReturn(); - UUID compositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - - // Create new modifications to use in the update - int newModificationsNumber = 2; - List newModificationList = createSomeSwitchModifications(TEST_GROUP2_ID, newModificationsNumber); - List newModificationUuids = newModificationList.stream().map(ModificationInfos::getUuid).toList(); - - // Update the composite modification with the new modifications - mockMvc.perform(put(URI_COMPOSITE_NETWORK_MODIF_BASE + "/" + compositeModificationUuid) - .content(mapper.writeValueAsString(newModificationUuids)).contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); - - // Get the composite modification content and verify it has been updated - mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + "/network-modifications?uuids={id}&onlyMetadata=false", compositeModificationUuid)) - .andExpect(status().isOk()).andReturn(); - List updatedCompositeContent = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - - assertEquals(newModificationsNumber, updatedCompositeContent.size()); - } - - @Test - void testUpdateNetworkCompositeModificationWithNonexistentUuid() throws Exception { - // Try to update a composite modification that doesn't exist - UUID nonExistentUuid = UUID.randomUUID(); - List modificationUuids = List.of(UUID.randomUUID()); - - mockMvc.perform(put(URI_COMPOSITE_NETWORK_MODIF_BASE + "/" + nonExistentUuid) - .content(mapper.writeValueAsString(modificationUuids)).contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isNotFound()); - } - - @Test - void testUpdateNetworkCompositeModificationWithEmptyList() throws Exception { - // Create a composite modification with some modifications - List modificationList = createSomeSwitchModifications(TEST_GROUP_ID, 2); - List modificationUuids = modificationList.stream().map(ModificationInfos::getUuid).toList(); - - MvcResult mvcResult = mockMvc.perform(post(URI_COMPOSITE_NETWORK_MODIF_BASE) - .content(mapper.writeValueAsString(modificationUuids)).contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andReturn(); - UUID compositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - - // Update the composite with an empty list of modifications - mockMvc.perform(put(URI_COMPOSITE_NETWORK_MODIF_BASE + "/" + compositeModificationUuid) - .content(mapper.writeValueAsString(Collections.emptyList())).contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); - - // Verify that the composite now contains no modifications - mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + "/network-modifications?uuids={id}&onlyMetadata=false", compositeModificationUuid)) - .andExpect(status().isOk()).andReturn(); - List updatedCompositeContent = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); - - assertTrue(updatedCompositeContent.isEmpty()); + assertEquals(3, Integer.parseInt(mvcResult.getResponse().getContentAsString())); } @Test @@ -2151,13 +1805,13 @@ void testSearchModificationInfos() throws Exception { .equipmentId("s1") .equipmentName(AttributeModification.toAttributeModification("newSubstationName", OperationType.SET)) .build(); - String substationModificationInfosJson = getJsonBody(substationModificationInfos, TEST_NETWORK_ID, null); + String substationModificationInfosJson = TestUtils.getJsonBody(substationModificationInfos, TEST_NETWORK_ID, null); MvcResult mvcResult1 = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(substationModificationInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertApplicationStatusOK(mvcResult1); // Generator Creation ID : v2 GeneratorCreationInfos generatorCreationInfos = ModificationCreation.getCreationGenerator("v2", "idGenerator1", "nameGenerator1", "1B", "v2load", "LOAD", "v1"); - String generatorCreationInfosJson = getJsonBody(generatorCreationInfos, TEST_NETWORK_ID, null); + String generatorCreationInfosJson = TestUtils.getJsonBody(generatorCreationInfos, TEST_NETWORK_ID, null); MvcResult mvcResult2 = runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(generatorCreationInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); assertNotNull(network.getGenerator("idGenerator1")); assertApplicationStatusOK(mvcResult2); @@ -2167,7 +1821,7 @@ void testSearchModificationInfos() throws Exception { .equipmentType(IdentifiableType.LOAD) .equipmentId("v5load") .build(); - String equipmentDeletionInfosJson = getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, null); + String equipmentDeletionInfosJson = TestUtils.getJsonBody(equipmentDeletionInfos, TEST_NETWORK_ID, null); runRequestAsync(mockMvc, post(NETWORK_MODIFICATION_URI).content(equipmentDeletionInfosJson).contentType(MediaType.APPLICATION_JSON), status().isOk()); MvcResult mvcModificationResult; Map> networkModificationsResult; diff --git a/src/test/java/org/gridsuite/modification/server/modifications/AbstractNetworkModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/AbstractNetworkModificationTest.java index ee5bf3a8d..bb38c72ed 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/AbstractNetworkModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/AbstractNetworkModificationTest.java @@ -17,7 +17,6 @@ import com.powsybl.network.store.client.PreloadingStrategy; import com.powsybl.network.store.iidm.impl.NetworkImpl; import org.gridsuite.modification.dto.ModificationInfos; -import org.gridsuite.modification.dto.ModificationsToCopyInfos; import org.gridsuite.modification.server.dto.NetworkModificationResult; import org.gridsuite.modification.server.dto.NetworkModificationsResult; import org.gridsuite.modification.server.entities.ModificationEntity; @@ -47,7 +46,6 @@ import java.util.stream.Collectors; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; -import static org.gridsuite.modification.server.utils.TestUtils.getJsonBodyModificationsToCopyInfos; import static org.gridsuite.modification.server.utils.assertions.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; @@ -249,10 +247,7 @@ public void testCopy() throws Exception { UUID modificationUuid = saveModification(modificationToCopy); - final String body = getJsonBodyModificationsToCopyInfos( - List.of(ModificationsToCopyInfos.builder().uuid(modificationUuid).build()), - AbstractNetworkModificationTest.TEST_NETWORK_ID, - null); + String body = TestUtils.getJsonBody(List.of(modificationUuid), AbstractNetworkModificationTest.TEST_NETWORK_ID, null); ResultActions mockMvcResultActions = mockMvc.perform(put(URI_NETWORK_MODIF_COPY) .content(body) .contentType(MediaType.APPLICATION_JSON)) 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 b69352209..893e13b5b 100644 --- a/src/test/java/org/gridsuite/modification/server/service/ModificationIndexationTest.java +++ b/src/test/java/org/gridsuite/modification/server/service/ModificationIndexationTest.java @@ -37,6 +37,7 @@ import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.util.Pair; import org.springframework.test.context.bean.override.mockito.MockitoBean; import java.util.*; @@ -307,10 +308,13 @@ 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, "")), + List.of(new ModificationApplicationContext(networkInfos.getNetworkUuuid(), variant2, UUID.randomUUID(), UUID.randomUUID())) + ); NetworkModificationsResult modificationsResult = networkModificationService.splitCompositeModifications( groupUuid2, - List.of(compositeUuid), - List.of(new ModificationApplicationContext(networkInfos.getNetworkUuuid(), variant2, UUID.randomUUID(), UUID.randomUUID())) + modificationContextInfos ).join(); /* diff --git a/src/test/java/org/gridsuite/modification/server/utils/ApiUtils.java b/src/test/java/org/gridsuite/modification/server/utils/ApiUtils.java index 3e34eedb1..58d55602b 100644 --- a/src/test/java/org/gridsuite/modification/server/utils/ApiUtils.java +++ b/src/test/java/org/gridsuite/modification/server/utils/ApiUtils.java @@ -10,7 +10,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.gridsuite.modification.dto.ModificationInfos; -import org.gridsuite.modification.dto.ModificationsToCopyInfos; import org.gridsuite.modification.server.dto.ModificationApplicationContext; import org.gridsuite.modification.server.dto.NetworkModificationResult; import org.gridsuite.modification.server.dto.NetworkModificationsResult; @@ -78,9 +77,7 @@ public static Optional putGroupsDuplications(MockMvc public static NetworkModificationsResult putGroupsWithCopy(MockMvc mockMvc, UUID targetGroupUuid, List modificationUuids, UUID networkUuid) throws Exception { ModificationApplicationContext applicationContext = new ModificationApplicationContext(networkUuid, UUID.randomUUID().toString(), UUID.randomUUID(), UUID.randomUUID(), Set.of()); - List modifications = modificationUuids.stream().map( - uuid -> ModificationsToCopyInfos.builder().uuid(uuid).build()).toList(); - String body = getObjectMapper().writeValueAsString(org.springframework.data.util.Pair.of(modifications, List.of(applicationContext))); + String body = getObjectMapper().writeValueAsString(org.springframework.data.util.Pair.of(modificationUuids, List.of(applicationContext))); ResultActions mockMvcResultActions = mockMvc.perform( put("/v1/groups/{groupUuid}", targetGroupUuid) diff --git a/src/test/java/org/gridsuite/modification/server/utils/TestUtils.java b/src/test/java/org/gridsuite/modification/server/utils/TestUtils.java index 4dc31289b..d9971e2f8 100644 --- a/src/test/java/org/gridsuite/modification/server/utils/TestUtils.java +++ b/src/test/java/org/gridsuite/modification/server/utils/TestUtils.java @@ -21,13 +21,13 @@ import mockwebserver3.MockWebServer; import org.apache.commons.text.StringSubstitutor; import org.gridsuite.modification.dto.ModificationInfos; -import org.gridsuite.modification.dto.ModificationsToCopyInfos; import org.gridsuite.modification.server.dto.*; import org.gridsuite.modification.server.modifications.NetworkModificationApplicator; import org.gridsuite.modification.server.service.ReportService; import org.junit.platform.commons.util.StringUtils; import org.mockito.ArgumentCaptor; import org.springframework.cloud.stream.binder.test.OutputDestination; +import org.springframework.data.util.Pair; import org.springframework.test.web.servlet.*; import java.io.IOException; @@ -227,7 +227,7 @@ public static String getJsonBody(List uuids, UUID networkUuid, String vari return createJsonPayload(uuids, networkUuid, variantId); } - public static String getJsonBodyModificationsToCopyInfos(List modifs, UUID networkUuid, String variantId) throws JsonProcessingException { + public static String getJsonBodyModificationCompositeInfos(List> modifs, UUID networkUuid, String variantId) throws JsonProcessingException { return createJsonPayload(modifs, networkUuid, variantId); }