Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pagination / filter / ordering #86

Merged
merged 108 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
3d76860
fix: new entities creation
Oct 4, 2023
12f4da9
fix: find / insert result fixed with new structure
Oct 4, 2023
321a978
fix: changed repository by service which is more accurate
Oct 4, 2023
4ebac81
fix: removed old entities
Oct 4, 2023
f641099
fix: changed table name
Oct 4, 2023
b1bb6ca
fix: tests, one last to fix
Oct 6, 2023
d22aaec
fix: add Lazy to ManyToOne relations
Oct 6, 2023
943d87d
fix: first implementation of new endpoints
Oct 6, 2023
9e30312
fix: all tests fixed, elements id/type added to DTO
Oct 9, 2023
a3274a9
fix: remove old changelog
Oct 9, 2023
612b8c5
fix: remove unused repository
Oct 9, 2023
6f2b461
fix: checkstyle
Oct 9, 2023
8531e89
fix: sonar bugs
Oct 9, 2023
8d07b01
fix: switch left to prepare future developments
Oct 9, 2023
004dccd
fix: add @Getter to DTO
Oct 9, 2023
2e3a91a
Merge remote-tracking branch 'origin/main' into fix_data_structure
Oct 9, 2023
4b09f16
fix: remove unused method
Oct 9, 2023
ceae040
fix: status now saved even if result does not exist yet
Oct 9, 2023
b49e364
fix: checkstyle
Oct 9, 2023
9c62720
fix: changelog
Oct 10, 2023
fa7e55b
feat: removed webflux - some tests not working yet
Oct 11, 2023
f673bfc
fix: remove webflux from supervision test class
Oct 11, 2023
39f167a
fix: async stop test
Oct 11, 2023
e3d1441
fix: checkstyle
Oct 11, 2023
d5c3f8f
fix: tests
Oct 11, 2023
a7f5ff0
fix: checkstyle
Oct 11, 2023
60ebf6d
fix: test
Oct 11, 2023
ce3830f
fix: mock had been removed by mistake
Oct 11, 2023
f47a2db
fix: interruption exception handling
Oct 11, 2023
165ebc6
fix: remove fixme
Oct 11, 2023
1915984
feat: first pageable implementation
Oct 12, 2023
8e7ddbb
fix: add copyright/author headers
Oct 12, 2023
90b3810
fix: add CONVERGED filter + add loading field to DTOs + checkstyle
Oct 12, 2023
7aa027e
fix: typo
Oct 12, 2023
18446eb
fix: move toEntity methods to entity classes
Oct 12, 2023
c29ba6c
fix: rename fromEntity
Oct 12, 2023
a8dc2ca
fix: renamed constraint by subjectLimitViolation
Oct 12, 2023
26e9efb
fix: update changelog
Oct 12, 2023
40e7c3b
fix: endpoints
Oct 12, 2023
05456eb
Merge remote-tracking branch 'origin/fix_data_structure' into remove_…
Oct 12, 2023
9ce3e94
Merge remote-tracking branch 'origin/remove_webflux' into pagination_…
Oct 12, 2023
a12d57a
fix: PR remarks
Oct 12, 2023
e6f4b0e
fix: first pagination implementation with working test
Oct 13, 2023
833708e
feat: move criteria methods to utils class + improve tests
Oct 16, 2023
399bfec
fix: tests an checkstyle
Oct 16, 2023
d0bd3e0
fix: PR remark
Oct 16, 2023
b093cee
fix: moved subjectName to subjectLimitViolationEntity
Oct 16, 2023
4da073b
fix: rename variable
Oct 16, 2023
cb4d7f2
Merge remote-tracking branch 'origin/remove_webflux' into pagination_…
Oct 16, 2023
cc19c5e
fix: DTO changes
Oct 17, 2023
e665987
fix: DTO and builder usage
Oct 17, 2023
4236b86
Merge remote-tracking branch 'origin/remove_webflux' into pagination_…
Oct 17, 2023
c2f3071
fix: checkstyle
Oct 17, 2023
eeb88f0
fix: remove PageDefault
Oct 17, 2023
53b274b
feat: implement other filters types
Oct 18, 2023
aa20f3a
fix: checkstyle
Oct 18, 2023
134e8a8
fix: test
Oct 18, 2023
891deba
feat: subjectLimitViolationRepository now working and tested
Oct 18, 2023
ea18403
fix: improve tests
Oct 18, 2023
f42ff76
fix: filterDTO + improve test coverage
Oct 18, 2023
b9a3b2d
fix: checkstyle
Oct 18, 2023
f053140
fix: code smells
Oct 18, 2023
1e57f37
fix: add tests, enum not working yet
Oct 18, 2023
e31f342
fix: remove CustomPageImpl
Oct 18, 2023
1ff1872
fix: enum now working with contains/startsWith + new tests
Oct 18, 2023
fea211b
fix: checkstyle
Oct 18, 2023
18a21c2
fix: escape query string
Oct 19, 2023
e969bd7
Merge remote-tracking branch 'origin/main' into pagination_filter_ord…
Oct 20, 2023
8801a98
fix: remove unused changelog
Oct 20, 2023
fefd378
fix: create parent interface to reduce code duplication
Oct 20, 2023
15ba896
fix: add comments + fix code smell
Oct 20, 2023
70c7e94
fix: improve code coverage by testing edge cases
Oct 20, 2023
1bf454c
fix: add 'paged' to endpoints
Oct 23, 2023
175f120
fix: remove paged from n endpoint
Oct 24, 2023
e2531c7
fix: test
Oct 24, 2023
f782e31
feat: add equals filter to handle enum select filters + rename filterDTO
Oct 25, 2023
3446e2c
fix: renamed computationStatus with status
Oct 25, 2023
981a461
fix: add urldecode for filters
Oct 25, 2023
286c98f
feat: add enum endpoints
Oct 26, 2023
1336d70
fix: PR remark and checkstyle
Oct 26, 2023
f904d83
fix: PR remarks
Oct 30, 2023
47d4ca2
fix: urldecode causes NPE if string is null
Oct 30, 2023
61ff9e6
Merge remote-tracking branch 'origin/main' into pagination_filter_ord…
Oct 30, 2023
66dd276
fix: sonar code smell
Oct 30, 2023
d27e517
fix: checkstyle
Oct 30, 2023
e25701d
fix: pagination is now made correctly instead of being made in memory
Nov 3, 2023
b1c74b8
fix: n+1 requests byu fetching ManyToOne relation in specification
Nov 3, 2023
a6e285c
Merge remote-tracking branch 'origin/main' into pagination_filter_ord…
Nov 3, 2023
ddc9101
fix: filter some more limit types
Nov 3, 2023
ea6431f
fix: make string filters case insensitive
Nov 3, 2023
e98a21b
fix: checkstyle
Nov 3, 2023
35eb775
fix: sonar code smells and bugs
Nov 6, 2023
0be8e5a
fix: circular reference
Nov 6, 2023
28bce8b
fix: checkstyle
Nov 6, 2023
4e4867d
Merge remote-tracking branch 'origin/main' into pagination_filter_ord…
Nov 6, 2023
4ea92b4
fix: checkstyle
Nov 6, 2023
89572df
fix: sonar bug
Nov 6, 2023
8adaba3
fix: enum was not excluded properly
Nov 6, 2023
f618f82
fix: filtering children now filters parents if they happen to be empty
Nov 6, 2023
929b7f0
Revert "fix: filtering children now filters parents if they happen to…
Nov 7, 2023
9aebfd1
fix: remove children filtering because of unwanted behaviour
Nov 7, 2023
2885266
fix: remove obsolete code
Nov 7, 2023
570fced
fix: remove obsolete endpoints + add test
Nov 7, 2023
4e1d90b
fix: checkstyle
Nov 7, 2023
3ea3e72
fix: copyright/author header + checkstyle
Nov 7, 2023
9955ae3
fix: add entitygraph option to prevent n+1 fetching
Nov 7, 2023
c70af99
fix: add select count to prevent future problems
Nov 7, 2023
c408ebc
fix: improve javadoc according to PR remarks
Nov 9, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<jib.from.image>gridsuite/java-simulator:2.0.0</jib.from.image>
<gridsuite-dependencies.version>27</gridsuite-dependencies.version>
<liquibase-hibernate-package>org.gridsuite.securityanalysis.server</liquibase-hibernate-package>
<db-util.version>1.0.5</db-util.version>
</properties>

