From fdd3458d95ccd32e5f6823fb4cbf2069bd22ed11 Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Tue, 7 May 2024 15:48:46 +0200 Subject: [PATCH 01/17] [GridDyna] Add some batch CRUD endpoints --- pom.xml | 2 +- .../filter/server/FilterController.java | 29 ++++++++ .../filter/server/FilterService.java | 69 +++++++++++-------- .../server/repositories/FilterRepository.java | 3 + .../AbstractFilterRepositoryProxy.java | 12 +++- 5 files changed, 82 insertions(+), 33 deletions(-) diff --git a/pom.xml b/pom.xml index f303696e..f2d8910a 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ 2.9.0 4.3.1 org.gridsuite.filter.server - 1.0.5 + 1.1.0-SNAPSHOT diff --git a/src/main/java/org/gridsuite/filter/server/FilterController.java b/src/main/java/org/gridsuite/filter/server/FilterController.java index 59371a21..b2a18276 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterController.java +++ b/src/main/java/org/gridsuite/filter/server/FilterController.java @@ -74,6 +74,16 @@ public ResponseEntity createFilter(@RequestParam("id") UUID filt .body(service.createFilter(filter)); } + @PostMapping(value = "/filters", consumes = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Create filters with provided uuids") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters has been successfully created")}) + public ResponseEntity> createFilters(@RequestBody Map filtersToCreateMap) { + filtersToCreateMap.forEach((uuid, expertFilter) -> expertFilter.setId(uuid)); + return ResponseEntity.ok() + .contentType(MediaType.APPLICATION_JSON) + .body(service.createFilters(filtersToCreateMap.values().stream().toList())); + } + @PostMapping(value = "/filters", params = "duplicateFrom") @Operation(summary = "Duplicate a filter") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The filter has been successfully created"), @@ -85,6 +95,17 @@ public ResponseEntity duplicateFilter(@RequestParam("duplicateFrom") UUID .orElse(ResponseEntity.notFound().build()); } + @PostMapping(value = "/filters", params = "duplicateFrom") + @Operation(summary = "Duplicate filters from provided uuids") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters has been successfully created"), + @ApiResponse(responseCode = "404", description = "Source filter not found")}) + public ResponseEntity> duplicateFilters(@RequestBody List filterUuids) { + Map uuidsMap = service.duplicateFilters(filterUuids); + return ResponseEntity.ok() + .contentType(MediaType.APPLICATION_JSON) + .body(uuidsMap); + } + @PutMapping(value = "/filters/{id}", consumes = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Modify a filter") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The filter has been successfully modified")}) @@ -105,6 +126,14 @@ public ResponseEntity deleteFilter(@PathVariable("id") UUID id) { return ResponseEntity.ok().build(); } + @DeleteMapping(value = "/filters") + @Operation(summary = "delete the filters") + @ApiResponse(responseCode = "200", description = "The filters have been deleted") + public ResponseEntity deleteFilters(@RequestBody List ids) { + service.deleteFilters(ids); + return ResponseEntity.ok().build(); + } + @GetMapping(value = "/filters/metadata") @Operation(summary = "get filters metadata") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "filters metadata"), diff --git a/src/main/java/org/gridsuite/filter/server/FilterService.java b/src/main/java/org/gridsuite/filter/server/FilterService.java index dc091df0..3054ece5 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterService.java +++ b/src/main/java/org/gridsuite/filter/server/FilterService.java @@ -10,6 +10,7 @@ import com.powsybl.iidm.network.Network; import com.powsybl.network.store.client.NetworkStoreService; import com.powsybl.network.store.client.PreloadingStrategy; +import org.apache.commons.collections4.CollectionUtils; import org.gridsuite.filter.AbstractFilter; import org.gridsuite.filter.FilterLoader; import org.gridsuite.filter.IFilterAttributes; @@ -19,39 +20,11 @@ import org.gridsuite.filter.server.dto.IdsByGroup; import org.gridsuite.filter.server.entities.AbstractFilterEntity; import org.gridsuite.filter.server.repositories.FilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.BatteryFilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.BusBarSectionFilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.DanglingLineFilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.GeneratorFilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.HvdcLineFilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.LccConverterStationFilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.LineFilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.LoadFilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.ShuntCompensatorFilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.StaticVarCompensatorFilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.SubstationFilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.ThreeWindingsTransformerFilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.TwoWindingsTransformerFilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.VoltageLevelFilterRepository; -import org.gridsuite.filter.server.repositories.criteriafilter.VscConverterStationFilterRepository; +import org.gridsuite.filter.server.repositories.criteriafilter.*; import org.gridsuite.filter.server.repositories.expertfilter.ExpertFilterRepository; import org.gridsuite.filter.server.repositories.identifierlistfilter.IdentifierListFilterRepository; import org.gridsuite.filter.server.repositories.proxies.AbstractFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.BatteryFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.BusBarSectionFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.DanglingLineFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.GeneratorFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.HvdcLineFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.LccConverterStationFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.LineFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.LoadFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.ShuntCompensatorFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.StaticVarCompensatorFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.SubstationFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.ThreeWindingsTransformerFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.TwoWindingsTransformerFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.VoltageLevelFilterRepositoryProxy; -import org.gridsuite.filter.server.repositories.proxies.criteriafilter.VscConverterStationFilterRepositoryProxy; +import org.gridsuite.filter.server.repositories.proxies.criteriafilter.*; import org.gridsuite.filter.server.repositories.proxies.expertfiler.ExpertFilterRepositoryProxy; import org.gridsuite.filter.server.repositories.proxies.identifierlistfilter.IdentifierListFilterRepositoryProxy; import org.gridsuite.filter.server.repositories.proxies.scriptfilter.ScriptFilterRepositoryProxy; @@ -81,6 +54,7 @@ public class FilterService { private static final String FILTER_LIST = "Filter list "; private static final String NOT_FOUND = " not found"; + public static final String FILTER_UUIDS_NOT_FOUND = "Some filter uuids not found while duplicating filters"; private final Map> filterRepositories = new HashMap<>(); @@ -164,6 +138,14 @@ public AbstractFilter createFilter(F filter) { return getRepository(filter).insert(filter); } + @Transactional(propagation = Propagation.REQUIRED) + public List createFilters(List filters) { + if (CollectionUtils.isEmpty(filters)) { + return Collections.emptyList(); + } + return getRepository(filters.get(0)).insertAll(filters); + } + @Transactional public Optional duplicateFilter(UUID sourceFilterId) { Optional sourceFilterOptional = getFilter(sourceFilterId); @@ -177,6 +159,28 @@ public Optional duplicateFilter(UUID sourceFilterId) { return Optional.empty(); } + @Transactional + public Map duplicateFilters(List filterUuids) { + Map uuidsMap = new HashMap<>(); + + List sourceFilters = getFilters(filterUuids); + + // check whether found all + if (filterUuids.size() != sourceFilters.size()) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, FILTER_UUIDS_NOT_FOUND); + } + + List filtersToDuplicate = sourceFilters.stream().peek(sourceFilter -> { + UUID newFilterId = UUID.randomUUID(); + uuidsMap.put(sourceFilter.getId(), newFilterId); + sourceFilter.setId(newFilterId); + }).toList(); + + createFilters(filtersToDuplicate); + + return uuidsMap; + } + private AbstractFilterRepositoryProxy> getRepository(AbstractFilter filter) { if (!filter.getType().equals(FilterType.CRITERIA)) { return filterRepositories.get(filter.getType().name()); @@ -212,6 +216,11 @@ public void deleteFilter(UUID id) { } } + public void deleteFilters(List ids) { + Objects.requireNonNull(ids); + filterRepositories.values().forEach(repository -> repository.deleteAllByIds(ids)); + } + public void deleteAll() { filterRepositories.values().forEach(AbstractFilterRepositoryProxy::deleteAll); } diff --git a/src/main/java/org/gridsuite/filter/server/repositories/FilterRepository.java b/src/main/java/org/gridsuite/filter/server/repositories/FilterRepository.java index f247cee6..c61549ec 100644 --- a/src/main/java/org/gridsuite/filter/server/repositories/FilterRepository.java +++ b/src/main/java/org/gridsuite/filter/server/repositories/FilterRepository.java @@ -30,4 +30,7 @@ public interface FilterRepository extends JpaRep @Transactional Integer removeById(UUID id); + + @Transactional + void deleteAllByIdIn(List ids); } diff --git a/src/main/java/org/gridsuite/filter/server/repositories/proxies/AbstractFilterRepositoryProxy.java b/src/main/java/org/gridsuite/filter/server/repositories/proxies/AbstractFilterRepositoryProxy.java index 7f48aa0d..fa038f46 100644 --- a/src/main/java/org/gridsuite/filter/server/repositories/proxies/AbstractFilterRepositoryProxy.java +++ b/src/main/java/org/gridsuite/filter/server/repositories/proxies/AbstractFilterRepositoryProxy.java @@ -8,11 +8,10 @@ package org.gridsuite.filter.server.repositories.proxies; import com.powsybl.commons.PowsyblException; - import org.gridsuite.filter.AbstractFilter; import org.gridsuite.filter.criteriafilter.*; import org.gridsuite.filter.server.dto.FilterAttributes; -import org.gridsuite.filter.server.entities.*; +import org.gridsuite.filter.server.entities.AbstractFilterEntity; import org.gridsuite.filter.server.entities.criteriafilter.*; import org.gridsuite.filter.server.repositories.FilterMetadata; import org.gridsuite.filter.server.repositories.FilterRepository; @@ -123,6 +122,11 @@ public AbstractFilter insert(AbstractFilter f) { return toDto(getRepository().save(fromDto(f))); } + public List insertAll(List filters) { + List savedFilterEntities = getRepository().saveAll(filters.stream().map(this::fromDto).toList()); + return savedFilterEntities.stream().map(this::toDto).toList(); + } + public void modify(UUID id, AbstractFilter f) { f.setId(id); toDto(getRepository().save(fromDto(f))); @@ -132,6 +136,10 @@ public boolean deleteById(UUID id) { return getRepository().removeById(id) != 0; } + public void deleteAllByIds(List ids) { + getRepository().deleteAllByIdIn(ids); + } + public void deleteAll() { getRepository().deleteAll(); } From 6a29931993c906d8cfa2e79473055afc6dc19904 Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Tue, 7 May 2024 16:19:47 +0200 Subject: [PATCH 02/17] Set to current version of filter library --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f2d8910a..f303696e 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ 2.9.0 4.3.1 org.gridsuite.filter.server - 1.1.0-SNAPSHOT + 1.0.5 From 3680536afde135b38563bd5367c6518ef7b49b01 Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Tue, 7 May 2024 17:30:55 +0200 Subject: [PATCH 03/17] Update URI path --- .../java/org/gridsuite/filter/server/FilterController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/gridsuite/filter/server/FilterController.java b/src/main/java/org/gridsuite/filter/server/FilterController.java index b2a18276..995eef51 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterController.java +++ b/src/main/java/org/gridsuite/filter/server/FilterController.java @@ -74,7 +74,7 @@ public ResponseEntity createFilter(@RequestParam("id") UUID filt .body(service.createFilter(filter)); } - @PostMapping(value = "/filters", consumes = MediaType.APPLICATION_JSON_VALUE) + @PostMapping(value = "/filters/batch", consumes = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Create filters with provided uuids") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters has been successfully created")}) public ResponseEntity> createFilters(@RequestBody Map filtersToCreateMap) { @@ -95,7 +95,7 @@ public ResponseEntity duplicateFilter(@RequestParam("duplicateFrom") UUID .orElse(ResponseEntity.notFound().build()); } - @PostMapping(value = "/filters", params = "duplicateFrom") + @PostMapping(value = "/filters/batch") @Operation(summary = "Duplicate filters from provided uuids") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters has been successfully created"), @ApiResponse(responseCode = "404", description = "Source filter not found")}) From dcebe97693577526d445cecc7ca7c521fbb14807 Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Thu, 6 Jun 2024 12:16:58 +0200 Subject: [PATCH 04/17] Add tests for new endpoints --- .../filter/server/FilterController.java | 6 +- .../server/FilterEntityControllerTest.java | 142 ++++++++++++++++-- 2 files changed, 136 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/gridsuite/filter/server/FilterController.java b/src/main/java/org/gridsuite/filter/server/FilterController.java index 995eef51..9929219f 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterController.java +++ b/src/main/java/org/gridsuite/filter/server/FilterController.java @@ -86,7 +86,7 @@ public ResponseEntity> createFilters(@RequestBody Map duplicateFilter(@RequestParam("duplicateFrom") UUID filterId) { return service.duplicateFilter(filterId).map(newFilterId -> ResponseEntity.ok() @@ -95,9 +95,9 @@ public ResponseEntity duplicateFilter(@RequestParam("duplicateFrom") UUID .orElse(ResponseEntity.notFound().build()); } - @PostMapping(value = "/filters/batch") + @PostMapping(value = "/filters/batch/duplicate") @Operation(summary = "Duplicate filters from provided uuids") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters has been successfully created"), + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The map of sourceUuid and newUuid of duplicated filters"), @ApiResponse(responseCode = "404", description = "Source filter not found")}) public ResponseEntity> duplicateFilters(@RequestBody List filterUuids) { Map uuidsMap = service.duplicateFilters(filterUuids); diff --git a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java index 63f9d909..ddf5ac0f 100644 --- a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java +++ b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java @@ -25,6 +25,7 @@ import jakarta.servlet.ServletException; import org.apache.commons.collections4.OrderedMap; import org.apache.commons.collections4.map.LinkedMap; +import org.assertj.core.api.Assertions; import org.gridsuite.filter.AbstractFilter; import org.gridsuite.filter.IFilterAttributes; import org.gridsuite.filter.criteriafilter.DanglingLineFilter; @@ -39,7 +40,9 @@ import org.gridsuite.filter.server.repositories.proxies.AbstractFilterRepositoryProxy; import org.gridsuite.filter.server.utils.FieldsMatcher; import org.gridsuite.filter.server.utils.MatcherJson; -import org.gridsuite.filter.utils.*; +import org.gridsuite.filter.utils.EquipmentType; +import org.gridsuite.filter.utils.FilterType; +import org.gridsuite.filter.utils.RangeType; import org.gridsuite.filter.utils.expertfilter.CombinatorType; import org.gridsuite.filter.utils.expertfilter.FieldType; import org.gridsuite.filter.utils.expertfilter.OperatorType; @@ -64,6 +67,7 @@ import org.springframework.util.MultiValueMap; import java.util.*; +import java.util.stream.Stream; import static org.apache.commons.lang3.StringUtils.join; import static org.gridsuite.filter.server.repositories.proxies.AbstractFilterRepositoryProxy.WRONG_FILTER_TYPE; @@ -716,9 +720,27 @@ public void testDuplicateFilter() throws Exception { modificationDate, lineFilter ); + + // --- insert filter --- // insertFilter(filterId1, lineCriteriaFilter); - mvc.perform(post("/" + FilterApi.API_VERSION + "/filters?duplicateFrom=" + filterId1)).andExpect(status().isOk()); + + // check the inserted filter checkFormFilter(filterId1, lineCriteriaFilter); + + // --- duplicate filter -- // + UUID newFilterId1 = duplicateFilter(filterId1); + + // check the duplicated filter whether it is matched to the original + lineCriteriaFilter.setId(newFilterId1); + checkFormFilter(newFilterId1, lineCriteriaFilter); + + // --- delete filters --- // + deleteFilter(filterId1); + deleteFilter(newFilterId1); + + // check empty after delete all + List allFilters = getAllFilters(); + Assertions.assertThat(allFilters).isEmpty(); } @Test @@ -1041,7 +1063,7 @@ private void checkExpertFilterExportAndMetadata(UUID filterId, String expectedJs assertEquals(FilterType.EXPERT, filterAttributes.get(0).getType()); assertEquals(equipmentType, filterAttributes.get(0).getEquipmentType()); - mvc.perform(delete(URL_TEMPLATE + "/" + filterId)).andExpect(status().isOk()); + deleteFilter(filterId); } private void checkFilterEvaluating(AbstractFilter filter, String expectedJson) throws Exception { @@ -1061,6 +1083,47 @@ private AbstractFilter insertFilter(UUID filterId, AbstractFilter filter) throws return objectMapper.readValue(response, AbstractFilter.class); } + private List insertFilters(Map filtersToCreateMap) throws Exception { + String response = mvc.perform(post(URL_TEMPLATE + "/batch") + .content(objectMapper.writeValueAsString(filtersToCreateMap)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + return objectMapper.readValue(response, new TypeReference<>() { }); + } + + private UUID duplicateFilter(UUID filterId) throws Exception { + String response = mvc.perform(post("/" + FilterApi.API_VERSION + "/filters?duplicateFrom=" + filterId)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + return objectMapper.readValue(response, UUID.class); + } + + private Map duplicateFilters(List sourceFilterUuids) throws Exception { + String response = mvc.perform(post(URL_TEMPLATE + "/batch/duplicate") + .content(objectMapper.writeValueAsString(sourceFilterUuids)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + return objectMapper.readValue(response, new TypeReference<>() { }); + } + + private void deleteFilter(UUID filterId) throws Exception { + mvc.perform(delete(URL_TEMPLATE + "/" + filterId)).andExpect(status().isOk()); + } + + private void deleteFilters(List filterUuids) throws Exception { + mvc.perform(delete(URL_TEMPLATE) + .content(objectMapper.writeValueAsString(filterUuids)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + private List getAllFilters() throws Exception { + String response = mvc.perform(get(URL_TEMPLATE) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + return objectMapper.readValue(response, new TypeReference<>() { }); + } + private void modifyFormFilter(UUID filterId, AbstractFilter newFilter, String userId) throws Exception { mvc.perform(put(URL_TEMPLATE + "/" + filterId) .content(objectMapper.writeValueAsString(newFilter)) @@ -1165,7 +1228,7 @@ private void insertInjectionFilter(EquipmentType equipmentType, UUID id, String .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) .andExpect(content().json(expectedJsonExport)); - mvc.perform(delete(URL_TEMPLATE + "/" + id)).andExpect(status().isOk()); + deleteFilter(id); } private void insertTransformerFilter(EquipmentType equipmentType, UUID id, String equipmentID, String equipmentName, @@ -1224,7 +1287,7 @@ private void insertTransformerFilter(EquipmentType equipmentType, UUID id, Strin .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) .andExpect(content().json(expectedJsonExport)); - mvc.perform(delete(URL_TEMPLATE + "/" + id)).andExpect(status().isOk()); + deleteFilter(id); } private void insertHvdcLineFilter(UUID id, String equipmentID, String equipmentName, @@ -1273,7 +1336,7 @@ private void insertHvdcLineFilter(UUID id, String equipmentID, String equipmentN .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) .andExpect(content().json(expectedJsonExport)); - mvc.perform(delete(URL_TEMPLATE + "/" + id)).andExpect(status().isOk()); + deleteFilter(id); filterAttributes = objectMapper.readValue( mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/metadata?ids={id}", id) @@ -1333,7 +1396,7 @@ private CriteriaFilter insertLineFilter(UUID id, String equipmentID, String equi .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) .andExpect(content().json(expectedJsonExport)); if (delete) { - mvc.perform(delete(URL_TEMPLATE + "/" + id)).andExpect(status().isOk()); + deleteFilter(id); } return filter; } @@ -1379,7 +1442,7 @@ private void insertVoltageLevelFilter(UUID id, String equipmentID, String equipm .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) .andExpect(content().json(expectedJsonExport)); - mvc.perform(delete(URL_TEMPLATE + "/" + id)).andExpect(status().isOk()); + deleteFilter(id); } private void insertSubstationFilter(UUID id, String equipmentID, String equipmentName, Set countries, @@ -1420,7 +1483,7 @@ private void insertSubstationFilter(UUID id, String equipmentID, String equipmen .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) .andExpect(content().json(expectedJsonExport)); - mvc.perform(delete(URL_TEMPLATE + "/" + id)).andExpect(status().isOk()); + deleteFilter(id); } private void checkFormFilter(UUID filterId, CriteriaFilter criteriaFilter) throws Exception { @@ -1994,4 +2057,65 @@ public void testExpertFilterLoadLinkToOtherFilterWithIsPartOfOperator() throws E checkExpertFilterExportAndMetadata(expertFilterId, expectedResultJson, EquipmentType.LOAD); checkFilterEvaluating(expertFilter, expectedResultJson); } + + @Test + public void testDuplicateFiltersInBatch() throws Exception { + UUID filterId1 = UUID.randomUUID(); + LineFilter lineFilter1 = LineFilter.builder().equipmentID("equipmentID1").equipmentName("equipmentName1") + .substationName1("substationName1") + .substationName2("substationName2").countries1(COUNTRIES1).countries2(COUNTRIES2) + .nominalVoltage1(new NumericalFilter(RangeType.RANGE, 5., 8.)) + .nominalVoltage2(new NumericalFilter(RangeType.EQUALITY, 6., null)) + .build(); + CriteriaFilter lineCriteriaFilter1 = new CriteriaFilter( + filterId1, + new Date(), + lineFilter1 + ); + + UUID filterId2 = UUID.randomUUID(); + LineFilter lineFilter2 = LineFilter.builder().equipmentID("equipmentID2").equipmentName("equipmentName2") + .substationName1("substationName3").countries1(COUNTRIES1).countries2(COUNTRIES2) + .substationName2("substationName4") + .nominalVoltage1(new NumericalFilter(RangeType.RANGE, 4., 9.)) + .nominalVoltage2(new NumericalFilter(RangeType.EQUALITY, 5., null)) + .build(); + CriteriaFilter lineCriteriaFilter2 = new CriteriaFilter( + filterId2, + new Date(), + lineFilter2 + ); + + Map filtersToCreateMap = Map.of( + filterId1, lineCriteriaFilter1, + filterId2, lineCriteriaFilter2 + ); + + // --- insert in batch --- // + insertFilters(filtersToCreateMap); + + // check inserted filters + checkFormFilter(filterId1, lineCriteriaFilter1); + checkFormFilter(filterId2, lineCriteriaFilter2); + + // --- duplicate in batch --- // + Map sourceAndNewUuidMap = duplicateFilters(List.of(filterId1, filterId2)); + + sourceAndNewUuidMap.forEach((sourceUuid, newUuid) -> filtersToCreateMap.get(sourceUuid).setId(newUuid)); + + // check each duplicated filter whether it is matched to the original + for (Map.Entry entry : sourceAndNewUuidMap.entrySet()) { + UUID sourceUuid = entry.getKey(); + UUID newUuid = entry.getValue(); + checkFormFilter(newUuid, (CriteriaFilter) filtersToCreateMap.get(sourceUuid)); + } + + // --- delete filters in batch -- // + deleteFilters(Stream.concat(sourceAndNewUuidMap.keySet().stream(), sourceAndNewUuidMap.values().stream()).toList()); + + // check empty after delete all + List allFilters = getAllFilters(); + Assertions.assertThat(allFilters).isEmpty(); + } + } From c50873785497ef6fd5b18e2d158e28527bad2416 Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Thu, 6 Jun 2024 12:39:13 +0200 Subject: [PATCH 05/17] Sonar --- .../org/gridsuite/filter/server/FilterService.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/gridsuite/filter/server/FilterService.java b/src/main/java/org/gridsuite/filter/server/FilterService.java index 3054ece5..0e582f64 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterService.java +++ b/src/main/java/org/gridsuite/filter/server/FilterService.java @@ -130,7 +130,7 @@ public List getFilters(List ids) { .stream() .flatMap(repository -> repository.getFilters(ids) .stream()) - .collect(Collectors.toList()); + .toList(); } @Transactional(propagation = Propagation.REQUIRED) @@ -166,17 +166,17 @@ public Map duplicateFilters(List filterUuids) { List sourceFilters = getFilters(filterUuids); // check whether found all - if (filterUuids.size() != sourceFilters.size()) { + if (sourceFilters.isEmpty() || sourceFilters.size() != filterUuids.size()) { throw new ResponseStatusException(HttpStatus.NOT_FOUND, FILTER_UUIDS_NOT_FOUND); } - List filtersToDuplicate = sourceFilters.stream().peek(sourceFilter -> { + sourceFilters.forEach(sourceFilter -> { UUID newFilterId = UUID.randomUUID(); uuidsMap.put(sourceFilter.getId(), newFilterId); sourceFilter.setId(newFilterId); - }).toList(); + }); - createFilters(filtersToDuplicate); + getRepository(sourceFilters.get(0)).insertAll(sourceFilters); return uuidsMap; } From 1190a4b7af6e7f51ab1b0b91f28a40a3063cf00a Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Tue, 11 Jun 2024 15:50:38 +0200 Subject: [PATCH 06/17] Add modify all endpoint --- .../filter/server/FilterController.java | 9 +++ .../filter/server/FilterService.java | 70 +++++++++++++++++-- .../AbstractFilterRepositoryProxy.java | 6 ++ 3 files changed, 81 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/gridsuite/filter/server/FilterController.java b/src/main/java/org/gridsuite/filter/server/FilterController.java index 9929219f..97d53fea 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterController.java +++ b/src/main/java/org/gridsuite/filter/server/FilterController.java @@ -118,6 +118,15 @@ public ResponseEntity changeFilter(@PathVariable UUID id, @RequestBody Abs } } + @PutMapping(value = "/filters/batch", consumes = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Modify filters in batch") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters has been successfully modified")}) + public ResponseEntity> changeFilters(@RequestBody Map filtersToModifyMap) { + return ResponseEntity.ok() + .contentType(MediaType.APPLICATION_JSON) + .body(service.changeFilters(filtersToModifyMap)); + } + @DeleteMapping(value = "/filters/{id}") @Operation(summary = "delete the filter") @ApiResponse(responseCode = "200", description = "The filter has been deleted") diff --git a/src/main/java/org/gridsuite/filter/server/FilterService.java b/src/main/java/org/gridsuite/filter/server/FilterService.java index 0e582f64..2cdceea1 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterService.java +++ b/src/main/java/org/gridsuite/filter/server/FilterService.java @@ -54,7 +54,7 @@ public class FilterService { private static final String FILTER_LIST = "Filter list "; private static final String NOT_FOUND = " not found"; - public static final String FILTER_UUIDS_NOT_FOUND = "Some filter uuids not found while duplicating filters"; + public static final String FILTER_UUIDS_NOT_FOUND = "Some filter uuids not found"; private final Map> filterRepositories = new HashMap<>(); @@ -143,7 +143,13 @@ public List createFilters(List filters) { if (CollectionUtils.isEmpty(filters)) { return Collections.emptyList(); } - return getRepository(filters.get(0)).insertAll(filters); + + Map, List> repositoryFiltersMap = filters.stream() + .collect(Collectors.groupingBy(this::getRepository)); + + List createdFilters = new ArrayList<>(); + repositoryFiltersMap.forEach((repository, subFilters) -> createdFilters.addAll(repository.insertAll(subFilters))); + return createdFilters; } @Transactional @@ -176,12 +182,16 @@ public Map duplicateFilters(List filterUuids) { sourceFilter.setId(newFilterId); }); - getRepository(sourceFilters.get(0)).insertAll(sourceFilters); + Map, List> repositoryFiltersMap = sourceFilters.stream() + .collect(Collectors.groupingBy(this::getRepository)); + + repositoryFiltersMap.forEach(AbstractFilterRepositoryProxy::insertAll); return uuidsMap; } - private AbstractFilterRepositoryProxy> getRepository(AbstractFilter filter) { + private AbstractFilterRepositoryProxy> getRepository(AbstractFilter filter) { if (!filter.getType().equals(FilterType.CRITERIA)) { return filterRepositories.get(filter.getType().name()); } @@ -209,6 +219,58 @@ public void changeFilter(UUID id, F newFilter, String notificationService.emitElementUpdated(id, userId); } + @Transactional + public List changeFilters(Map filtersToModifyMap) { + List filterUuids = filtersToModifyMap.keySet().stream().toList(); + List oldFilters = getFilters(filterUuids); + + // check whether found all + if (oldFilters.isEmpty() || oldFilters.size() != filterUuids.size()) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, FILTER_UUIDS_NOT_FOUND); + } + + // collect filters into two lists which have type changed or not changed + Map> filtersTypeNotChangedOrChanged = oldFilters.stream().collect(Collectors + .partitioningBy(oldFilter -> oldFilter.getType() == filtersToModifyMap.get(oldFilter.getId()).getType())); + List filtersTypeNotChanged = filtersTypeNotChangedOrChanged.get(Boolean.TRUE); + List filtersTypeChanged = filtersTypeNotChangedOrChanged.get(Boolean.FALSE); + + List changedFilters = new ArrayList<>(); + + // --- perform change filters which have type not changed --- // + Map, List> repositoryFiltersMap = filtersTypeNotChanged.stream() + .map(filter -> { + AbstractFilter newFilter = filtersToModifyMap.get(filter.getId()); + newFilter.setId(filter.getId()); + return newFilter; + }) + .collect(Collectors.groupingBy(this::getRepository)); + repositoryFiltersMap.forEach((repository, subFilters) -> + changedFilters.addAll(repository.modifyAll(subFilters.stream().collect(Collectors.toMap(AbstractFilter::getId, filter -> filter))))); + + // --- perform change filters which have type changed --- // + List filterTypeChangedToModify = filtersTypeChanged.stream() + .filter(filter -> filter.getType() != FilterType.SCRIPT && + filtersToModifyMap.get(filter.getId()).getType() != FilterType.SCRIPT) + .toList(); + + repositoryFiltersMap = filterTypeChangedToModify.stream() + .map(filter -> { + AbstractFilter newFilter = filtersToModifyMap.get(filter.getId()); + newFilter.setId(filter.getId()); + return newFilter; + }) + .collect(Collectors.groupingBy(this::getRepository)); + + // delete old filters which have type changed + repositoryFiltersMap.forEach((repository, subFilters) -> + repository.deleteAllByIds(subFilters.stream().map(AbstractFilter::getId).toList())); + // create new filters with existing ids + repositoryFiltersMap.forEach((repository, subFilters) -> changedFilters.addAll(repository.insertAll(subFilters))); + + return changedFilters; + } + public void deleteFilter(UUID id) { Objects.requireNonNull(id); if (filterRepositories.values().stream().noneMatch(repository -> repository.deleteById(id))) { diff --git a/src/main/java/org/gridsuite/filter/server/repositories/proxies/AbstractFilterRepositoryProxy.java b/src/main/java/org/gridsuite/filter/server/repositories/proxies/AbstractFilterRepositoryProxy.java index fa038f46..0a394bd0 100644 --- a/src/main/java/org/gridsuite/filter/server/repositories/proxies/AbstractFilterRepositoryProxy.java +++ b/src/main/java/org/gridsuite/filter/server/repositories/proxies/AbstractFilterRepositoryProxy.java @@ -132,6 +132,12 @@ public void modify(UUID id, AbstractFilter f) { toDto(getRepository().save(fromDto(f))); } + public List modifyAll(Map filtersToModifyMap) { + filtersToModifyMap.forEach((uuid, expertFilter) -> expertFilter.setId(uuid)); + List savedFilterEntities = getRepository().saveAll(filtersToModifyMap.values().stream().map(this::fromDto).toList()); + return savedFilterEntities.stream().map(this::toDto).toList(); + } + public boolean deleteById(UUID id) { return getRepository().removeById(id) != 0; } From 2251b0c95907ffde511feecf533ae04f0355dd99 Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Tue, 11 Jun 2024 18:03:09 +0200 Subject: [PATCH 07/17] Add tests --- .../filter/server/FilterService.java | 22 ++-- .../server/FilterEntityControllerTest.java | 102 ++++++++++++++++-- 2 files changed, 106 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/gridsuite/filter/server/FilterService.java b/src/main/java/org/gridsuite/filter/server/FilterService.java index 2cdceea1..dbc09073 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterService.java +++ b/src/main/java/org/gridsuite/filter/server/FilterService.java @@ -229,16 +229,16 @@ public List changeFilters(Map filtersToMod throw new ResponseStatusException(HttpStatus.NOT_FOUND, FILTER_UUIDS_NOT_FOUND); } - // collect filters into two lists which have type changed or not changed - Map> filtersTypeNotChangedOrChanged = oldFilters.stream().collect(Collectors - .partitioningBy(oldFilter -> oldFilter.getType() == filtersToModifyMap.get(oldFilter.getId()).getType())); - List filtersTypeNotChanged = filtersTypeNotChangedOrChanged.get(Boolean.TRUE); - List filtersTypeChanged = filtersTypeNotChangedOrChanged.get(Boolean.FALSE); + // collect filters into two lists which have repository changed or not changed + Map> filtersReposNotChangedOrChanged = oldFilters.stream().collect(Collectors + .partitioningBy(oldFilter -> getRepository(oldFilter) == getRepository(filtersToModifyMap.get(oldFilter.getId())))); + List filtersReposNotChanged = filtersReposNotChangedOrChanged.get(Boolean.TRUE); + List filtersReposChanged = filtersReposNotChangedOrChanged.get(Boolean.FALSE); List changedFilters = new ArrayList<>(); - // --- perform change filters which have type not changed --- // - Map, List> repositoryFiltersMap = filtersTypeNotChanged.stream() + // --- perform change filters which have repository not changed --- // + Map, List> repositoryFiltersMap = filtersReposNotChanged.stream() .map(filter -> { AbstractFilter newFilter = filtersToModifyMap.get(filter.getId()); newFilter.setId(filter.getId()); @@ -248,13 +248,13 @@ public List changeFilters(Map filtersToMod repositoryFiltersMap.forEach((repository, subFilters) -> changedFilters.addAll(repository.modifyAll(subFilters.stream().collect(Collectors.toMap(AbstractFilter::getId, filter -> filter))))); - // --- perform change filters which have type changed --- // - List filterTypeChangedToModify = filtersTypeChanged.stream() + // --- perform change filters which have repository changed --- // + List filtersReposChangedToModify = filtersReposChanged.stream() .filter(filter -> filter.getType() != FilterType.SCRIPT && filtersToModifyMap.get(filter.getId()).getType() != FilterType.SCRIPT) .toList(); - repositoryFiltersMap = filterTypeChangedToModify.stream() + repositoryFiltersMap = filtersReposChangedToModify.stream() .map(filter -> { AbstractFilter newFilter = filtersToModifyMap.get(filter.getId()); newFilter.setId(filter.getId()); @@ -262,7 +262,7 @@ public List changeFilters(Map filtersToMod }) .collect(Collectors.groupingBy(this::getRepository)); - // delete old filters which have type changed + // delete old filters which have repository changed repositoryFiltersMap.forEach((repository, subFilters) -> repository.deleteAllByIds(subFilters.stream().map(AbstractFilter::getId).toList())); // create new filters with existing ids diff --git a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java index ddf5ac0f..989db0bf 100644 --- a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java +++ b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java @@ -706,9 +706,8 @@ public void testSubstationFilter() throws Exception { } @Test - public void testDuplicateFilter() throws Exception { + public void testLineFilterCrud() throws Exception { UUID filterId1 = UUID.fromString("99999999-e0c4-413a-8e3e-78e9027d300f"); - Date modificationDate = new Date(); LineFilter lineFilter = LineFilter.builder().equipmentID("equipmentID").equipmentName("equipmentName") .substationName1("substationName1") .substationName2("substationName2").countries1(COUNTRIES1).countries2(COUNTRIES2) @@ -716,8 +715,8 @@ public void testDuplicateFilter() throws Exception { .nominalVoltage2(new NumericalFilter(RangeType.EQUALITY, 6., null)) .build(); CriteriaFilter lineCriteriaFilter = new CriteriaFilter( - filterId1, - modificationDate, + null, + new Date(), lineFilter ); @@ -725,6 +724,7 @@ public void testDuplicateFilter() throws Exception { insertFilter(filterId1, lineCriteriaFilter); // check the inserted filter + lineCriteriaFilter.setId(filterId1); checkFormFilter(filterId1, lineCriteriaFilter); // --- duplicate filter -- // @@ -734,6 +734,41 @@ public void testDuplicateFilter() throws Exception { lineCriteriaFilter.setId(newFilterId1); checkFormFilter(newFilterId1, lineCriteriaFilter); + // --- modify filter --- // + LineFilter lineFilter2 = LineFilter.builder().equipmentID("equipmentID").equipmentName("equipmentName") + .substationName1("substationName1") + .substationName2("substationName2").countries1(COUNTRIES2).countries2(COUNTRIES1) + .nominalVoltage1(new NumericalFilter(RangeType.RANGE, 4., 9.)) + .nominalVoltage2(new NumericalFilter(RangeType.EQUALITY, 5., null)) + .build(); + CriteriaFilter lineCriteriaFilter2 = new CriteriaFilter( + null, + new Date(), + lineFilter2 + ); + modifyFilter(filterId1, lineCriteriaFilter2, "userId"); + + // check the modified filter + lineCriteriaFilter2.setId(filterId1); + checkFormFilter(filterId1, lineCriteriaFilter2); + + // --- modify filter with equipment type changed --- // + GeneratorFilter generatorFilter = GeneratorFilter.builder().equipmentID("eqId1").equipmentName("gen1") + .substationName("s1") + .countries(new TreeSet<>(Set.of("FR", "BE"))) + .nominalVoltage(new NumericalFilter(RangeType.RANGE, 50., null)) + .build(); + CriteriaFilter generatorCriteriaFilter = new CriteriaFilter( + null, + new Date(), + generatorFilter + ); + modifyFilter(filterId1, generatorCriteriaFilter, "userId"); + + // check the modified filter + generatorCriteriaFilter.setId(filterId1); + checkFormFilter(filterId1, generatorCriteriaFilter); + // --- delete filters --- // deleteFilter(filterId1); deleteFilter(newFilterId1); @@ -1106,6 +1141,23 @@ private Map duplicateFilters(List sourceFilterUuids) throws Ex return objectMapper.readValue(response, new TypeReference<>() { }); } + private void modifyFilter(UUID filterId, AbstractFilter filter, String userId) throws Exception { + mvc.perform(put(URL_TEMPLATE + "/" + filterId) + .content(objectMapper.writeValueAsString(filter)) + .contentType(APPLICATION_JSON) + .header(USER_ID_HEADER, userId)) + .andExpect(status().isOk()); + checkElementUpdatedMessageSent(filterId, userId); + } + + private List modifyFilters(Map filtersToModifyMap) throws Exception { + String response = mvc.perform(put(URL_TEMPLATE + "/batch") + .content(objectMapper.writeValueAsString(filtersToModifyMap)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + return objectMapper.readValue(response, new TypeReference<>() { }); + } + private void deleteFilter(UUID filterId) throws Exception { mvc.perform(delete(URL_TEMPLATE + "/" + filterId)).andExpect(status().isOk()); } @@ -2059,7 +2111,7 @@ public void testExpertFilterLoadLinkToOtherFilterWithIsPartOfOperator() throws E } @Test - public void testDuplicateFiltersInBatch() throws Exception { + public void testLineFiltersCrudInBatch() throws Exception { UUID filterId1 = UUID.randomUUID(); LineFilter lineFilter1 = LineFilter.builder().equipmentID("equipmentID1").equipmentName("equipmentName1") .substationName1("substationName1") @@ -2068,7 +2120,7 @@ public void testDuplicateFiltersInBatch() throws Exception { .nominalVoltage2(new NumericalFilter(RangeType.EQUALITY, 6., null)) .build(); CriteriaFilter lineCriteriaFilter1 = new CriteriaFilter( - filterId1, + null, new Date(), lineFilter1 ); @@ -2081,7 +2133,7 @@ public void testDuplicateFiltersInBatch() throws Exception { .nominalVoltage2(new NumericalFilter(RangeType.EQUALITY, 5., null)) .build(); CriteriaFilter lineCriteriaFilter2 = new CriteriaFilter( - filterId2, + null, new Date(), lineFilter2 ); @@ -2095,7 +2147,9 @@ public void testDuplicateFiltersInBatch() throws Exception { insertFilters(filtersToCreateMap); // check inserted filters + lineCriteriaFilter1.setId(filterId1); checkFormFilter(filterId1, lineCriteriaFilter1); + lineCriteriaFilter2.setId(filterId2); checkFormFilter(filterId2, lineCriteriaFilter2); // --- duplicate in batch --- // @@ -2110,6 +2164,40 @@ public void testDuplicateFiltersInBatch() throws Exception { checkFormFilter(newUuid, (CriteriaFilter) filtersToCreateMap.get(sourceUuid)); } + // --- modify filters in batch --- // + LineFilter lineFilter3 = LineFilter.builder().equipmentID("equipmentID").equipmentName("equipmentName") + .substationName1("substationName1") + .substationName2("substationName2").countries1(COUNTRIES2).countries2(COUNTRIES1) + .nominalVoltage1(new NumericalFilter(RangeType.RANGE, 3., 10.)) + .nominalVoltage2(new NumericalFilter(RangeType.EQUALITY, 4., null)) + .build(); + CriteriaFilter lineCriteriaFilter3 = new CriteriaFilter( + null, + new Date(), + lineFilter3 + ); + GeneratorFilter generatorFilter = GeneratorFilter.builder().equipmentID("eqId1").equipmentName("gen1") + .substationName("s1") + .countries(new TreeSet<>(Set.of("FR", "BE"))) + .nominalVoltage(new NumericalFilter(RangeType.RANGE, 50., null)) + .build(); + CriteriaFilter generatorCriteriaFilter = new CriteriaFilter( + null, + new Date(), + generatorFilter + ); + Map filtersToModifyMap = Map.of( + filterId1, lineCriteriaFilter3, + filterId2, generatorCriteriaFilter + ); + modifyFilters(filtersToModifyMap); + + // check modified filters + lineCriteriaFilter3.setId(filterId1); + checkFormFilter(filterId1, lineCriteriaFilter3); + generatorCriteriaFilter.setId(filterId2); + checkFormFilter(filterId2, generatorCriteriaFilter); + // --- delete filters in batch -- // deleteFilters(Stream.concat(sourceAndNewUuidMap.keySet().stream(), sourceAndNewUuidMap.values().stream()).toList()); From c0ac2fcfe70da191e3ff7084823fb5cc86d27d48 Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Tue, 18 Jun 2024 13:25:07 +0200 Subject: [PATCH 08/17] Update to filter library 1.0.8 --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index a0fdd650..de4b2bb1 100644 --- a/pom.xml +++ b/pom.xml @@ -101,6 +101,7 @@ org.gridsuite gridsuite-filter + 1.0.8 com.fasterxml.jackson.core From f551b4c435a76745c6a987f1830a5c6f3f535c20 Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Fri, 21 Jun 2024 20:13:56 +0200 Subject: [PATCH 09/17] Update description for endpoints --- .../org/gridsuite/filter/server/FilterController.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/gridsuite/filter/server/FilterController.java b/src/main/java/org/gridsuite/filter/server/FilterController.java index 97d53fea..19126aea 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterController.java +++ b/src/main/java/org/gridsuite/filter/server/FilterController.java @@ -75,8 +75,8 @@ public ResponseEntity createFilter(@RequestParam("id") UUID filt } @PostMapping(value = "/filters/batch", consumes = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Create filters with provided uuids") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters has been successfully created")}) + @Operation(summary = "Create filters from provided uuids") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters have been successfully created")}) public ResponseEntity> createFilters(@RequestBody Map filtersToCreateMap) { filtersToCreateMap.forEach((uuid, expertFilter) -> expertFilter.setId(uuid)); return ResponseEntity.ok() @@ -107,7 +107,7 @@ public ResponseEntity> duplicateFilters(@RequestBody List } @PutMapping(value = "/filters/{id}", consumes = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Modify a filter") + @Operation(summary = "Modify a filter from a provided fitler uuid and the whole new filter object") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The filter has been successfully modified")}) public ResponseEntity changeFilter(@PathVariable UUID id, @RequestBody AbstractFilter filter, @RequestHeader("userId") String userId) { try { @@ -119,8 +119,8 @@ public ResponseEntity changeFilter(@PathVariable UUID id, @RequestBody Abs } @PutMapping(value = "/filters/batch", consumes = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Modify filters in batch") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters has been successfully modified")}) + @Operation(summary = "Modify filters in batch from a provided map of each filter uuid and the corresponding whole new filter object") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters have been successfully modified")}) public ResponseEntity> changeFilters(@RequestBody Map filtersToModifyMap) { return ResponseEntity.ok() .contentType(MediaType.APPLICATION_JSON) From 54201b9c11e4491bb878611b82f82b188a8fc488 Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Mon, 1 Jul 2024 12:34:19 +0200 Subject: [PATCH 10/17] Using AssertJ recursive for test expert rules --- pom.xml | 2 +- .../ExpertFilterRepositoryProxy.java | 108 +++++++++--------- .../server/FilterEntityControllerTest.java | 5 +- .../server/utils/assertions/Assertions.java | 21 ++++ .../server/utils/assertions/DTOAssert.java | 38 ++++++ 5 files changed, 119 insertions(+), 55 deletions(-) create mode 100644 src/test/java/org/gridsuite/filter/server/utils/assertions/Assertions.java create mode 100644 src/test/java/org/gridsuite/filter/server/utils/assertions/DTOAssert.java diff --git a/pom.xml b/pom.xml index 654f3fc5..d8741aff 100644 --- a/pom.xml +++ b/pom.xml @@ -102,7 +102,7 @@ org.gridsuite gridsuite-filter - 1.0.8 + 1.1.0-SNAPSHOT com.fasterxml.jackson.core diff --git a/src/main/java/org/gridsuite/filter/server/repositories/proxies/expertfiler/ExpertFilterRepositoryProxy.java b/src/main/java/org/gridsuite/filter/server/repositories/proxies/expertfiler/ExpertFilterRepositoryProxy.java index 5d44d15f..df6caca3 100644 --- a/src/main/java/org/gridsuite/filter/server/repositories/proxies/expertfiler/ExpertFilterRepositoryProxy.java +++ b/src/main/java/org/gridsuite/filter/server/repositories/proxies/expertfiler/ExpertFilterRepositoryProxy.java @@ -23,10 +23,7 @@ import org.gridsuite.filter.utils.FilterType; import org.gridsuite.filter.utils.expertfilter.DataType; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -57,97 +54,104 @@ public AbstractFilter toDto(ExpertFilterEntity filterEntity) { .build(); } - public static AbstractExpertRule entityToDto(ExpertRuleEntity filterEntity) { - switch (filterEntity.getDataType()) { + public static AbstractExpertRule entityToDto(ExpertRuleEntity expertRuleEntity) { + switch (expertRuleEntity.getDataType()) { case COMBINATOR -> { return CombinatorExpertRule.builder() - .combinator(filterEntity.getCombinator()) - .field(filterEntity.getField()) - .operator(filterEntity.getOperator()) - .rules(entitiesToDto(filterEntity.getRules())) + .id(expertRuleEntity.getId()) + .combinator(expertRuleEntity.getCombinator()) + .field(expertRuleEntity.getField()) + .operator(expertRuleEntity.getOperator()) + .rules(entitiesToDto(expertRuleEntity.getRules())) .build(); } case BOOLEAN -> { - ExpertRuleValueEntity booleanFilterEntity = (ExpertRuleValueEntity) filterEntity; + ExpertRuleValueEntity booleanExpertRuleEntity = (ExpertRuleValueEntity) expertRuleEntity; BooleanExpertRule.BooleanExpertRuleBuilder ruleBuilder = BooleanExpertRule.builder() - .field(booleanFilterEntity.getField()) - .operator(booleanFilterEntity.getOperator()); - if (booleanFilterEntity.getValue() != null) { - ruleBuilder.value(Boolean.parseBoolean(booleanFilterEntity.getValue())); + .id(expertRuleEntity.getId()) + .field(booleanExpertRuleEntity.getField()) + .operator(booleanExpertRuleEntity.getOperator()); + if (booleanExpertRuleEntity.getValue() != null) { + ruleBuilder.value(Boolean.parseBoolean(booleanExpertRuleEntity.getValue())); } return ruleBuilder.build(); } case NUMBER -> { - ExpertRuleValueEntity numberFilterEntity = (ExpertRuleValueEntity) filterEntity; + ExpertRuleValueEntity numberExpertEntity = (ExpertRuleValueEntity) expertRuleEntity; NumberExpertRule.NumberExpertRuleBuilder ruleBuilder = NumberExpertRule.builder() - .field(filterEntity.getField()) - .operator(filterEntity.getOperator()); - if (numberFilterEntity.getValue() != null) { - if (isMultipleCriteriaOperator(numberFilterEntity.getOperator())) { // for multiple values - ruleBuilder.values(Stream.of(numberFilterEntity.getValue().split(",")).map(Double::valueOf).collect(Collectors.toSet())); + .id(expertRuleEntity.getId()) + .field(expertRuleEntity.getField()) + .operator(expertRuleEntity.getOperator()); + if (numberExpertEntity.getValue() != null) { + if (isMultipleCriteriaOperator(numberExpertEntity.getOperator())) { // for multiple values + ruleBuilder.values(Stream.of(numberExpertEntity.getValue().split(",")).map(Double::valueOf).collect(Collectors.toSet())); } else { // for single value - ruleBuilder.value(Double.valueOf(numberFilterEntity.getValue())); + ruleBuilder.value(Double.valueOf(numberExpertEntity.getValue())); } } return ruleBuilder.build(); } case STRING -> { - ExpertRuleValueEntity stringFilterEntity = (ExpertRuleValueEntity) filterEntity; + ExpertRuleValueEntity stringExpertRuleEntity = (ExpertRuleValueEntity) expertRuleEntity; StringExpertRule.StringExpertRuleBuilder ruleBuilder = StringExpertRule.builder() - .field(filterEntity.getField()) - .operator(filterEntity.getOperator()); - if (stringFilterEntity.getValue() != null) { - if (isMultipleCriteriaOperator(stringFilterEntity.getOperator())) { // for multiple values - ruleBuilder.values(Stream.of(stringFilterEntity.getValue().split(",")).collect(Collectors.toSet())); + .id(expertRuleEntity.getId()) + .field(expertRuleEntity.getField()) + .operator(expertRuleEntity.getOperator()); + if (stringExpertRuleEntity.getValue() != null) { + if (isMultipleCriteriaOperator(stringExpertRuleEntity.getOperator())) { // for multiple values + ruleBuilder.values(Stream.of(stringExpertRuleEntity.getValue().split(",")).collect(Collectors.toSet())); } else { // for single value - ruleBuilder.value(stringFilterEntity.getValue()); + ruleBuilder.value(stringExpertRuleEntity.getValue()); } } return ruleBuilder.build(); } case ENUM -> { - ExpertRuleValueEntity enumFilterEntity = (ExpertRuleValueEntity) filterEntity; + ExpertRuleValueEntity enumExpertRuleEntity = (ExpertRuleValueEntity) expertRuleEntity; EnumExpertRule.EnumExpertRuleBuilder ruleBuilder = EnumExpertRule.builder() - .field(enumFilterEntity.getField()) - .operator(enumFilterEntity.getOperator()); - if (enumFilterEntity.getValue() != null) { - if (isMultipleCriteriaOperator(enumFilterEntity.getOperator())) { // for multiple values - ruleBuilder.values(Stream.of(enumFilterEntity.getValue().split(",")).collect(Collectors.toSet())); + .id(expertRuleEntity.getId()) + .field(enumExpertRuleEntity.getField()) + .operator(enumExpertRuleEntity.getOperator()); + if (enumExpertRuleEntity.getValue() != null) { + if (isMultipleCriteriaOperator(enumExpertRuleEntity.getOperator())) { // for multiple values + ruleBuilder.values(Stream.of(enumExpertRuleEntity.getValue().split(",")).collect(Collectors.toSet())); } else { // for single value - ruleBuilder.value(enumFilterEntity.getValue()); + ruleBuilder.value(enumExpertRuleEntity.getValue()); } } return ruleBuilder.build(); } case FILTER_UUID -> { - ExpertRuleValueEntity filterUuidFilterEntity = (ExpertRuleValueEntity) filterEntity; + ExpertRuleValueEntity filterUuidExpertRuleEntity = (ExpertRuleValueEntity) expertRuleEntity; FilterUuidExpertRule.FilterUuidExpertRuleBuilder ruleBuilder = FilterUuidExpertRule.builder() - .field(filterEntity.getField()) - .operator(filterEntity.getOperator()); - if (filterUuidFilterEntity.getValue() != null) { - if (isMultipleCriteriaOperator(filterUuidFilterEntity.getOperator())) { // for multiple values - ruleBuilder.values(Stream.of(filterUuidFilterEntity.getValue().split(",")).collect(Collectors.toSet())); + .id(expertRuleEntity.getId()) + .field(expertRuleEntity.getField()) + .operator(expertRuleEntity.getOperator()); + if (filterUuidExpertRuleEntity.getValue() != null) { + if (isMultipleCriteriaOperator(filterUuidExpertRuleEntity.getOperator())) { // for multiple values + ruleBuilder.values(Stream.of(filterUuidExpertRuleEntity.getValue().split(",")).collect(Collectors.toSet())); } else { // for single value - ruleBuilder.value(filterUuidFilterEntity.getValue()); + ruleBuilder.value(filterUuidExpertRuleEntity.getValue()); } } return ruleBuilder.build(); } case PROPERTIES -> { - ExpertRulePropertiesEntity propertiesFilterEntity = (ExpertRulePropertiesEntity) filterEntity; + ExpertRulePropertiesEntity propertiesExpertRuleEntity = (ExpertRulePropertiesEntity) expertRuleEntity; return PropertiesExpertRule.builder() - .field(propertiesFilterEntity.getField()) - .operator(propertiesFilterEntity.getOperator()) - .propertyValues(propertiesFilterEntity.getPropertyValues()) - .propertyName(propertiesFilterEntity.getPropertyName()) + .id(expertRuleEntity.getId()) + .field(propertiesExpertRuleEntity.getField()) + .operator(propertiesExpertRuleEntity.getOperator()) + .propertyValues(propertiesExpertRuleEntity.getPropertyValues()) + .propertyName(propertiesExpertRuleEntity.getPropertyName()) .build(); } default -> - throw new PowsyblException("Unknown rule data type: " + filterEntity.getDataType() + ", supported data types are: " + Arrays.stream(DataType.values()).map(Enum::name).collect(Collectors.joining(", "))); + throw new PowsyblException("Unknown rule data type: " + expertRuleEntity.getDataType() + ", supported data types are: " + Arrays.stream(DataType.values()).map(Enum::name).collect(Collectors.joining(", "))); } } @@ -178,7 +182,7 @@ public ExpertFilterEntity fromDto(AbstractFilter dto) { ExpertRuleEntity.ExpertRuleEntityBuilder expertRuleEntityBuilder = null; if (filter.getDataType() == DataType.COMBINATOR) { expertRuleEntityBuilder = ExpertRuleEntity.builder() - .id(UUID.randomUUID()) + .id(Optional.ofNullable(filter.getId()).orElse(UUID.randomUUID())) .combinator(filter.getCombinator()) .operator(filter.getOperator()) .dataType(filter.getDataType()) @@ -187,7 +191,7 @@ public ExpertFilterEntity fromDto(AbstractFilter dto) { if (filter.getDataType() == DataType.PROPERTIES) { PropertiesExpertRule propertiesRule = (PropertiesExpertRule) filter; expertRuleEntityBuilder = ExpertRulePropertiesEntity.builder() - .id(UUID.randomUUID()) + .id(Optional.ofNullable(filter.getId()).orElse(UUID.randomUUID())) .combinator(filter.getCombinator()) .operator(filter.getOperator()) .dataType(filter.getDataType()) @@ -201,7 +205,7 @@ public ExpertFilterEntity fromDto(AbstractFilter dto) { filter.getDataType() == DataType.ENUM || filter.getDataType() == DataType.FILTER_UUID) { expertRuleEntityBuilder = ExpertRuleValueEntity.builder() - .id(UUID.randomUUID()) + .id(Optional.ofNullable(filter.getId()).orElse(UUID.randomUUID())) .combinator(filter.getCombinator()) .operator(filter.getOperator()) .dataType(filter.getDataType()) diff --git a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java index 989db0bf..76c483ac 100644 --- a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java +++ b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java @@ -25,7 +25,6 @@ import jakarta.servlet.ServletException; import org.apache.commons.collections4.OrderedMap; import org.apache.commons.collections4.map.LinkedMap; -import org.assertj.core.api.Assertions; import org.gridsuite.filter.AbstractFilter; import org.gridsuite.filter.IFilterAttributes; import org.gridsuite.filter.criteriafilter.DanglingLineFilter; @@ -40,6 +39,7 @@ import org.gridsuite.filter.server.repositories.proxies.AbstractFilterRepositoryProxy; import org.gridsuite.filter.server.utils.FieldsMatcher; import org.gridsuite.filter.server.utils.MatcherJson; +import org.gridsuite.filter.server.utils.assertions.Assertions; import org.gridsuite.filter.utils.EquipmentType; import org.gridsuite.filter.utils.FilterType; import org.gridsuite.filter.utils.RangeType; @@ -1586,7 +1586,8 @@ private void matchIdentifierListFilterInfos(IdentifierListFilter identifierListF private void matchExpertFilterInfos(ExpertFilter expertFilter1, ExpertFilter expertFilter2) { matchFilterInfos(expertFilter1, expertFilter2); - assertTrue(new MatcherJson<>(objectMapper, expertFilter2.getRules()).matchesSafely(expertFilter1.getRules())); + Assertions.assertThat(expertFilter1).recursivelyEquals(expertFilter2, "id", "topologyKind" /* not persisted field */); + // assertTrue(new MatcherJson<>(objectMapper, expertFilter2.getRules()).matchesSafely(expertFilter1.getRules())); } private void checkElementUpdatedMessageSent(UUID elementUuid, String userId) { diff --git a/src/test/java/org/gridsuite/filter/server/utils/assertions/Assertions.java b/src/test/java/org/gridsuite/filter/server/utils/assertions/Assertions.java new file mode 100644 index 00000000..ddf8c5a8 --- /dev/null +++ b/src/test/java/org/gridsuite/filter/server/utils/assertions/Assertions.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2024, 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.filter.server.utils.assertions; + +import org.assertj.core.util.CheckReturnValue; +import org.gridsuite.filter.expertfilter.ExpertFilter; + +/** + * @author Thang PHAM + * {@link org.assertj.core.api.Assertions Assertions} completed with our custom assertions classes. + */ +public class Assertions extends org.assertj.core.api.Assertions { + @CheckReturnValue + public static DTOAssert assertThat(T actual) { + return new DTOAssert<>(actual); + } +} diff --git a/src/test/java/org/gridsuite/filter/server/utils/assertions/DTOAssert.java b/src/test/java/org/gridsuite/filter/server/utils/assertions/DTOAssert.java new file mode 100644 index 00000000..cc6005f8 --- /dev/null +++ b/src/test/java/org/gridsuite/filter/server/utils/assertions/DTOAssert.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2024, 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.filter.server.utils.assertions; + +import org.assertj.core.api.AbstractAssert; +import org.assertj.core.api.recursive.comparison.RecursiveComparisonConfiguration; + +import java.time.Instant; +import java.util.Date; +import java.util.UUID; + +/** + * @author Thang PHAM + */ +public class DTOAssert extends AbstractAssert, T> { + public DTOAssert(T actual) { + super(actual, DTOAssert.class); + } + + public DTOAssert recursivelyEquals(T other, String... fieldsToIgnore) { + isNotNull(); + usingRecursiveComparison(this.getRecursiveConfiguration(fieldsToIgnore)).isEqualTo(other); + return myself; + } + + private RecursiveComparisonConfiguration getRecursiveConfiguration(String... fieldsToIgnore) { + return RecursiveComparisonConfiguration.builder() + .withIgnoreAllOverriddenEquals(true) // For equals test, need specific tests + .withIgnoredFieldsOfTypes(UUID.class, Date.class, Instant.class) // For these types, need specific tests (uuid from db for example) + .withIgnoreCollectionOrder(true) // For collection order test, need specific tests + .withIgnoredFields(fieldsToIgnore) + .build(); + } +} From e8236a890df41f9599729dde2fb40f98ca4a819c Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Mon, 1 Jul 2024 17:13:55 +0200 Subject: [PATCH 11/17] undo set id from dto to entity --- pom.xml | 2 +- .../ExpertFilterRepositoryProxy.java | 18 +++++++----------- .../server/FilterEntityControllerTest.java | 3 +-- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index d8741aff..faaa9dcc 100644 --- a/pom.xml +++ b/pom.xml @@ -102,7 +102,7 @@ org.gridsuite gridsuite-filter - 1.1.0-SNAPSHOT + 1.0.9 com.fasterxml.jackson.core diff --git a/src/main/java/org/gridsuite/filter/server/repositories/proxies/expertfiler/ExpertFilterRepositoryProxy.java b/src/main/java/org/gridsuite/filter/server/repositories/proxies/expertfiler/ExpertFilterRepositoryProxy.java index df6caca3..a3130ba3 100644 --- a/src/main/java/org/gridsuite/filter/server/repositories/proxies/expertfiler/ExpertFilterRepositoryProxy.java +++ b/src/main/java/org/gridsuite/filter/server/repositories/proxies/expertfiler/ExpertFilterRepositoryProxy.java @@ -23,7 +23,10 @@ import org.gridsuite.filter.utils.FilterType; import org.gridsuite.filter.utils.expertfilter.DataType; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -58,7 +61,6 @@ public static AbstractExpertRule entityToDto(ExpertRuleEntity expertRuleEntity) switch (expertRuleEntity.getDataType()) { case COMBINATOR -> { return CombinatorExpertRule.builder() - .id(expertRuleEntity.getId()) .combinator(expertRuleEntity.getCombinator()) .field(expertRuleEntity.getField()) .operator(expertRuleEntity.getOperator()) @@ -68,7 +70,6 @@ public static AbstractExpertRule entityToDto(ExpertRuleEntity expertRuleEntity) case BOOLEAN -> { ExpertRuleValueEntity booleanExpertRuleEntity = (ExpertRuleValueEntity) expertRuleEntity; BooleanExpertRule.BooleanExpertRuleBuilder ruleBuilder = BooleanExpertRule.builder() - .id(expertRuleEntity.getId()) .field(booleanExpertRuleEntity.getField()) .operator(booleanExpertRuleEntity.getOperator()); if (booleanExpertRuleEntity.getValue() != null) { @@ -79,7 +80,6 @@ public static AbstractExpertRule entityToDto(ExpertRuleEntity expertRuleEntity) case NUMBER -> { ExpertRuleValueEntity numberExpertEntity = (ExpertRuleValueEntity) expertRuleEntity; NumberExpertRule.NumberExpertRuleBuilder ruleBuilder = NumberExpertRule.builder() - .id(expertRuleEntity.getId()) .field(expertRuleEntity.getField()) .operator(expertRuleEntity.getOperator()); if (numberExpertEntity.getValue() != null) { @@ -95,7 +95,6 @@ public static AbstractExpertRule entityToDto(ExpertRuleEntity expertRuleEntity) case STRING -> { ExpertRuleValueEntity stringExpertRuleEntity = (ExpertRuleValueEntity) expertRuleEntity; StringExpertRule.StringExpertRuleBuilder ruleBuilder = StringExpertRule.builder() - .id(expertRuleEntity.getId()) .field(expertRuleEntity.getField()) .operator(expertRuleEntity.getOperator()); if (stringExpertRuleEntity.getValue() != null) { @@ -111,7 +110,6 @@ public static AbstractExpertRule entityToDto(ExpertRuleEntity expertRuleEntity) case ENUM -> { ExpertRuleValueEntity enumExpertRuleEntity = (ExpertRuleValueEntity) expertRuleEntity; EnumExpertRule.EnumExpertRuleBuilder ruleBuilder = EnumExpertRule.builder() - .id(expertRuleEntity.getId()) .field(enumExpertRuleEntity.getField()) .operator(enumExpertRuleEntity.getOperator()); if (enumExpertRuleEntity.getValue() != null) { @@ -127,7 +125,6 @@ public static AbstractExpertRule entityToDto(ExpertRuleEntity expertRuleEntity) ExpertRuleValueEntity filterUuidExpertRuleEntity = (ExpertRuleValueEntity) expertRuleEntity; FilterUuidExpertRule.FilterUuidExpertRuleBuilder ruleBuilder = FilterUuidExpertRule.builder() - .id(expertRuleEntity.getId()) .field(expertRuleEntity.getField()) .operator(expertRuleEntity.getOperator()); if (filterUuidExpertRuleEntity.getValue() != null) { @@ -143,7 +140,6 @@ public static AbstractExpertRule entityToDto(ExpertRuleEntity expertRuleEntity) case PROPERTIES -> { ExpertRulePropertiesEntity propertiesExpertRuleEntity = (ExpertRulePropertiesEntity) expertRuleEntity; return PropertiesExpertRule.builder() - .id(expertRuleEntity.getId()) .field(propertiesExpertRuleEntity.getField()) .operator(propertiesExpertRuleEntity.getOperator()) .propertyValues(propertiesExpertRuleEntity.getPropertyValues()) @@ -182,7 +178,7 @@ public ExpertFilterEntity fromDto(AbstractFilter dto) { ExpertRuleEntity.ExpertRuleEntityBuilder expertRuleEntityBuilder = null; if (filter.getDataType() == DataType.COMBINATOR) { expertRuleEntityBuilder = ExpertRuleEntity.builder() - .id(Optional.ofNullable(filter.getId()).orElse(UUID.randomUUID())) + .id(UUID.randomUUID()) .combinator(filter.getCombinator()) .operator(filter.getOperator()) .dataType(filter.getDataType()) @@ -191,7 +187,7 @@ public ExpertFilterEntity fromDto(AbstractFilter dto) { if (filter.getDataType() == DataType.PROPERTIES) { PropertiesExpertRule propertiesRule = (PropertiesExpertRule) filter; expertRuleEntityBuilder = ExpertRulePropertiesEntity.builder() - .id(Optional.ofNullable(filter.getId()).orElse(UUID.randomUUID())) + .id(UUID.randomUUID()) .combinator(filter.getCombinator()) .operator(filter.getOperator()) .dataType(filter.getDataType()) @@ -205,7 +201,7 @@ public ExpertFilterEntity fromDto(AbstractFilter dto) { filter.getDataType() == DataType.ENUM || filter.getDataType() == DataType.FILTER_UUID) { expertRuleEntityBuilder = ExpertRuleValueEntity.builder() - .id(Optional.ofNullable(filter.getId()).orElse(UUID.randomUUID())) + .id(UUID.randomUUID()) .combinator(filter.getCombinator()) .operator(filter.getOperator()) .dataType(filter.getDataType()) diff --git a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java index 76c483ac..5655f9b7 100644 --- a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java +++ b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java @@ -1586,8 +1586,7 @@ private void matchIdentifierListFilterInfos(IdentifierListFilter identifierListF private void matchExpertFilterInfos(ExpertFilter expertFilter1, ExpertFilter expertFilter2) { matchFilterInfos(expertFilter1, expertFilter2); - Assertions.assertThat(expertFilter1).recursivelyEquals(expertFilter2, "id", "topologyKind" /* not persisted field */); - // assertTrue(new MatcherJson<>(objectMapper, expertFilter2.getRules()).matchesSafely(expertFilter1.getRules())); + Assertions.assertThat(expertFilter1).recursivelyEquals(expertFilter2, "topologyKind" /* not persisted field */); } private void checkElementUpdatedMessageSent(UUID elementUuid, String userId) { From 0e8609f4d7eb269c5885122f0afc7ad7d7f4edcf Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Mon, 1 Jul 2024 20:03:39 +0200 Subject: [PATCH 12/17] Correct as suggest of Etienne --- .../filter/server/FilterController.java | 26 +++---- .../filter/server/FilterService.java | 76 ++++--------------- .../AbstractFilterRepositoryProxy.java | 10 +-- .../server/FilterEntityControllerTest.java | 16 ++-- 4 files changed, 40 insertions(+), 88 deletions(-) diff --git a/src/main/java/org/gridsuite/filter/server/FilterController.java b/src/main/java/org/gridsuite/filter/server/FilterController.java index 19126aea..9391eb21 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterController.java +++ b/src/main/java/org/gridsuite/filter/server/FilterController.java @@ -75,7 +75,7 @@ public ResponseEntity createFilter(@RequestParam("id") UUID filt } @PostMapping(value = "/filters/batch", consumes = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Create filters from provided uuids") + @Operation(summary = "Create filters from given ids") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters have been successfully created")}) public ResponseEntity> createFilters(@RequestBody Map filtersToCreateMap) { filtersToCreateMap.forEach((uuid, expertFilter) -> expertFilter.setId(uuid)); @@ -86,7 +86,7 @@ public ResponseEntity> createFilters(@RequestBody Map duplicateFilter(@RequestParam("duplicateFrom") UUID filterId) { return service.duplicateFilter(filterId).map(newFilterId -> ResponseEntity.ok() @@ -96,8 +96,8 @@ public ResponseEntity duplicateFilter(@RequestParam("duplicateFrom") UUID } @PostMapping(value = "/filters/batch/duplicate") - @Operation(summary = "Duplicate filters from provided uuids") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The map of sourceUuid and newUuid of duplicated filters"), + @Operation(summary = "Duplicate filters from given ids") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters of given ids has been successfully duplicated"), @ApiResponse(responseCode = "404", description = "Source filter not found")}) public ResponseEntity> duplicateFilters(@RequestBody List filterUuids) { Map uuidsMap = service.duplicateFilters(filterUuids); @@ -107,24 +107,24 @@ public ResponseEntity> duplicateFilters(@RequestBody List } @PutMapping(value = "/filters/{id}", consumes = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Modify a filter from a provided fitler uuid and the whole new filter object") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The filter has been successfully modified")}) - public ResponseEntity changeFilter(@PathVariable UUID id, @RequestBody AbstractFilter filter, @RequestHeader("userId") String userId) { + @Operation(summary = "Update a filter from a given id and the whole new filter object") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The filter has been successfully updated")}) + public ResponseEntity updateFilter(@PathVariable UUID id, @RequestBody AbstractFilter filter, @RequestHeader("userId") String userId) { try { - service.changeFilter(id, filter, userId); - return ResponseEntity.ok().build(); + AbstractFilter updatedFilter = service.updateFilter(id, filter, userId); + return ResponseEntity.ok().body(updatedFilter); } catch (EntityNotFoundException ignored) { return ResponseEntity.notFound().build(); } } @PutMapping(value = "/filters/batch", consumes = MediaType.APPLICATION_JSON_VALUE) - @Operation(summary = "Modify filters in batch from a provided map of each filter uuid and the corresponding whole new filter object") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters have been successfully modified")}) - public ResponseEntity> changeFilters(@RequestBody Map filtersToModifyMap) { + @Operation(summary = "Update filters in batch from a given map of each filter id and the corresponding whole new filter object") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters have been successfully updated")}) + public ResponseEntity> updateFilters(@RequestBody Map filtersToUpdateMap, @RequestHeader("userId") String userId) { return ResponseEntity.ok() .contentType(MediaType.APPLICATION_JSON) - .body(service.changeFilters(filtersToModifyMap)); + .body(service.updateFilters(filtersToUpdateMap, userId)); } @DeleteMapping(value = "/filters/{id}") diff --git a/src/main/java/org/gridsuite/filter/server/FilterService.java b/src/main/java/org/gridsuite/filter/server/FilterService.java index dbc09073..93d2de1a 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterService.java +++ b/src/main/java/org/gridsuite/filter/server/FilterService.java @@ -35,7 +35,6 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.server.ResponseStatusException; @@ -133,19 +132,19 @@ public List getFilters(List ids) { .toList(); } - @Transactional(propagation = Propagation.REQUIRED) + @Transactional public AbstractFilter createFilter(F filter) { return getRepository(filter).insert(filter); } - @Transactional(propagation = Propagation.REQUIRED) + @Transactional public List createFilters(List filters) { if (CollectionUtils.isEmpty(filters)) { return Collections.emptyList(); } Map, List> repositoryFiltersMap = filters.stream() - .collect(Collectors.groupingBy(this::getRepository)); + .collect(Collectors.groupingBy(this::getRepository)); List createdFilters = new ArrayList<>(); repositoryFiltersMap.forEach((repository, subFilters) -> createdFilters.addAll(repository.insertAll(subFilters))); @@ -199,76 +198,33 @@ public Map duplicateFilters(List filterUuids) { } @Transactional - public void changeFilter(UUID id, F newFilter, String userId) { - Optional f = getFilter(id); - if (f.isPresent()) { - if (getRepository(f.get()) == getRepository(newFilter)) { // filter type has not changed - getRepository(newFilter).modify(id, newFilter); + public AbstractFilter updateFilter(UUID id, F newFilter, String userId) { + Optional filterOpt = getFilter(id); + AbstractFilter modifiedOrCreatedFilter; + if (filterOpt.isPresent()) { + if (getRepository(filterOpt.get()) == getRepository(newFilter)) { // filter type has not changed + modifiedOrCreatedFilter = getRepository(newFilter).modify(id, newFilter); } else { // filter type has changed - if (f.get().getType() == FilterType.SCRIPT || newFilter.getType() == FilterType.SCRIPT) { + if (filterOpt.get().getType() == FilterType.SCRIPT || newFilter.getType() == FilterType.SCRIPT) { throw new PowsyblException(WRONG_FILTER_TYPE); } else { - getRepository(f.get()).deleteById(id); + getRepository(filterOpt.get()).deleteById(id); newFilter.setId(id); - createFilter(newFilter); + modifiedOrCreatedFilter = createFilter(newFilter); } } } else { throw new ResponseStatusException(HttpStatus.NOT_FOUND, FILTER_LIST + id + NOT_FOUND); } notificationService.emitElementUpdated(id, userId); + return modifiedOrCreatedFilter; } @Transactional - public List changeFilters(Map filtersToModifyMap) { - List filterUuids = filtersToModifyMap.keySet().stream().toList(); - List oldFilters = getFilters(filterUuids); - - // check whether found all - if (oldFilters.isEmpty() || oldFilters.size() != filterUuids.size()) { - throw new ResponseStatusException(HttpStatus.NOT_FOUND, FILTER_UUIDS_NOT_FOUND); - } - - // collect filters into two lists which have repository changed or not changed - Map> filtersReposNotChangedOrChanged = oldFilters.stream().collect(Collectors - .partitioningBy(oldFilter -> getRepository(oldFilter) == getRepository(filtersToModifyMap.get(oldFilter.getId())))); - List filtersReposNotChanged = filtersReposNotChangedOrChanged.get(Boolean.TRUE); - List filtersReposChanged = filtersReposNotChangedOrChanged.get(Boolean.FALSE); - - List changedFilters = new ArrayList<>(); - - // --- perform change filters which have repository not changed --- // - Map, List> repositoryFiltersMap = filtersReposNotChanged.stream() - .map(filter -> { - AbstractFilter newFilter = filtersToModifyMap.get(filter.getId()); - newFilter.setId(filter.getId()); - return newFilter; - }) - .collect(Collectors.groupingBy(this::getRepository)); - repositoryFiltersMap.forEach((repository, subFilters) -> - changedFilters.addAll(repository.modifyAll(subFilters.stream().collect(Collectors.toMap(AbstractFilter::getId, filter -> filter))))); - - // --- perform change filters which have repository changed --- // - List filtersReposChangedToModify = filtersReposChanged.stream() - .filter(filter -> filter.getType() != FilterType.SCRIPT && - filtersToModifyMap.get(filter.getId()).getType() != FilterType.SCRIPT) + public List updateFilters(Map filtersToUpdateMap, String userId) { + return filtersToUpdateMap.keySet().stream() + .map(filterUuid -> updateFilter(filterUuid, filtersToUpdateMap.get(filterUuid), userId)) .toList(); - - repositoryFiltersMap = filtersReposChangedToModify.stream() - .map(filter -> { - AbstractFilter newFilter = filtersToModifyMap.get(filter.getId()); - newFilter.setId(filter.getId()); - return newFilter; - }) - .collect(Collectors.groupingBy(this::getRepository)); - - // delete old filters which have repository changed - repositoryFiltersMap.forEach((repository, subFilters) -> - repository.deleteAllByIds(subFilters.stream().map(AbstractFilter::getId).toList())); - // create new filters with existing ids - repositoryFiltersMap.forEach((repository, subFilters) -> changedFilters.addAll(repository.insertAll(subFilters))); - - return changedFilters; } public void deleteFilter(UUID id) { diff --git a/src/main/java/org/gridsuite/filter/server/repositories/proxies/AbstractFilterRepositoryProxy.java b/src/main/java/org/gridsuite/filter/server/repositories/proxies/AbstractFilterRepositoryProxy.java index 0a394bd0..a9c66139 100644 --- a/src/main/java/org/gridsuite/filter/server/repositories/proxies/AbstractFilterRepositoryProxy.java +++ b/src/main/java/org/gridsuite/filter/server/repositories/proxies/AbstractFilterRepositoryProxy.java @@ -127,15 +127,9 @@ public List insertAll(List filters) { return savedFilterEntities.stream().map(this::toDto).toList(); } - public void modify(UUID id, AbstractFilter f) { + public AbstractFilter modify(UUID id, AbstractFilter f) { f.setId(id); - toDto(getRepository().save(fromDto(f))); - } - - public List modifyAll(Map filtersToModifyMap) { - filtersToModifyMap.forEach((uuid, expertFilter) -> expertFilter.setId(uuid)); - List savedFilterEntities = getRepository().saveAll(filtersToModifyMap.values().stream().map(this::fromDto).toList()); - return savedFilterEntities.stream().map(this::toDto).toList(); + return toDto(getRepository().save(fromDto(f))); } public boolean deleteById(UUID id) { diff --git a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java index 5655f9b7..d2d5c5bc 100644 --- a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java +++ b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java @@ -746,7 +746,7 @@ public void testLineFilterCrud() throws Exception { new Date(), lineFilter2 ); - modifyFilter(filterId1, lineCriteriaFilter2, "userId"); + updateFilter(filterId1, lineCriteriaFilter2, "userId"); // check the modified filter lineCriteriaFilter2.setId(filterId1); @@ -763,7 +763,7 @@ public void testLineFilterCrud() throws Exception { new Date(), generatorFilter ); - modifyFilter(filterId1, generatorCriteriaFilter, "userId"); + updateFilter(filterId1, generatorCriteriaFilter, "userId"); // check the modified filter generatorCriteriaFilter.setId(filterId1); @@ -1141,7 +1141,7 @@ private Map duplicateFilters(List sourceFilterUuids) throws Ex return objectMapper.readValue(response, new TypeReference<>() { }); } - private void modifyFilter(UUID filterId, AbstractFilter filter, String userId) throws Exception { + private void updateFilter(UUID filterId, AbstractFilter filter, String userId) throws Exception { mvc.perform(put(URL_TEMPLATE + "/" + filterId) .content(objectMapper.writeValueAsString(filter)) .contentType(APPLICATION_JSON) @@ -1150,11 +1150,13 @@ private void modifyFilter(UUID filterId, AbstractFilter filter, String userId) t checkElementUpdatedMessageSent(filterId, userId); } - private List modifyFilters(Map filtersToModifyMap) throws Exception { + private List updateFilters(Map filtersToUpdateMap, String userId) throws Exception { String response = mvc.perform(put(URL_TEMPLATE + "/batch") - .content(objectMapper.writeValueAsString(filtersToModifyMap)) - .contentType(APPLICATION_JSON)) + .content(objectMapper.writeValueAsString(filtersToUpdateMap)) + .contentType(APPLICATION_JSON) + .header(USER_ID_HEADER, userId)) .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + filtersToUpdateMap.keySet().forEach(filterId -> checkElementUpdatedMessageSent(filterId, userId)); return objectMapper.readValue(response, new TypeReference<>() { }); } @@ -2190,7 +2192,7 @@ public void testLineFiltersCrudInBatch() throws Exception { filterId1, lineCriteriaFilter3, filterId2, generatorCriteriaFilter ); - modifyFilters(filtersToModifyMap); + updateFilters(filtersToModifyMap, "userId"); // check modified filters lineCriteriaFilter3.setId(filterId1); From 1f22f0be3047291aeccbe1a0088fb7958fadb59a Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Mon, 1 Jul 2024 20:08:51 +0200 Subject: [PATCH 13/17] Tiny correction for description --- src/main/java/org/gridsuite/filter/server/FilterController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/gridsuite/filter/server/FilterController.java b/src/main/java/org/gridsuite/filter/server/FilterController.java index 9391eb21..c0850509 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterController.java +++ b/src/main/java/org/gridsuite/filter/server/FilterController.java @@ -97,7 +97,7 @@ public ResponseEntity duplicateFilter(@RequestParam("duplicateFrom") UUID @PostMapping(value = "/filters/batch/duplicate") @Operation(summary = "Duplicate filters from given ids") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters of given ids has been successfully duplicated"), + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters of given ids have been successfully duplicated"), @ApiResponse(responseCode = "404", description = "Source filter not found")}) public ResponseEntity> duplicateFilters(@RequestBody List filterUuids) { Map uuidsMap = service.duplicateFilters(filterUuids); From d11226a6106e56389bb9fa234ab3ea3845dfd12b Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Mon, 1 Jul 2024 21:15:01 +0200 Subject: [PATCH 14/17] Sonar Call transactional methods via an injected dependency instead of directly via 'this' --- .../org/gridsuite/filter/server/FilterService.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/gridsuite/filter/server/FilterService.java b/src/main/java/org/gridsuite/filter/server/FilterService.java index 93d2de1a..ff0b530f 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterService.java +++ b/src/main/java/org/gridsuite/filter/server/FilterService.java @@ -33,6 +33,7 @@ import org.gridsuite.filter.utils.FilterServiceUtils; import org.gridsuite.filter.utils.FilterType; import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Lazy; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -61,6 +62,8 @@ public class FilterService { private final NotificationService notificationService; + private final FilterService self; + public FilterService(final ScriptFilterRepository scriptFiltersRepository, final LineFilterRepository lineFilterRepository, final GeneratorFilterRepository generatorFilterRepository, @@ -80,7 +83,8 @@ public FilterService(final ScriptFilterRepository scriptFiltersRepository, final IdentifierListFilterRepository identifierListFilterRepository, final ExpertFilterRepository expertFilterRepository, NetworkStoreService networkStoreService, - NotificationService notificationService) { + NotificationService notificationService, + @Lazy FilterService self) { filterRepositories.put(EquipmentType.LINE.name(), new LineFilterRepositoryProxy(lineFilterRepository)); filterRepositories.put(EquipmentType.GENERATOR.name(), new GeneratorFilterRepositoryProxy(generatorFilterRepository)); filterRepositories.put(EquipmentType.LOAD.name(), new LoadFilterRepositoryProxy(loadFilterRepository)); @@ -104,6 +108,7 @@ public FilterService(final ScriptFilterRepository scriptFiltersRepository, filterRepositories.put(FilterType.EXPERT.name(), new ExpertFilterRepositoryProxy(expertFilterRepository)); this.networkStoreService = networkStoreService; this.notificationService = notificationService; + this.self = self; } public List getFilters() { @@ -158,7 +163,7 @@ public Optional duplicateFilter(UUID sourceFilterId) { UUID newFilterId = UUID.randomUUID(); AbstractFilter sourceFilter = sourceFilterOptional.get(); sourceFilter.setId(newFilterId); - createFilter(sourceFilter); + self.createFilter(sourceFilter); return Optional.of(newFilterId); } return Optional.empty(); @@ -210,7 +215,7 @@ public AbstractFilter updateFilter(UUID id, F newFilt } else { getRepository(filterOpt.get()).deleteById(id); newFilter.setId(id); - modifiedOrCreatedFilter = createFilter(newFilter); + modifiedOrCreatedFilter = self.createFilter(newFilter); } } } else { @@ -223,7 +228,7 @@ public AbstractFilter updateFilter(UUID id, F newFilt @Transactional public List updateFilters(Map filtersToUpdateMap, String userId) { return filtersToUpdateMap.keySet().stream() - .map(filterUuid -> updateFilter(filterUuid, filtersToUpdateMap.get(filterUuid), userId)) + .map(filterUuid -> self.updateFilter(filterUuid, filtersToUpdateMap.get(filterUuid), userId)) .toList(); } From cb40b78ca2317ace19b5d24fe44299bd59a4e655 Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Mon, 1 Jul 2024 21:50:50 +0200 Subject: [PATCH 15/17] Enrich test for update in batch with none existing filter id --- .../filter/server/FilterController.java | 4 +- .../filter/server/FilterService.java | 10 +++-- .../server/FilterEntityControllerTest.java | 37 ++++++++++++++++--- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/gridsuite/filter/server/FilterController.java b/src/main/java/org/gridsuite/filter/server/FilterController.java index c0850509..ef69145a 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterController.java +++ b/src/main/java/org/gridsuite/filter/server/FilterController.java @@ -121,10 +121,10 @@ public ResponseEntity updateFilter(@PathVariable UUID id, @Reque @PutMapping(value = "/filters/batch", consumes = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Update filters in batch from a given map of each filter id and the corresponding whole new filter object") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters have been successfully updated")}) - public ResponseEntity> updateFilters(@RequestBody Map filtersToUpdateMap, @RequestHeader("userId") String userId) { + public ResponseEntity> updateFilters(@RequestBody Map filtersToUpdateMap) { return ResponseEntity.ok() .contentType(MediaType.APPLICATION_JSON) - .body(service.updateFilters(filtersToUpdateMap, userId)); + .body(service.updateFilters(filtersToUpdateMap)); } @DeleteMapping(value = "/filters/{id}") diff --git a/src/main/java/org/gridsuite/filter/server/FilterService.java b/src/main/java/org/gridsuite/filter/server/FilterService.java index ff0b530f..196150ad 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterService.java +++ b/src/main/java/org/gridsuite/filter/server/FilterService.java @@ -221,14 +221,18 @@ public AbstractFilter updateFilter(UUID id, F newFilt } else { throw new ResponseStatusException(HttpStatus.NOT_FOUND, FILTER_LIST + id + NOT_FOUND); } - notificationService.emitElementUpdated(id, userId); + + if (userId != null) { + notificationService.emitElementUpdated(id, userId); + } + return modifiedOrCreatedFilter; } @Transactional - public List updateFilters(Map filtersToUpdateMap, String userId) { + public List updateFilters(Map filtersToUpdateMap) { return filtersToUpdateMap.keySet().stream() - .map(filterUuid -> self.updateFilter(filterUuid, filtersToUpdateMap.get(filterUuid), userId)) + .map(filterUuid -> self.updateFilter(filterUuid, filtersToUpdateMap.get(filterUuid), null)) .toList(); } diff --git a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java index d2d5c5bc..1412d90e 100644 --- a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java +++ b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java @@ -1150,16 +1150,21 @@ private void updateFilter(UUID filterId, AbstractFilter filter, String userId) t checkElementUpdatedMessageSent(filterId, userId); } - private List updateFilters(Map filtersToUpdateMap, String userId) throws Exception { + private List updateFilters(Map filtersToUpdateMap) throws Exception { String response = mvc.perform(put(URL_TEMPLATE + "/batch") .content(objectMapper.writeValueAsString(filtersToUpdateMap)) - .contentType(APPLICATION_JSON) - .header(USER_ID_HEADER, userId)) + .contentType(APPLICATION_JSON)) .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); - filtersToUpdateMap.keySet().forEach(filterId -> checkElementUpdatedMessageSent(filterId, userId)); return objectMapper.readValue(response, new TypeReference<>() { }); } + private void updateFiltersWithNoneExistingId(Map filtersToUpdateMap) throws Exception { + mvc.perform(put(URL_TEMPLATE + "/batch") + .content(objectMapper.writeValueAsString(filtersToUpdateMap)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isNotFound()); + } + private void deleteFilter(UUID filterId) throws Exception { mvc.perform(delete(URL_TEMPLATE + "/" + filterId)).andExpect(status().isOk()); } @@ -2188,11 +2193,11 @@ public void testLineFiltersCrudInBatch() throws Exception { new Date(), generatorFilter ); - Map filtersToModifyMap = Map.of( + Map filtersToUpdateMap = Map.of( filterId1, lineCriteriaFilter3, filterId2, generatorCriteriaFilter ); - updateFilters(filtersToModifyMap, "userId"); + updateFilters(filtersToUpdateMap); // check modified filters lineCriteriaFilter3.setId(filterId1); @@ -2200,6 +2205,26 @@ public void testLineFiltersCrudInBatch() throws Exception { generatorCriteriaFilter.setId(filterId2); checkFormFilter(filterId2, generatorCriteriaFilter); + // --- modify filters in batch with a none existing id --- // + GeneratorFilter generatorFilter2 = GeneratorFilter.builder().equipmentID("eqId1").equipmentName("gen1") + .substationName("s1") + .countries(new TreeSet<>(Set.of("FR", "BE"))) + .nominalVoltage(new NumericalFilter(RangeType.RANGE, 60., null)) + .build(); + CriteriaFilter generatorCriteriaFilter2 = new CriteriaFilter( + null, + new Date(), + generatorFilter2 + ); + + Map filtersToUpdateMap2 = Map.of( + UUID.randomUUID(), lineCriteriaFilter3, + filterId2, generatorCriteriaFilter2 + ); + updateFiltersWithNoneExistingId(filtersToUpdateMap2); + // check modified filters => filter with filterId2 should not be changed + checkFormFilter(filterId2, generatorCriteriaFilter); + // --- delete filters in batch -- // deleteFilters(Stream.concat(sourceAndNewUuidMap.keySet().stream(), sourceAndNewUuidMap.values().stream()).toList()); From 6c2ba17f68a347a0902eb4d2b4d335b52cbcbd43 Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Wed, 3 Jul 2024 19:45:26 +0200 Subject: [PATCH 16/17] Correct following some comments of Mathieu --- .../filter/server/FilterService.java | 5 +- .../ExpertFilterRepositoryProxy.java | 12 +- .../server/FilterEntityControllerTest.java | 117 +++++++++++------- 3 files changed, 84 insertions(+), 50 deletions(-) diff --git a/src/main/java/org/gridsuite/filter/server/FilterService.java b/src/main/java/org/gridsuite/filter/server/FilterService.java index 196150ad..9bcf0a17 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterService.java +++ b/src/main/java/org/gridsuite/filter/server/FilterService.java @@ -54,7 +54,7 @@ public class FilterService { private static final String FILTER_LIST = "Filter list "; private static final String NOT_FOUND = " not found"; - public static final String FILTER_UUIDS_NOT_FOUND = "Some filter uuids not found"; + public static final String FILTER_UUIDS_NOT_FOUND = "Some filter uuids have not bean found"; private final Map> filterRepositories = new HashMap<>(); @@ -169,6 +169,9 @@ public Optional duplicateFilter(UUID sourceFilterId) { return Optional.empty(); } + /** + * @return Map of uuids of copied filters and uuids of new filters + */ @Transactional public Map duplicateFilters(List filterUuids) { Map uuidsMap = new HashMap<>(); diff --git a/src/main/java/org/gridsuite/filter/server/repositories/proxies/expertfiler/ExpertFilterRepositoryProxy.java b/src/main/java/org/gridsuite/filter/server/repositories/proxies/expertfiler/ExpertFilterRepositoryProxy.java index a3130ba3..31169506 100644 --- a/src/main/java/org/gridsuite/filter/server/repositories/proxies/expertfiler/ExpertFilterRepositoryProxy.java +++ b/src/main/java/org/gridsuite/filter/server/repositories/proxies/expertfiler/ExpertFilterRepositoryProxy.java @@ -80,8 +80,8 @@ public static AbstractExpertRule entityToDto(ExpertRuleEntity expertRuleEntity) case NUMBER -> { ExpertRuleValueEntity numberExpertEntity = (ExpertRuleValueEntity) expertRuleEntity; NumberExpertRule.NumberExpertRuleBuilder ruleBuilder = NumberExpertRule.builder() - .field(expertRuleEntity.getField()) - .operator(expertRuleEntity.getOperator()); + .field(numberExpertEntity.getField()) + .operator(numberExpertEntity.getOperator()); if (numberExpertEntity.getValue() != null) { if (isMultipleCriteriaOperator(numberExpertEntity.getOperator())) { // for multiple values ruleBuilder.values(Stream.of(numberExpertEntity.getValue().split(",")).map(Double::valueOf).collect(Collectors.toSet())); @@ -95,8 +95,8 @@ public static AbstractExpertRule entityToDto(ExpertRuleEntity expertRuleEntity) case STRING -> { ExpertRuleValueEntity stringExpertRuleEntity = (ExpertRuleValueEntity) expertRuleEntity; StringExpertRule.StringExpertRuleBuilder ruleBuilder = StringExpertRule.builder() - .field(expertRuleEntity.getField()) - .operator(expertRuleEntity.getOperator()); + .field(stringExpertRuleEntity.getField()) + .operator(stringExpertRuleEntity.getOperator()); if (stringExpertRuleEntity.getValue() != null) { if (isMultipleCriteriaOperator(stringExpertRuleEntity.getOperator())) { // for multiple values ruleBuilder.values(Stream.of(stringExpertRuleEntity.getValue().split(",")).collect(Collectors.toSet())); @@ -125,8 +125,8 @@ public static AbstractExpertRule entityToDto(ExpertRuleEntity expertRuleEntity) ExpertRuleValueEntity filterUuidExpertRuleEntity = (ExpertRuleValueEntity) expertRuleEntity; FilterUuidExpertRule.FilterUuidExpertRuleBuilder ruleBuilder = FilterUuidExpertRule.builder() - .field(expertRuleEntity.getField()) - .operator(expertRuleEntity.getOperator()); + .field(filterUuidExpertRuleEntity.getField()) + .operator(filterUuidExpertRuleEntity.getOperator()); if (filterUuidExpertRuleEntity.getValue() != null) { if (isMultipleCriteriaOperator(filterUuidExpertRuleEntity.getOperator())) { // for multiple values ruleBuilder.values(Stream.of(filterUuidExpertRuleEntity.getValue().split(",")).collect(Collectors.toSet())); diff --git a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java index 1412d90e..c7a62c36 100644 --- a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java +++ b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java @@ -62,6 +62,7 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -248,14 +249,14 @@ public void testLineFilter() throws Exception { assertThrows("Network '" + NETWORK_NOT_FOUND_UUID + "' not found", ServletException.class, () -> mvc.perform(get(URL_TEMPLATE + "/" + filterId1 + "/export?networkUuid=" + NETWORK_NOT_FOUND_UUID) .contentType(APPLICATION_JSON))); - mvc.perform(get(URL_TEMPLATE + "/" + filterId1 + "/export?networkUuid=" + NETWORK_UUID) + mvc.perform(get(URL_TEMPLATE + "/" + filterId1 + "/export").param("networkUuid", NETWORK_UUID.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) .andExpect(content().json("[{\"id\":\"NHV1_NHV2_1\",\"type\":\"LINE\"}]")); List filterAttributes = objectMapper.readValue( - mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/metadata?ids={id}", filterId1) + mvc.perform(get(URL_TEMPLATE + "/metadata").param("ids", filterId1.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(), @@ -293,7 +294,7 @@ public void testLineFilter() throws Exception { matchFilterInfos(filterAttributes.get(0), filterId1, FilterType.CRITERIA, EquipmentType.HVDC_LINE, modificationDate); filterAttributes = objectMapper.readValue( - mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/metadata?ids={id}", filterId1) + mvc.perform(get(URL_TEMPLATE + "/metadata").param("ids", filterId1.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(), @@ -312,7 +313,7 @@ public void testLineFilter() throws Exception { modifyFormFilter(filterId1, generatorFormFilter, userId); filterAttributes = objectMapper.readValue( - mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/metadata?ids={id}", filterId1) + mvc.perform(get(URL_TEMPLATE + "/metadata").param("ids", filterId1.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(), @@ -925,7 +926,7 @@ public void testExportFilters() throws Exception { params.add("variantId", VARIANT_ID_1); List filterEquipments = objectMapper.readValue( - mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/export").params(params) + mvc.perform(get(URL_TEMPLATE + "/export").params(params) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(), @@ -1007,7 +1008,7 @@ public void testGetIdentifiablesCount() throws Exception { "ids[g4]", List.of(UUID.randomUUID().toString()) )); Map identifiablesCount = objectMapper.readValue( - mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/identifiables-count") + mvc.perform(get(URL_TEMPLATE + "/identifiables-count") .params(params) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) @@ -1058,14 +1059,14 @@ private void checkIdentifiableAttributes(List identifiab } private void checkIdentifierListFilterExportAndMetadata(UUID filterId, String expectedJson, EquipmentType equipmentType) throws Exception { - mvc.perform(get(URL_TEMPLATE + "/" + filterId + "/export?networkUuid=" + NETWORK_UUID) + mvc.perform(get(URL_TEMPLATE + "/" + filterId + "/export").param("networkUuid", NETWORK_UUID.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) .andExpect(content().json(expectedJson)); List filterAttributes = objectMapper.readValue( - mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/metadata?ids={id}", filterId) + mvc.perform(get(URL_TEMPLATE + "/metadata").param("ids", filterId.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(), @@ -1079,14 +1080,14 @@ private void checkIdentifierListFilterExportAndMetadata(UUID filterId, String ex } private void checkExpertFilterExportAndMetadata(UUID filterId, String expectedJson, EquipmentType equipmentType) throws Exception { - mvc.perform(get(URL_TEMPLATE + "/" + filterId + "/export?networkUuid=" + NETWORK_UUID) + mvc.perform(get(URL_TEMPLATE + "/" + filterId + "/export").param("networkUuid", NETWORK_UUID.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) .andExpect(content().json(expectedJson)); List filterAttributes = objectMapper.readValue( - mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/metadata?ids={id}", filterId) + mvc.perform(get(URL_TEMPLATE + "/metadata").param("ids", filterId.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(), @@ -1102,7 +1103,7 @@ private void checkExpertFilterExportAndMetadata(UUID filterId, String expectedJs } private void checkFilterEvaluating(AbstractFilter filter, String expectedJson) throws Exception { - mvc.perform(post(URL_TEMPLATE + "/evaluate?networkUuid=" + NETWORK_UUID) + mvc.perform(post(URL_TEMPLATE + "/evaluate").param("networkUuid", NETWORK_UUID.toString()) .content(objectMapper.writeValueAsString(filter)) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) @@ -1127,7 +1128,7 @@ private List insertFilters(Map filtersToCr } private UUID duplicateFilter(UUID filterId) throws Exception { - String response = mvc.perform(post("/" + FilterApi.API_VERSION + "/filters?duplicateFrom=" + filterId)) + String response = mvc.perform(post(URL_TEMPLATE).param("duplicateFrom", filterId.toString())) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(); return objectMapper.readValue(response, UUID.class); @@ -1269,7 +1270,7 @@ private void insertInjectionFilter(EquipmentType equipmentType, UUID id, String checkFormFilter(id, injectionFilter); List filterAttributes = objectMapper.readValue( - mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/metadata?ids={id}", id) + mvc.perform(get(URL_TEMPLATE + "/metadata").param("ids", id.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(), @@ -1281,8 +1282,13 @@ private void insertInjectionFilter(EquipmentType equipmentType, UUID id, String assertEquals(FilterType.CRITERIA, filterAttributes.get(0).getType()); assertEquals(equipmentType, filterAttributes.get(0).getEquipmentType()); - mvc.perform(get(URL_TEMPLATE + "/" + id + "/export?networkUuid=" + networkUuid + (variantId != null ? "&variantId=" + variantId : "")) - .contentType(APPLICATION_JSON)) + MockHttpServletRequestBuilder requestBuilder = get(URL_TEMPLATE + "/" + id + "/export") + .param("networkUuid", networkUuid.toString()); + if (variantId != null) { + requestBuilder.param("variantId", variantId); + } + + mvc.perform(requestBuilder.contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) .andExpect(content().json(expectedJsonExport)); @@ -1328,7 +1334,7 @@ private void insertTransformerFilter(EquipmentType equipmentType, UUID id, Strin checkFormFilter(id, transformerFilter); List filterAttributes = objectMapper.readValue( - mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/metadata?ids={id}", id) + mvc.perform(get(URL_TEMPLATE + "/metadata").param("ids", id.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(), @@ -1340,11 +1346,16 @@ private void insertTransformerFilter(EquipmentType equipmentType, UUID id, Strin assertEquals(FilterType.CRITERIA, filterAttributes.get(0).getType()); assertEquals(equipmentType, filterAttributes.get(0).getEquipmentType()); - mvc.perform(get(URL_TEMPLATE + "/" + id + "/export?networkUuid=" + networkUuid + (variantId != null ? "&variantId=" + variantId : "")) - .contentType(APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(content().json(expectedJsonExport)); + MockHttpServletRequestBuilder requestBuilder = get(URL_TEMPLATE + "/" + id + "/export") + .param("networkUuid", networkUuid.toString()); + if (variantId != null) { + requestBuilder.param("variantId", variantId); + } + + mvc.perform(requestBuilder.contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(content().json(expectedJsonExport)); deleteFilter(id); } @@ -1379,7 +1390,7 @@ private void insertHvdcLineFilter(UUID id, String equipmentID, String equipmentN matchFilterInfos(filterAttributes.get(0), id, FilterType.CRITERIA, EquipmentType.HVDC_LINE, modificationDate); filterAttributes = objectMapper.readValue( - mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/metadata?ids={id}", id) + mvc.perform(get(URL_TEMPLATE + "/metadata").param("ids", id.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(), @@ -1389,16 +1400,21 @@ private void insertHvdcLineFilter(UUID id, String equipmentID, String equipmentN assertEquals(1, filterAttributes.size()); matchFilterInfos(filterAttributes.get(0), id, FilterType.CRITERIA, EquipmentType.HVDC_LINE, modificationDate); - mvc.perform(get(URL_TEMPLATE + "/" + id + "/export?networkUuid=" + networkUuid + (variantId != null ? "&variantId=" + variantId : "")) - .contentType(APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(content().json(expectedJsonExport)); + MockHttpServletRequestBuilder requestBuilder = get(URL_TEMPLATE + "/" + id + "/export") + .param("networkUuid", networkUuid.toString()); + if (variantId != null) { + requestBuilder.param("variantId", variantId); + } + + mvc.perform(requestBuilder.contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(content().json(expectedJsonExport)); deleteFilter(id); filterAttributes = objectMapper.readValue( - mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/metadata?ids={id}", id) + mvc.perform(get(URL_TEMPLATE + "/metadata").param("ids", id.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(), @@ -1437,7 +1453,7 @@ private CriteriaFilter insertLineFilter(UUID id, String equipmentID, String equi insertFilter(id, filter); checkFormFilter(id, filter); List filterAttributes = objectMapper.readValue( - mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/metadata?ids={id}", id) + mvc.perform(get(URL_TEMPLATE + "/metadata").param("ids", id.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(), @@ -1449,8 +1465,13 @@ private CriteriaFilter insertLineFilter(UUID id, String equipmentID, String equi assertEquals(FilterType.CRITERIA, filterAttributes.get(0).getType()); assertEquals(EquipmentType.LINE, filterAttributes.get(0).getEquipmentType()); - mvc.perform(get(URL_TEMPLATE + "/" + id + "/export?networkUuid=" + networkUuid + (variantId != null ? "&variantId=" + variantId : "")) - .contentType(APPLICATION_JSON)) + MockHttpServletRequestBuilder requestBuilder = get(URL_TEMPLATE + "/" + id + "/export") + .param("networkUuid", networkUuid.toString()); + if (variantId != null) { + requestBuilder.param("variantId", variantId); + } + + mvc.perform(requestBuilder.contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) .andExpect(content().json(expectedJsonExport)); @@ -1484,7 +1505,7 @@ private void insertVoltageLevelFilter(UUID id, String equipmentID, String equipm checkFormFilter(id, filter); List filterAttributes = objectMapper.readValue( - mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/metadata?ids={id}", id) + mvc.perform(get(URL_TEMPLATE + "/metadata").param("ids", id.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(), @@ -1495,11 +1516,16 @@ private void insertVoltageLevelFilter(UUID id, String equipmentID, String equipm assertEquals(id, filterAttributes.get(0).getId()); assertEquals(FilterType.CRITERIA, filterAttributes.get(0).getType()); - mvc.perform(get(URL_TEMPLATE + "/" + id + "/export?networkUuid=" + networkUuid + (variantId != null ? "&variantId=" + variantId : "")) - .contentType(APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(content().json(expectedJsonExport)); + MockHttpServletRequestBuilder requestBuilder = get(URL_TEMPLATE + "/" + id + "/export") + .param("networkUuid", networkUuid.toString()); + if (variantId != null) { + requestBuilder.param("variantId", variantId); + } + + mvc.perform(requestBuilder.contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(content().json(expectedJsonExport)); deleteFilter(id); } @@ -1525,7 +1551,7 @@ private void insertSubstationFilter(UUID id, String equipmentID, String equipmen checkFormFilter(id, filter); List filterAttributes = objectMapper.readValue( - mvc.perform(get("/" + FilterApi.API_VERSION + "/filters/metadata?ids={id}", id) + mvc.perform(get(URL_TEMPLATE + "/metadata").param("ids", id.toString()) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(), @@ -1536,11 +1562,16 @@ private void insertSubstationFilter(UUID id, String equipmentID, String equipmen assertEquals(id, filterAttributes.get(0).getId()); assertEquals(FilterType.CRITERIA, filterAttributes.get(0).getType()); - mvc.perform(get(URL_TEMPLATE + "/" + id + "/export?networkUuid=" + networkUuid + (variantId != null ? "&variantId=" + variantId : "")) - .contentType(APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(content().json(expectedJsonExport)); + MockHttpServletRequestBuilder requestBuilder = get(URL_TEMPLATE + "/" + id + "/export") + .param("networkUuid", networkUuid.toString()); + if (variantId != null) { + requestBuilder.param("variantId", variantId); + } + + mvc.perform(requestBuilder.contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(content().json(expectedJsonExport)); deleteFilter(id); } From 0713dfcfcdf114cc398c529567da126033b92272 Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Wed, 10 Jul 2024 13:01:17 +0200 Subject: [PATCH 17/17] change url path in the filte-server endpoint for duplication in batch --- src/main/java/org/gridsuite/filter/server/FilterController.java | 2 +- .../org/gridsuite/filter/server/FilterEntityControllerTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/gridsuite/filter/server/FilterController.java b/src/main/java/org/gridsuite/filter/server/FilterController.java index ef69145a..c6ef88e5 100644 --- a/src/main/java/org/gridsuite/filter/server/FilterController.java +++ b/src/main/java/org/gridsuite/filter/server/FilterController.java @@ -95,7 +95,7 @@ public ResponseEntity duplicateFilter(@RequestParam("duplicateFrom") UUID .orElse(ResponseEntity.notFound().build()); } - @PostMapping(value = "/filters/batch/duplicate") + @PostMapping(value = "/filters/duplicate/batch") @Operation(summary = "Duplicate filters from given ids") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Filters of given ids have been successfully duplicated"), @ApiResponse(responseCode = "404", description = "Source filter not found")}) diff --git a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java index c7a62c36..5805d111 100644 --- a/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java +++ b/src/test/java/org/gridsuite/filter/server/FilterEntityControllerTest.java @@ -1135,7 +1135,7 @@ private UUID duplicateFilter(UUID filterId) throws Exception { } private Map duplicateFilters(List sourceFilterUuids) throws Exception { - String response = mvc.perform(post(URL_TEMPLATE + "/batch/duplicate") + String response = mvc.perform(post(URL_TEMPLATE + "/duplicate/batch") .content(objectMapper.writeValueAsString(sourceFilterUuids)) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()).andReturn().getResponse().getContentAsString();