From 9eed97f9daf845871e778973fa8cf165ba658465 Mon Sep 17 00:00:00 2001 From: Florent MILLOT <75525996+flomillot@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:33:24 +0100 Subject: [PATCH] Migration of the parameters from study-server (#59) The parameters are now stored directly in this service. Only the UUID for each study is stored in study-server. Signed-off-by: Florent MILLOT --- pom.xml | 19 -- .../server/SensitivityAnalysisController.java | 29 +- ...nsitivityAnalysisParametersController.java | 96 +++++++ .../server/dto/ReportInfos.java | 20 ++ .../server/dto/SensitivityHVDC.java | 4 + .../server/dto/SensitivityInjection.java | 4 + .../server/dto/SensitivityInjectionsSet.java | 4 + .../server/dto/SensitivityNodes.java | 4 + .../server/dto/SensitivityPST.java | 4 + .../parameters/LoadFlowParametersValues.java | 22 ++ .../SensitivityAnalysisParametersInfos.java | 66 +++++ .../AbstractSensitivityFactorEntity.java | 57 ++++ .../EquipmentsContainerEmbeddable.java | 48 ++++ .../SensitivityAnalysisParametersEntity.java | 233 ++++++++++++++++ .../SensitivityFactorForInjectionEntity.java | 24 ++ .../SensitivityFactorForNodeEntity.java | 24 ++ ...ensitivityFactorWithDistribTypeEntity.java | 30 ++ ...ivityFactorWithSensiTypeForHvdcEntity.java | 30 ++ ...tivityFactorWithSensiTypeForPstEntity.java | 30 ++ ...nsitivityAnalysisParametersRepository.java | 19 ++ .../SensitivityAnalysisParametersService.java | 113 ++++++++ .../SensitivityAnalysisResultContext.java | 3 +- .../SensitivityAnalysisRunContext.java | 11 +- .../service/SensitivityAnalysisService.java | 17 +- .../SensitivityAnalysisWorkerService.java | 22 +- .../changesets/changelog_20231226T170539Z.xml | 105 +++++++ .../db/changelog/db.changelog-master.yaml | 3 + .../SensitivityAnalysisControllerTest.java | 172 +++++------- .../SensitivityAnalysisParametersTest.java | 263 ++++++++++++++++++ .../dto/SensitivityAnalysisInputDataTest.java | 6 +- .../SensitivityAnalysisServiceTest.java | 102 +++---- .../server/util/assertions/Assertions.java | 53 ++++ .../server/util/assertions/DTOAssert.java | 38 +++ 33 files changed, 1461 insertions(+), 214 deletions(-) create mode 100644 src/main/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisParametersController.java create mode 100644 src/main/java/org/gridsuite/sensitivityanalysis/server/dto/ReportInfos.java create mode 100644 src/main/java/org/gridsuite/sensitivityanalysis/server/dto/parameters/LoadFlowParametersValues.java create mode 100644 src/main/java/org/gridsuite/sensitivityanalysis/server/dto/parameters/SensitivityAnalysisParametersInfos.java create mode 100644 src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/AbstractSensitivityFactorEntity.java create mode 100644 src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/EquipmentsContainerEmbeddable.java create mode 100644 src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityAnalysisParametersEntity.java create mode 100644 src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorForInjectionEntity.java create mode 100644 src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorForNodeEntity.java create mode 100644 src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorWithDistribTypeEntity.java create mode 100644 src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorWithSensiTypeForHvdcEntity.java create mode 100644 src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorWithSensiTypeForPstEntity.java create mode 100644 src/main/java/org/gridsuite/sensitivityanalysis/server/repositories/SensitivityAnalysisParametersRepository.java create mode 100644 src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisParametersService.java create mode 100644 src/main/resources/db/changelog/changesets/changelog_20231226T170539Z.xml create mode 100644 src/test/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisParametersTest.java create mode 100644 src/test/java/org/gridsuite/sensitivityanalysis/server/util/assertions/Assertions.java create mode 100644 src/test/java/org/gridsuite/sensitivityanalysis/server/util/assertions/DTOAssert.java diff --git a/pom.xml b/pom.xml index 28552664..73ec21a6 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,6 @@ 2.7.0 org.gridsuite.sensitivityanalysis.server - 3.11.1 1.0.5 @@ -222,11 +221,6 @@ junit-vintage-engine test - - org.mockito - mockito-core - test - org.springframework.boot spring-boot-starter-test @@ -248,19 +242,6 @@ ${db-util.version} test - - - - - org.mockito - mockito-inline - ${mockito-inline.version} - test - diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisController.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisController.java index 28d60ec7..aee9154b 100644 --- a/src/main/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisController.java +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisController.java @@ -17,22 +17,17 @@ 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.sensitivityanalysis.server.dto.SensitivityAnalysisCsvFileInfos; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityAnalysisInputData; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityAnalysisStatus; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityResultFilterOptions; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityRunQueryResult; +import org.gridsuite.sensitivityanalysis.server.dto.*; import org.gridsuite.sensitivityanalysis.server.dto.nonevacuatedenergy.NonEvacuatedEnergyInputData; import org.gridsuite.sensitivityanalysis.server.dto.nonevacuatedenergy.NonEvacuatedEnergyStatus; -import org.gridsuite.sensitivityanalysis.server.service.SensitivityAnalysisRunContext; +import org.gridsuite.sensitivityanalysis.server.dto.parameters.LoadFlowParametersValues; +import org.gridsuite.sensitivityanalysis.server.dto.resultselector.ResultTab; +import org.gridsuite.sensitivityanalysis.server.dto.resultselector.ResultsSelector; import org.gridsuite.sensitivityanalysis.server.service.SensitivityAnalysisService; import org.gridsuite.sensitivityanalysis.server.service.SensitivityAnalysisWorkerService; -import org.springframework.http.HttpHeaders; import org.gridsuite.sensitivityanalysis.server.service.nonevacuatedenergy.NonEvacuatedEnergyRunContext; import org.gridsuite.sensitivityanalysis.server.service.nonevacuatedenergy.NonEvacuatedEnergyService; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityFactorsIdsByGroup; -import org.gridsuite.sensitivityanalysis.server.dto.resultselector.ResultTab; -import org.gridsuite.sensitivityanalysis.server.dto.resultselector.ResultsSelector; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -41,9 +36,7 @@ import java.util.UUID; import static org.gridsuite.sensitivityanalysis.server.service.NotificationService.HEADER_USER_ID; -import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; -import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM; -import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE; +import static org.springframework.http.MediaType.*; /** * @author Franck Lecuyer @@ -87,9 +80,10 @@ public ResponseEntity run(@Parameter(description = "N @Parameter(description = "reportUuid") @RequestParam(name = "reportUuid", required = false) UUID reportUuid, @Parameter(description = "reporterId") @RequestParam(name = "reporterId", required = false) String reporterId, @Parameter(description = "The type name for the report") @RequestParam(name = "reportType", required = false, defaultValue = "SensitivityAnalysis") String reportType, - @RequestBody SensitivityAnalysisInputData sensitivityAnalysisInputData, + @Parameter(description = "parametersUuid") @RequestParam(name = "parametersUuid", required = false) UUID parametersUuid, + @RequestBody LoadFlowParametersValues loadFlowParametersValues, @RequestHeader(HEADER_USER_ID) String userId) { - SensitivityAnalysisResult result = workerService.run(new SensitivityAnalysisRunContext(networkUuid, variantId, sensitivityAnalysisInputData, null, provider, reportUuid, reporterId, reportType, userId)); + SensitivityAnalysisResult result = workerService.run(networkUuid, variantId, provider, new ReportInfos(reportUuid, reporterId, reportType), userId, parametersUuid, loadFlowParametersValues); return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result); } @@ -106,9 +100,10 @@ public ResponseEntity 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, @Parameter(description = "The type name for the report") @RequestParam(name = "reportType", required = false, defaultValue = "SensitivityAnalysis") String reportType, - @RequestBody SensitivityAnalysisInputData sensitivityAnalysisInputData, + @Parameter(description = "parametersUuid") @RequestParam(name = "parametersUuid", required = false) UUID parametersUuid, + @RequestBody LoadFlowParametersValues loadFlowParametersValues, @RequestHeader(HEADER_USER_ID) String userId) { - UUID resultUuid = service.runAndSaveResult(new SensitivityAnalysisRunContext(networkUuid, variantId, sensitivityAnalysisInputData, receiver, provider, reportUuid, reporterId, reportType, userId)); + UUID resultUuid = service.runAndSaveResult(networkUuid, variantId, receiver, provider, new ReportInfos(reportUuid, reporterId, reportType), userId, parametersUuid, loadFlowParametersValues); return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(resultUuid); } diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisParametersController.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisParametersController.java new file mode 100644 index 00000000..8b8cff36 --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisParametersController.java @@ -0,0 +1,96 @@ +/** + * 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.sensitivityanalysis.server; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.gridsuite.sensitivityanalysis.server.dto.parameters.SensitivityAnalysisParametersInfos; +import org.gridsuite.sensitivityanalysis.server.service.SensitivityAnalysisParametersService; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.UUID; + +/** + * @author Florent MILLOT + */ + +@RestController +@RequestMapping(value = "/" + SensitivityAnalysisApi.API_VERSION + "/parameters") +@Tag(name = "Sensitivity analysis parameters") +public class SensitivityAnalysisParametersController { + + private final SensitivityAnalysisParametersService parametersService; + + public SensitivityAnalysisParametersController(SensitivityAnalysisParametersService parametersService) { + this.parametersService = parametersService; + } + + @PostMapping(value = "/default", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Create default parameters") + @ApiResponse(responseCode = "200", description = "Default parameters were created") + public ResponseEntity createDefaultParameters() { + return ResponseEntity.ok(parametersService.createDefaultParameters()); + } + + @PostMapping(value = "", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Create parameters") + @ApiResponse(responseCode = "200", description = "parameters were created") + public ResponseEntity createParameters( + @RequestBody SensitivityAnalysisParametersInfos parametersInfos) { + return ResponseEntity.ok(parametersService.createParameters(parametersInfos)); + } + + @PostMapping(value = "/{sourceParametersUuid}", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Duplicate parameters") + @ApiResponse(responseCode = "200", description = "parameters were duplicated") + @ApiResponse(responseCode = "404", description = "source parameters were not found") + public ResponseEntity duplicateParameters( + @Parameter(description = "source parameters UUID") @PathVariable("sourceParametersUuid") UUID sourceParametersUuid) { + return ResponseEntity.of(parametersService.duplicateParameters(sourceParametersUuid)); + } + + @GetMapping(value = "/{uuid}", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Get parameters") + @ApiResponse(responseCode = "200", description = "parameters were returned") + @ApiResponse(responseCode = "404", description = "parameters were not found") + public ResponseEntity getParameters( + @Parameter(description = "parameters UUID") @PathVariable("uuid") UUID parametersUuid) { + return ResponseEntity.of(parametersService.getParameters(parametersUuid)); + } + + @GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Get all parameters") + @ApiResponse(responseCode = "200", description = "the list of all parameters was returned") + public ResponseEntity> getAllParameters() { + return ResponseEntity.ok(parametersService.getAllParameters()); + } + + @PutMapping(value = "/{uuid}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Update parameters") + @ApiResponse(responseCode = "200", description = "parameters were updated") + public ResponseEntity updateParameters( + @Parameter(description = "parameters UUID") @PathVariable("uuid") UUID parametersUuid, + @RequestBody SensitivityAnalysisParametersInfos parametersInfos) { + parametersService.updateParameters(parametersUuid, parametersInfos); + return ResponseEntity.ok().build(); + } + + @DeleteMapping(value = "/{uuid}", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Delete parameters") + @ApiResponse(responseCode = "200", description = "parameters were deleted") + public ResponseEntity deleteParameters( + @Parameter(description = "parameters UUID") @PathVariable("uuid") UUID parametersUuid) { + parametersService.deleteParameters(parametersUuid); + return ResponseEntity.ok().build(); + } +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/ReportInfos.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/ReportInfos.java new file mode 100644 index 00000000..9b308632 --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/ReportInfos.java @@ -0,0 +1,20 @@ +/** + * 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.sensitivityanalysis.server.dto; + +import java.util.UUID; + +/** + * @author Florent MILLOT + */ +public record ReportInfos( + UUID reportUuid, + String reporterId, + String reportType +) { +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityHVDC.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityHVDC.java index 5823383d..a227ffa3 100644 --- a/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityHVDC.java +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityHVDC.java @@ -7,6 +7,7 @@ package org.gridsuite.sensitivityanalysis.server.dto; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -18,6 +19,7 @@ * @author Franck Lecuyer */ @SuperBuilder +@AllArgsConstructor @NoArgsConstructor @Getter @Setter @@ -30,4 +32,6 @@ public class SensitivityHVDC { List hvdcs; List contingencies; + + boolean activated; } diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityInjection.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityInjection.java index b8791240..ed204c04 100644 --- a/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityInjection.java +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityInjection.java @@ -7,6 +7,7 @@ package org.gridsuite.sensitivityanalysis.server.dto; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -18,6 +19,7 @@ * @author Franck Lecuyer */ @SuperBuilder +@AllArgsConstructor @NoArgsConstructor @Getter @Setter @@ -28,5 +30,7 @@ public class SensitivityInjection { List injections; List contingencies; + + boolean activated; } diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityInjectionsSet.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityInjectionsSet.java index b0e4229c..9bfb2ecb 100644 --- a/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityInjectionsSet.java +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityInjectionsSet.java @@ -7,6 +7,7 @@ package org.gridsuite.sensitivityanalysis.server.dto; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -18,6 +19,7 @@ * @author Franck Lecuyer */ @SuperBuilder +@AllArgsConstructor @NoArgsConstructor @Getter @Setter @@ -30,4 +32,6 @@ public class SensitivityInjectionsSet { SensitivityAnalysisInputData.DistributionType distributionType; List contingencies; + + boolean activated; } diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityNodes.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityNodes.java index 176a8203..85871643 100644 --- a/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityNodes.java +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityNodes.java @@ -7,6 +7,7 @@ package org.gridsuite.sensitivityanalysis.server.dto; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -18,6 +19,7 @@ * @author Franck Lecuyer */ @SuperBuilder +@AllArgsConstructor @NoArgsConstructor @Getter @Setter @@ -28,5 +30,7 @@ public class SensitivityNodes { List equipmentsInVoltageRegulation; List contingencies; + + boolean activated; } diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityPST.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityPST.java index 2ba573b4..0be6cf4e 100644 --- a/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityPST.java +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityPST.java @@ -7,6 +7,7 @@ package org.gridsuite.sensitivityanalysis.server.dto; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -18,6 +19,7 @@ * @author Franck Lecuyer */ @SuperBuilder +@AllArgsConstructor @NoArgsConstructor @Getter @Setter @@ -30,5 +32,7 @@ public class SensitivityPST { List psts; List contingencies; + + boolean activated; } diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/parameters/LoadFlowParametersValues.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/parameters/LoadFlowParametersValues.java new file mode 100644 index 00000000..a0af08d1 --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/parameters/LoadFlowParametersValues.java @@ -0,0 +1,22 @@ +/** + 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.sensitivityanalysis.server.dto.parameters; + +import com.powsybl.loadflow.LoadFlowParameters; +import lombok.Builder; + +import java.util.Map; + +/** + * @author David Braquart + */ +@Builder +public record LoadFlowParametersValues( + LoadFlowParameters commonParameters, + Map specificParameters) { +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/parameters/SensitivityAnalysisParametersInfos.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/parameters/SensitivityAnalysisParametersInfos.java new file mode 100644 index 00000000..53c35ddc --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/dto/parameters/SensitivityAnalysisParametersInfos.java @@ -0,0 +1,66 @@ +/** + * 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.sensitivityanalysis.server.dto.parameters; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import org.gridsuite.sensitivityanalysis.server.dto.*; +import org.gridsuite.sensitivityanalysis.server.entities.parameters.SensitivityAnalysisParametersEntity; + +import java.time.ZonedDateTime; +import java.util.List; +import java.util.UUID; + +/** + * @author Ghazwa Rehili + */ +@Getter +@Setter +@AllArgsConstructor +@Builder +@NoArgsConstructor +@Schema(description = "Sensitivity analysis parameters") +public class SensitivityAnalysisParametersInfos { + + @Schema(description = "Parameters ID") + private UUID uuid; + + @Schema(description = "Parameters date") + private ZonedDateTime date; + + @Schema(description = "Parameters name") + private String name; + + @Builder.Default + private double flowFlowSensitivityValueThreshold = 0.0; + + @Builder.Default + private double angleFlowSensitivityValueThreshold = 0.0; + + @Builder.Default + private double flowVoltageSensitivityValueThreshold = 0.0; + + @Builder.Default + List sensitivityInjectionsSet = List.of(); + + @Builder.Default + List sensitivityInjection = List.of(); + + @Builder.Default + List sensitivityHVDC = List.of(); + + @Builder.Default + List sensitivityPST = List.of(); + + @Builder.Default + List sensitivityNodes = List.of(); + + public SensitivityAnalysisParametersEntity toEntity() { + return new SensitivityAnalysisParametersEntity(this); + } +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/AbstractSensitivityFactorEntity.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/AbstractSensitivityFactorEntity.java new file mode 100644 index 00000000..aca89069 --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/AbstractSensitivityFactorEntity.java @@ -0,0 +1,57 @@ +/** + * 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.sensitivityanalysis.server.entities.parameters; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.List; +import java.util.UUID; + +/** + * @author Ghazwa Rehili + */ +@NoArgsConstructor +@Getter +@Setter +@MappedSuperclass +public abstract class AbstractSensitivityFactorEntity { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private UUID id; + + // liquidbase add foreignKey everytime, you need to delete it + @ElementCollection + @CollectionTable( + name = "monitoredBranch", + joinColumns = @JoinColumn(name = "SensitivityFactorId") + ) + private List monitoredBranch; + + // liquidbase add foreignKey everytime, you need to delete it + @ElementCollection + @CollectionTable( + name = "injections", + joinColumns = @JoinColumn(name = "SensitivityFactorId") + ) + private List injections; + + // liquidbase add foreignKey everytime, you need to delete it + @ElementCollection + @CollectionTable( + name = "contingencies", + joinColumns = @JoinColumn(name = "SensitivityFactorId") + ) + private List contingencies; + + @Column(name = "activated", columnDefinition = "boolean default true") + private boolean activated; +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/EquipmentsContainerEmbeddable.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/EquipmentsContainerEmbeddable.java new file mode 100644 index 00000000..17db42e3 --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/EquipmentsContainerEmbeddable.java @@ -0,0 +1,48 @@ +/** + * 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.sensitivityanalysis.server.entities.parameters; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.gridsuite.sensitivityanalysis.server.dto.EquipmentsContainer; + +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author Hugo Marcellin + */ +@Getter +@AllArgsConstructor +@NoArgsConstructor +@Embeddable +public class EquipmentsContainerEmbeddable { + + @Column(name = "containerId") + private UUID containerId; + + @Column(name = "containerName") + private String containerName; + + public static List toEmbeddableContainerEquipments(List containers) { + return containers == null ? null : + containers.stream() + .map(container -> new EquipmentsContainerEmbeddable(container.getContainerId(), container.getContainerName())) + .collect(Collectors.toList()); + } + + public static List fromEmbeddableContainerEquipments(List containers) { + return containers == null ? null : + containers.stream() + .map(container -> new EquipmentsContainer(container.getContainerId(), container.getContainerName())) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityAnalysisParametersEntity.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityAnalysisParametersEntity.java new file mode 100644 index 00000000..236b8605 --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityAnalysisParametersEntity.java @@ -0,0 +1,233 @@ +/** + * 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.sensitivityanalysis.server.entities.parameters; + +import jakarta.persistence.*; +import lombok.*; +import org.gridsuite.sensitivityanalysis.server.dto.*; +import org.gridsuite.sensitivityanalysis.server.dto.parameters.SensitivityAnalysisParametersInfos; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * @author Ghazwa Rehili + */ +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@Entity +@Builder +@Table(name = "sensitivityAnalysisParameters") +public class SensitivityAnalysisParametersEntity { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private UUID id; + + @Column(name = "flowFlowSensitivityValueThreshold") + private double flowFlowSensitivityValueThreshold = 0.0; + + @Column(name = "angleFlowSensitivityValueThreshold") + private double angleFlowSensitivityValueThreshold = 0.0; + + @Column(name = "flowVoltageSensitivityValueThreshold") + private double flowVoltageSensitivityValueThreshold = 0.0; + + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + @JoinColumn(name = "sensitivity_analysis_parameters_id") + private List sensitivityInjectionsSets = new ArrayList<>(); + + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + @JoinColumn(name = "sensitivity_analysis_parameters_id") + private List sensitivityInjections = new ArrayList<>(); + + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + @JoinColumn(name = "sensitivity_analysis_parameters_id") + private List sensitivityHVDCs = new ArrayList<>(); + + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + @JoinColumn(name = "sensitivity_analysis_parameters_id") + private List sensitivityPSTs = new ArrayList<>(); + + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + @JoinColumn(name = "sensitivity_analysis_parameters_id") + private List sensitivityNodes = new ArrayList<>(); + + public SensitivityAnalysisParametersEntity(@NonNull SensitivityAnalysisParametersInfos parametersInfos) { + assignAttributes(parametersInfos); + } + + /** + * Copy used to duplicate in DB with .save. + * The ID is changed. The date is updated. + * + * @return a copy of the entity + */ + public SensitivityAnalysisParametersEntity copy() { + return this.toInfos().toEntity(); + } + + public void update(@NonNull SensitivityAnalysisParametersInfos parametersInfos) { + assignAttributes(parametersInfos); + } + + public void assignAttributes(@NonNull SensitivityAnalysisParametersInfos parametersInfos) { + this.flowFlowSensitivityValueThreshold = parametersInfos.getFlowFlowSensitivityValueThreshold(); + this.angleFlowSensitivityValueThreshold = parametersInfos.getAngleFlowSensitivityValueThreshold(); + this.flowVoltageSensitivityValueThreshold = parametersInfos.getFlowVoltageSensitivityValueThreshold(); + this.sensitivityInjectionsSets.clear(); + this.sensitivityInjectionsSets.addAll(convertInjectionsSets(parametersInfos.getSensitivityInjectionsSet())); + this.sensitivityInjections.clear(); + this.sensitivityInjections.addAll(convertInjections(parametersInfos.getSensitivityInjection())); + this.sensitivityHVDCs.clear(); + this.sensitivityHVDCs.addAll(convertHdvcs(parametersInfos.getSensitivityHVDC())); + this.sensitivityPSTs.clear(); + this.sensitivityPSTs.addAll(convertPsts(parametersInfos.getSensitivityPST())); + this.sensitivityNodes.clear(); + this.sensitivityNodes.addAll(convertNodes(parametersInfos.getSensitivityNodes())); + } + + private List convertInjectionsSets(List sensitivityInjectionsSets) { + List sensitivityInjectionsSetEntities = new ArrayList<>(); + if (sensitivityInjectionsSets != null) { + for (SensitivityInjectionsSet sensitivityInjectionsSet : sensitivityInjectionsSets) { + SensitivityFactorWithDistribTypeEntity entity = new SensitivityFactorWithDistribTypeEntity(); + entity.setDistributionType(sensitivityInjectionsSet.getDistributionType()); + entity.setMonitoredBranch(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityInjectionsSet.getMonitoredBranches())); + entity.setInjections(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityInjectionsSet.getInjections())); + entity.setContingencies(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityInjectionsSet.getContingencies())); + entity.setActivated(sensitivityInjectionsSet.isActivated()); + sensitivityInjectionsSetEntities.add(entity); + } + } + return sensitivityInjectionsSetEntities; + } + + private List convertInjections(List sensitivityInjections) { + List sensitivityInjectionEntities = new ArrayList<>(); + if (sensitivityInjections != null) { + for (SensitivityInjection sensitivityInjection : sensitivityInjections) { + SensitivityFactorForInjectionEntity entity = new SensitivityFactorForInjectionEntity(); + entity.setMonitoredBranch(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityInjection.getMonitoredBranches())); + entity.setInjections(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityInjection.getInjections())); + entity.setContingencies(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityInjection.getContingencies())); + entity.setActivated(sensitivityInjection.isActivated()); + sensitivityInjectionEntities.add(entity); + } + } + return sensitivityInjectionEntities; + } + + private List convertHdvcs(List sensitivityHvdcs) { + List sensitivityHvdcEntities = new ArrayList<>(); + if (sensitivityHvdcs != null) { + for (SensitivityHVDC sensitivityHvdc : sensitivityHvdcs) { + SensitivityFactorWithSensiTypeForHvdcEntity entity = new SensitivityFactorWithSensiTypeForHvdcEntity(); + entity.setMonitoredBranch(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityHvdc.getMonitoredBranches())); + entity.setInjections(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityHvdc.getHvdcs())); + entity.setSensitivityType(sensitivityHvdc.getSensitivityType()); + entity.setContingencies(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityHvdc.getContingencies())); + entity.setActivated(sensitivityHvdc.isActivated()); + sensitivityHvdcEntities.add(entity); + } + } + return sensitivityHvdcEntities; + } + + private List convertPsts(List sensitivityPsts) { + List sensitivityPstEntities = new ArrayList<>(); + if (sensitivityPsts != null) { + for (SensitivityPST sensitivityPst : sensitivityPsts) { + SensitivityFactorWithSensiTypeForPstEntity entity = new SensitivityFactorWithSensiTypeForPstEntity(); + entity.setSensitivityType(sensitivityPst.getSensitivityType()); + entity.setMonitoredBranch(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityPst.getMonitoredBranches())); + entity.setInjections(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityPst.getPsts())); + entity.setContingencies(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityPst.getContingencies())); + entity.setActivated(sensitivityPst.isActivated()); + sensitivityPstEntities.add(entity); + } + } + return sensitivityPstEntities; + } + + private List convertNodes(List sensitivityNodes) { + List sensitivityNodeEntities = new ArrayList<>(); + if (sensitivityNodes != null) { + for (SensitivityNodes sensitivityNode : sensitivityNodes) { + SensitivityFactorForNodeEntity entity = new SensitivityFactorForNodeEntity(); + entity.setMonitoredBranch(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityNode.getMonitoredVoltageLevels())); + entity.setInjections(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityNode.getEquipmentsInVoltageRegulation())); + entity.setContingencies(EquipmentsContainerEmbeddable.toEmbeddableContainerEquipments(sensitivityNode.getContingencies())); + entity.setActivated(sensitivityNode.isActivated()); + sensitivityNodeEntities.add(entity); + } + } + return sensitivityNodeEntities; + } + + public SensitivityAnalysisParametersInfos toInfos() { + + List sensiInjectionsSets = new ArrayList<>(); + this.sensitivityInjectionsSets.stream().map(sensitivityInjectionsSet -> new SensitivityInjectionsSet( + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityInjectionsSet.getMonitoredBranch()), + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityInjectionsSet.getInjections()), + sensitivityInjectionsSet.getDistributionType(), + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityInjectionsSet.getContingencies()), + sensitivityInjectionsSet.isActivated() + )).forEach(sensiInjectionsSets::add); + + List sensiInjections = new ArrayList<>(); + this.sensitivityInjections.stream().map(sensitivityInjection -> new SensitivityInjection( + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityInjection.getMonitoredBranch()), + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityInjection.getInjections()), + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityInjection.getContingencies()), + sensitivityInjection.isActivated() + )).forEach(sensiInjections::add); + + List sensiHvdcs = new ArrayList<>(); + this.sensitivityHVDCs.stream().map(sensitivityHvdc -> new SensitivityHVDC( + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityHvdc.getMonitoredBranch()), + sensitivityHvdc.getSensitivityType(), + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityHvdc.getInjections()), + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityHvdc.getContingencies()), + sensitivityHvdc.isActivated() + )).forEach(sensiHvdcs::add); + + List sensiPsts = new ArrayList<>(); + this.sensitivityPSTs.stream().map(sensitivityPst -> new SensitivityPST( + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityPst.getMonitoredBranch()), + sensitivityPst.getSensitivityType(), + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityPst.getInjections()), + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityPst.getContingencies()), + sensitivityPst.isActivated() + )).forEach(sensiPsts::add); + + List sensiNodes = new ArrayList<>(); + this.sensitivityNodes.stream().map(sensitivityNode -> new SensitivityNodes( + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityNode.getMonitoredBranch()), + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityNode.getInjections()), + EquipmentsContainerEmbeddable.fromEmbeddableContainerEquipments(sensitivityNode.getContingencies()), + sensitivityNode.isActivated() + )).forEach(sensiNodes::add); + + return SensitivityAnalysisParametersInfos.builder() + .uuid(this.id) + .flowFlowSensitivityValueThreshold(this.flowFlowSensitivityValueThreshold) + .angleFlowSensitivityValueThreshold(this.angleFlowSensitivityValueThreshold) + .flowVoltageSensitivityValueThreshold(this.flowVoltageSensitivityValueThreshold) + .sensitivityInjectionsSet(sensiInjectionsSets) + .sensitivityInjection(sensiInjections) + .sensitivityHVDC(sensiHvdcs) + .sensitivityPST(sensiPsts) + .sensitivityNodes(sensiNodes) + .build(); + } +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorForInjectionEntity.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorForInjectionEntity.java new file mode 100644 index 00000000..437626f9 --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorForInjectionEntity.java @@ -0,0 +1,24 @@ +/** + * 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.sensitivityanalysis.server.entities.parameters; + +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * @author Ghazwa Rehili + */ +@AllArgsConstructor +@Getter +@Setter +@Entity +@Table(name = "sensitivityFactorForInjectionEntity") +public class SensitivityFactorForInjectionEntity extends AbstractSensitivityFactorEntity { +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorForNodeEntity.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorForNodeEntity.java new file mode 100644 index 00000000..2a4ebf00 --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorForNodeEntity.java @@ -0,0 +1,24 @@ +/** + * 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.sensitivityanalysis.server.entities.parameters; + +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * @author Ghazwa Rehili + */ +@AllArgsConstructor +@Getter +@Setter +@Entity +@Table(name = "sensitivityFactorForNodeEntity") +public class SensitivityFactorForNodeEntity extends AbstractSensitivityFactorEntity { +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorWithDistribTypeEntity.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorWithDistribTypeEntity.java new file mode 100644 index 00000000..df90487e --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorWithDistribTypeEntity.java @@ -0,0 +1,30 @@ +/** + * 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.sensitivityanalysis.server.entities.parameters; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.gridsuite.sensitivityanalysis.server.dto.SensitivityAnalysisInputData; + +/** + * @author Ghazwa Rehili + */ +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@Entity +@Table(name = "sensitivityFactorWithDistribTypeEntity") +public class SensitivityFactorWithDistribTypeEntity extends AbstractSensitivityFactorEntity { + + @Column(name = "distributionType") + @Enumerated(EnumType.STRING) + private SensitivityAnalysisInputData.DistributionType distributionType; +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorWithSensiTypeForHvdcEntity.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorWithSensiTypeForHvdcEntity.java new file mode 100644 index 00000000..e71b2f95 --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorWithSensiTypeForHvdcEntity.java @@ -0,0 +1,30 @@ +/** + * 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.sensitivityanalysis.server.entities.parameters; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.gridsuite.sensitivityanalysis.server.dto.SensitivityAnalysisInputData; + +/** + * @author Ghazwa Rehili + */ +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@Entity +@Table(name = "sensitivityFactorWithSensiTypeForHvdcEntity") +public class SensitivityFactorWithSensiTypeForHvdcEntity extends AbstractSensitivityFactorEntity { + + @Column(name = "sensitivityType") + @Enumerated(EnumType.STRING) + private SensitivityAnalysisInputData.SensitivityType sensitivityType; +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorWithSensiTypeForPstEntity.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorWithSensiTypeForPstEntity.java new file mode 100644 index 00000000..943af777 --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/entities/parameters/SensitivityFactorWithSensiTypeForPstEntity.java @@ -0,0 +1,30 @@ +/** + * 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.sensitivityanalysis.server.entities.parameters; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.gridsuite.sensitivityanalysis.server.dto.SensitivityAnalysisInputData; + +/** + * @author Ghazwa Rehili + */ +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@Entity +@Table(name = "sensitivityFactorWithSensiTypeForPstEntity") +public class SensitivityFactorWithSensiTypeForPstEntity extends AbstractSensitivityFactorEntity { + + @Column(name = "sensitivityType") + @Enumerated(EnumType.STRING) + private SensitivityAnalysisInputData.SensitivityType sensitivityType; +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/repositories/SensitivityAnalysisParametersRepository.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/repositories/SensitivityAnalysisParametersRepository.java new file mode 100644 index 00000000..38e7dad5 --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/repositories/SensitivityAnalysisParametersRepository.java @@ -0,0 +1,19 @@ +/** + * 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.sensitivityanalysis.server.repositories; + +import org.gridsuite.sensitivityanalysis.server.entities.parameters.SensitivityAnalysisParametersEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.UUID; + +/** + * @author Florent MILLOT + */ +public interface SensitivityAnalysisParametersRepository extends JpaRepository { +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisParametersService.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisParametersService.java new file mode 100644 index 00000000..c1c79747 --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisParametersService.java @@ -0,0 +1,113 @@ +/** + * 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.sensitivityanalysis.server.service; + +import com.powsybl.sensitivity.SensitivityAnalysisParameters; +import org.gridsuite.sensitivityanalysis.server.dto.*; +import org.gridsuite.sensitivityanalysis.server.dto.parameters.LoadFlowParametersValues; +import org.gridsuite.sensitivityanalysis.server.dto.parameters.SensitivityAnalysisParametersInfos; +import org.gridsuite.sensitivityanalysis.server.entities.parameters.SensitivityAnalysisParametersEntity; +import org.gridsuite.sensitivityanalysis.server.repositories.SensitivityAnalysisParametersRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author Florent MILLOT + */ +@Service +public class SensitivityAnalysisParametersService { + + private final SensitivityAnalysisParametersRepository sensitivityAnalysisParametersRepository; + + public SensitivityAnalysisParametersService(SensitivityAnalysisParametersRepository sensitivityAnalysisParametersRepository) { + this.sensitivityAnalysisParametersRepository = sensitivityAnalysisParametersRepository; + } + + public UUID createDefaultParameters() { + return createParameters(SensitivityAnalysisParametersInfos.builder().build()); + } + + public UUID createParameters(SensitivityAnalysisParametersInfos parametersInfos) { + return sensitivityAnalysisParametersRepository.save(parametersInfos.toEntity()).getId(); + } + + @Transactional + public Optional duplicateParameters(UUID sourceParametersId) { + return sensitivityAnalysisParametersRepository.findById(sourceParametersId) + .map(SensitivityAnalysisParametersEntity::copy) + .map(sensitivityAnalysisParametersRepository::save) + .map(SensitivityAnalysisParametersEntity::getId); + } + + public Optional getParameters(UUID parametersUuid) { + return sensitivityAnalysisParametersRepository.findById(parametersUuid).map(SensitivityAnalysisParametersEntity::toInfos); + } + + public List getAllParameters() { + return sensitivityAnalysisParametersRepository.findAll().stream().map(SensitivityAnalysisParametersEntity::toInfos).toList(); + } + + @Transactional + public void updateParameters(UUID parametersUuid, SensitivityAnalysisParametersInfos parametersInfos) { + sensitivityAnalysisParametersRepository.findById(parametersUuid).orElseThrow().update(parametersInfos); + } + + public void deleteParameters(UUID parametersUuid) { + sensitivityAnalysisParametersRepository.deleteById(parametersUuid); + } + + public SensitivityAnalysisInputData buildInputData(UUID parametersUuid, LoadFlowParametersValues loadFlowParametersValues) { + + Objects.requireNonNull(loadFlowParametersValues); + + SensitivityAnalysisParametersInfos sensitivityAnalysisParametersInfos = parametersUuid != null ? + sensitivityAnalysisParametersRepository.findById(parametersUuid) + .map(SensitivityAnalysisParametersEntity::toInfos) + .orElse(SensitivityAnalysisParametersInfos.builder().build()) + : + SensitivityAnalysisParametersInfos.builder().build(); + + SensitivityAnalysisParameters sensitivityAnalysisParameters = SensitivityAnalysisParameters.load(); + sensitivityAnalysisParameters.setAngleFlowSensitivityValueThreshold(sensitivityAnalysisParametersInfos.getAngleFlowSensitivityValueThreshold()); + sensitivityAnalysisParameters.setFlowFlowSensitivityValueThreshold(sensitivityAnalysisParametersInfos.getFlowFlowSensitivityValueThreshold()); + sensitivityAnalysisParameters.setFlowVoltageSensitivityValueThreshold(sensitivityAnalysisParametersInfos.getFlowVoltageSensitivityValueThreshold()); + sensitivityAnalysisParameters.setLoadFlowParameters(loadFlowParametersValues.commonParameters()); + + SensitivityAnalysisInputData sensitivityAnalysisInputData = new SensitivityAnalysisInputData(); + sensitivityAnalysisInputData.setParameters(sensitivityAnalysisParameters); + sensitivityAnalysisInputData.setLoadFlowSpecificParameters(loadFlowParametersValues.specificParameters()); + sensitivityAnalysisInputData.setSensitivityInjectionsSets(sensitivityAnalysisParametersInfos.getSensitivityInjectionsSet() + .stream() + .filter(SensitivityInjectionsSet::isActivated) + .collect(Collectors.toList())); + sensitivityAnalysisInputData.setSensitivityInjections(sensitivityAnalysisParametersInfos.getSensitivityInjection() + .stream() + .filter(SensitivityInjection::isActivated) + .collect(Collectors.toList())); + sensitivityAnalysisInputData.setSensitivityHVDCs(sensitivityAnalysisParametersInfos.getSensitivityHVDC() + .stream() + .filter(SensitivityHVDC::isActivated) + .collect(Collectors.toList())); + sensitivityAnalysisInputData.setSensitivityPSTs(sensitivityAnalysisParametersInfos.getSensitivityPST() + .stream() + .filter(SensitivityPST::isActivated) + .collect(Collectors.toList())); + sensitivityAnalysisInputData.setSensitivityNodes(sensitivityAnalysisParametersInfos.getSensitivityNodes() + .stream() + .filter(SensitivityNodes::isActivated) + .collect(Collectors.toList())); + + return sensitivityAnalysisInputData; + } +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisResultContext.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisResultContext.java index 2bf43ae1..c6e998d8 100644 --- a/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisResultContext.java +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisResultContext.java @@ -10,6 +10,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.powsybl.commons.PowsyblException; +import org.gridsuite.sensitivityanalysis.server.dto.ReportInfos; import org.gridsuite.sensitivityanalysis.server.dto.SensitivityAnalysisInputData; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; @@ -76,7 +77,7 @@ public static SensitivityAnalysisResultContext fromMessage(Message messa String reporterId = headers.containsKey(REPORTER_ID_HEADER) ? (String) headers.get(REPORTER_ID_HEADER) : null; String reportType = headers.containsKey(REPORT_TYPE_HEADER) ? (String) headers.get(REPORT_TYPE_HEADER) : null; SensitivityAnalysisRunContext runContext = new SensitivityAnalysisRunContext(networkUuid, - variantId, sensitivityAnalysisInputData, receiver, provider, reportUuid, reporterId, reportType, userId); + variantId, sensitivityAnalysisInputData, receiver, provider, new ReportInfos(reportUuid, reporterId, reportType), userId); return new SensitivityAnalysisResultContext(resultUuid, runContext); } diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisRunContext.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisRunContext.java index 3f5fcbf1..9bcb6f5f 100644 --- a/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisRunContext.java +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisRunContext.java @@ -7,6 +7,7 @@ package org.gridsuite.sensitivityanalysis.server.service; import lombok.Getter; +import org.gridsuite.sensitivityanalysis.server.dto.ReportInfos; import org.gridsuite.sensitivityanalysis.server.dto.SensitivityAnalysisInputData; import java.util.Objects; @@ -40,17 +41,17 @@ public class SensitivityAnalysisRunContext { public SensitivityAnalysisRunContext(UUID networkUuid, String variantId, SensitivityAnalysisInputData sensitivityAnalysisInputData, - String receiver, String provider, UUID reportUuid, - String reporterId, String reportType, String userId) { + String receiver, String provider, + ReportInfos reportInfos, String userId) { this.networkUuid = Objects.requireNonNull(networkUuid); this.variantId = variantId; this.sensitivityAnalysisInputData = Objects.requireNonNull(sensitivityAnalysisInputData); this.sensitivityAnalysisInputs = new SensitivityAnalysisInputs(); this.receiver = receiver; this.provider = provider; - this.reportUuid = reportUuid; - this.reporterId = reporterId; - this.reportType = reportType; + this.reportUuid = reportInfos == null ? null : reportInfos.reportUuid(); + this.reporterId = reportInfos == null ? null : reportInfos.reporterId(); + this.reportType = reportInfos == null ? null : reportInfos.reportType(); this.userId = userId; } } diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisService.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisService.java index 6b8a28f6..883264a0 100644 --- a/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisService.java +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisService.java @@ -14,11 +14,9 @@ import org.gridsuite.sensitivityanalysis.server.dto.SensitivityAnalysisCsvFileInfos; import org.gridsuite.sensitivityanalysis.server.dto.SensitivityWithContingency; import org.gridsuite.sensitivityanalysis.server.dto.resultselector.ResultTab; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityFactorsIdsByGroup; +import org.gridsuite.sensitivityanalysis.server.dto.*; +import org.gridsuite.sensitivityanalysis.server.dto.parameters.LoadFlowParametersValues; import org.gridsuite.sensitivityanalysis.server.dto.resultselector.ResultsSelector; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityAnalysisStatus; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityResultFilterOptions; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityRunQueryResult; import org.gridsuite.sensitivityanalysis.server.repositories.SensitivityAnalysisResultRepository; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -60,6 +58,8 @@ public class SensitivityAnalysisService { private final FilterService filterService; + private final SensitivityAnalysisParametersService parametersService; + private final ObjectMapper objectMapper; public SensitivityAnalysisService(@Value("${sensitivity-analysis.default-provider}") String defaultProvider, @@ -68,6 +68,7 @@ public SensitivityAnalysisService(@Value("${sensitivity-analysis.default-provide NotificationService notificationService, ActionsService actionsService, FilterService filterService, + SensitivityAnalysisParametersService parametersService, ObjectMapper objectMapper) { this.defaultProvider = defaultProvider; this.resultRepository = Objects.requireNonNull(resultRepository); @@ -75,10 +76,16 @@ public SensitivityAnalysisService(@Value("${sensitivity-analysis.default-provide this.notificationService = notificationService; this.actionsService = actionsService; this.filterService = filterService; + this.parametersService = parametersService; this.objectMapper = Objects.requireNonNull(objectMapper); } - public UUID runAndSaveResult(SensitivityAnalysisRunContext runContext) { + public UUID runAndSaveResult(UUID networkUuid, String variantId, String receiver, String provider, ReportInfos reportInfos, String userId, UUID parametersUuid, LoadFlowParametersValues loadFlowParametersValues) { + + SensitivityAnalysisInputData inputData = parametersService.buildInputData(parametersUuid, loadFlowParametersValues); + + SensitivityAnalysisRunContext runContext = new SensitivityAnalysisRunContext(networkUuid, variantId, inputData, receiver, provider, reportInfos, userId); + Objects.requireNonNull(runContext); var resultUuid = uuidGeneratorService.generate(); diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisWorkerService.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisWorkerService.java index 0867a715..1e3d59ec 100644 --- a/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisWorkerService.java +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisWorkerService.java @@ -22,7 +22,10 @@ import com.powsybl.sensitivity.SensitivityAnalysisParameters; import com.powsybl.sensitivity.SensitivityAnalysisResult; import org.apache.commons.lang3.StringUtils; +import org.gridsuite.sensitivityanalysis.server.dto.ReportInfos; +import org.gridsuite.sensitivityanalysis.server.dto.SensitivityAnalysisInputData; import org.gridsuite.sensitivityanalysis.server.dto.SensitivityAnalysisStatus; +import org.gridsuite.sensitivityanalysis.server.dto.parameters.LoadFlowParametersValues; import org.gridsuite.sensitivityanalysis.server.repositories.SensitivityAnalysisResultRepository; import org.gridsuite.sensitivityanalysis.server.util.SensitivityAnalysisRunnerSupplier; import org.slf4j.Logger; @@ -77,14 +80,20 @@ public class SensitivityAnalysisWorkerService { private final SensitivityAnalysisInputBuilderService sensitivityAnalysisInputBuilderService; + private final SensitivityAnalysisParametersService parametersService; + private final SensitivityAnalysisObserver sensitivityAnalysisObserver; private Function sensitivityAnalysisFactorySupplier; - public SensitivityAnalysisWorkerService(NetworkStoreService networkStoreService, ReportService reportService, NotificationService notificationService, + public SensitivityAnalysisWorkerService(NetworkStoreService networkStoreService, + ReportService reportService, + NotificationService notificationService, SensitivityAnalysisInputBuilderService sensitivityAnalysisInputBuilderService, SensitivityAnalysisExecutionService sensitivityAnalysisExecutionService, - SensitivityAnalysisResultRepository resultRepository, ObjectMapper objectMapper, + SensitivityAnalysisResultRepository resultRepository, + ObjectMapper objectMapper, + SensitivityAnalysisParametersService parametersService, SensitivityAnalysisRunnerSupplier sensitivityAnalysisRunnerSupplier, SensitivityAnalysisObserver sensitivityAnalysisObserver) { this.networkStoreService = Objects.requireNonNull(networkStoreService); @@ -94,6 +103,7 @@ public SensitivityAnalysisWorkerService(NetworkStoreService networkStoreService, this.sensitivityAnalysisInputBuilderService = sensitivityAnalysisInputBuilderService; this.resultRepository = Objects.requireNonNull(resultRepository); this.objectMapper = Objects.requireNonNull(objectMapper); + this.parametersService = parametersService; sensitivityAnalysisFactorySupplier = sensitivityAnalysisRunnerSupplier::getRunner; this.sensitivityAnalysisObserver = sensitivityAnalysisObserver; } @@ -114,9 +124,13 @@ private Network getNetwork(UUID networkUuid, String variantId) { return network; } - public SensitivityAnalysisResult run(SensitivityAnalysisRunContext context) { + public SensitivityAnalysisResult run(UUID networkUuid, String variantId, String provider, ReportInfos reportInfos, String userId, UUID parametersUuid, LoadFlowParametersValues loadFlowParametersValues) { + + SensitivityAnalysisInputData inputData = parametersService.buildInputData(parametersUuid, loadFlowParametersValues); + + SensitivityAnalysisRunContext runContext = new SensitivityAnalysisRunContext(networkUuid, variantId, inputData, null, provider, reportInfos, userId); try { - return run(context, null); + return run(runContext, null); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return null; diff --git a/src/main/resources/db/changelog/changesets/changelog_20231226T170539Z.xml b/src/main/resources/db/changelog/changesets/changelog_20231226T170539Z.xml new file mode 100644 index 00000000..f6163d85 --- /dev/null +++ b/src/main/resources/db/changelog/changesets/changelog_20231226T170539Z.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index 8a7395db..7144ba31 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -18,3 +18,6 @@ databaseChangeLog: - include: file: changesets/changelog_20240205T102706Z.xml relativeToChangelogFile: true + - include: + file: changesets/changelog_20231226T170539Z.xml + relativeToChangelogFile: true diff --git a/src/test/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisControllerTest.java b/src/test/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisControllerTest.java index d4aa1364..e87c3805 100644 --- a/src/test/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisControllerTest.java +++ b/src/test/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisControllerTest.java @@ -10,52 +10,29 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.powsybl.commons.reporter.Reporter; import com.powsybl.computation.ComputationManager; -import com.powsybl.contingency.BranchContingency; -import com.powsybl.contingency.BusbarSectionContingency; -import com.powsybl.contingency.Contingency; -import com.powsybl.contingency.ContingencyContext; -import com.powsybl.contingency.ContingencyContextType; -import com.powsybl.contingency.DanglingLineContingency; -import com.powsybl.contingency.GeneratorContingency; -import com.powsybl.contingency.HvdcLineContingency; -import com.powsybl.contingency.LineContingency; -import com.powsybl.contingency.ShuntCompensatorContingency; -import com.powsybl.contingency.StaticVarCompensatorContingency; -import com.powsybl.contingency.ThreeWindingsTransformerContingency; -import com.powsybl.contingency.TwoWindingsTransformerContingency; +import com.powsybl.contingency.*; import com.powsybl.iidm.network.IdentifiableType; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.VariantManagerConstants; import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; +import com.powsybl.loadflow.LoadFlowParameters; import com.powsybl.network.store.client.NetworkStoreService; import com.powsybl.network.store.client.PreloadingStrategy; import com.powsybl.network.store.iidm.impl.NetworkFactoryImpl; - -import com.powsybl.sensitivity.SensitivityAnalysis; -import com.powsybl.sensitivity.SensitivityAnalysisParameters; -import com.powsybl.sensitivity.SensitivityAnalysisResult; -import com.powsybl.sensitivity.SensitivityFactor; -import com.powsybl.sensitivity.SensitivityFunctionType; -import com.powsybl.sensitivity.SensitivityValue; -import com.powsybl.sensitivity.SensitivityVariableType; +import com.powsybl.sensitivity.*; import lombok.SneakyThrows; import org.gridsuite.sensitivityanalysis.server.dto.*; +import org.gridsuite.sensitivityanalysis.server.dto.parameters.LoadFlowParametersValues; import org.gridsuite.sensitivityanalysis.server.dto.resultselector.ResultTab; import org.gridsuite.sensitivityanalysis.server.dto.resultselector.ResultsSelector; import org.gridsuite.sensitivityanalysis.server.dto.resultselector.SortKey; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityRunQueryResult; import org.gridsuite.sensitivityanalysis.server.entities.ContingencyEmbeddable; import org.gridsuite.sensitivityanalysis.server.entities.SensitivityEntity; import org.gridsuite.sensitivityanalysis.server.repositories.SensitivityRepository; -import org.gridsuite.sensitivityanalysis.server.service.ActionsService; -import org.gridsuite.sensitivityanalysis.server.service.FilterService; -import org.gridsuite.sensitivityanalysis.server.service.ReportService; -import org.gridsuite.sensitivityanalysis.server.service.SensitivityAnalysisWorkerService; -import org.gridsuite.sensitivityanalysis.server.service.UuidGeneratorService; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.gridsuite.sensitivityanalysis.server.service.*; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.MockitoAnnotations; import org.mockito.stubbing.Answer; import org.springframework.beans.factory.annotation.Autowired; @@ -70,53 +47,35 @@ import org.springframework.messaging.Message; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextHierarchy; -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 java.nio.charset.StandardCharsets; -import java.util.Comparator; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import java.util.stream.Stream; import static com.powsybl.network.store.model.NetworkStoreApi.VERSION; import static java.util.Comparator.comparing; -import static org.gridsuite.sensitivityanalysis.server.service.NotificationService.CANCEL_MESSAGE; -import static org.gridsuite.sensitivityanalysis.server.service.NotificationService.FAIL_MESSAGE; -import static org.gridsuite.sensitivityanalysis.server.service.NotificationService.HEADER_USER_ID; +import static org.gridsuite.sensitivityanalysis.server.service.NotificationService.*; import static org.gridsuite.sensitivityanalysis.server.util.TestUtils.unzip; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyList; -import static org.mockito.ArgumentMatchers.eq; +import static org.junit.Assert.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** * @author Franck Lecuyer */ -@RunWith(SpringRunner.class) @AutoConfigureMockMvc @SpringBootTest @ContextHierarchy({@ContextConfiguration(classes = {SensitivityAnalysisApplication.class, TestChannelBinderConfiguration.class})}) -public class SensitivityAnalysisControllerTest { +class SensitivityAnalysisControllerTest { private static final UUID NETWORK_UUID = UUID.randomUUID(); private static final UUID NETWORK_STOP_UUID = UUID.randomUUID(); @@ -271,15 +230,16 @@ public class SensitivityAnalysisControllerTest { private static final String ERROR_MESSAGE = "Error message test"; - private static String SENSITIVITY_INPUT_1; - private static String SENSITIVITY_INPUT_2; - private static String SENSITIVITY_INPUT_3; - private static String SENSITIVITY_INPUT_4; - private static String SENSITIVITY_INPUT_5; - private static String SENSITIVITY_INPUT_6; - private static String SENSITIVITY_INPUT_HVDC_DELTA_A; - private static String SENSITIVITY_INPUT_LOAD_PROPORTIONAL_MAXP; - private static String SENSITIVITY_INPUT_VENTILATION; + private static String DEFAULT_LOADFLOW_PARAMS; + private static SensitivityAnalysisInputData SENSITIVITY_INPUT_1; + private static SensitivityAnalysisInputData SENSITIVITY_INPUT_2; + private static SensitivityAnalysisInputData SENSITIVITY_INPUT_3; + private static SensitivityAnalysisInputData SENSITIVITY_INPUT_4; + private static SensitivityAnalysisInputData SENSITIVITY_INPUT_5; + private static SensitivityAnalysisInputData SENSITIVITY_INPUT_6; + private static SensitivityAnalysisInputData SENSITIVITY_INPUT_HVDC_DELTA_A; + private static SensitivityAnalysisInputData SENSITIVITY_INPUT_LOAD_PROPORTIONAL_MAXP; + private static SensitivityAnalysisInputData SENSITIVITY_INPUT_VENTILATION; @Autowired private OutputDestination output; @@ -305,6 +265,9 @@ public class SensitivityAnalysisControllerTest { @SpyBean private SensitivityAnalysisWorkerService workerService; + @SpyBean + private SensitivityAnalysisParametersService parametersService; + @Value("${sensitivity-analysis.default-provider}") String defaultSensitivityAnalysisProvider; @@ -317,10 +280,10 @@ public class SensitivityAnalysisControllerTest { private Network network; private Network network1; - @Before + @BeforeEach @SneakyThrows - public void setUp() { - MockitoAnnotations.initMocks(this); + void setUp() { + MockitoAnnotations.openMocks(this); // network store service mocking network = EurostagTutorialExample1Factory.createWithMoreGenerators(new NetworkFactoryImpl()); @@ -342,6 +305,12 @@ public void setUp() { return network1; }); + LoadFlowParametersValues loadFlowParametersValues = LoadFlowParametersValues.builder() + .commonParameters(LoadFlowParameters.load()) + .specificParameters(Map.of()) + .build(); + DEFAULT_LOADFLOW_PARAMS = mapper.writeValueAsString(loadFlowParametersValues); + SensitivityAnalysisInputData sensitivityAnalysisInputData1 = SensitivityAnalysisInputData.builder() .sensitivityInjectionsSets(List.of(SensitivityInjectionsSet.builder() .monitoredBranches(List.of(new EquipmentsContainer(MONITORED_BRANCHES_FILTERS_INJECTIONS_SET_UUID, "name1"))) @@ -368,40 +337,40 @@ public void setUp() { .contingencies(List.of(new EquipmentsContainer(CONTINGENCIES_NODES_UUID, "name18"))).build())) .parameters(SensitivityAnalysisParameters.load()) .build(); - SENSITIVITY_INPUT_1 = mapper.writeValueAsString(sensitivityAnalysisInputData1); + SENSITIVITY_INPUT_1 = sensitivityAnalysisInputData1; SensitivityAnalysisInputData sensitivityAnalysisInputData2 = mapper.convertValue(sensitivityAnalysisInputData1, SensitivityAnalysisInputData.class); sensitivityAnalysisInputData2.getSensitivityInjectionsSets().get(0).setDistributionType(SensitivityAnalysisInputData.DistributionType.PROPORTIONAL); - SENSITIVITY_INPUT_2 = mapper.writeValueAsString(sensitivityAnalysisInputData2); + SENSITIVITY_INPUT_2 = sensitivityAnalysisInputData2; SensitivityAnalysisInputData sensitivityAnalysisInputData3 = mapper.convertValue(sensitivityAnalysisInputData1, SensitivityAnalysisInputData.class); sensitivityAnalysisInputData3.getSensitivityInjectionsSets().get(0).getInjections().get(0).setContainerId(HVDC_FILTERS_UUID); - SENSITIVITY_INPUT_3 = mapper.writeValueAsString(sensitivityAnalysisInputData3); + SENSITIVITY_INPUT_3 = sensitivityAnalysisInputData3; SensitivityAnalysisInputData sensitivityAnalysisInputData4 = mapper.convertValue(sensitivityAnalysisInputData1, SensitivityAnalysisInputData.class); sensitivityAnalysisInputData4.getSensitivityInjectionsSets().get(0).getMonitoredBranches().get(0).setContainerId(MONITORED_VOLTAGE_LEVELS_FILTERS_NODES_UUID); - SENSITIVITY_INPUT_4 = mapper.writeValueAsString(sensitivityAnalysisInputData4); + SENSITIVITY_INPUT_4 = sensitivityAnalysisInputData4; SensitivityAnalysisInputData sensitivityAnalysisInputData5 = mapper.convertValue(sensitivityAnalysisInputData1, SensitivityAnalysisInputData.class); sensitivityAnalysisInputData5.getSensitivityInjections().get(0).getMonitoredBranches().get(0).setContainerId(MONITORED_VOLTAGE_LEVELS_FILTERS_NODES_UUID); - SENSITIVITY_INPUT_5 = mapper.writeValueAsString(sensitivityAnalysisInputData5); + SENSITIVITY_INPUT_5 = sensitivityAnalysisInputData5; SensitivityAnalysisInputData sensitivityAnalysisInputData6 = mapper.convertValue(sensitivityAnalysisInputData1, SensitivityAnalysisInputData.class); sensitivityAnalysisInputData6.getSensitivityPSTs().get(0).getPsts().get(0).setContainerId(GENERATORS_FILTERS_INJECTIONS_UUID); - SENSITIVITY_INPUT_6 = mapper.writeValueAsString(sensitivityAnalysisInputData6); + SENSITIVITY_INPUT_6 = sensitivityAnalysisInputData6; SensitivityAnalysisInputData sensitivityAnalysisInputDataHvdcWithDeltaA = mapper.convertValue(sensitivityAnalysisInputData1, SensitivityAnalysisInputData.class); sensitivityAnalysisInputDataHvdcWithDeltaA.getSensitivityHVDCs().get(0).setSensitivityType(SensitivityAnalysisInputData.SensitivityType.DELTA_A); - SENSITIVITY_INPUT_HVDC_DELTA_A = mapper.writeValueAsString(sensitivityAnalysisInputDataHvdcWithDeltaA); + SENSITIVITY_INPUT_HVDC_DELTA_A = sensitivityAnalysisInputDataHvdcWithDeltaA; SensitivityAnalysisInputData sensitivityAnalysisInputDataLoadWithProportionalMaxP = mapper.convertValue(sensitivityAnalysisInputData1, SensitivityAnalysisInputData.class); sensitivityAnalysisInputDataLoadWithProportionalMaxP.getSensitivityInjectionsSets().get(0).setDistributionType(SensitivityAnalysisInputData.DistributionType.PROPORTIONAL_MAXP); sensitivityAnalysisInputDataLoadWithProportionalMaxP.getSensitivityInjectionsSets().get(0).getInjections().get(1).setContainerId(LOADS_FILTERS_INJECTIONS_SET_WITH_BAD_DISTRIBUTION_TYPE_UUID); - SENSITIVITY_INPUT_LOAD_PROPORTIONAL_MAXP = mapper.writeValueAsString(sensitivityAnalysisInputDataLoadWithProportionalMaxP); + SENSITIVITY_INPUT_LOAD_PROPORTIONAL_MAXP = sensitivityAnalysisInputDataLoadWithProportionalMaxP; SensitivityAnalysisInputData sensitivityAnalysisInputDataVentilation = mapper.convertValue(sensitivityAnalysisInputData1, SensitivityAnalysisInputData.class); sensitivityAnalysisInputDataVentilation.getSensitivityInjectionsSets().get(0).setDistributionType(SensitivityAnalysisInputData.DistributionType.VENTILATION); - SENSITIVITY_INPUT_VENTILATION = mapper.writeValueAsString(sensitivityAnalysisInputDataVentilation); + SENSITIVITY_INPUT_VENTILATION = sensitivityAnalysisInputDataVentilation; // action service mocking given(actionsService.getContingencyList(CONTINGENCIES_INJECTIONS_SET_UUID, NETWORK_UUID, VARIANT_1_ID)).willReturn(CONTINGENCIES); @@ -521,33 +490,36 @@ public void setUp() { // added for testStatus can return null, after runTest @SneakyThrows - @After - public void tearDown() { + @AfterEach + void tearDown() { mockMvc.perform(delete("/" + VERSION + "/results")) .andExpect(status().isOk()); } @Test - public void runTest() throws Exception { + void runTest() throws Exception { + MockitoAnnotations.openMocks(this); // run with specific variant + doReturn(SENSITIVITY_INPUT_1).when(parametersService).buildInputData(any(), any()); MvcResult result = mockMvc.perform(post( "/" + VERSION + "/networks/{networkUuid}/run?reportType=SensitivityAnalysis&variantId=" + VARIANT_3_ID, NETWORK_UUID) .contentType(MediaType.APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") - .content(SENSITIVITY_INPUT_1)) + .content(DEFAULT_LOADFLOW_PARAMS)) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andReturn(); assertEquals(mapper.writeValueAsString(RESULT_VARIANT), result.getResponse().getContentAsString()); // run with implicit initial variant - for (String sensitivityInput : List.of(SENSITIVITY_INPUT_1, SENSITIVITY_INPUT_2, SENSITIVITY_INPUT_3, SENSITIVITY_INPUT_4, SENSITIVITY_INPUT_5, SENSITIVITY_INPUT_6, SENSITIVITY_INPUT_LOAD_PROPORTIONAL_MAXP, SENSITIVITY_INPUT_VENTILATION)) { + for (SensitivityAnalysisInputData sensitivityInput : List.of(SENSITIVITY_INPUT_1, SENSITIVITY_INPUT_2, SENSITIVITY_INPUT_3, SENSITIVITY_INPUT_4, SENSITIVITY_INPUT_5, SENSITIVITY_INPUT_6, SENSITIVITY_INPUT_LOAD_PROPORTIONAL_MAXP, SENSITIVITY_INPUT_VENTILATION)) { + doReturn(sensitivityInput).when(parametersService).buildInputData(any(), any()); result = mockMvc.perform(post( "/" + VERSION + "/networks/{networkUuid}/run?reportType=SensitivityAnalysis", NETWORK_UUID) .contentType(MediaType.APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") - .content(sensitivityInput)) + .content(DEFAULT_LOADFLOW_PARAMS)) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andReturn(); @@ -555,11 +527,12 @@ public void runTest() throws Exception { } // run with OpenLoadFlow provider and sensitivityType DELTA_A for HVDC + doReturn(SENSITIVITY_INPUT_HVDC_DELTA_A).when(parametersService).buildInputData(any(), any()); result = mockMvc.perform(post( "/" + VERSION + "/networks/{networkUuid}/run?reportType=SensitivityAnalysis&provider=OpenLoadFlow", NETWORK_UUID) .contentType(MediaType.APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") - .content(SENSITIVITY_INPUT_HVDC_DELTA_A)) + .content(DEFAULT_LOADFLOW_PARAMS)) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andReturn(); @@ -567,12 +540,12 @@ public void runTest() throws Exception { } @Test - public void runAndSaveTest() throws Exception { + void runAndSaveTest() throws Exception { MvcResult result = mockMvc.perform(post( "/" + VERSION + "/networks/{networkUuid}/run-and-save?reportType=SensitivityAnalysis&receiver=me&variantId=" + VARIANT_2_ID, NETWORK_UUID) .contentType(MediaType.APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") - .content(SENSITIVITY_INPUT_1)) + .content(DEFAULT_LOADFLOW_PARAMS)) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andReturn(); @@ -772,7 +745,8 @@ public void testDeterministicResult() throws Exception { "/" + VERSION + "/networks/{networkUuid}/run-and-save?reportType=SensitivityAnalysis&receiver=me&variantId=" + VARIANT_2_ID, NETWORK_UUID) .contentType(MediaType.APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") - .content(SENSITIVITY_INPUT_1)) + .content(DEFAULT_LOADFLOW_PARAMS)) + .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andReturn(); @@ -827,12 +801,12 @@ private List createSortedSensitivityList(Comparator requestBuilder.queryParam(String.format("ids[%s]", key), list.stream().map(UUID::toString).toArray(String[]::new))); MvcResult result = mockMvc.perform(requestBuilder) @@ -879,12 +853,12 @@ public void testGetFactorsCount() throws Exception { } @Test - public void stopTest() throws Exception { + void stopTest() throws Exception { mockMvc.perform(post( "/" + VERSION + "/networks/{networkUuid}/run-and-save?reportType=SensitivityAnalysis&receiver=me&variantId=" + VARIANT_2_ID, NETWORK_STOP_UUID) .contentType(MediaType.APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") - .content(SENSITIVITY_INPUT_1)) + .content(DEFAULT_LOADFLOW_PARAMS)) .andExpect(status().isOk()); // stop sensitivity analysis @@ -900,12 +874,12 @@ public void stopTest() throws Exception { @SneakyThrows @Test - public void runTestWithError() { + void runTestWithError() { MvcResult result = mockMvc.perform(post( "/" + VERSION + "/networks/{networkUuid}/run-and-save?reportType=SensitivityAnalysis&receiver=me&variantId=" + VARIANT_1_ID, NETWORK_ERROR_UUID) .contentType(MediaType.APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") - .content(SENSITIVITY_INPUT_1)) + .content(DEFAULT_LOADFLOW_PARAMS)) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andReturn(); @@ -924,12 +898,12 @@ public void runTestWithError() { @SneakyThrows @Test - public void runWithReportTest() { + void runWithReportTest() { MvcResult result = mockMvc.perform(post( "/" + VERSION + "/networks/{networkUuid}/run?reportType=SensitivityAnalysis&reportUuid=" + REPORT_UUID + "&reporterId=" + UUID.randomUUID(), NETWORK_UUID) .contentType(MediaType.APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") - .content(SENSITIVITY_INPUT_1)) + .content(DEFAULT_LOADFLOW_PARAMS)) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andReturn(); @@ -937,7 +911,7 @@ public void runWithReportTest() { } @Test - public void getProvidersTest() throws Exception { + void getProvidersTest() throws Exception { mockMvc.perform(get("/" + VERSION + "/providers")) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) @@ -946,7 +920,7 @@ public void getProvidersTest() throws Exception { } @Test - public void getDefaultProviderTest() throws Exception { + void getDefaultProviderTest() throws Exception { mockMvc.perform(get("/" + VERSION + "/default-provider")) .andExpect(status().isOk()) .andExpect(content().contentType(new MediaType(MediaType.TEXT_PLAIN, StandardCharsets.UTF_8))) diff --git a/src/test/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisParametersTest.java b/src/test/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisParametersTest.java new file mode 100644 index 00000000..c8485412 --- /dev/null +++ b/src/test/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisParametersTest.java @@ -0,0 +1,263 @@ +/** + * 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.sensitivityanalysis.server; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.powsybl.loadflow.LoadFlowParameters; +import com.powsybl.sensitivity.SensitivityAnalysisParameters; +import org.assertj.core.api.Assertions; +import org.gridsuite.sensitivityanalysis.server.dto.*; +import org.gridsuite.sensitivityanalysis.server.dto.parameters.LoadFlowParametersValues; +import org.gridsuite.sensitivityanalysis.server.dto.parameters.SensitivityAnalysisParametersInfos; +import org.gridsuite.sensitivityanalysis.server.entities.parameters.SensitivityAnalysisParametersEntity; +import org.gridsuite.sensitivityanalysis.server.repositories.SensitivityAnalysisParametersRepository; +import org.gridsuite.sensitivityanalysis.server.service.SensitivityAnalysisParametersService; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static org.gridsuite.sensitivityanalysis.server.util.assertions.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * @author Florent MILLOT + */ +@SpringBootTest +@AutoConfigureMockMvc +@Transactional +public class SensitivityAnalysisParametersTest { + + private static final String URI_PARAMETERS_BASE = "/v1/parameters"; + + private static final String URI_PARAMETERS_GET_PUT = URI_PARAMETERS_BASE + "/"; + + @Autowired + MockMvc mockMvc; + + @Autowired + ObjectMapper mapper; + + @Autowired + SensitivityAnalysisParametersService parametersService; + + @Autowired + SensitivityAnalysisParametersRepository parametersRepository; + + @AfterEach + public void tearOff() { + parametersRepository.deleteAll(); + } + + @Test + void testCreate() throws Exception { + + SensitivityAnalysisParametersInfos parametersToCreate = buildParameters(); + String parametersToCreateJson = mapper.writeValueAsString(parametersToCreate); + + mockMvc.perform(post(URI_PARAMETERS_BASE).content(parametersToCreateJson).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn(); + + SensitivityAnalysisParametersInfos createdParameters = parametersRepository.findAll().get(0).toInfos(); + + assertThat(createdParameters).recursivelyEquals(parametersToCreate); + } + + @Test + void testCreateDefaultValues() throws Exception { + + SensitivityAnalysisParametersInfos defaultParameters = SensitivityAnalysisParametersInfos.builder().build(); + + mockMvc.perform(post(URI_PARAMETERS_BASE + "/default")) + .andExpect(status().isOk()).andReturn(); + + SensitivityAnalysisParametersInfos createdParameters = parametersRepository.findAll().get(0).toInfos(); + + assertThat(createdParameters).recursivelyEquals(defaultParameters); + } + + @Test + void testRead() throws Exception { + + SensitivityAnalysisParametersInfos parametersToRead = buildParameters(); + + UUID parametersUuid = saveAndReturnId(parametersToRead); + + MvcResult mvcResult = mockMvc.perform(get(URI_PARAMETERS_GET_PUT + parametersUuid)) + .andExpect(status().isOk()).andReturn(); + String resultAsString = mvcResult.getResponse().getContentAsString(); + SensitivityAnalysisParametersInfos receivedParameters = mapper.readValue(resultAsString, new TypeReference<>() { + }); + + assertThat(receivedParameters).recursivelyEquals(parametersToRead); + } + + @Test + void testUpdate() throws Exception { + + SensitivityAnalysisParametersInfos parametersToUpdate = buildParameters(); + + UUID parametersUuid = saveAndReturnId(parametersToUpdate); + + parametersToUpdate = buildParametersUpdate(); + + String parametersToUpdateJson = mapper.writeValueAsString(parametersToUpdate); + + mockMvc.perform(put(URI_PARAMETERS_GET_PUT + parametersUuid).content(parametersToUpdateJson).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + SensitivityAnalysisParametersInfos updatedParameters = parametersRepository.findById(parametersUuid).get().toInfos(); + + assertThat(updatedParameters).recursivelyEquals(parametersToUpdate); + } + + @Test + void testDelete() throws Exception { + + SensitivityAnalysisParametersInfos parametersToDelete = buildParameters(); + + UUID parametersUuid = saveAndReturnId(parametersToDelete); + + mockMvc.perform(delete(URI_PARAMETERS_GET_PUT + parametersUuid)).andExpect(status().isOk()).andReturn(); + + List storedParameters = parametersRepository.findAll(); + + assertThat(storedParameters).isEmpty(); + } + + @Test + void testGetAll() throws Exception { + SensitivityAnalysisParametersInfos parameters1 = buildParameters(); + + SensitivityAnalysisParametersInfos parameters2 = buildParametersUpdate(); + + saveAndReturnId(parameters1); + + saveAndReturnId(parameters2); + + MvcResult mvcResult = mockMvc.perform(get(URI_PARAMETERS_BASE)) + .andExpect(status().isOk()).andReturn(); + String resultAsString = mvcResult.getResponse().getContentAsString(); + List receivedParameters = mapper.readValue(resultAsString, new TypeReference<>() { + }); + + Assertions.assertThat(receivedParameters).hasSize(2); + } + + @Test + void testDuplicate() throws Exception { + + SensitivityAnalysisParametersInfos parametersToCreate = buildParameters(); + String parametersToCreateJson = mapper.writeValueAsString(parametersToCreate); + + mockMvc.perform(post(URI_PARAMETERS_BASE).content(parametersToCreateJson).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn(); + SensitivityAnalysisParametersInfos createdParameters = parametersRepository.findAll().get(0).toInfos(); + + mockMvc.perform(post(URI_PARAMETERS_BASE + "/" + UUID.randomUUID())) + .andExpect(status().isNotFound()); + + mockMvc.perform(post(URI_PARAMETERS_BASE + "/" + createdParameters.getUuid())) + .andExpect(status().isOk()); + + SensitivityAnalysisParametersInfos duplicatedParameters = parametersRepository.findAll().get(1).toInfos(); + assertThat(duplicatedParameters).recursivelyEquals(createdParameters); + } + + @Test + void buildInputDataTest() { + SensitivityAnalysisParametersInfos parametersInfos = buildParameters(); + UUID parametersUuid = saveAndReturnId(parametersInfos); + LoadFlowParametersValues loadFlowParametersValues = LoadFlowParametersValues.builder() + .commonParameters(LoadFlowParameters.load()) + .specificParameters(Map.of("reactiveRangeCheckMode", "TARGET_P", "plausibleActivePowerLimit", "5000.0")) + .build(); + + SensitivityAnalysisInputData inputData = parametersService.buildInputData(parametersUuid, loadFlowParametersValues); + + // now we check that each field contains the good value + SensitivityAnalysisParameters sensitivityAnalysisParameters = inputData.getParameters(); + assertThat(sensitivityAnalysisParameters.getLoadFlowParameters()).recursivelyEquals(loadFlowParametersValues.commonParameters()); + assertThat(sensitivityAnalysisParameters) + .extracting( + SensitivityAnalysisParameters::getAngleFlowSensitivityValueThreshold, + SensitivityAnalysisParameters::getFlowFlowSensitivityValueThreshold, + SensitivityAnalysisParameters::getFlowVoltageSensitivityValueThreshold) + .containsExactly( + parametersInfos.getAngleFlowSensitivityValueThreshold(), + parametersInfos.getFlowFlowSensitivityValueThreshold(), + parametersInfos.getFlowVoltageSensitivityValueThreshold()); + + assertEquals(inputData.getLoadFlowSpecificParameters(), loadFlowParametersValues.specificParameters()); + + assertEquals(inputData.getSensitivityInjections().size(), parametersInfos.getSensitivityInjection().size()); + assertThat(inputData.getSensitivityInjections().get(0)).recursivelyEquals(parametersInfos.getSensitivityInjection().get(0)); + assertEquals(inputData.getSensitivityInjectionsSets().size(), parametersInfos.getSensitivityInjectionsSet().size()); + assertThat(inputData.getSensitivityInjectionsSets().get(0)).recursivelyEquals(parametersInfos.getSensitivityInjectionsSet().get(0)); + assertEquals(inputData.getSensitivityPSTs().size(), parametersInfos.getSensitivityPST().size()); + assertThat(inputData.getSensitivityPSTs().get(0)).recursivelyEquals(parametersInfos.getSensitivityPST().get(0)); + assertEquals(inputData.getSensitivityHVDCs().size(), parametersInfos.getSensitivityHVDC().size()); + assertThat(inputData.getSensitivityHVDCs().get(0)).recursivelyEquals(parametersInfos.getSensitivityHVDC().get(0)); + assertEquals(inputData.getSensitivityNodes().size(), parametersInfos.getSensitivityNodes().size()); + assertThat(inputData.getSensitivityNodes().get(0)).recursivelyEquals(parametersInfos.getSensitivityNodes().get(0)); + } + + /** + * Save parameters into the repository and return its UUID. + */ + protected UUID saveAndReturnId(SensitivityAnalysisParametersInfos parametersInfos) { + return parametersRepository.save(parametersInfos.toEntity()).getId(); + } + + public static SensitivityAnalysisParametersInfos buildParameters() { + EquipmentsContainer equipments1 = new EquipmentsContainer(UUID.fromString("cf399ef3-7f14-4884-8c82-1c90300da321"), "identifiable1"); + EquipmentsContainer equipments2 = new EquipmentsContainer(UUID.fromString("cf399ef3-7f14-4884-8c82-1c90300da322"), "identifiable2"); + EquipmentsContainer equipments3 = new EquipmentsContainer(UUID.fromString("cf399ef3-7f14-4884-8c82-1c90300da323"), "identifiable3"); + SensitivityInjectionsSet injectionsSet = new SensitivityInjectionsSet(List.of(equipments2), List.of(equipments1), SensitivityAnalysisInputData.DistributionType.PROPORTIONAL, List.of(equipments3), true); + SensitivityInjection injections = new SensitivityInjection(List.of(equipments1), List.of(equipments2), List.of(equipments3), true); + SensitivityHVDC hvdc = new SensitivityHVDC(List.of(equipments1), SensitivityAnalysisInputData.SensitivityType.DELTA_MW, List.of(equipments2), List.of(equipments3), true); + SensitivityPST pst = new SensitivityPST(List.of(equipments2), SensitivityAnalysisInputData.SensitivityType.DELTA_MW, List.of(equipments1), List.of(equipments3), true); + SensitivityNodes nodes = new SensitivityNodes(List.of(equipments1), List.of(equipments2), List.of(equipments3), true); + + return SensitivityAnalysisParametersInfos.builder() + .flowFlowSensitivityValueThreshold(90) + .angleFlowSensitivityValueThreshold(0.6) + .flowVoltageSensitivityValueThreshold(0.1) + .sensitivityInjectionsSet(List.of(injectionsSet)) + .sensitivityInjection(List.of(injections)) + .sensitivityHVDC(List.of(hvdc)) + .sensitivityPST(List.of(pst)) + .sensitivityNodes(List.of(nodes)) + .build(); + } + + protected SensitivityAnalysisParametersInfos buildParametersUpdate() { + return SensitivityAnalysisParametersInfos.builder() + .flowFlowSensitivityValueThreshold(91) + .angleFlowSensitivityValueThreshold(0.7) + .flowVoltageSensitivityValueThreshold(0.2) + .sensitivityInjectionsSet(List.of()) + .sensitivityInjection(List.of()) + .sensitivityHVDC(List.of()) + .sensitivityPST(List.of()) + .sensitivityNodes(List.of()) + .build(); + } +} + diff --git a/src/test/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityAnalysisInputDataTest.java b/src/test/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityAnalysisInputDataTest.java index f9ab0958..3fff38e7 100644 --- a/src/test/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityAnalysisInputDataTest.java +++ b/src/test/java/org/gridsuite/sensitivityanalysis/server/dto/SensitivityAnalysisInputDataTest.java @@ -127,7 +127,7 @@ public void testEmptyInputTranslation() { .build(); ReporterModel reporter = new ReporterModel("a", "b"); SensitivityAnalysisRunContext context; - context = new SensitivityAnalysisRunContext(NETWORK_UUID, VARIANT_ID, inputData, null, null, null, null, null, null); + context = new SensitivityAnalysisRunContext(NETWORK_UUID, VARIANT_ID, inputData, null, null, null, null); inputBuilderService.build(context, NETWORK, reporter); Collection reports; reports = reporter.getReports(); @@ -157,7 +157,7 @@ public void testFilterPbInputTranslation() { .contingencies(List.of(new EquipmentsContainer(UUID.randomUUID(), "u10"), new EquipmentsContainer(UUID.randomUUID(), "u11"))) .build())) .build(); - context = new SensitivityAnalysisRunContext(NETWORK_UUID, VARIANT_ID, inputData, null, null, null, null, null, null); + context = new SensitivityAnalysisRunContext(NETWORK_UUID, VARIANT_ID, inputData, null, null, null, null); inputBuilderService.build(context, NETWORK, reporter); Collection reports = reporter.getReports(); assertThat(reports, not(nullValue())); @@ -177,7 +177,7 @@ public void testFilterWiderPbInputTranslation() { SensitivityAnalysisInputData inputData = inputBuilder .build(); - context = new SensitivityAnalysisRunContext(NETWORK_UUID, VARIANT_ID, inputData, null, null, null, null, null, null); + context = new SensitivityAnalysisRunContext(NETWORK_UUID, VARIANT_ID, inputData, null, null, null, null); final ReporterModel reporter = new ReporterModel("a", "b"); var thrown = assertThrows(NullPointerException.class, () -> inputBuilderService.build(context, NETWORK, reporter)); assertThat(thrown, Matchers.instanceOf(NullPointerException.class)); diff --git a/src/test/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisServiceTest.java b/src/test/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisServiceTest.java index 9892e418..382ba1ab 100644 --- a/src/test/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisServiceTest.java +++ b/src/test/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisServiceTest.java @@ -4,31 +4,23 @@ */ package org.gridsuite.sensitivityanalysis.server.service; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; -import java.util.stream.Stream; - +import com.powsybl.commons.reporter.Reporter; +import com.powsybl.computation.ComputationManager; +import com.powsybl.contingency.ContingencyContext; +import com.powsybl.contingency.ContingencyContextType; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.VariantManagerConstants; +import com.powsybl.network.store.client.NetworkStoreService; +import com.powsybl.network.store.client.PreloadingStrategy; +import com.powsybl.network.store.iidm.impl.NetworkFactoryImpl; +import com.powsybl.sensitivity.*; import lombok.SneakyThrows; import org.gridsuite.sensitivityanalysis.server.SensibilityAnalysisException; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityAnalysisCsvFileInfos; +import org.gridsuite.sensitivityanalysis.server.SensitivityAnalysisApplication; +import org.gridsuite.sensitivityanalysis.server.dto.*; import org.gridsuite.sensitivityanalysis.server.dto.resultselector.ResultTab; import org.gridsuite.sensitivityanalysis.server.dto.resultselector.ResultsSelector; -import org.gridsuite.sensitivityanalysis.server.SensitivityAnalysisApplication; import org.gridsuite.sensitivityanalysis.server.dto.resultselector.SortKey; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityAnalysisInputData; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityOfTo; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityRunQueryResult; -import org.gridsuite.sensitivityanalysis.server.dto.SensitivityWithContingency; import org.hamcrest.Matchers; import org.hamcrest.collection.IsIterableContainingInOrder; import org.hamcrest.core.Every; @@ -46,37 +38,23 @@ import org.springframework.test.context.ContextHierarchy; import org.springframework.test.context.junit4.SpringRunner; -import com.powsybl.commons.reporter.Reporter; -import com.powsybl.computation.ComputationManager; -import com.powsybl.contingency.ContingencyContext; -import com.powsybl.contingency.ContingencyContextType; -import com.powsybl.iidm.network.Network; -import com.powsybl.iidm.network.VariantManagerConstants; -import com.powsybl.network.store.client.NetworkStoreService; -import com.powsybl.network.store.client.PreloadingStrategy; -import com.powsybl.network.store.iidm.impl.NetworkFactoryImpl; -import com.powsybl.sensitivity.SensitivityAnalysis; -import com.powsybl.sensitivity.SensitivityAnalysisParameters; -import com.powsybl.sensitivity.SensitivityAnalysisResult; -import com.powsybl.sensitivity.SensitivityFactor; -import com.powsybl.sensitivity.SensitivityFunctionType; -import com.powsybl.sensitivity.SensitivityValue; -import com.powsybl.sensitivity.SensitivityVariableType; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; +import java.util.stream.Stream; + import static org.gridsuite.sensitivityanalysis.server.util.OrderMatcher.isOrderedAccordingTo; import static org.gridsuite.sensitivityanalysis.server.util.TestUtils.unzip; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.*; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyList; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.*; /** * @author Laurent Garnier @@ -93,6 +71,9 @@ public class SensitivityAnalysisServiceTest { @SpyBean SensitivityAnalysisService analysisService; + @SpyBean + private SensitivityAnalysisParametersService parametersService; + @MockBean private NetworkStoreService networkStoreService; @@ -147,10 +128,9 @@ private static SensitivityAnalysisInputData getDummyInputData() { @Test public void test0() { - SensitivityAnalysisRunContext context = new SensitivityAnalysisRunContext(NETWORK_UUID, VARIANT_ID, - getDummyInputData(), null, null, null, null, null, null); - testBasic(true, context); - testBasic(false, context); + doReturn(getDummyInputData()).when(parametersService).buildInputData(any(), any()); + testBasic(true); + testBasic(false); } @Test @@ -164,24 +144,24 @@ public void testWithLFParams() { .parameters(null) // null LF params .loadFlowSpecificParameters(null) .build(); - SensitivityAnalysisRunContext context = new SensitivityAnalysisRunContext(NETWORK_UUID, VARIANT_ID, - inputData, null, "OpenLoadFlow", null, null, null, null); - testBasic(true, context); + doReturn(inputData).when(parametersService).buildInputData(any(), any()); + testBasic(true); // with non-null LF params inputData.setParameters(SensitivityAnalysisParameters.load()); - testBasic(true, context); + // PS : no need to mock again, it will return the updated inputData + testBasic(true); // with empty specific parameters inputData.setLoadFlowSpecificParameters(Map.of()); - testBasic(true, context); + testBasic(true); // with 2 specific parameters inputData.setLoadFlowSpecificParameters(Map.of("reactiveRangeCheckMode", "TARGET_P", "plausibleActivePowerLimit", "5000.0")); - testBasic(true, context); + testBasic(true); } - private void testBasic(boolean specific, SensitivityAnalysisRunContext context) { + private void testBasic(boolean specific) { List aleaIds = List.of("a1", "a2", "a3"); final List contingenciesStatuses = aleaIds.stream() .map(aleaId -> new SensitivityAnalysisResult.SensitivityContingencyStatus(aleaId, SensitivityAnalysisResult.Status.SUCCESS)) @@ -219,7 +199,7 @@ private void testBasic(boolean specific, SensitivityAnalysisRunContext context) any(SensitivityAnalysisParameters.class), any(ComputationManager.class), any(Reporter.class))) .willReturn(CompletableFuture.completedFuture(result)); - UUID gottenResultUuid = analysisService.runAndSaveResult(context); + UUID gottenResultUuid = analysisService.runAndSaveResult(NETWORK_UUID, VARIANT_ID, null, "OpenLoadFlow", null, null, null, null); assertThat(gottenResultUuid, not(nullValue())); assertThat(gottenResultUuid, is(resultUuid)); @@ -311,9 +291,9 @@ public void testNoNKStillOK() throws Exception { any(SensitivityAnalysisParameters.class), any(ComputationManager.class), any(Reporter.class))) .willReturn(CompletableFuture.completedFuture(result)); - UUID gottenResultUuid = analysisService.runAndSaveResult( - new SensitivityAnalysisRunContext(NETWORK_UUID, VARIANT_ID, - getDummyInputData(), null, null, null, null, null, null)); + doReturn(getDummyInputData()).when(parametersService).buildInputData(any(), any()); + UUID gottenResultUuid = analysisService.runAndSaveResult(NETWORK_UUID, VARIANT_ID, + null, null, null, null, null, null); assertThat(gottenResultUuid, not(nullValue())); assertThat(gottenResultUuid, is(resultUuid)); @@ -422,9 +402,9 @@ private void testNoN(boolean specific) throws Exception { any(SensitivityAnalysisParameters.class), any(ComputationManager.class), any(Reporter.class))) .willReturn(CompletableFuture.completedFuture(result)); - UUID gottenResultUuid = analysisService.runAndSaveResult( - new SensitivityAnalysisRunContext(NETWORK_UUID, VARIANT_ID, - getDummyInputData(), null, null, null, null, null, null)); + doReturn(getDummyInputData()).when(parametersService).buildInputData(any(), any()); + UUID gottenResultUuid = analysisService.runAndSaveResult(NETWORK_UUID, VARIANT_ID, + null, null, null, null, null, null); assertThat(gottenResultUuid, not(nullValue())); assertThat(gottenResultUuid, is(resultUuid)); diff --git a/src/test/java/org/gridsuite/sensitivityanalysis/server/util/assertions/Assertions.java b/src/test/java/org/gridsuite/sensitivityanalysis/server/util/assertions/Assertions.java new file mode 100644 index 00000000..db4c939c --- /dev/null +++ b/src/test/java/org/gridsuite/sensitivityanalysis/server/util/assertions/Assertions.java @@ -0,0 +1,53 @@ +/** + * 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.sensitivityanalysis.server.util.assertions; + +import com.powsybl.loadflow.LoadFlowParameters; +import org.assertj.core.util.CheckReturnValue; +import org.gridsuite.sensitivityanalysis.server.dto.*; +import org.gridsuite.sensitivityanalysis.server.dto.parameters.SensitivityAnalysisParametersInfos; + +/** + * @author Florent MILLOT + * {@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(SensitivityAnalysisParametersInfos actual) { + return new DTOAssert<>(actual); + } + + @CheckReturnValue + public static DTOAssert assertThat(LoadFlowParameters actual) { + return new DTOAssert<>(actual); + } + + @CheckReturnValue + public static DTOAssert assertThat(SensitivityInjectionsSet actual) { + return new DTOAssert<>(actual); + } + + @CheckReturnValue + public static DTOAssert assertThat(SensitivityInjection actual) { + return new DTOAssert<>(actual); + } + + @CheckReturnValue + public static DTOAssert assertThat(SensitivityHVDC actual) { + return new DTOAssert<>(actual); + } + + @CheckReturnValue + public static DTOAssert assertThat(SensitivityPST actual) { + return new DTOAssert<>(actual); + } + + @CheckReturnValue + public static DTOAssert assertThat(SensitivityNodes actual) { + return new DTOAssert<>(actual); + } +} diff --git a/src/test/java/org/gridsuite/sensitivityanalysis/server/util/assertions/DTOAssert.java b/src/test/java/org/gridsuite/sensitivityanalysis/server/util/assertions/DTOAssert.java new file mode 100644 index 00000000..18813102 --- /dev/null +++ b/src/test/java/org/gridsuite/sensitivityanalysis/server/util/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.sensitivityanalysis.server.util.assertions; + +import org.assertj.core.api.AbstractAssert; +import org.assertj.core.api.recursive.comparison.RecursiveComparisonConfiguration; + +import java.time.ZonedDateTime; +import java.util.Date; +import java.util.UUID; + +/** + * @author Tristan Chuine + * @author Slimane Amar + */ +public class DTOAssert extends AbstractAssert, T> { + public DTOAssert(T actual) { + super(actual, DTOAssert.class); + } + + public DTOAssert recursivelyEquals(T other) { + isNotNull(); + usingRecursiveComparison(this.getRecursiveConfiguration()).isEqualTo(other); + return myself; + } + + private RecursiveComparisonConfiguration getRecursiveConfiguration() { + return RecursiveComparisonConfiguration.builder() + .withIgnoreAllOverriddenEquals(true) // For equals test, need specific tests + .withIgnoredFieldsOfTypes(UUID.class, Date.class, ZonedDateTime.class) // For these types, need specific tests (uuid from db for example) + .withIgnoreCollectionOrder(true) // For collection order test, need specific tests + .build(); + } +}