<build>
Expand Down Expand Up @@ -271,6 +272,12 @@
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>db-util</artifactId>
<version>${db-util.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ protected ResponseEntity<Object> handleStudyException(SecurityAnalysisException
switch (exception.getType()) {
case RESULT_NOT_FOUND :
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(exception.getType());
case INVALID_FILTER_FORMAT:
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(exception.getType());
default:
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.*;
import com.powsybl.commons.reporter.ReporterModelDeserializer;
import com.powsybl.commons.reporter.ReporterModelJsonModule;
import com.powsybl.contingency.json.ContingencyJsonModule;
Expand Down Expand Up @@ -46,7 +45,8 @@ public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter()
}

private ObjectMapper createObjectMapper() {
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json()
.featuresToEnable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS).build();
objectMapper.registerModule(new ContingencyJsonModule());
objectMapper.registerModule(new SecurityAnalysisJsonModule());
objectMapper.registerModule(new LoadFlowParametersJsonModule());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package org.gridsuite.securityanalysis.server;

import com.powsybl.loadflow.LoadFlowResult;
import com.powsybl.security.SecurityAnalysisResult;
import com.powsybl.security.results.PreContingencyResult;
import io.swagger.v3.oas.annotations.Operation;
Expand All @@ -15,17 +16,19 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.gridsuite.securityanalysis.server.dto.SubjectLimitViolationResultDTO;
import org.gridsuite.securityanalysis.server.dto.ContingencyResultDTO;
import org.gridsuite.securityanalysis.server.dto.SecurityAnalysisParametersInfos;
import org.gridsuite.securityanalysis.server.dto.SecurityAnalysisStatus;
import org.gridsuite.securityanalysis.server.dto.*;
import org.gridsuite.securityanalysis.server.service.SecurityAnalysisResultService;
import org.gridsuite.securityanalysis.server.service.SecurityAnalysisRunContext;
import org.gridsuite.securityanalysis.server.service.SecurityAnalysisService;
import org.gridsuite.securityanalysis.server.service.SecurityAnalysisWorkerService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
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;

Expand All @@ -40,13 +43,16 @@
@RequestMapping(value = "/" + SecurityAnalysisApi.API_VERSION)
@Tag(name = "Security analysis server")
public class SecurityAnalysisController {
private final SecurityAnalysisService service;
private final SecurityAnalysisService securityAnalysisService;

private final SecurityAnalysisResultService securityAnalysisResultService;

private final SecurityAnalysisWorkerService workerService;

public SecurityAnalysisController(SecurityAnalysisService service, SecurityAnalysisWorkerService workerService) {
this.service = service;
public SecurityAnalysisController(SecurityAnalysisService securityAnalysisService, SecurityAnalysisWorkerService workerService, SecurityAnalysisResultService securityAnalysisResultService) {
this.securityAnalysisService = securityAnalysisService;
this.workerService = workerService;
this.securityAnalysisResultService = securityAnalysisResultService;
}

@PostMapping(value = "/networks/{networkUuid}/run", produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
Expand All @@ -62,7 +68,7 @@ public ResponseEntity<SecurityAnalysisResult> run(@Parameter(description = "Netw
@Parameter(description = "reportUuid") @RequestParam(name = "reportUuid", required = false) UUID reportUuid,
@Parameter(description = "reporterId") @RequestParam(name = "reporterId", required = false) String reporterId,
@RequestBody(required = false) SecurityAnalysisParametersInfos parameters) {
String providerToUse = provider != null ? provider : service.getDefaultProvider();
String providerToUse = provider != null ? provider : securityAnalysisService.getDefaultProvider();
SecurityAnalysisResult result = workerService.run(new SecurityAnalysisRunContext(networkUuid, variantId, contigencyListNames, null, providerToUse, parameters, reportUuid, reporterId));

return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result);
Expand All @@ -82,8 +88,8 @@ public ResponseEntity<UUID> runAndSave(@Parameter(description = "Network UUID")
@Parameter(description = "reportUuid") @RequestParam(name = "reportUuid", required = false) UUID reportUuid,
@Parameter(description = "reporterId") @RequestParam(name = "reporterId", required = false) String reporterId,
@RequestBody(required = false) SecurityAnalysisParametersInfos parameters) {
String providerToUse = provider != null ? provider : service.getDefaultProvider();
UUID resultUuid = service.runAndSaveResult(new SecurityAnalysisRunContext(networkUuid, variantId, contigencyListNames, receiver, providerToUse, parameters, reportUuid, reporterId));
String providerToUse = provider != null ? provider : securityAnalysisService.getDefaultProvider();
UUID resultUuid = securityAnalysisService.runAndSaveResult(new SecurityAnalysisRunContext(networkUuid, variantId, contigencyListNames, receiver, providerToUse, parameters, reportUuid, reporterId));
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(resultUuid);
}

Expand All @@ -92,32 +98,37 @@ public ResponseEntity<UUID> runAndSave(@Parameter(description = "Network UUID")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result"),
@ApiResponse(responseCode = "404", description = "Security analysis result has not been found")})
public ResponseEntity<PreContingencyResult> getNResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {
PreContingencyResult result = service.getNResult(resultUuid);
PreContingencyResult result = securityAnalysisResultService.findNResult(resultUuid);

return result != null
? ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result)
: ResponseEntity.notFound().build();
}

@GetMapping(value = "/results/{resultUuid}/nmk-contingencies-result", produces = APPLICATION_JSON_VALUE)
@GetMapping(value = "/results/{resultUuid}/nmk-contingencies-result/paged", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Get a security analysis result from the database - NMK contingencies result")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result"),
@ApiResponse(responseCode = "404", description = "Security analysis result has not been found")})
public ResponseEntity<List<ContingencyResultDTO>> getNmKContingenciesResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {
List<ContingencyResultDTO> result = service.getNmKContingenciesResult(resultUuid);
public ResponseEntity<Page<ContingencyResultDTO>> getNmKContingenciesResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid,
@Parameter(description = "Filters") @RequestParam(name = "filters", required = false) String stringFilters,
Tristan-WorkGH marked this conversation as resolved.
Show resolved Hide resolved
@Parameter(description = "Pagination parameters") Pageable pageable) {
String decodedStringFilters = stringFilters != null ? URLDecoder.decode(stringFilters, StandardCharsets.UTF_8) : null;
Page<ContingencyResultDTO> result = securityAnalysisResultService.findNmKContingenciesResult(resultUuid, decodedStringFilters, pageable);

return result != null
? ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result)
: ResponseEntity.notFound().build();
}

@GetMapping(value = "/results/{resultUuid}/nmk-constraints-result", produces = APPLICATION_JSON_VALUE)
@GetMapping(value = "/results/{resultUuid}/nmk-constraints-result/paged", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Get a security analysis result from the database - NMK contingencies result")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result"),
@ApiResponse(responseCode = "404", description = "Security analysis result has not been found")})
public ResponseEntity<List<SubjectLimitViolationResultDTO>> getNmKConstraintsResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {

List<SubjectLimitViolationResultDTO> result = service.getNmKConstraintsResult(resultUuid);
public ResponseEntity<Page<SubjectLimitViolationResultDTO>> getNmKConstraintsResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid,
@Parameter(description = "Filters") @RequestParam(name = "filters", required = false) String stringFilters,
@Parameter(description = "Pagination parameters") Pageable pageable) {
String decodedStringFilters = stringFilters != null ? URLDecoder.decode(stringFilters, StandardCharsets.UTF_8) : null;
Page<SubjectLimitViolationResultDTO> result = securityAnalysisResultService.findNmKConstraintsResult(resultUuid, decodedStringFilters, pageable);
return result != null
? ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result)
: ResponseEntity.notFound().build();
Expand All @@ -127,31 +138,31 @@ public ResponseEntity<List<SubjectLimitViolationResultDTO>> getNmKConstraintsRes
@Operation(summary = "Delete a security analysis result from the database")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result has been deleted")})
public ResponseEntity<Void> deleteResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {
service.deleteResult(resultUuid);
securityAnalysisService.deleteResult(resultUuid);
return ResponseEntity.ok().build();
}

