From a7cbf1a00fec8c6bf740a62a5b2ef51289b13710 Mon Sep 17 00:00:00 2001 From: Franck LECUYER Date: Wed, 28 Jan 2026 11:53:49 +0100 Subject: [PATCH 1/2] Change endpoint to get modifications from composite modifications, using an UUID list instead of a single UUID. Signed-off-by: Franck LECUYER --- .../server/NetworkModificationController.java | 10 +++++----- .../NetworkModificationRepository.java | 16 ++++++++++------ .../service/NetworkModificationService.java | 6 +++--- .../server/ModificationControllerTest.java | 14 +++++++------- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java b/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java index 8ca2a1e9a..bc0503889 100644 --- a/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java +++ b/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java @@ -224,14 +224,14 @@ public ResponseEntity createNetworkCompositeModification(@RequestBody List return ResponseEntity.ok().body(networkModificationService.createNetworkCompositeModification(modificationUuids)); } - @GetMapping(value = "/network-composite-modification/{uuid}/network-modifications", produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Get the list of the network modifications inside a composite modification") - @ApiResponse(responseCode = "200", description = "List of the modifications inside the composite modification") - public ResponseEntity> getNetworkModificationsFromComposite(@PathVariable("uuid") UUID compositeModificationUuid, + @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(compositeModificationUuid, onlyMetadata) + .body(networkModificationService.getNetworkModificationsFromComposite(compositeModificationUuids, onlyMetadata) ); } 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 b56fd5dcf..b40ac4bdc 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java @@ -514,19 +514,23 @@ private List getModificationsInfosNonTransactional(List } /** - * returns the data from all the network modifications contained in the composite modification sent as parameter + * returns the data from all the network modifications contained in the composite modifications sent as parameter * but only returns the basic data common to all the modifications form the ModificationInfos, not from the extended classes */ @Transactional(readOnly = true) - public List getBasicNetworkModificationsFromComposite(@NonNull UUID uuid) { - List networkModificationsUuids = modificationRepository.findModificationIdsByCompositeModificationId(uuid); - Map entitiesById = modificationRepository.findBaseDataByIdIn(networkModificationsUuids).stream() + public List getBasicNetworkModificationsFromComposite(@NonNull List uuids) { + List result = new ArrayList<>(); + uuids.forEach(uuid -> { + List networkModificationsUuids = modificationRepository.findModificationIdsByCompositeModificationId(uuid); + Map entitiesById = modificationRepository.findBaseDataByIdIn(networkModificationsUuids).stream() .collect(Collectors.toMap(ModificationEntity::getId, Function.identity())); - return networkModificationsUuids.stream() + result.addAll(networkModificationsUuids.stream() .map(entitiesById::get) .filter(Objects::nonNull) .map(this::toModificationsInfosOptimizedForTabular) - .toList(); + .toList()); + }); + return result; } @Transactional(readOnly = true) 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 476bb5c16..d0487ea21 100644 --- a/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java @@ -129,11 +129,11 @@ public void verifyModifications(UUID groupUuid, Set modificationUuids) { } @Transactional(readOnly = true) - public List getNetworkModificationsFromComposite(UUID compositeModificationUuid, boolean onlyMetadata) { + public List getNetworkModificationsFromComposite(List compositeModificationUuids, boolean onlyMetadata) { if (onlyMetadata) { - return networkModificationRepository.getBasicNetworkModificationsFromComposite(compositeModificationUuid); + return networkModificationRepository.getBasicNetworkModificationsFromComposite(compositeModificationUuids); } else { - return networkModificationRepository.getCompositeModificationsInfos(List.of(compositeModificationUuid)); + return networkModificationRepository.getCompositeModificationsInfos(compositeModificationUuids); } } diff --git a/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java b/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java index c5c9c8c9f..ba0a1829a 100644 --- a/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java +++ b/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java @@ -106,7 +106,7 @@ class ModificationControllerTest { 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-modification/"; + 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"; @@ -809,7 +809,7 @@ void testNetworkCompositeModification() throws Exception { 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 + compositeModificationUuid + "/network-modifications")) + 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()); @@ -824,7 +824,7 @@ void testNetworkCompositeModification() throws Exception { assertNull(((EquipmentAttributeModificationInfos) compositeModificationContent.get(0)).getEquipmentId()); // get the composite modification (complete data) - mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + compositeModificationUuid + "/network-modifications?onlyMetadata=false")) + 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<>() { }); assertEquals("open", ((EquipmentAttributeModificationInfos) compositeModificationContent.get(0)).getEquipmentAttributeName()); @@ -870,7 +870,7 @@ void testNetworkCompositeModificationOld() throws Exception { 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 + compositeModificationUuid + "/network-modifications")) + 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()); @@ -882,7 +882,7 @@ void testNetworkCompositeModificationOld() throws Exception { assertNull(((EquipmentAttributeModificationInfos) compositeModificationContent.get(0)).getEquipmentId()); // get the composite modification (complete data) - mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + compositeModificationUuid + "/network-modifications?onlyMetadata=false")) + 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<>() { }); assertEquals("open", ((EquipmentAttributeModificationInfos) compositeModificationContent.get(0)).getEquipmentAttributeName()); @@ -1793,7 +1793,7 @@ void testUpdateNetworkCompositeModification() throws Exception { .andExpect(status().isOk()); // Get the composite modification content and verify it has been updated - mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + compositeModificationUuid + "/network-modifications?onlyMetadata=false")) + 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<>() { }); @@ -1828,7 +1828,7 @@ void testUpdateNetworkCompositeModificationWithEmptyList() throws Exception { .andExpect(status().isOk()); // Verify that the composite now contains no modifications - mvcResult = mockMvc.perform(get(URI_GET_COMPOSITE_NETWORK_MODIF_CONTENT + compositeModificationUuid + "/network-modifications?onlyMetadata=false")) + 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<>() { }); From c7e3aee1b134a458c5dde28a2facf745168a6d15 Mon Sep 17 00:00:00 2001 From: Franck LECUYER Date: Mon, 2 Feb 2026 15:28:22 +0100 Subject: [PATCH 2/2] Changes after review Signed-off-by: Franck LECUYER --- .../repositories/ModificationRepository.java | 3 +++ .../NetworkModificationRepository.java | 20 ++++++++----------- .../server/ModificationControllerTest.java | 20 ++++++++++++++++++- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/gridsuite/modification/server/repositories/ModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/ModificationRepository.java index b17666ffa..2ee765f40 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/ModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/ModificationRepository.java @@ -62,6 +62,9 @@ public interface ModificationRepository extends JpaRepository findModificationIdsByCompositeModificationId(UUID uuid); + @Query(value = "SELECT cast(modification_id AS VARCHAR) FROM composite_modification_sub_modifications WHERE id IN (?1) ORDER BY modifications_order", nativeQuery = true) + List findModificationIdsByCompositeModificationIdIn(List uuids); + Integer countByGroupIdAndStashed(UUID groupId, boolean stashed); @Query(value = "SELECT cast(operational_limits_groups_id AS VARCHAR) FROM line_modification_operational_limits_groups WHERE branch_id IN ?1", nativeQuery = true) 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 b40ac4bdc..57c201a97 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java @@ -519,18 +519,14 @@ private List getModificationsInfosNonTransactional(List */ @Transactional(readOnly = true) public List getBasicNetworkModificationsFromComposite(@NonNull List uuids) { - List result = new ArrayList<>(); - uuids.forEach(uuid -> { - List networkModificationsUuids = modificationRepository.findModificationIdsByCompositeModificationId(uuid); - Map entitiesById = modificationRepository.findBaseDataByIdIn(networkModificationsUuids).stream() - .collect(Collectors.toMap(ModificationEntity::getId, Function.identity())); - result.addAll(networkModificationsUuids.stream() - .map(entitiesById::get) - .filter(Objects::nonNull) - .map(this::toModificationsInfosOptimizedForTabular) - .toList()); - }); - return result; + List networkModificationsUuids = modificationRepository.findModificationIdsByCompositeModificationIdIn(uuids); + Map entitiesById = modificationRepository.findBaseDataByIdIn(networkModificationsUuids).stream() + .collect(Collectors.toMap(ModificationEntity::getId, Function.identity())); + return new ArrayList<>(networkModificationsUuids.stream() + .map(entitiesById::get) + .filter(Objects::nonNull) + .map(this::toModificationsInfosOptimizedForTabular) + .toList()); } @Transactional(readOnly = true) diff --git a/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java b/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java index ba0a1829a..4ec138b38 100644 --- a/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java +++ b/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java @@ -805,9 +805,9 @@ void testNetworkCompositeModification() throws Exception { UUID compositeModificationUuid = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); assertThat(modificationRepository.getModificationInfo(compositeModificationUuid)).recursivelyEquals(compositeModificationInfos); - // get the modification infos (metadata only) 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(); @@ -823,6 +823,24 @@ void testNetworkCompositeModification() throws Exception { 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();