diff --git a/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java b/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java index f359bfe8..4184e694 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java @@ -30,14 +30,10 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; import java.util.List; import java.util.UUID; import static org.gridsuite.computation.service.NotificationService.HEADER_USER_ID; -import static org.gridsuite.computation.utils.FilterUtils.fromStringFiltersToDTO; -import static org.gridsuite.computation.utils.FilterUtils.fromStringGlobalFiltersToDTO; import static org.springframework.http.MediaType.*; /** @@ -126,17 +122,15 @@ public ResponseEntity runAndSave(@Parameter(description = "Network UUID") public ResponseEntity> getNResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid, @Parameter(description = "network Uuid") @RequestParam(name = "networkUuid", required = false) UUID networkUuid, @Parameter(description = "variant Id") @RequestParam(name = "variantId", required = false) String variantId, - @Parameter(description = "Filters") @RequestParam(name = "filters", required = false) String stringFilters, + @Parameter(description = "Filters") @RequestParam(name = "filters", required = false) String filters, @Parameter(description = "Global Filters") @RequestParam(name = "globalFilters", required = false) String globalFilters, @Parameter(description = "Pageable parameters for pagination and sorting") Sort sort) { - String decodedStringFilters = stringFilters != null ? URLDecoder.decode(stringFilters, StandardCharsets.UTF_8) : null; - String decodedStringGlobalFilters = globalFilters != null ? URLDecoder.decode(globalFilters, StandardCharsets.UTF_8) : null; List result = securityAnalysisResultService.findNResult( resultUuid, networkUuid, variantId, - fromStringFiltersToDTO(decodedStringFilters, securityAnalysisResultService.getObjectMapper()), - fromStringGlobalFiltersToDTO(decodedStringGlobalFilters, securityAnalysisResultService.getObjectMapper()), + filters, + globalFilters, sort); return result != null @@ -149,10 +143,23 @@ public ResponseEntity> getNResult(@P @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result csv export"), @ApiResponse(responseCode = "404", description = "Security analysis result has not been found")}) public ResponseEntity getNResultZippedCsv(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid, - @Parameter(description = "Translation properties") @RequestBody CsvTranslationDTO csvTranslations) { + @Parameter(description = "network Uuid") @RequestParam(name = "networkUuid", required = false) UUID networkUuid, + @Parameter(description = "variant Id") @RequestParam(name = "variantId", required = false) String variantId, + @Parameter(description = "Filters") @RequestParam(name = "filters", required = false) String filters, + @Parameter(description = "Global Filters") @RequestParam(name = "globalFilters", required = false) String globalFilters, + @Parameter(description = "Translation properties") @RequestBody CsvTranslationDTO csvTranslations, + @Parameter(description = "Sort parameters") Sort sort) { return ResponseEntity.ok() .contentType(APPLICATION_OCTET_STREAM) - .body(securityAnalysisResultService.findNResultZippedCsv(resultUuid, csvTranslations)); + .body(securityAnalysisResultService.findNResultZippedCsv( + resultUuid, + networkUuid, + variantId, + filters, + globalFilters, + sort, + csvTranslations + )); } @GetMapping(value = "/results/{resultUuid}/nmk-contingencies-result/paged", produces = APPLICATION_JSON_VALUE) @@ -162,12 +169,10 @@ public ResponseEntity getNResultZippedCsv(@Parameter(description = "Resu public ResponseEntity> getPagedNmKContingenciesResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid, @Parameter(description = "network Uuid") @RequestParam(name = "networkUuid", required = false) UUID networkUuid, @Parameter(description = "variant Id") @RequestParam(name = "variantId", required = false) String variantId, - @Parameter(description = "Filters") @RequestParam(name = "filters", required = false) String stringFilters, + @Parameter(description = "Filters") @RequestParam(name = "filters", required = false) String filters, @Parameter(description = "Global Filters") @RequestParam(name = "globalFilters", required = false) String globalFilters, @Parameter(description = "Pagination parameters") Pageable pageable) { - String decodedStringFilters = stringFilters != null ? URLDecoder.decode(stringFilters, StandardCharsets.UTF_8) : null; - String decodedStringGlobalFilters = globalFilters != null ? URLDecoder.decode(globalFilters, StandardCharsets.UTF_8) : null; - Page result = securityAnalysisResultService.findNmKContingenciesPaged(resultUuid, networkUuid, variantId, decodedStringFilters, decodedStringGlobalFilters, pageable); + Page result = securityAnalysisResultService.findNmKContingenciesPaged(resultUuid, networkUuid, variantId, filters, globalFilters, pageable); return result != null ? ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result) @@ -191,10 +196,23 @@ public ResponseEntity> getNmKContingenciesResult(@Par @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result csv export"), @ApiResponse(responseCode = "404", description = "Security analysis result has not been found")}) public ResponseEntity getNmKContingenciesResultZippedCsv(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid, - @Parameter(description = "Translation properties") @RequestBody CsvTranslationDTO csvTranslations) { + @Parameter(description = "network Uuid") @RequestParam(name = "networkUuid", required = false) UUID networkUuid, + @Parameter(description = "variant Id") @RequestParam(name = "variantId", required = false) String variantId, + @Parameter(description = "Filters") @RequestParam(name = "filters", required = false) String filters, + @Parameter(description = "Global Filters") @RequestParam(name = "globalFilters", required = false) String globalFilters, + @Parameter(description = "Translation properties") @RequestBody CsvTranslationDTO csvTranslations, + @Parameter(description = "Sort parameters") Sort sort) { return ResponseEntity.ok() .contentType(MediaType.APPLICATION_OCTET_STREAM) - .body(securityAnalysisResultService.findNmKContingenciesResultZippedCsv(resultUuid, csvTranslations)); + .body(securityAnalysisResultService.findNmKContingenciesResultZippedCsv( + resultUuid, + networkUuid, + variantId, + filters, + globalFilters, + sort, + csvTranslations + )); } @GetMapping(value = "/results/{resultUuid}/nmk-constraints-result/paged", produces = APPLICATION_JSON_VALUE) @@ -204,12 +222,10 @@ public ResponseEntity getNmKContingenciesResultZippedCsv(@Parameter(desc public ResponseEntity> getNmKConstraintsResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid, @Parameter(description = "network Uuid") @RequestParam(name = "networkUuid", required = false) UUID networkUuid, @Parameter(description = "variant Id") @RequestParam(name = "variantId", required = false) String variantId, - @Parameter(description = "Filters") @RequestParam(name = "filters", required = false) String stringFilters, + @Parameter(description = "Filters") @RequestParam(name = "filters", required = false) String filters, @Parameter(description = "Global Filters") @RequestParam(name = "globalFilters", required = false) String globalFilters, @Parameter(description = "Pagination parameters") Pageable pageable) { - String decodedStringFilters = stringFilters != null ? URLDecoder.decode(stringFilters, StandardCharsets.UTF_8) : null; - String decodedStringGlobalFilters = globalFilters != null ? URLDecoder.decode(globalFilters, StandardCharsets.UTF_8) : null; - Page result = securityAnalysisResultService.findNmKConstraintsResultPaged(resultUuid, networkUuid, variantId, decodedStringFilters, decodedStringGlobalFilters, pageable); + Page result = securityAnalysisResultService.findNmKConstraintsResultPaged(resultUuid, networkUuid, variantId, filters, globalFilters, pageable); return result != null ? ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result) : ResponseEntity.notFound().build(); @@ -220,10 +236,24 @@ public ResponseEntity> getNmKConstraintsRes @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result csv export"), @ApiResponse(responseCode = "404", description = "Security analysis result has not been found")}) public ResponseEntity getNmKContraintsResultZippedCsv(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid, - @Parameter(description = "Translation properties") @RequestBody CsvTranslationDTO csvTranslations) { + @Parameter(description = "network Uuid") @RequestParam(name = "networkUuid", required = false) UUID networkUuid, + @Parameter(description = "variant Id") @RequestParam(name = "variantId", required = false) String variantId, + @Parameter(description = "Filters") @RequestParam(name = "filters", required = false) String filters, + @Parameter(description = "Global Filters") @RequestParam(name = "globalFilters", required = false) String globalFilters, + @Parameter(description = "Translation properties") @RequestBody CsvTranslationDTO csvTranslations, + @Parameter(description = "Sort parameters") Sort sort) { + return ResponseEntity.ok() - .contentType(MediaType.APPLICATION_OCTET_STREAM) - .body(securityAnalysisResultService.findNmKConstraintsResultZippedCsv(resultUuid, csvTranslations)); + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .body(securityAnalysisResultService.findNmKConstraintsResultZippedCsv( + resultUuid, + networkUuid, + variantId, + filters, + globalFilters, + sort, + csvTranslations + )); } @DeleteMapping(value = "/results", produces = APPLICATION_JSON_VALUE) diff --git a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisResultService.java b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisResultService.java index fd020cc8..49d0b356 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisResultService.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisResultService.java @@ -33,9 +33,12 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; import static org.gridsuite.computation.error.ComputationBusinessErrorCode.INVALID_SORT_FORMAT; import static org.gridsuite.computation.error.ComputationBusinessErrorCode.RESULT_NOT_FOUND; @@ -127,20 +130,11 @@ public SecurityAnalysisResultService(SecurityAnalysisResultRepository securityAn this.self = self; } - @Transactional(readOnly = true) - public List findNResult(UUID resultUuid, UUID networkUuid, String variantId, List resourceFilters, GlobalFilter globalFilter, Sort sort) { + private List findNResult(UUID resultUuid, List resourceFilters, Sort sort) { assertResultExists(resultUuid); assertPreContingenciesSortAllowed(sort); - List allResourceFilters = new ArrayList<>(); - if (resourceFilters != null) { - allResourceFilters.addAll(resourceFilters); - } - if (globalFilter != null) { - Optional resourceGlobalFilters = filterService.getResourceFilterN(networkUuid, variantId, globalFilter); - resourceGlobalFilters.ifPresent(allResourceFilters::add); - } - Specification specification = preContingencyLimitViolationSpecificationBuilder.buildSpecification(resultUuid, allResourceFilters); + Specification specification = preContingencyLimitViolationSpecificationBuilder.buildSpecification(resultUuid, resourceFilters); List preContingencyLimitViolation = preContingencyLimitViolationRepository.findAll(specification, sort); return preContingencyLimitViolation.stream() .map(PreContingencyLimitViolationResultDTO::toDto) @@ -148,9 +142,14 @@ public List findNResult(UUID resultUuid, } @Transactional(readOnly = true) - public byte[] findNResultZippedCsv(UUID resultUuid, CsvTranslationDTO csvTranslations) { - List result = self.findNResult(resultUuid, null, null, List.of(), null, Sort.by(Sort.Direction.ASC, AbstractLimitViolationEntity.Fields.subjectLimitViolation + SpecificationUtils.FIELD_SEPARATOR + SubjectLimitViolationEntity.Fields.subjectId)); + public List findNResult(UUID resultUuid, UUID networkUuid, String variantId, String stringFilters, String stringGlobalFilters, Sort sort) { + List resourceFilters = getAllResourceFilters(stringFilters, stringGlobalFilters, globalFilter -> filterService.getResourceFilterN(networkUuid, variantId, globalFilter)); + return findNResult(resultUuid, resourceFilters, sort); + } + @Transactional(readOnly = true) + public byte[] findNResultZippedCsv(UUID resultUuid, UUID networkUuid, String variantId, String stringFilters, String stringGlobalFilters, Sort sort, CsvTranslationDTO csvTranslations) { + List result = self.findNResult(resultUuid, networkUuid, variantId, stringFilters, stringGlobalFilters, sort); return CsvExportUtils.csvRowsToZippedCsv(csvTranslations.headers(), csvTranslations.language(), result.stream().map(r -> r.toCsvRow(csvTranslations.enumValueTranslations(), csvTranslations.language())).toList()); } @@ -158,7 +157,8 @@ public byte[] findNResultZippedCsv(UUID resultUuid, CsvTranslationDTO csvTransla public Page findNmKContingenciesPaged(UUID resultUuid, UUID networkUuid, String variantId, String stringFilters, String stringGlobalFilters, Pageable pageable) { assertResultExists(resultUuid); - Page contingencyPageBis = self.findContingenciesPage(resultUuid, networkUuid, variantId, fromStringFiltersToDTO(stringFilters, objectMapper), fromStringGlobalFiltersToDTO(stringGlobalFilters, objectMapper), pageable); + List allResourceFilters = getAllResourceFilters(stringFilters, stringGlobalFilters, globalFilter -> filterService.getResourceFilterContingencies(networkUuid, variantId, globalFilter)); + Page contingencyPageBis = self.findContingenciesPage(resultUuid, allResourceFilters, pageable); return contingencyPageBis.map(ContingencyResultDTO::toDto); } @@ -177,9 +177,8 @@ public List findNmKContingenciesResult(UUID resultUuid) { } @Transactional(readOnly = true) - public byte[] findNmKContingenciesResultZippedCsv(UUID resultUuid, CsvTranslationDTO csvTranslations) { - List result = self.findNmKContingenciesResult(resultUuid); - + public byte[] findNmKContingenciesResultZippedCsv(UUID resultUuid, UUID networkUuid, String variantId, String stringFilters, String stringGlobalFilters, Sort sort, CsvTranslationDTO csvTranslations) { + List result = self.findNmKContingenciesPaged(resultUuid, networkUuid, variantId, stringFilters, stringGlobalFilters, Pageable.unpaged(sort)).getContent(); return CsvExportUtils.csvRowsToZippedCsv(csvTranslations.headers(), csvTranslations.language(), result.stream().map(r -> r.toCsvRows(csvTranslations.enumValueTranslations(), csvTranslations.language())).flatMap(List::stream).toList()); } @@ -187,7 +186,8 @@ public byte[] findNmKContingenciesResultZippedCsv(UUID resultUuid, CsvTranslatio public Page findNmKConstraintsResultPaged(UUID resultUuid, UUID networkUuid, String variantId, String stringFilters, String stringGlobalFilters, Pageable pageable) { assertResultExists(resultUuid); - Page subjectLimitViolationsPage = self.findSubjectLimitViolationsPage(resultUuid, networkUuid, variantId, fromStringFiltersToDTO(stringFilters, objectMapper), fromStringGlobalFiltersToDTO(stringGlobalFilters, objectMapper), pageable); + List allResourceFilters = getAllResourceFilters(stringFilters, stringGlobalFilters, globalFilter -> filterService.getResourceFilterSubjectLimitViolations(networkUuid, variantId, globalFilter)); + Page subjectLimitViolationsPage = findSubjectLimitViolationsPage(resultUuid, allResourceFilters, pageable); return subjectLimitViolationsPage.map(SubjectLimitViolationResultDTO::toDto); } @@ -208,9 +208,8 @@ public List findNmKConstraintsResult(UUID result } @Transactional(readOnly = true) - public byte[] findNmKConstraintsResultZippedCsv(UUID resultUuid, CsvTranslationDTO csvTranslations) { - List result = self.findNmKConstraintsResult(resultUuid); - + public byte[] findNmKConstraintsResultZippedCsv(UUID resultUuid, UUID networkUuid, String variantId, String stringFilters, String stringGlobalFilters, Sort sort, CsvTranslationDTO csvTranslations) { + List result = self.findNmKConstraintsResultPaged(resultUuid, networkUuid, variantId, stringFilters, stringGlobalFilters, Pageable.unpaged(sort)).getContent(); return CsvExportUtils.csvRowsToZippedCsv(csvTranslations.headers(), csvTranslations.language(), result.stream().map(r -> r.toCsvRows(csvTranslations.enumValueTranslations(), csvTranslations.language())).flatMap(List::stream).toList()); } @@ -305,19 +304,11 @@ private static Page emptyPage(Pageable pageable) { } @Transactional(readOnly = true) - public Page findContingenciesPage(UUID resultUuid, UUID networkUuid, String variantId, List resourceFilters, GlobalFilter globalFilter, Pageable pageable) { + public Page findContingenciesPage(UUID resultUuid, List resourceFilters, Pageable pageable) { Objects.requireNonNull(resultUuid); assertNmKContingenciesSortAllowed(pageable.getSort()); Pageable modifiedPageable = addDefaultSortAndRemoveChildrenSorting(pageable, ContingencyEntity.Fields.uuid); - List allResourceFilters = new ArrayList<>(); - if (resourceFilters != null) { - allResourceFilters.addAll(resourceFilters); - } - if (globalFilter != null) { - Optional resourceGlobalFilters = filterService.getResourceFilterContingencies(networkUuid, variantId, globalFilter); - resourceGlobalFilters.ifPresent(allResourceFilters::add); - } - Specification specification = contingencySpecificationBuilder.buildSpecification(resultUuid, allResourceFilters); + Specification specification = contingencySpecificationBuilder.buildSpecification(resultUuid, resourceFilters); // WARN org.hibernate.hql.internal.ast.QueryTranslatorImpl - // HHH000104: firstResult/maxResults specified with collection fetch; applying in memory! // cf. https://vladmihalcea.com/fix-hibernate-hhh000104-entity-fetch-pagination-warning-message/ @@ -342,26 +333,17 @@ public Page findContingenciesPage(UUID resultUuid, UUID netwo Page contingenciesPage = new PageImpl<>(contingencies, pageable, uuidPage.getTotalElements()); // then we append the missing data, and filter some of the Lazy Loaded collections - appendLimitViolationsAndElementsToContingenciesResult(contingenciesPage, allResourceFilters); + appendLimitViolationsAndElementsToContingenciesResult(contingenciesPage, resourceFilters); return contingenciesPage; } } - @Transactional(readOnly = true) - public Page findSubjectLimitViolationsPage(UUID resultUuid, UUID networkUuid, String variantId, List resourceFilters, GlobalFilter globalFilter, Pageable pageable) { + private Page findSubjectLimitViolationsPage(UUID resultUuid, List resourceFilters, Pageable pageable) { Objects.requireNonNull(resultUuid); assertNmKSubjectLimitViolationsSortAllowed(pageable.getSort()); Pageable modifiedPageable = addDefaultSortAndRemoveChildrenSorting(pageable, SubjectLimitViolationEntity.Fields.id); - List allResourceFilters = new ArrayList<>(); - if (resourceFilters != null) { - allResourceFilters.addAll(resourceFilters); - } - if (globalFilter != null) { - Optional resourceGlobalFilters = filterService.getResourceFilterSubjectLimitViolations(networkUuid, variantId, globalFilter); - resourceGlobalFilters.ifPresent(allResourceFilters::add); - } - Specification specification = subjectLimitViolationSpecificationBuilder.buildSpecification(resultUuid, allResourceFilters); + Specification specification = subjectLimitViolationSpecificationBuilder.buildSpecification(resultUuid, resourceFilters); // WARN org.hibernate.hql.internal.ast.QueryTranslatorImpl - // HHH000104: firstResult/maxResults specified with collection fetch; applying in memory! // cf. https://vladmihalcea.com/fix-hibernate-hhh000104-entity-fetch-pagination-warning-message/ @@ -377,14 +359,14 @@ public Page findSubjectLimitViolationsPage(UUID res // Since springboot 3.2, the return value of Page.empty() is not serializable. See https://github.com/spring-projects/spring-data-commons/issues/2987 return (Page) emptyPage(pageable); } else { - List uuids = uuidPage.map(u -> u.getId()).toList(); + List uuids = uuidPage.map(SubjectLimitViolationRepository.EntityId::getId).toList(); // Then we fetch the main entities data for each UUID List subjectLimitViolations = subjectLimitViolationRepository.findAllByIdIn(uuids); subjectLimitViolations.sort(Comparator.comparing(lm -> uuids.indexOf(lm.getId()))); Page subjectLimitViolationPage = new PageImpl<>(subjectLimitViolations, pageable, uuidPage.getTotalElements()); // then we append the missing data, and filter some of the Lazy Loaded collections - appendLimitViolationsAndContingencyElementsToSubjectLimitViolationsResult(subjectLimitViolationPage, allResourceFilters); + appendLimitViolationsAndContingencyElementsToSubjectLimitViolationsResult(subjectLimitViolationPage, resourceFilters); return subjectLimitViolationPage; } @@ -420,6 +402,24 @@ public List findNmKC return contingencyRepository.findComputingStatus(resultUuid); } + private List getAllResourceFilters(String stringFilters, String stringGlobalFilter, Function> getResourceGlobalFilter) { + String decodedStringFilters = stringFilters != null ? URLDecoder.decode(stringFilters, StandardCharsets.UTF_8) : null; + String decodedStringGlobalFilters = stringGlobalFilter != null ? URLDecoder.decode(stringGlobalFilter, StandardCharsets.UTF_8) : null; + + List resourceFilters = fromStringFiltersToDTO(decodedStringFilters, objectMapper); + GlobalFilter globalFilter = fromStringGlobalFiltersToDTO(decodedStringGlobalFilters, objectMapper); + List allResourceFilters = new ArrayList<>(); + + if (resourceFilters != null) { + allResourceFilters.addAll(resourceFilters); + } + if (globalFilter != null) { + Optional resourceGlobalFilters = getResourceGlobalFilter.apply(globalFilter); + resourceGlobalFilters.ifPresent(allResourceFilters::add); + } + return allResourceFilters; + } + private void appendLimitViolationsAndElementsToContingenciesResult(Page contingencies, List resourceFilters) { // using the the Hibernate First-Level Cache or Persistence Context @@ -443,7 +443,7 @@ private void appendLimitViolationsAndContingencyElementsToSubjectLimitViolations // cf.https://vladmihalcea.com/spring-data-jpa-multiplebagfetchexception/ if (!subjectLimitViolations.isEmpty()) { List subjectLimitViolationsUuids = subjectLimitViolations.stream() - .map(c -> c.getId()) + .map(SubjectLimitViolationEntity::getId) .toList(); Specification specification = subjectLimitViolationSpecificationBuilder.buildLimitViolationsSpecification(subjectLimitViolationsUuids, resourceFilters); subjectLimitViolationRepository.findAll(specification); @@ -555,17 +555,17 @@ private static Comparator getCommonComparator(S } private Pageable addDefaultSortAndRemoveChildrenSorting(Pageable pageable, String defaultSortColumn) { + // Can't use both distinct and sort on nested field here, so we have to remove "children" sorting. Maybe there is a way to do it ? + // https://github.com/querydsl/querydsl/issues/2443 + Sort finalSort = Sort.by(pageable.getSort().filter(sortOrder -> !sortOrder.getProperty().startsWith("contingencyLimitViolations")).toList()); + //if it's already sorted by our defaultColumn we don't add another sort by the same column + if (finalSort.getOrderFor(defaultSortColumn) == null) { + finalSort = finalSort.and(Sort.by(DEFAULT_SORT_DIRECTION, defaultSortColumn)); + } if (pageable.isPaged()) { - // Can't use both distinct and sort on nested field here, so we have to remove "children" sorting. Maybe there is a way to do it ? - // https://github.com/querydsl/querydsl/issues/2443 - Sort finalSort = Sort.by(pageable.getSort().filter(sortOrder -> !sortOrder.getProperty().startsWith("contingencyLimitViolations")).toList()); - //if it's already sorted by our defaultColumn we don't add another sort by the same column - if (finalSort.getOrderFor(defaultSortColumn) == null) { - finalSort = finalSort.and(Sort.by(DEFAULT_SORT_DIRECTION, defaultSortColumn)); - } return PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), finalSort); + } else { + return Pageable.unpaged(finalSort); } - //nothing to do if the request is not paged - return pageable; } } diff --git a/src/test/java/org/gridsuite/securityanalysis/server/FindContingenciesTest.java b/src/test/java/org/gridsuite/securityanalysis/server/FindContingenciesTest.java index 4335755a..280008aa 100644 --- a/src/test/java/org/gridsuite/securityanalysis/server/FindContingenciesTest.java +++ b/src/test/java/org/gridsuite/securityanalysis/server/FindContingenciesTest.java @@ -88,7 +88,7 @@ void tearDown() { }) void findFilteredContingencyResultsTest(List filters, Pageable pageable, List expectedResult, Integer expectedSelectCount) { reset(); - Page contingenciesPage = securityAnalysisResultService.findContingenciesPage(resultEntity.getId(), null, null, filters, null, pageable); + Page contingenciesPage = securityAnalysisResultService.findContingenciesPage(resultEntity.getId(), filters, pageable); // assert contingency ids to check parent filters assertThat(contingenciesPage.getContent()).extracting(ContingencyEntity.Fields.contingencyId).containsExactlyElementsOf(expectedResult.stream().map(c -> c.getContingency().getContingencyId()).toList()); @@ -111,7 +111,7 @@ void findFilteredContingencyResultsTest(List filters, Pageabl "provideForbiddenFilter" }) void testSortAndFilterErrors(List filters, Pageable pageable, Exception expectedException) { - Exception exception = assertThrows(expectedException.getClass(), () -> securityAnalysisResultService.findContingenciesPage(resultEntity.getId(), null, null, filters, null, pageable)); + Exception exception = assertThrows(expectedException.getClass(), () -> securityAnalysisResultService.findContingenciesPage(resultEntity.getId(), filters, pageable)); assertEquals(expectedException.getMessage(), exception.getMessage()); } diff --git a/src/test/java/org/gridsuite/securityanalysis/server/FindPreContingencyLimitViolationTest.java b/src/test/java/org/gridsuite/securityanalysis/server/FindPreContingencyLimitViolationTest.java index 9d6b1ea6..2bd51ce5 100644 --- a/src/test/java/org/gridsuite/securityanalysis/server/FindPreContingencyLimitViolationTest.java +++ b/src/test/java/org/gridsuite/securityanalysis/server/FindPreContingencyLimitViolationTest.java @@ -6,6 +6,8 @@ */ package org.gridsuite.securityanalysis.server; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.ThreeSides; import org.gridsuite.computation.dto.ResourceFilterDTO; @@ -49,6 +51,9 @@ class FindPreContingencyLimitViolationTest { @Autowired private SecurityAnalysisResultService securityAnalysisResultService; + @Autowired + private ObjectMapper mapper; + @BeforeAll void setUp() { // network store service mocking @@ -70,9 +75,9 @@ void tearDown() { "provideEachColumnFilter", "provideChildFilterWithTolerance" }) - void findFilteredPrecontingencyLimitViolationResultsTest(List filters, Sort sort, List expectedResult, Integer expectedSelectCount) { + void findFilteredPrecontingencyLimitViolationResultsTest(List filters, Sort sort, List expectedResult, Integer expectedSelectCount) throws JsonProcessingException { reset(); - List preContingencyLimitViolation = securityAnalysisResultService.findNResult(resultEntity.getId(), null, null, filters, null, sort); + List preContingencyLimitViolation = securityAnalysisResultService.findNResult(resultEntity.getId(), null, null, mapper.writeValueAsString(filters), null, sort); // assert subject ids to check parent filters assertThat(preContingencyLimitViolation).extracting(SubjectLimitViolationEntity.Fields.subjectId) diff --git a/src/test/java/org/gridsuite/securityanalysis/server/FindSubjectLimitViolationsTest.java b/src/test/java/org/gridsuite/securityanalysis/server/FindSubjectLimitViolationsTest.java index 2e60b3a4..a2d7e3f8 100644 --- a/src/test/java/org/gridsuite/securityanalysis/server/FindSubjectLimitViolationsTest.java +++ b/src/test/java/org/gridsuite/securityanalysis/server/FindSubjectLimitViolationsTest.java @@ -6,6 +6,8 @@ */ package org.gridsuite.securityanalysis.server; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.ThreeSides; import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; @@ -60,6 +62,9 @@ class FindSubjectLimitViolationsTest { @Autowired private SecurityAnalysisResultService securityAnalysisResultService; + @Autowired + private ObjectMapper mapper; + @BeforeAll void setUp() { // network store service mocking @@ -81,25 +86,24 @@ void tearDown() { "provideChildSorting", "provideEachColumnFilter" }) - void findFilteredSubjectLimitViolationResultsTest(List filters, Pageable pageable, List expectedResult, Integer expectedSelectCount) { + void findFilteredSubjectLimitViolationResultsTest(List filters, Pageable pageable, List expectedResult, Integer expectedSelectCount) throws JsonProcessingException { reset(); - Page subjectLimitViolationPage = securityAnalysisResultService.findSubjectLimitViolationsPage(resultEntity.getId(), null, null, filters, null, pageable); + Page subjectLimitViolationPage = securityAnalysisResultService.findNmKConstraintsResultPaged(resultEntity.getId(), null, null, mapper.writeValueAsString(filters), null, pageable); // assert subject ids to check parent filters assertThat(subjectLimitViolationPage.getContent()).extracting("subjectId").containsExactlyElementsOf(expectedResult.stream().map(SubjectLimitViolationResultDTO::getSubjectId).toList()); assertThat(subjectLimitViolationPage.getContent().stream() - .map(SubjectLimitViolationResultDTO::toDto).map(lm -> lm.getContingencies().stream().map(c -> c.getLimitViolation().getLocationId()).toList())) + .map(lm -> lm.getContingencies().stream().map(c -> c.getLimitViolation().getLocationId()).toList())) .containsExactlyElementsOf(expectedResult.stream().map(slm -> slm.getContingencies().stream().map(FindSubjectLimitViolationsTest::getContingencyLimitViolationDTOLocationId).toList()).toList()); // assert limit violation contingency ids to check nested filters assertThat(subjectLimitViolationPage.getContent().stream() - .map(SubjectLimitViolationResultDTO::toDto) .map(lm -> lm.getContingencies().stream().map(c -> c.getContingency().getContingencyId()).toList())) .containsExactlyElementsOf(expectedResult.stream().map(c -> c.getContingencies().stream().map(FindSubjectLimitViolationsTest::getContingencyLimitViolationDTOContingencyId).toList()).toList()); // select count check to prevent potential n+1 problems - // 1 -> parent UUIDs ; empty parents, no count or children request - // 4 -> parent UUIDs + parents + children + contingencyElements ; no count (number of element < page size) - // 5 -> parent UUIDs + count + parents + children + contingencyElements + // 2 -> assertResultExists ; parent UUIDs ; empty parents, no count or children request + // 5 -> assertResultExists ; parent UUIDs + parents + children + contingencyElements ; no count (number of element < page size) + // 6 -> assertResultExists ; parent UUIDs + count + parents + children + contingencyElements assertSelectCount(expectedSelectCount); } @@ -109,27 +113,27 @@ void findFilteredSubjectLimitViolationResultsTest(List filter "provideForbiddenFilter" }) void testSortAndFilterErrors(List filters, Pageable pageable, Exception expectedException) { - Exception exception = assertThrows(expectedException.getClass(), () -> securityAnalysisResultService.findSubjectLimitViolationsPage(resultEntity.getId(), null, null, filters, null, pageable)); + Exception exception = assertThrows(expectedException.getClass(), () -> securityAnalysisResultService.findNmKConstraintsResultPaged(resultEntity.getId(), null, null, mapper.writeValueAsString(filters), null, pageable)); assertEquals(expectedException.getMessage(), exception.getMessage()); } private static Stream providePageableAndSortOnly() { return Stream.of( - Arguments.of(List.of(), PageRequest.of(0, 30, Sort.by(Sort.Direction.ASC, "subjectId")), RESULT_CONSTRAINTS.stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).toList(), 4), - Arguments.of(List.of(), PageRequest.of(0, 30, Sort.by(Sort.Direction.DESC, "subjectId")), RESULT_CONSTRAINTS.stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId).reversed()).toList(), 4), - Arguments.of(List.of(), PageRequest.of(0, 2, Sort.by(Sort.Direction.ASC, "subjectId")), RESULT_CONSTRAINTS.stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).toList().subList(0, 2), 5), - Arguments.of(List.of(), PageRequest.of(1, 2, Sort.by(Sort.Direction.ASC, "subjectId")), RESULT_CONSTRAINTS.stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).toList().subList(2, Math.min(RESULT_CONSTRAINTS.size(), 4)), 5) + Arguments.of(List.of(), PageRequest.of(0, 30, Sort.by(Sort.Direction.ASC, "subjectId")), RESULT_CONSTRAINTS.stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).toList(), 5), + Arguments.of(List.of(), PageRequest.of(0, 30, Sort.by(Sort.Direction.DESC, "subjectId")), RESULT_CONSTRAINTS.stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId).reversed()).toList(), 5), + Arguments.of(List.of(), PageRequest.of(0, 2, Sort.by(Sort.Direction.ASC, "subjectId")), RESULT_CONSTRAINTS.stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).toList().subList(0, 2), 6), + Arguments.of(List.of(), PageRequest.of(1, 2, Sort.by(Sort.Direction.ASC, "subjectId")), RESULT_CONSTRAINTS.stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).toList().subList(2, Math.min(RESULT_CONSTRAINTS.size(), 4)), 6) ); } private static Stream provideParentFilter() { return Stream.of( Arguments.of(List.of(new ResourceFilterDTO(ResourceFilterDTO.DataType.TEXT, ResourceFilterDTO.Type.CONTAINS, "3", SubjectLimitViolationEntity.Fields.subjectId)), PageRequest.of(0, 30, Sort.by(Sort.Direction.ASC, "subjectId")), - RESULT_CONSTRAINTS.stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).filter(c -> c.getSubjectId().contains("3")).toList(), 4), + RESULT_CONSTRAINTS.stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).filter(c -> c.getSubjectId().contains("3")).toList(), 5), Arguments.of(List.of(new ResourceFilterDTO(ResourceFilterDTO.DataType.TEXT, ResourceFilterDTO.Type.STARTS_WITH, "l", SubjectLimitViolationEntity.Fields.subjectId)), PageRequest.of(0, 30, Sort.by(Sort.Direction.ASC, "subjectId")), - RESULT_CONSTRAINTS.stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).filter(c -> c.getSubjectId().startsWith("l")).toList(), 4), + RESULT_CONSTRAINTS.stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).filter(c -> c.getSubjectId().startsWith("l")).toList(), 5), Arguments.of(List.of(new ResourceFilterDTO(ResourceFilterDTO.DataType.TEXT, ResourceFilterDTO.Type.STARTS_WITH, "3", SubjectLimitViolationEntity.Fields.subjectId)), PageRequest.of(0, 30, Sort.by(Sort.Direction.ASC, "subjectId")), - RESULT_CONSTRAINTS.stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).filter(c -> c.getSubjectId().startsWith("3")).toList(), 1) + RESULT_CONSTRAINTS.stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).filter(c -> c.getSubjectId().startsWith("3")).toList(), 2) ); } @@ -138,11 +142,11 @@ private static Stream provideChildFilter() { Arguments.of(List.of(new ResourceFilterDTO(ResourceFilterDTO.DataType.TEXT, ResourceFilterDTO.Type.CONTAINS, "2", SubjectLimitViolationEntity.Fields.contingencyLimitViolations + SpecificationUtils.FIELD_SEPARATOR + ContingencyLimitViolationEntity.Fields.contingency + SpecificationUtils.FIELD_SEPARATOR + ContingencyEntity.Fields.contingencyId)), PageRequest.of(0, 2, Sort.by(Sort.Direction.ASC, "subjectId")), getResultConstraintsWithNestedFilter(c -> c.getContingency().getContingencyId().contains("2")) .stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).toList() - .subList(0, 2), 5), // find 1st page of size 2 of contingencies, filtered by SubjectId + .subList(0, 2), 6), // find 1st page of size 2 of contingencies, filtered by SubjectId Arguments.of(List.of(new ResourceFilterDTO(ResourceFilterDTO.DataType.TEXT, ResourceFilterDTO.Type.STARTS_WITH, "CURRENT", SubjectLimitViolationEntity.Fields.contingencyLimitViolations + SpecificationUtils.FIELD_SEPARATOR + AbstractLimitViolationEntity.Fields.limitType)), PageRequest.of(0, 2, Sort.by(Sort.Direction.ASC, "subjectId")), getResultConstraintsWithNestedFilter(c -> c.getLimitViolation().getLimitType().equals(LimitViolationType.CURRENT)) .stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).toList() - .subList(0, 2), 5) + .subList(0, 2), 6) ); } @@ -201,17 +205,17 @@ private static Arguments buildArgumentsForChildrenSorting(Sort childrenSort, Com getResultConstraintsSorted( childrenComparator, Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)) - .subList(0, 4), 5); + .subList(0, 4), 6); } private static Stream provideEachColumnFilter() { return Stream.of( Arguments.of(List.of(new ResourceFilterDTO(ResourceFilterDTO.DataType.TEXT, ResourceFilterDTO.Type.CONTAINS, "CO", SubjectLimitViolationEntity.Fields.contingencyLimitViolations + SpecificationUtils.FIELD_SEPARATOR + ContingencyLimitViolationEntity.Fields.contingency + SpecificationUtils.FIELD_SEPARATOR + ContingencyEntity.Fields.status)), PageRequest.of(0, 30, Sort.by(Sort.Direction.ASC, "subjectId")), - getResultConstraintsWithNestedFilter(c -> c.getContingency().getStatus().contains("CO")).stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).toList(), 4), + getResultConstraintsWithNestedFilter(c -> c.getContingency().getStatus().contains("CO")).stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).toList(), 5), Arguments.of(List.of(new ResourceFilterDTO(ResourceFilterDTO.DataType.TEXT, ResourceFilterDTO.Type.EQUALS, "ONE", SubjectLimitViolationEntity.Fields.contingencyLimitViolations + SpecificationUtils.FIELD_SEPARATOR + AbstractLimitViolationEntity.Fields.side)), PageRequest.of(0, 30, Sort.by(Sort.Direction.ASC, "subjectId")), - getResultConstraintsWithNestedFilter(c -> c.getLimitViolation().getSide() != null && c.getLimitViolation().getSide().equals(ThreeSides.ONE)).stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).toList(), 4), + getResultConstraintsWithNestedFilter(c -> c.getLimitViolation().getSide() != null && c.getLimitViolation().getSide().equals(ThreeSides.ONE)).stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).toList(), 5), Arguments.of(List.of(new ResourceFilterDTO(ResourceFilterDTO.DataType.TEXT, ResourceFilterDTO.Type.EQUALS, "l6_name", SubjectLimitViolationEntity.Fields.contingencyLimitViolations + SpecificationUtils.FIELD_SEPARATOR + AbstractLimitViolationEntity.Fields.limitName)), PageRequest.of(0, 30, Sort.by(Sort.Direction.ASC, "subjectId")), - getResultConstraintsWithNestedFilter(c -> c.getLimitViolation().getLimitName().equals("l6_name")).stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).toList(), 4) + getResultConstraintsWithNestedFilter(c -> c.getLimitViolation().getLimitName().equals("l6_name")).stream().sorted(Comparator.comparing(SubjectLimitViolationResultDTO::getSubjectId)).toList(), 5) ); } diff --git a/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisControllerTest.java b/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisControllerTest.java index eb9404ab..efeb8f36 100644 --- a/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisControllerTest.java +++ b/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisControllerTest.java @@ -32,6 +32,7 @@ import org.gridsuite.computation.utils.SpecificationUtils; import org.gridsuite.securityanalysis.server.dto.*; import org.gridsuite.securityanalysis.server.entities.AbstractLimitViolationEntity; +import org.gridsuite.securityanalysis.server.entities.ContingencyEntity; import org.gridsuite.securityanalysis.server.entities.SubjectLimitViolationEntity; import org.gridsuite.securityanalysis.server.repositories.SubjectLimitViolationRepository; import org.gridsuite.securityanalysis.server.service.ActionsService; @@ -917,6 +918,7 @@ void getZippedCsvResults() throws Exception { assertEquals("me", resultMessage.getHeaders().get("receiver")); checkAllZippedCsvResults(); + checkFiltersOnZippedCsvResults(); } @Test @@ -962,7 +964,7 @@ private List getCsvHeaderFromResource(String resourcePath, String lang) private void checkAllZippedCsvResults() throws Exception { SQLStatementCountValidator.reset(); - checkZippedCsvResult("n-result", "/results/n-result-en.csv", "en"); + checkZippedCsvResult("n-result", "/results/n-result-en.csv", "en", AbstractLimitViolationEntity.Fields.subjectLimitViolation + SpecificationUtils.FIELD_SEPARATOR + SubjectLimitViolationEntity.Fields.subjectId, null); /* * SELECT * assert result exists @@ -971,10 +973,10 @@ private void checkAllZippedCsvResults() throws Exception { assertRequestsCount(2, 0, 0, 0); SQLStatementCountValidator.reset(); - checkZippedCsvResult("n-result", "/results/n-result-fr.csv", "fr"); + checkZippedCsvResult("n-result", "/results/n-result-fr.csv", "fr", AbstractLimitViolationEntity.Fields.subjectLimitViolation + SpecificationUtils.FIELD_SEPARATOR + SubjectLimitViolationEntity.Fields.subjectId, null); SQLStatementCountValidator.reset(); - checkZippedCsvResult("nmk-contingencies-result", "/results/nmk-contingencies-result-en.csv", "en"); + checkZippedCsvResult("nmk-contingencies-result", "/results/nmk-contingencies-result-en.csv", "en", ContingencyEntity.Fields.contingencyId, null); /* * SELECT @@ -983,14 +985,14 @@ private void checkAllZippedCsvResults() throws Exception { * join contingency_entity_contingency_elements * join contingency_limit_violation and subject_limit_violation */ - assertRequestsCount(4, 0, 0, 0); + assertRequestsCount(5, 0, 0, 0); SQLStatementCountValidator.reset(); - checkZippedCsvResult("nmk-contingencies-result", "/results/nmk-contingencies-result-fr.csv", "fr"); - assertRequestsCount(4, 0, 0, 0); + checkZippedCsvResult("nmk-contingencies-result", "/results/nmk-contingencies-result-fr.csv", "fr", ContingencyEntity.Fields.contingencyId, null); + assertRequestsCount(5, 0, 0, 0); SQLStatementCountValidator.reset(); - checkZippedCsvResult("nmk-constraints-result", "/results/nmk-constraints-result-en.csv", "en"); + checkZippedCsvResult("nmk-constraints-result", "/results/nmk-constraints-result-en.csv", "en", SubjectLimitViolationEntity.Fields.subjectId, null); /* * SELECT * assert result exists @@ -998,11 +1000,20 @@ private void checkAllZippedCsvResults() throws Exception { * join contingency_limit_violation * join contingency_entity_contingency_elements */ - assertRequestsCount(4, 0, 0, 0); + assertRequestsCount(5, 0, 0, 0); SQLStatementCountValidator.reset(); - checkZippedCsvResult("nmk-constraints-result", "/results/nmk-constraints-result-fr.csv", "fr"); - assertRequestsCount(4, 0, 0, 0); + checkZippedCsvResult("nmk-constraints-result", "/results/nmk-constraints-result-fr.csv", "fr", SubjectLimitViolationEntity.Fields.subjectId, null); + assertRequestsCount(5, 0, 0, 0); + } + + private void checkFiltersOnZippedCsvResults() throws Exception { + List filterN = List.of(new ResourceFilterDTO(ResourceFilterDTO.DataType.TEXT, ResourceFilterDTO.Type.EQUALS, new String[]{"CURRENT"}, AbstractLimitViolationEntity.Fields.limitType)); + List filterNmK = List.of(new ResourceFilterDTO(ResourceFilterDTO.DataType.TEXT, ResourceFilterDTO.Type.EQUALS, new String[]{"CURRENT"}, SubjectLimitViolationEntity.Fields.contingencyLimitViolations + SpecificationUtils.FIELD_SEPARATOR + AbstractLimitViolationEntity.Fields.limitType)); + + checkZippedCsvResult("n-result", "/results/n-result-with-filter-en.csv", "en", AbstractLimitViolationEntity.Fields.subjectLimitViolation + SpecificationUtils.FIELD_SEPARATOR + SubjectLimitViolationEntity.Fields.subjectId, filterN); + checkZippedCsvResult("nmk-contingencies-result", "/results/nmk-contingencies-result-with-filter-en.csv", "en", ContingencyEntity.Fields.contingencyId, filterNmK); + checkZippedCsvResult("nmk-constraints-result", "/results/nmk-constraints-result-with-filter-en.csv", "en", SubjectLimitViolationEntity.Fields.subjectId, filterNmK); } private void checkCsvResultFromBytes(String expectedCsvResource, byte[] resultAsByteArray) throws Exception { @@ -1031,15 +1042,20 @@ private void checkCsvResultFromBytes(String expectedCsvResource, byte[] resultAs } } - private void checkZippedCsvResult(String resultType, String expectedCsvResource, String lang) throws Exception { + private void checkZippedCsvResult(String resultType, String expectedCsvResource, String lang, String sortField, List filter) throws Exception { CsvTranslationDTO csvTranslationDTO = CsvTranslationDTO.builder() .headers(getCsvHeaderFromResource(expectedCsvResource, lang)) .enumValueTranslations("en".equalsIgnoreCase(lang) ? ENUM_TRANSLATIONS_EN : ENUM_TRANSLATIONS_FR) .language(lang) .build(); + String jsonFilter = new ObjectMapper().writeValueAsString(filter); + String encodedFilter = URLEncoder.encode(jsonFilter, StandardCharsets.UTF_8); + // get csv file as binary (zip) byte[] resultAsByteArray = mockMvc.perform(post("/" + VERSION + "/results/" + RESULT_UUID + "/" + resultType + "/csv") + .param("sort", sortField) + .param("filters", encodedFilter) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(csvTranslationDTO))) .andExpectAll( diff --git a/src/test/resources/results/n-result-with-filter-en.csv b/src/test/resources/results/n-result-with-filter-en.csv new file mode 100644 index 00000000..a2dd6086 --- /dev/null +++ b/src/test/resources/results/n-result-with-filter-en.csv @@ -0,0 +1,3 @@ +Equipment,Violation type,Bus,Limit name,Load (% limit),Load (% PATL),Actual overload,Upcoming overload,Next limit name,Limit (A or kV),PATL (A),Calculated value (A or kV),Side +l3,Current,,l3_name,110,,,,,10,,11,Side 1 +l6,Current,,l6_name,110,,1200,,,10,,11,Side 1 diff --git a/src/test/resources/results/nmk-constraints-result-en.csv b/src/test/resources/results/nmk-constraints-result-en.csv index 812f5864..5937d594 100644 --- a/src/test/resources/results/nmk-constraints-result-en.csv +++ b/src/test/resources/results/nmk-constraints-result-en.csv @@ -9,6 +9,9 @@ l3,l8,Converged,Current,,l3_name,110,,,,,10,,11,Side 1 l3,l9,Converged,Current,,l3_name,110,,,,,10,,11,Side 1 l3,la,Converged,Current,,l3_name,110,,,,,10,,11,Side 1 l3,lb,Converged,Current,,l3_name,110,,,,,10,,11,Side 1 +l6,f1,Failed,Current,,l6_name,110,,1200,,,10,,11,Side 1 +l6,f2,Failed,Current,,l6_name,110,,1200,,,10,,11,Side 1 +l6,f3,Failed,Current,,l6_name,110,,1200,,,10,,11,Side 1 vl1,l1,Converged,High voltage,"vl1 (VLGEN_0, VLLOAD_0)",IST,,,0,,,400,,410, vl1,l2,Converged,High voltage,"vl1 (VLGEN_0, VLLOAD_0)",IST,,,0,,,400,,410, vl1,l3,Converged,High voltage,"vl1 (VLGEN_0, VLLOAD_0)",IST,,,0,,,400,,410, @@ -19,9 +22,6 @@ vl1,l8,Converged,High voltage,"vl1 (VLGEN_0, VLLOAD_0)",IST,,,0,,,400,,410, vl1,l9,Converged,High voltage,"vl1 (VLGEN_0, VLLOAD_0)",IST,,,0,,,400,,410, vl1,la,Converged,High voltage,"vl1 (VLGEN_0, VLLOAD_0)",IST,,,0,,,400,,410, vl1,lb,Converged,High voltage,"vl1 (VLGEN_0, VLLOAD_0)",IST,,,0,,,400,,410, -l6,f1,Failed,Current,,l6_name,110,,1200,,,10,,11,Side 1 -l6,f2,Failed,Current,,l6_name,110,,1200,,,10,,11,Side 1 -l6,f3,Failed,Current,,l6_name,110,,1200,,,10,,11,Side 1 vl7,f1,Failed,High voltage,vl7,vl7_name,,,0,,,400,,410, vl7,f2,Failed,High voltage,vl7,vl7_name,,,0,,,400,,410, vl7,f3,Failed,High voltage,vl7,vl7_name,,,0,,,400,,410, diff --git a/src/test/resources/results/nmk-constraints-result-fr.csv b/src/test/resources/results/nmk-constraints-result-fr.csv index 4ba1c9fb..cbd34dc6 100644 --- a/src/test/resources/results/nmk-constraints-result-fr.csv +++ b/src/test/resources/results/nmk-constraints-result-fr.csv @@ -9,6 +9,9 @@ l3;l8;Convergence;Intensité;;l3_name;110;;;;;10;;11;Côté 1 l3;l9;Convergence;Intensité;;l3_name;110;;;;;10;;11;Côté 1 l3;la;Convergence;Intensité;;l3_name;110;;;;;10;;11;Côté 1 l3;lb;Convergence;Intensité;;l3_name;110;;;;;10;;11;Côté 1 +l6;f1;Echec;Intensité;;l6_name;110;;1200;;;10;;11;Côté 1 +l6;f2;Echec;Intensité;;l6_name;110;;1200;;;10;;11;Côté 1 +l6;f3;Echec;Intensité;;l6_name;110;;1200;;;10;;11;Côté 1 vl1;l1;Convergence;Tension haute;vl1 (VLGEN_0, VLLOAD_0);IST;;;0;;;400;;410; vl1;l2;Convergence;Tension haute;vl1 (VLGEN_0, VLLOAD_0);IST;;;0;;;400;;410; vl1;l3;Convergence;Tension haute;vl1 (VLGEN_0, VLLOAD_0);IST;;;0;;;400;;410; @@ -19,9 +22,6 @@ vl1;l8;Convergence;Tension haute;vl1 (VLGEN_0, VLLOAD_0);IST;;;0;;;400;;410; vl1;l9;Convergence;Tension haute;vl1 (VLGEN_0, VLLOAD_0);IST;;;0;;;400;;410; vl1;la;Convergence;Tension haute;vl1 (VLGEN_0, VLLOAD_0);IST;;;0;;;400;;410; vl1;lb;Convergence;Tension haute;vl1 (VLGEN_0, VLLOAD_0);IST;;;0;;;400;;410; -l6;f1;Echec;Intensité;;l6_name;110;;1200;;;10;;11;Côté 1 -l6;f2;Echec;Intensité;;l6_name;110;;1200;;;10;;11;Côté 1 -l6;f3;Echec;Intensité;;l6_name;110;;1200;;;10;;11;Côté 1 vl7;f1;Echec;Tension haute;vl7;vl7_name;;;0;;;400;;410; vl7;f2;Echec;Tension haute;vl7;vl7_name;;;0;;;400;;410; vl7;f3;Echec;Tension haute;vl7;vl7_name;;;0;;;400;;410; diff --git a/src/test/resources/results/nmk-constraints-result-with-filter-en.csv b/src/test/resources/results/nmk-constraints-result-with-filter-en.csv new file mode 100644 index 00000000..79af21b7 --- /dev/null +++ b/src/test/resources/results/nmk-constraints-result-with-filter-en.csv @@ -0,0 +1,14 @@ +Equipment,Contingency,Status,Violation type,Bus,Limit name,Load (% limit),Load (% PATL),Actual overload,Upcoming overload,Next limit name,Limit (A or kV),PATL (A),Calculated value (A or kV),Side +l3,l1,Converged,Current,,l3_name,110,,,,,10,,11,Side 1 +l3,l2,Converged,Current,,l3_name,110,,,,,10,,11,Side 1 +l3,l3,Converged,Current,,l3_name,110,,,,,10,,11,Side 1 +l3,l4,Converged,Current,,l3_name,110,,,,,10,,11,Side 1 +l3,l6,Converged,Current,,l3_name,110,,,,,10,,11,Side 1 +l3,l7,Converged,Current,,l3_name,110,,,,,10,,11,Side 1 +l3,l8,Converged,Current,,l3_name,110,,,,,10,,11,Side 1 +l3,l9,Converged,Current,,l3_name,110,,,,,10,,11,Side 1 +l3,la,Converged,Current,,l3_name,110,,,,,10,,11,Side 1 +l3,lb,Converged,Current,,l3_name,110,,,,,10,,11,Side 1 +l6,f1,Failed,Current,,l6_name,110,,1200,,,10,,11,Side 1 +l6,f2,Failed,Current,,l6_name,110,,1200,,,10,,11,Side 1 +l6,f3,Failed,Current,,l6_name,110,,1200,,,10,,11,Side 1 diff --git a/src/test/resources/results/nmk-contingencies-result-en.csv b/src/test/resources/results/nmk-contingencies-result-en.csv index f68b5f24..890d6bc1 100644 --- a/src/test/resources/results/nmk-contingencies-result-en.csv +++ b/src/test/resources/results/nmk-contingencies-result-en.csv @@ -1,4 +1,10 @@ Contingency,Status,Equipment,Violation type,Bus,Limit name,Load (% limit),Load (% PATL),Actual overload,Upcoming overload,Next limit name,Limit (A or kV),PATL (A),Calculated value (A or kV),Side +f1,Failed,l6,Current,,l6_name,110,,1200,,,10,,11,Side 1 +f1,Failed,vl7,High voltage,vl7,vl7_name,,,0,,,400,,410, +f2,Failed,l6,Current,,l6_name,110,,1200,,,10,,11,Side 1 +f2,Failed,vl7,High voltage,vl7,vl7_name,,,0,,,400,,410, +f3,Failed,l6,Current,,l6_name,110,,1200,,,10,,11,Side 1 +f3,Failed,vl7,High voltage,vl7,vl7_name,,,0,,,400,,410, l1,Converged,l3,Current,,l3_name,110,,,,,10,,11,Side 1 l1,Converged,vl1,High voltage,"vl1 (VLGEN_0, VLLOAD_0)",IST,,,0,,,400,,410, l2,Converged,l3,Current,,l3_name,110,,,,,10,,11,Side 1 @@ -19,9 +25,3 @@ la,Converged,l3,Current,,l3_name,110,,,,,10,,11,Side 1 la,Converged,vl1,High voltage,"vl1 (VLGEN_0, VLLOAD_0)",IST,,,0,,,400,,410, lb,Converged,l3,Current,,l3_name,110,,,,,10,,11,Side 1 lb,Converged,vl1,High voltage,"vl1 (VLGEN_0, VLLOAD_0)",IST,,,0,,,400,,410, -f1,Failed,l6,Current,,l6_name,110,,1200,,,10,,11,Side 1 -f1,Failed,vl7,High voltage,vl7,vl7_name,,,0,,,400,,410, -f2,Failed,l6,Current,,l6_name,110,,1200,,,10,,11,Side 1 -f2,Failed,vl7,High voltage,vl7,vl7_name,,,0,,,400,,410, -f3,Failed,l6,Current,,l6_name,110,,1200,,,10,,11,Side 1 -f3,Failed,vl7,High voltage,vl7,vl7_name,,,0,,,400,,410, diff --git a/src/test/resources/results/nmk-contingencies-result-fr.csv b/src/test/resources/results/nmk-contingencies-result-fr.csv index d75cda30..5bb792e7 100644 --- a/src/test/resources/results/nmk-contingencies-result-fr.csv +++ b/src/test/resources/results/nmk-contingencies-result-fr.csv @@ -1,4 +1,10 @@ Aléa;Statut;Ouvrage;Type de contrainte;Noeud électrique;Nom de la limite;Charge (% limite);Charge (% IST);Tempo effective;Tempo imminente;Nom de la limite suivante;Limite (A ou kV);IST (A);Valeur calculée (A ou kV);Côté +f1;Echec;l6;Intensité;;l6_name;110;;1200;;;10;;11;Côté 1 +f1;Echec;vl7;Tension haute;vl7;vl7_name;;;0;;;400;;410; +f2;Echec;l6;Intensité;;l6_name;110;;1200;;;10;;11;Côté 1 +f2;Echec;vl7;Tension haute;vl7;vl7_name;;;0;;;400;;410; +f3;Echec;l6;Intensité;;l6_name;110;;1200;;;10;;11;Côté 1 +f3;Echec;vl7;Tension haute;vl7;vl7_name;;;0;;;400;;410; l1;Convergence;l3;Intensité;;l3_name;110;;;;;10;;11;Côté 1 l1;Convergence;vl1;Tension haute;vl1 (VLGEN_0, VLLOAD_0);IST;;;0;;;400;;410; l2;Convergence;l3;Intensité;;l3_name;110;;;;;10;;11;Côté 1 @@ -19,9 +25,3 @@ la;Convergence;l3;Intensité;;l3_name;110;;;;;10;;11;Côté 1 la;Convergence;vl1;Tension haute;vl1 (VLGEN_0, VLLOAD_0);IST;;;0;;;400;;410; lb;Convergence;l3;Intensité;;l3_name;110;;;;;10;;11;Côté 1 lb;Convergence;vl1;Tension haute;vl1 (VLGEN_0, VLLOAD_0);IST;;;0;;;400;;410; -f1;Echec;l6;Intensité;;l6_name;110;;1200;;;10;;11;Côté 1 -f1;Echec;vl7;Tension haute;vl7;vl7_name;;;0;;;400;;410; -f2;Echec;l6;Intensité;;l6_name;110;;1200;;;10;;11;Côté 1 -f2;Echec;vl7;Tension haute;vl7;vl7_name;;;0;;;400;;410; -f3;Echec;l6;Intensité;;l6_name;110;;1200;;;10;;11;Côté 1 -f3;Echec;vl7;Tension haute;vl7;vl7_name;;;0;;;400;;410; diff --git a/src/test/resources/results/nmk-contingencies-result-with-filter-en.csv b/src/test/resources/results/nmk-contingencies-result-with-filter-en.csv new file mode 100644 index 00000000..2b963e1c --- /dev/null +++ b/src/test/resources/results/nmk-contingencies-result-with-filter-en.csv @@ -0,0 +1,14 @@ +Contingency,Status,Equipment,Violation type,Bus,Limit name,Load (% limit),Load (% PATL),Actual overload,Upcoming overload,Next limit name,Limit (A or kV),PATL (A),Calculated value (A or kV),Side +f1,Failed,l6,Current,,l6_name,110,,1200,,,10,,11,Side 1 +f2,Failed,l6,Current,,l6_name,110,,1200,,,10,,11,Side 1 +f3,Failed,l6,Current,,l6_name,110,,1200,,,10,,11,Side 1 +l1,Converged,l3,Current,,l3_name,110,,,,,10,,11,Side 1 +l2,Converged,l3,Current,,l3_name,110,,,,,10,,11,Side 1 +l3,Converged,l3,Current,,l3_name,110,,,,,10,,11,Side 1 +l4,Converged,l3,Current,,l3_name,110,,,,,10,,11,Side 1 +l6,Converged,l3,Current,,l3_name,110,,,,,10,,11,Side 1 +l7,Converged,l3,Current,,l3_name,110,,,,,10,,11,Side 1 +l8,Converged,l3,Current,,l3_name,110,,,,,10,,11,Side 1 +l9,Converged,l3,Current,,l3_name,110,,,,,10,,11,Side 1 +la,Converged,l3,Current,,l3_name,110,,,,,10,,11,Side 1 +lb,Converged,l3,Current,,l3_name,110,,,,,10,,11,Side 1