@DeleteMapping(value = "/results", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Delete all security analysis results from the database")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "All security analysis results have been deleted")})
public ResponseEntity<Void> deleteResults() {
service.deleteResults();
securityAnalysisService.deleteResults();
return ResponseEntity.ok().build();
}

@GetMapping(value = "/results/{resultUuid}/status", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Get the security analysis status from the database")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis status")})
public ResponseEntity<SecurityAnalysisStatus> getStatus(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {
SecurityAnalysisStatus result = service.getStatus(resultUuid);
SecurityAnalysisStatus result = securityAnalysisService.getStatus(resultUuid);
return ResponseEntity.ok().body(result);
}

@PutMapping(value = "/results/invalidate-status", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Invalidate the security analysis status from the database")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis status has been invalidated")})
public ResponseEntity<Void> invalidateStatus(@Parameter(description = "Result uuids") @RequestParam(name = "resultUuid") List<UUID> resultUuids) {
service.setStatus(resultUuids, SecurityAnalysisStatus.NOT_DONE);
securityAnalysisService.setStatus(resultUuids, SecurityAnalysisStatus.NOT_DONE);
return ResponseEntity.ok().build();
}

Expand All @@ -160,7 +171,7 @@ public ResponseEntity<Void> invalidateStatus(@Parameter(description = "Result uu
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis has been stopped")})
public ResponseEntity<Void> stop(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid,
@Parameter(description = "Result receiver") @RequestParam(name = "receiver", required = false) String receiver) {
service.stop(resultUuid, receiver);
securityAnalysisService.stop(resultUuid, receiver);
return ResponseEntity.ok().build();
}

Expand All @@ -169,13 +180,20 @@ public ResponseEntity<Void> stop(@Parameter(description = "Result UUID") @PathVa
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Security analysis providers have been found")})
public ResponseEntity<List<String>> getProviders() {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON)
.body(service.getProviders());
.body(securityAnalysisService.getProviders());
}

@GetMapping(value = "/default-provider", produces = TEXT_PLAIN_VALUE)
@Operation(summary = "Get security analysis default provider")
@ApiResponses(@ApiResponse(responseCode = "200", description = "The security analysis default provider has been found"))
public ResponseEntity<String> getDefaultProvider() {
return ResponseEntity.ok().body(service.getDefaultProvider());
return ResponseEntity.ok().body(securityAnalysisService.getDefaultProvider());
}

@GetMapping(value = "/computation-status", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Get available computation status")
@ApiResponses(@ApiResponse(responseCode = "200", description = "List of available computation status"))
public ResponseEntity<LoadFlowResult.ComponentResult.Status[]> getComputationStatus() {
return ResponseEntity.ok().body(LoadFlowResult.ComponentResult.Status.values());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
@Builder
public class ContingencyDTO {
private String contingencyId;
private String computationStatus;
private String status;
private List<ContingencyElementDTO> elements;

public static ContingencyDTO toDto(ContingencyEntity contingency) {
return ContingencyDTO.builder()
.contingencyId(contingency.getContingencyId())
.computationStatus(contingency.getStatus())
.status(contingency.getStatus())
.elements(contingency.getContingencyElements().stream().map(ContingencyElementDTO::toDto).collect(Collectors.toList()))
.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright (c) 2023, 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.securityanalysis.server.dto;

import com.fasterxml.jackson.annotation.JsonProperty;

/**
* An object that can be used to filter data with the JPA Criteria API (via Spring Specification)
* @param dataType the type of data we want to filter (text, number)
* @param type the type of filter (contains, startsWith...)
* @param value the value of the filter
* @param column the column / field on which the filter will be applied
*
* @author Kevin Le Saulnier <kevin.lesaulnier at rte-france.com>
*/
public record ResourceFilterDTO(DataType dataType, Type type, Object value, Column column) {

public enum DataType {
@JsonProperty("text")
Tristan-WorkGH marked this conversation as resolved.
Show resolved Hide resolved
TEXT,
}

public enum Type {
Tristan-WorkGH marked this conversation as resolved.
Show resolved Hide resolved
CONTAINS,
@JsonProperty("startsWith")
Tristan-WorkGH marked this conversation as resolved.
Show resolved Hide resolved
STARTS_WITH,
EQUALS
}

public enum Column {
@JsonProperty("contingencyId")
CONTINGENCY_ID,
STATUS,
@JsonProperty("subjectId")
SUBJECT_ID
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
@Entity
@Table(name = "contingency_limit_violation")
public class ContingencyLimitViolationEntity extends AbstractLimitViolationEntity {
@ManyToOne(fetch = FetchType.LAZY)
@ManyToOne
@Setter
private ContingencyEntity contingency;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import jakarta.persistence.*;
import lombok.*;
import org.gridsuite.securityanalysis.server.dto.SecurityAnalysisStatus;
import org.gridsuite.securityanalysis.server.service.SecurityAnalysisResultService;
import org.jgrapht.alg.util.Pair;

import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -51,7 +51,7 @@ public SecurityAnalysisResultEntity(UUID id) {
}

public static SecurityAnalysisResultEntity toEntity(UUID resultUuid, SecurityAnalysisResult securityAnalysisResult, SecurityAnalysisStatus securityAnalysisStatus) {
Map<String, SubjectLimitViolationEntity> subjectLimitViolationsBySubjectId = SecurityAnalysisResultService.getUniqueSubjectLimitViolationsFromResult(securityAnalysisResult)
Map<String, SubjectLimitViolationEntity> subjectLimitViolationsBySubjectId = getUniqueSubjectLimitViolationsFromResult(securityAnalysisResult)
.stream().collect(Collectors.toMap(
SubjectLimitViolationEntity::getSubjectId,
subjectLimitViolation -> subjectLimitViolation)
Expand Down Expand Up @@ -85,4 +85,14 @@ public static SecurityAnalysisResultEntity toEntity(UUID resultUuid, SecurityAna
subjectLimitViolations.forEach(subjectLimitViolation -> subjectLimitViolation.setResult(securityAnalysisResultEntity));
return securityAnalysisResultEntity;
}

private static List<SubjectLimitViolationEntity> getUniqueSubjectLimitViolationsFromResult(SecurityAnalysisResult securityAnalysisResult) {
return Stream.concat(
securityAnalysisResult.getPostContingencyResults().stream().flatMap(pcr -> pcr.getLimitViolationsResult().getLimitViolations().stream()),
securityAnalysisResult.getPreContingencyResult().getLimitViolationsResult().getLimitViolations().stream())
.map(lm -> new Pair<>(lm.getSubjectId(), lm.getSubjectName()))
.distinct()
.map(pair -> new SubjectLimitViolationEntity(pair.getFirst(), pair.getSecond()))
.toList();
}
}
Loading
Loading