From 100e2924b683c8e1335da5c2b440a7dd0bfe771f Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Wed, 18 Mar 2026 20:02:01 +0100 Subject: [PATCH 1/3] Move Dynamic Simulation Params to Dynamic Simulation server Signed-off-by: Thang PHAM --- .../DynamicSimulationController.java | 8 +- ...DynamicSimulationParametersController.java | 80 +++++- .../dto/DynamicSimulationParametersInfos.java | 13 +- .../ds/server/dto/curve/CurveInfos.java | 9 +- .../ds/server/dto/network/NetworkInfos.java | 5 +- .../dto/solver/AbstractSolverInfos.java | 6 +- .../ds/server/dto/solver/IdaSolverInfos.java | 2 +- .../ds/server/dto/solver/SimSolverInfos.java | 2 +- .../ds/server/dto/solver/SolverInfos.java | 7 +- .../ds/server/dto/solver/SolverTypeInfos.java | 26 -- ...tractManuallyAssignedIdentifierEntity.java | 2 +- .../{model => entities}/ResultEntity.java | 2 +- .../DynamicSimulationParametersEntity.java | 186 ++++++++++++++ .../parameters/curve/CurveEntity.java | 68 +++++ .../network/NetworkParametersEntity.java | 153 ++++++++++++ .../solver/IdaSolverParametersEntity.java | 73 ++++++ .../solver/SimSolverParametersEntity.java | 133 ++++++++++ .../solver/SolverParametersEntity.java | 185 ++++++++++++++ ...DynamicSimulationParametersRepository.java | 27 ++ .../server/repository/ResultRepository.java | 2 +- .../DynamicSimulationResultService.java | 2 +- .../DynamicSimulationWorkerService.java | 2 +- .../DynamicSimulationResultContext.java | 23 +- .../contexts/DynamicSimulationRunContext.java | 2 + .../service/parameters}/ParameterUtils.java | 96 +++----- .../service/parameters/ParametersService.java | 21 +- .../impl/ParametersServiceImpl.java | 113 ++++++++- .../changesets/changelog_20260318T185133Z.xml | 136 ++++++++++ .../db/changelog/db.changelog-master.yaml | 4 + ...stractDynamicSimulationControllerTest.java | 4 + ...DynamicSimulationControllerIEEE14Test.java | 26 +- .../DynamicSimulationControllerTest.java | 62 +++-- ...ulationParametersControllerIEEE14Test.java | 26 +- ...micSimulationParametersControllerTest.java | 233 ++++++++++++++++++ .../controller/utils/ParameterTestUtils.java | 60 +++++ .../dto/XmlSerializableParameterTest.java | 8 +- .../DynamicSimulationResultServiceTest.java | 2 +- 37 files changed, 1634 insertions(+), 175 deletions(-) delete mode 100644 src/main/java/org/gridsuite/ds/server/dto/solver/SolverTypeInfos.java rename src/main/java/org/gridsuite/ds/server/{model => entities}/AbstractManuallyAssignedIdentifierEntity.java (96%) rename src/main/java/org/gridsuite/ds/server/{model => entities}/ResultEntity.java (98%) create mode 100644 src/main/java/org/gridsuite/ds/server/entities/parameters/DynamicSimulationParametersEntity.java create mode 100644 src/main/java/org/gridsuite/ds/server/entities/parameters/curve/CurveEntity.java create mode 100644 src/main/java/org/gridsuite/ds/server/entities/parameters/network/NetworkParametersEntity.java create mode 100644 src/main/java/org/gridsuite/ds/server/entities/parameters/solver/IdaSolverParametersEntity.java create mode 100644 src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SimSolverParametersEntity.java create mode 100644 src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SolverParametersEntity.java create mode 100644 src/main/java/org/gridsuite/ds/server/repository/DynamicSimulationParametersRepository.java rename src/{test/java/org/gridsuite/ds/server/controller/utils => main/java/org/gridsuite/ds/server/service/parameters}/ParameterUtils.java (56%) create mode 100644 src/main/resources/db/changelog/changesets/changelog_20260318T185133Z.xml create mode 100644 src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationParametersControllerTest.java create mode 100644 src/test/java/org/gridsuite/ds/server/controller/utils/ParameterTestUtils.java diff --git a/src/main/java/org/gridsuite/ds/server/controller/DynamicSimulationController.java b/src/main/java/org/gridsuite/ds/server/controller/DynamicSimulationController.java index e87bf954..a7f736cb 100644 --- a/src/main/java/org/gridsuite/ds/server/controller/DynamicSimulationController.java +++ b/src/main/java/org/gridsuite/ds/server/controller/DynamicSimulationController.java @@ -14,8 +14,8 @@ import io.swagger.v3.oas.annotations.tags.Tag; import org.apache.commons.collections4.CollectionUtils; import org.gridsuite.computation.dto.ReportInfos; -import org.gridsuite.ds.server.dto.DynamicSimulationParametersInfos; import org.gridsuite.ds.server.dto.DynamicSimulationStatus; +import org.gridsuite.ds.server.dto.event.EventInfos; import org.gridsuite.ds.server.service.DynamicSimulationResultService; import org.gridsuite.ds.server.service.DynamicSimulationService; import org.gridsuite.ds.server.service.contexts.DynamicSimulationRunContext; @@ -64,7 +64,8 @@ public ResponseEntity run(@PathVariable("networkUuid") UUID networkUuid, @RequestParam(name = "reportType", required = false, defaultValue = "DynamicSimulation") String reportType, @RequestParam(name = "provider", required = false) String provider, @RequestParam(name = "debug", required = false, defaultValue = "false") boolean debug, - @RequestBody DynamicSimulationParametersInfos parameters, + @RequestParam(name = "parametersUuid") UUID parametersUuid, + @RequestBody List events, @RequestHeader(HEADER_USER_ID) String userId) { DynamicSimulationRunContext dynamicSimulationRunContext = parametersService.createRunContext( @@ -75,7 +76,8 @@ public ResponseEntity run(@PathVariable("networkUuid") UUID networkUuid, mappingName, ReportInfos.builder().reportUuid(reportId).reporterId(reportName).computationType(reportType).build(), userId, - parameters, + parametersUuid, + events, debug); UUID resultUuid = dynamicSimulationService.runAndSaveResult(dynamicSimulationRunContext); diff --git a/src/main/java/org/gridsuite/ds/server/controller/DynamicSimulationParametersController.java b/src/main/java/org/gridsuite/ds/server/controller/DynamicSimulationParametersController.java index 4e6c1e5b..f9a9e412 100644 --- a/src/main/java/org/gridsuite/ds/server/controller/DynamicSimulationParametersController.java +++ b/src/main/java/org/gridsuite/ds/server/controller/DynamicSimulationParametersController.java @@ -7,6 +7,7 @@ package org.gridsuite.ds.server.controller; 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.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; @@ -18,6 +19,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.util.List; import java.util.Optional; import java.util.UUID; @@ -36,14 +38,82 @@ public DynamicSimulationParametersController(ParametersService parametersService this.parametersService = parametersService; } - @PostMapping(value = "/values", produces = MediaType.APPLICATION_JSON_VALUE) + @PostMapping(value = "", consumes = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Create parameters") + @ApiResponse(responseCode = "200", description = "parameters were created") + public ResponseEntity createParameters( + @RequestBody DynamicSimulationParametersInfos parametersInfos) { + return ResponseEntity.ok(parametersService.createParameters(parametersInfos)); + } + + @PostMapping(value = "/default") + @Operation(summary = "Create default parameters") + @ApiResponse(responseCode = "200", description = "Default parameters were created") + public ResponseEntity createDefaultParameters() { + return ResponseEntity.ok(parametersService.createDefaultParameters()); + } + + @PostMapping(value = "", params = "duplicateFrom", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Duplicate parameters") + @ApiResponse(responseCode = "200", description = "parameters were duplicated") + public ResponseEntity duplicateParameters( + @Parameter(description = "source parameters UUID") @RequestParam("duplicateFrom") UUID sourceParametersUuid) { + return ResponseEntity.ok(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.ok(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().body(parametersService.getAllParameters()); + } + + @PutMapping(value = "/{uuid}", consumes = 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(required = false) DynamicSimulationParametersInfos parametersInfos) { + parametersService.updateParameters(parametersUuid, parametersInfos); + return ResponseEntity.ok().build(); + } + + @DeleteMapping(value = "/{uuid}") + @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(); + } + + @GetMapping(value = "/{uuid}/provider", produces = MediaType.TEXT_PLAIN_VALUE) + @Operation(summary = "Get provider") + @ApiResponse(responseCode = "200", description = "provider were returned") + @ApiResponse(responseCode = "404", description = "provider were not found") + public ResponseEntity getProvider( + @Parameter(description = "parameters UUID") @PathVariable("uuid") UUID parametersUuid) { + return ResponseEntity.ok(parametersService.getProvider(parametersUuid)); + } + + @GetMapping(value = "/{uuid}/values", produces = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Get the dynamic simulation parameters values") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The dynamic simulation parameters values"), @ApiResponse(responseCode = "404", description = "The dynamic simulation parameters has not been found")}) - public ResponseEntity getParametersValues(@RequestParam(name = "networkUuid") UUID networkUuid, - @RequestParam(name = "variantId", required = false) String variantId, - @RequestBody DynamicSimulationParametersInfos parameters) { - DynamicSimulationParametersValues parametersValues = parametersService.getParametersValues(parameters, networkUuid, variantId); + public ResponseEntity getParametersValues( + @Parameter(description = "parameters UUID") @PathVariable("uuid") UUID parametersUuid, + @RequestParam(name = "networkUuid") UUID networkUuid, + @RequestParam(name = "variantId", required = false) String variantId) { + DynamicSimulationParametersValues parametersValues = parametersService.getParametersValues(parametersUuid, networkUuid, variantId); return ResponseEntity.of(Optional.ofNullable(parametersValues)); } } diff --git a/src/main/java/org/gridsuite/ds/server/dto/DynamicSimulationParametersInfos.java b/src/main/java/org/gridsuite/ds/server/dto/DynamicSimulationParametersInfos.java index 805b185b..ab34065e 100644 --- a/src/main/java/org/gridsuite/ds/server/dto/DynamicSimulationParametersInfos.java +++ b/src/main/java/org/gridsuite/ds/server/dto/DynamicSimulationParametersInfos.java @@ -9,16 +9,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; +import com.powsybl.dynawo.DynawoSimulationParameters.SolverType; +import lombok.*; import org.gridsuite.ds.server.dto.curve.CurveInfos; -import org.gridsuite.ds.server.dto.event.EventInfos; import org.gridsuite.ds.server.dto.network.NetworkInfos; import org.gridsuite.ds.server.dto.solver.SolverInfos; import java.util.List; +import java.util.UUID; /** * @author Thang PHAM @@ -27,17 +25,18 @@ @AllArgsConstructor @Getter @Setter +@Builder @JsonIgnoreProperties(ignoreUnknown = true) public class DynamicSimulationParametersInfos { + private UUID id; private String provider; @JsonInclude(JsonInclude.Include.NON_EMPTY) private Double startTime; @JsonInclude(JsonInclude.Include.NON_EMPTY) private Double stopTime; private String mapping; - private String solverId; + private SolverType solver; private List solvers; private NetworkInfos network; private List curves; - private List events; } diff --git a/src/main/java/org/gridsuite/ds/server/dto/curve/CurveInfos.java b/src/main/java/org/gridsuite/ds/server/dto/curve/CurveInfos.java index aa6612f1..3598da42 100644 --- a/src/main/java/org/gridsuite/ds/server/dto/curve/CurveInfos.java +++ b/src/main/java/org/gridsuite/ds/server/dto/curve/CurveInfos.java @@ -8,12 +8,11 @@ package org.gridsuite.ds.server.dto.curve; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; +import lombok.*; import org.gridsuite.ds.server.utils.EquipmentType; +import java.util.UUID; + /** * @author Thang PHAM */ @@ -21,8 +20,10 @@ @AllArgsConstructor @Getter @Setter +@Builder @JsonIgnoreProperties(ignoreUnknown = true) public class CurveInfos { + private UUID id; private EquipmentType equipmentType; private String equipmentId; private String variableId; diff --git a/src/main/java/org/gridsuite/ds/server/dto/network/NetworkInfos.java b/src/main/java/org/gridsuite/ds/server/dto/network/NetworkInfos.java index b754d7c3..29ccaad2 100644 --- a/src/main/java/org/gridsuite/ds/server/dto/network/NetworkInfos.java +++ b/src/main/java/org/gridsuite/ds/server/dto/network/NetworkInfos.java @@ -14,6 +14,7 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; +import java.util.UUID; /** * @author Thang PHAM @@ -46,7 +47,7 @@ public class NetworkInfos implements XmlSerializableParameter { public static final String NETWORK_ID = "NETWORK"; - private String id = NETWORK_ID; + private UUID id; private double capacitorNoReclosingDelay; @@ -91,7 +92,7 @@ public class NetworkInfos implements XmlSerializableParameter { @Override public void writeParameter(XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement(DYN_BASE_URI, "set"); - writer.writeAttribute("id", id); + writer.writeAttribute("id", NETWORK_ID); XmlSerializableParameter.writeParameter(writer, ParameterType.DOUBLE, CAPACITOR_NO_RECLOSING_DELAY, Double.toString(capacitorNoReclosingDelay)); XmlSerializableParameter.writeParameter(writer, ParameterType.DOUBLE, DANGLING_LINE_CURRENT_LIMIT_MAX_TIME_OPERATION, Double.toString(danglingLineCurrentLimitMaxTimeOperation)); diff --git a/src/main/java/org/gridsuite/ds/server/dto/solver/AbstractSolverInfos.java b/src/main/java/org/gridsuite/ds/server/dto/solver/AbstractSolverInfos.java index d5f05f43..03200816 100644 --- a/src/main/java/org/gridsuite/ds/server/dto/solver/AbstractSolverInfos.java +++ b/src/main/java/org/gridsuite/ds/server/dto/solver/AbstractSolverInfos.java @@ -8,6 +8,7 @@ package org.gridsuite.ds.server.dto.solver; import com.fasterxml.jackson.annotation.JsonProperty; +import com.powsybl.dynawo.DynawoSimulationParameters.SolverType; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -16,6 +17,7 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; +import java.util.UUID; /** * @author Thang PHAM @@ -50,8 +52,8 @@ public abstract class AbstractSolverInfos implements SolverInfos { public static final String MAXIMUM_NUMBER_SLOW_STEP_INCREASE = "maximumNumberSlowStepIncrease"; public static final String MINIMAL_ACCEPTABLE_STEP = "minimalAcceptableStep"; - private String id; - private SolverTypeInfos type; + private UUID id; + private SolverType type; // Important note: must using @JsonProperty to precise property's name when serialize/deserialize // fields which begin by a minuscule following by a majuscule, for example 'hMxxx', otherwise jackson diff --git a/src/main/java/org/gridsuite/ds/server/dto/solver/IdaSolverInfos.java b/src/main/java/org/gridsuite/ds/server/dto/solver/IdaSolverInfos.java index 0fedf33a..60e09fd3 100644 --- a/src/main/java/org/gridsuite/ds/server/dto/solver/IdaSolverInfos.java +++ b/src/main/java/org/gridsuite/ds/server/dto/solver/IdaSolverInfos.java @@ -47,7 +47,7 @@ public class IdaSolverInfos extends AbstractSolverInfos { @Override public void writeParameter(XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement(DYN_BASE_URI, "set"); - writer.writeAttribute("id", getId()); + writer.writeAttribute("id", getType().name()); XmlSerializableParameter.writeParameter(writer, ParameterType.INT, SOLVER_ORDER, Integer.toString(order)); XmlSerializableParameter.writeParameter(writer, ParameterType.DOUBLE, INIT_STEP, Double.toString(initStep)); diff --git a/src/main/java/org/gridsuite/ds/server/dto/solver/SimSolverInfos.java b/src/main/java/org/gridsuite/ds/server/dto/solver/SimSolverInfos.java index 8a7e199c..a2da8b58 100644 --- a/src/main/java/org/gridsuite/ds/server/dto/solver/SimSolverInfos.java +++ b/src/main/java/org/gridsuite/ds/server/dto/solver/SimSolverInfos.java @@ -91,7 +91,7 @@ public class SimSolverInfos extends AbstractSolverInfos { @Override public void writeParameter(XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement(DYN_BASE_URI, "set"); - writer.writeAttribute("id", getId()); + writer.writeAttribute("id", getType().name()); XmlSerializableParameter.writeParameter(writer, ParameterType.DOUBLE, H_MIN, Double.toString(hMin)); XmlSerializableParameter.writeParameter(writer, ParameterType.DOUBLE, H_MAX, Double.toString(hMax)); diff --git a/src/main/java/org/gridsuite/ds/server/dto/solver/SolverInfos.java b/src/main/java/org/gridsuite/ds/server/dto/solver/SolverInfos.java index b720fab8..b065f02f 100644 --- a/src/main/java/org/gridsuite/ds/server/dto/solver/SolverInfos.java +++ b/src/main/java/org/gridsuite/ds/server/dto/solver/SolverInfos.java @@ -9,8 +9,11 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.powsybl.dynawo.DynawoSimulationParameters.SolverType; import org.gridsuite.ds.server.dto.XmlSerializableParameter; +import java.util.UUID; + /** * @author Thang PHAM */ @@ -23,7 +26,7 @@ @JsonSubTypes.Type(value = IdaSolverInfos.class, name = "IDA"), @JsonSubTypes.Type(value = SimSolverInfos.class, name = "SIM")}) public interface SolverInfos extends XmlSerializableParameter { - String getId(); + UUID getId(); - SolverTypeInfos getType(); + SolverType getType(); } diff --git a/src/main/java/org/gridsuite/ds/server/dto/solver/SolverTypeInfos.java b/src/main/java/org/gridsuite/ds/server/dto/solver/SolverTypeInfos.java deleted file mode 100644 index f2c56eb1..00000000 --- a/src/main/java/org/gridsuite/ds/server/dto/solver/SolverTypeInfos.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2023, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package org.gridsuite.ds.server.dto.solver; - -import com.powsybl.dynawo.DynawoSimulationParameters; - -/** - * @author Thang PHAM - */ -public enum SolverTypeInfos { - SIM, - IDA; - - public DynawoSimulationParameters.SolverType toSolverType() { - switch (this) { - case SIM : return DynawoSimulationParameters.SolverType.SIM; - case IDA : return DynawoSimulationParameters.SolverType.IDA; - default : return null; - } - } -} diff --git a/src/main/java/org/gridsuite/ds/server/model/AbstractManuallyAssignedIdentifierEntity.java b/src/main/java/org/gridsuite/ds/server/entities/AbstractManuallyAssignedIdentifierEntity.java similarity index 96% rename from src/main/java/org/gridsuite/ds/server/model/AbstractManuallyAssignedIdentifierEntity.java rename to src/main/java/org/gridsuite/ds/server/entities/AbstractManuallyAssignedIdentifierEntity.java index a151b247..298af76f 100644 --- a/src/main/java/org/gridsuite/ds/server/model/AbstractManuallyAssignedIdentifierEntity.java +++ b/src/main/java/org/gridsuite/ds/server/entities/AbstractManuallyAssignedIdentifierEntity.java @@ -4,7 +4,7 @@ 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.ds.server.model; +package org.gridsuite.ds.server.entities; import jakarta.persistence.MappedSuperclass; import jakarta.persistence.PostLoad; diff --git a/src/main/java/org/gridsuite/ds/server/model/ResultEntity.java b/src/main/java/org/gridsuite/ds/server/entities/ResultEntity.java similarity index 98% rename from src/main/java/org/gridsuite/ds/server/model/ResultEntity.java rename to src/main/java/org/gridsuite/ds/server/entities/ResultEntity.java index 33ad9821..5dd4e794 100644 --- a/src/main/java/org/gridsuite/ds/server/model/ResultEntity.java +++ b/src/main/java/org/gridsuite/ds/server/entities/ResultEntity.java @@ -4,7 +4,7 @@ * 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.ds.server.model; +package org.gridsuite.ds.server.entities; import jakarta.persistence.*; import lombok.Getter; diff --git a/src/main/java/org/gridsuite/ds/server/entities/parameters/DynamicSimulationParametersEntity.java b/src/main/java/org/gridsuite/ds/server/entities/parameters/DynamicSimulationParametersEntity.java new file mode 100644 index 00000000..4339713f --- /dev/null +++ b/src/main/java/org/gridsuite/ds/server/entities/parameters/DynamicSimulationParametersEntity.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2026, 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.ds.server.entities.parameters; + +import com.powsybl.dynawo.DynawoSimulationParameters.SolverType; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.apache.commons.collections4.CollectionUtils; +import org.gridsuite.ds.server.dto.DynamicSimulationParametersInfos; +import org.gridsuite.ds.server.dto.curve.CurveInfos; +import org.gridsuite.ds.server.dto.network.NetworkInfos; +import org.gridsuite.ds.server.dto.solver.SolverInfos; +import org.gridsuite.ds.server.entities.parameters.curve.CurveEntity; +import org.gridsuite.ds.server.entities.parameters.network.NetworkParametersEntity; +import org.gridsuite.ds.server.entities.parameters.solver.SolverParametersEntity; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author Thang PHAM + */ +@NoArgsConstructor +@Getter +@Setter +@Entity +@Table(name = "dynamic_simulation_parameters") +public class DynamicSimulationParametersEntity { + @Id + @Column(name = "id") + private UUID id; + + @Column(name = "provider") + private String provider; + + @Column(name = "start_time") + private double startTime; + + @Column(name = "stop_time") + private double stopTime; + + @Column(name = "solver_id") + @Enumerated(EnumType.STRING) + private SolverType solver; + + @Column(name = "mapping") + private String mapping; + + @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) + @JoinColumn(name = "dynamic_simulation_parameters_id", + foreignKey = @ForeignKey(name = "solver_parameters_dynamic_simulation_parameters_id_fk")) + @OrderColumn(name = "pos") + private List solvers = new ArrayList<>(); + + @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) + @JoinColumn(name = "network_parameters_id", + foreignKey = @ForeignKey(name = "dynamic_simulation_parameters_network_parameters_id_fk")) + private NetworkParametersEntity network; + + @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) + @JoinColumn(name = "dynamic_simulation_parameters_id", + foreignKey = @ForeignKey(name = "curve_dynamic_simulation_parameters_id_fk")) + @OrderColumn(name = "pos") + private List curves = new ArrayList<>(); + + public DynamicSimulationParametersEntity(DynamicSimulationParametersInfos parametersInfos) { + assignAttributes(parametersInfos); + } + + public void assignAttributes(DynamicSimulationParametersInfos parametersInfos) { + if (id == null) { + id = UUID.randomUUID(); + } + provider = parametersInfos.getProvider(); + startTime = parametersInfos.getStartTime() != null ? parametersInfos.getStartTime() : 0; + stopTime = parametersInfos.getStopTime() != null ? parametersInfos.getStopTime() : 0; + mapping = parametersInfos.getMapping(); + solver = parametersInfos.getSolver(); + + // --- Solvers --- + assignSolvers(parametersInfos.getSolvers()); + + // --- Network --- + assignNetwork(parametersInfos.getNetwork()); + + // --- Curves --- + assignCurves(parametersInfos.getCurves()); + } + + private void assignSolvers(List solverInfosList) { + if (CollectionUtils.isEmpty(solverInfosList)) { + solvers.clear(); + return; + } + + // build existing solvers Map + Map solversByIdMap = solvers.stream().collect(Collectors.toMap(SolverParametersEntity::getId, solverEntity -> solverEntity)); + + // merge existing and add new solvers + List mergedSolvers = new ArrayList<>(); + for (SolverInfos solverInfos : solverInfosList) { + if (solverInfos.getId() != null) { + SolverParametersEntity existingEntity = solversByIdMap.get(solverInfos.getId()); + existingEntity.update(solverInfos); + mergedSolvers.add(existingEntity); + } else { + mergedSolvers.add(SolverParametersEntity.fromDto(solverInfos)); + } + } + + // by clear/addAll, existing elements that are not present in the new list will be removed systematically + solvers.clear(); + solvers.addAll(mergedSolvers); + } + + private void assignNetwork(NetworkInfos networkInfos) { + if (networkInfos == null) { + network = null; + return; + } + + if (networkInfos.getId() != null) { + network.update(networkInfos); + } else { + network = new NetworkParametersEntity(networkInfos); + } + } + + private void assignCurves(List curveInfosList) { + if (CollectionUtils.isEmpty(curveInfosList)) { + curves.clear(); + return; + } + + // build existing curves Map + Map curvesByIdMap = curves.stream().collect(Collectors.toMap(CurveEntity::getId, curveEntity -> curveEntity)); + + // merge existing and add new curves + List mergedCurves = new ArrayList<>(); + for (CurveInfos curveInfos : curveInfosList) { + if (curveInfos.getId() != null) { + CurveEntity existingEntity = curvesByIdMap.get(curveInfos.getId()); + existingEntity.update(curveInfos); + mergedCurves.add(existingEntity); + } else { + mergedCurves.add(new CurveEntity(curveInfos)); + } + } + + // by clear/addAll, existing elements that are not present in the new list will be removed systematically + curves.clear(); + curves.addAll(mergedCurves); + } + + public void update(DynamicSimulationParametersInfos parametersInfos) { + assignAttributes(parametersInfos); + } + + public DynamicSimulationParametersInfos toDto(boolean toDuplicate) { + DynamicSimulationParametersInfos dto = new DynamicSimulationParametersInfos(); + dto.setId(toDuplicate ? null : id); + dto.setProvider(provider); + dto.setStartTime(startTime); + dto.setStopTime(stopTime); + dto.setMapping(mapping); + dto.setSolver(solver); + + dto.setSolvers(solvers != null + ? solvers.stream().map(solverEntity -> solverEntity.toDto(toDuplicate)).collect(Collectors.toList()) + : Collections.emptyList()); + + dto.setNetwork(network != null ? network.toDto(toDuplicate) : null); + + dto.setCurves(curves != null + ? curves.stream().map(curve -> curve.toDto(toDuplicate)).collect(Collectors.toList()) + : Collections.emptyList()); + + return dto; + } +} diff --git a/src/main/java/org/gridsuite/ds/server/entities/parameters/curve/CurveEntity.java b/src/main/java/org/gridsuite/ds/server/entities/parameters/curve/CurveEntity.java new file mode 100644 index 00000000..2c53eb94 --- /dev/null +++ b/src/main/java/org/gridsuite/ds/server/entities/parameters/curve/CurveEntity.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2026, 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.ds.server.entities.parameters.curve; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.gridsuite.ds.server.dto.curve.CurveInfos; +import org.gridsuite.ds.server.utils.EquipmentType; + +import java.util.UUID; + +/** + * @author Thang PHAM + */ +@NoArgsConstructor +@Getter +@Setter +@Entity +@Table(name = "curve", indexes = @Index(name = "idx_curve_dynamic_simulation_parameters_id", + columnList = "dynamic_simulation_parameters_id")) +public class CurveEntity { + + @Id + @Column(name = "id") + private UUID id; + + @Column(name = "equipment_type") + @Enumerated(EnumType.STRING) + private EquipmentType equipmentType; + + @Column(name = "equipment_id") + private String equipmentId; + + @Column(name = "variable_id") + private String variableId; + + public CurveEntity(CurveInfos curveInfos) { + assignAttributes(curveInfos); + } + + public void assignAttributes(CurveInfos curveInfos) { + if (id == null) { + id = UUID.randomUUID(); + } + equipmentType = curveInfos.getEquipmentType(); + equipmentId = curveInfos.getEquipmentId(); + variableId = curveInfos.getVariableId(); + } + + public void update(CurveInfos curveInfos) { + assignAttributes(curveInfos); + } + + public CurveInfos toDto(boolean toDuplicate) { + CurveInfos curveInfos = new CurveInfos(); + curveInfos.setId(toDuplicate ? null : id); + curveInfos.setEquipmentType(equipmentType); + curveInfos.setEquipmentId(equipmentId); + curveInfos.setVariableId(variableId); + return curveInfos; + } +} diff --git a/src/main/java/org/gridsuite/ds/server/entities/parameters/network/NetworkParametersEntity.java b/src/main/java/org/gridsuite/ds/server/entities/parameters/network/NetworkParametersEntity.java new file mode 100644 index 00000000..f99f9a65 --- /dev/null +++ b/src/main/java/org/gridsuite/ds/server/entities/parameters/network/NetworkParametersEntity.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2026, 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.ds.server.entities.parameters.network; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.gridsuite.ds.server.dto.network.NetworkInfos; + +import java.util.UUID; + +/** + * @author Thang PHAM + */ +@NoArgsConstructor +@Getter +@Setter +@Entity +@Table(name = "network_parameters") +public class NetworkParametersEntity { + + @Id + @Column(name = "id") + private UUID id; + + @Column(name = "capacitor_no_reclosing_delay") + private double capacitorNoReclosingDelay; + + @Column(name = "dangling_line_current_limit_max_time_operation") + private double danglingLineCurrentLimitMaxTimeOperation; + + @Column(name = "line_current_limit_max_time_operation") + private double lineCurrentLimitMaxTimeOperation; + + @Column(name = "load_tp") + private double loadTp; + + @Column(name = "load_tq") + private double loadTq; + + @Column(name = "load_alpha") + private double loadAlpha; + + @Column(name = "load_alpha_long") + private double loadAlphaLong; + + @Column(name = "load_beta") + private double loadBeta; + + @Column(name = "load_beta_long") + private double loadBetaLong; + + @Column(name = "load_is_controllable") + private boolean loadIsControllable; + + @Column(name = "load_is_restorative") + private boolean loadIsRestorative; + + @Column(name = "load_zp_max") + private double loadZPMax; + + @Column(name = "load_zq_max") + private double loadZQMax; + + @Column(name = "reactance_no_reclosing_delay") + private double reactanceNoReclosingDelay; + + @Column(name = "transformer_current_limit_max_time_operation") + private double transformerCurrentLimitMaxTimeOperation; + + @Column(name = "transformer_t1st_ht") + private double transformerT1StHT; + + @Column(name = "transformer_t1st_tht") + private double transformerT1StTHT; + + @Column(name = "transformer_t_next_ht") + private double transformerTNextHT; + + @Column(name = "transformer_t_next_tht") + private double transformerTNextTHT; + + @Column(name = "transformer_tol_v") + private double transformerTolV; + + public NetworkParametersEntity(NetworkInfos networkInfos) { + assignAttributes(networkInfos); + } + + public void assignAttributes(NetworkInfos networkInfos) { + if (id == null) { + id = UUID.randomUUID(); + } + capacitorNoReclosingDelay = networkInfos.getCapacitorNoReclosingDelay(); + danglingLineCurrentLimitMaxTimeOperation = networkInfos.getDanglingLineCurrentLimitMaxTimeOperation(); + lineCurrentLimitMaxTimeOperation = networkInfos.getLineCurrentLimitMaxTimeOperation(); + loadTp = networkInfos.getLoadTp(); + loadTq = networkInfos.getLoadTq(); + loadAlpha = networkInfos.getLoadAlpha(); + loadAlphaLong = networkInfos.getLoadAlphaLong(); + loadBeta = networkInfos.getLoadBeta(); + loadBetaLong = networkInfos.getLoadBetaLong(); + loadIsControllable = networkInfos.isLoadIsControllable(); + loadIsRestorative = networkInfos.isLoadIsRestorative(); + loadZPMax = networkInfos.getLoadZPMax(); + loadZQMax = networkInfos.getLoadZQMax(); + reactanceNoReclosingDelay = networkInfos.getReactanceNoReclosingDelay(); + transformerCurrentLimitMaxTimeOperation = networkInfos.getTransformerCurrentLimitMaxTimeOperation(); + transformerT1StHT = networkInfos.getTransformerT1StHT(); + transformerT1StTHT = networkInfos.getTransformerT1StTHT(); + transformerTNextHT = networkInfos.getTransformerTNextHT(); + transformerTNextTHT = networkInfos.getTransformerTNextTHT(); + transformerTolV = networkInfos.getTransformerTolV(); + } + + public void update(NetworkInfos networkInfos) { + assignAttributes(networkInfos); + } + + public NetworkInfos toDto(boolean toDuplicate) { + NetworkInfos networkInfos = new NetworkInfos(); + networkInfos.setId(toDuplicate ? null : id); + networkInfos.setCapacitorNoReclosingDelay(capacitorNoReclosingDelay); + networkInfos.setDanglingLineCurrentLimitMaxTimeOperation(danglingLineCurrentLimitMaxTimeOperation); + networkInfos.setLineCurrentLimitMaxTimeOperation(lineCurrentLimitMaxTimeOperation); + networkInfos.setLoadTp(loadTp); + networkInfos.setLoadTq(loadTq); + networkInfos.setLoadAlpha(loadAlpha); + networkInfos.setLoadAlphaLong(loadAlphaLong); + networkInfos.setLoadBeta(loadBeta); + networkInfos.setLoadBetaLong(loadBetaLong); + networkInfos.setLoadIsControllable(loadIsControllable); + networkInfos.setLoadIsRestorative(loadIsRestorative); + networkInfos.setLoadZPMax(loadZPMax); + networkInfos.setLoadZQMax(loadZQMax); + networkInfos.setReactanceNoReclosingDelay(reactanceNoReclosingDelay); + networkInfos.setTransformerCurrentLimitMaxTimeOperation(transformerCurrentLimitMaxTimeOperation); + networkInfos.setTransformerT1StHT(transformerT1StHT); + networkInfos.setTransformerT1StTHT(transformerT1StTHT); + networkInfos.setTransformerTNextHT(transformerTNextHT); + networkInfos.setTransformerTNextTHT(transformerTNextTHT); + networkInfos.setTransformerTolV(transformerTolV); + return networkInfos; + } +} diff --git a/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/IdaSolverParametersEntity.java b/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/IdaSolverParametersEntity.java new file mode 100644 index 00000000..236e3e73 --- /dev/null +++ b/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/IdaSolverParametersEntity.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2026, 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.ds.server.entities.parameters.solver; + +import jakarta.persistence.Column; +import jakarta.persistence.DiscriminatorValue; +import jakarta.persistence.Entity; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.gridsuite.ds.server.dto.solver.IdaSolverInfos; +import org.gridsuite.ds.server.dto.solver.SolverInfos; + +/** + * @author Thang PHAM + */ +@NoArgsConstructor +@Getter +@Setter +@Entity +@DiscriminatorValue("IDA") +public class IdaSolverParametersEntity extends SolverParametersEntity { + + @Column(name = "order_value") + private int order; + + @Column(name = "init_step") + private double initStep; + + @Column(name = "min_step") + private double minStep; + + @Column(name = "max_step") + private double maxStep; + + @Column(name = "abs_accuracy") + private double absAccuracy; + + @Column(name = "rel_accuracy") + private double relAccuracy; + + public IdaSolverParametersEntity(IdaSolverInfos solverInfos) { + assignAttributes(solverInfos); + } + + public void assignAttributes(IdaSolverInfos solverInfos) { + super.assignAttributes(solverInfos); + order = solverInfos.getOrder(); + initStep = solverInfos.getInitStep(); + minStep = solverInfos.getMinStep(); + maxStep = solverInfos.getMaxStep(); + absAccuracy = solverInfos.getAbsAccuracy(); + relAccuracy = solverInfos.getRelAccuracy(); + } + + @Override + public SolverInfos toDto(boolean toDuplicate) { + IdaSolverInfos dto = IdaSolverInfos.builder() + .order(order) + .initStep(initStep) + .minStep(minStep) + .maxStep(maxStep) + .absAccuracy(absAccuracy) + .relAccuracy(relAccuracy) + .build(); + super.fillDto(dto, toDuplicate); + return dto; + } +} diff --git a/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SimSolverParametersEntity.java b/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SimSolverParametersEntity.java new file mode 100644 index 00000000..884adad3 --- /dev/null +++ b/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SimSolverParametersEntity.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2026, 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.ds.server.entities.parameters.solver; + +import jakarta.persistence.Column; +import jakarta.persistence.DiscriminatorValue; +import jakarta.persistence.Entity; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.gridsuite.ds.server.dto.solver.SimSolverInfos; +import org.gridsuite.ds.server.dto.solver.SolverInfos; + +/** + * @author Thang PHAM + */ +@NoArgsConstructor +@Getter +@Setter +@Entity +@DiscriminatorValue("SIM") +public class SimSolverParametersEntity extends SolverParametersEntity { + + @Column(name = "h_min") + private double hMin; + + @Column(name = "h_max") + private double hMax; + + @Column(name = "k_reduce_step") + private double kReduceStep; + + @Column(name = "max_newton_try") + private int maxNewtonTry; + + @Column(name = "linear_solver_name") + private String linearSolverName; + + @Column(name = "f_norm_tol") + private double fNormTol; + + @Column(name = "initial_add_tol") + private double initialAddTol; + + @Column(name = "sc_step_tol") + private double scStepTol; + + @Column(name = "mx_new_t_step") + private double mxNewTStep; + + @Column(name = "msbset") + private int msbset; + + @Column(name = "mx_iter") + private int mxIter; + + @Column(name = "print_fl") + private int printFl; + + @Column(name = "optimize_algebraic_residuals_evaluations") + private boolean optimizeAlgebraicResidualsEvaluations; + + @Column(name = "skip_nr_if_initial_guess_ok") + private boolean skipNRIfInitialGuessOK; + + @Column(name = "enable_silent_z") + private boolean enableSilentZ; + + @Column(name = "optimize_reinit_algebraic_residuals_evaluations") + private boolean optimizeReInitAlgebraicResidualsEvaluations; + + @Column(name = "min_mode_change_type_alg_restoration") + private String minimumModeChangeTypeForAlgebraicRestoration; + + @Column(name = "min_mode_change_type_alg_restoration_init") + private String minimumModeChangeTypeForAlgebraicRestorationInit; + + public SimSolverParametersEntity(SimSolverInfos solverInfos) { + assignAttributes(solverInfos); + } + + public void assignAttributes(SimSolverInfos solverInfos) { + super.assignAttributes(solverInfos); + hMin = solverInfos.getHMin(); + hMax = solverInfos.getHMax(); + kReduceStep = solverInfos.getKReduceStep(); + maxNewtonTry = solverInfos.getMaxNewtonTry(); + linearSolverName = solverInfos.getLinearSolverName(); + fNormTol = solverInfos.getFNormTol(); + initialAddTol = solverInfos.getInitialAddTol(); + scStepTol = solverInfos.getScStepTol(); + mxNewTStep = solverInfos.getMxNewTStep(); + msbset = solverInfos.getMsbset(); + mxIter = solverInfos.getMxIter(); + printFl = solverInfos.getPrintFl(); + optimizeAlgebraicResidualsEvaluations = solverInfos.isOptimizeAlgebraicResidualsEvaluations(); + skipNRIfInitialGuessOK = solverInfos.isSkipNRIfInitialGuessOK(); + enableSilentZ = solverInfos.isEnableSilentZ(); + optimizeReInitAlgebraicResidualsEvaluations = solverInfos.isOptimizeReInitAlgebraicResidualsEvaluations(); + minimumModeChangeTypeForAlgebraicRestoration = solverInfos.getMinimumModeChangeTypeForAlgebraicRestoration(); + minimumModeChangeTypeForAlgebraicRestorationInit = solverInfos.getMinimumModeChangeTypeForAlgebraicRestorationInit(); + } + + @Override + public SolverInfos toDto(boolean toDuplicate) { + SimSolverInfos dto = SimSolverInfos.builder() + .hMin(hMin) + .hMax(hMax) + .kReduceStep(kReduceStep) + .maxNewtonTry(maxNewtonTry) + .linearSolverName(linearSolverName) + .fNormTol(fNormTol) + .initialAddTol(initialAddTol) + .scStepTol(scStepTol) + .mxNewTStep(mxNewTStep) + .msbset(msbset) + .mxIter(mxIter) + .printFl(printFl) + .optimizeAlgebraicResidualsEvaluations(optimizeAlgebraicResidualsEvaluations) + .skipNRIfInitialGuessOK(skipNRIfInitialGuessOK) + .enableSilentZ(enableSilentZ) + .optimizeReInitAlgebraicResidualsEvaluations(optimizeReInitAlgebraicResidualsEvaluations) + .minimumModeChangeTypeForAlgebraicRestoration(minimumModeChangeTypeForAlgebraicRestoration) + .minimumModeChangeTypeForAlgebraicRestorationInit(minimumModeChangeTypeForAlgebraicRestorationInit) + .build(); + super.fillDto(dto, toDuplicate); + return dto; + } +} diff --git a/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SolverParametersEntity.java b/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SolverParametersEntity.java new file mode 100644 index 00000000..a88f2bf8 --- /dev/null +++ b/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SolverParametersEntity.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2026, 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.ds.server.entities.parameters.solver; + +import com.powsybl.dynawo.DynawoSimulationParameters.SolverType; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.gridsuite.ds.server.dto.solver.AbstractSolverInfos; +import org.gridsuite.ds.server.dto.solver.IdaSolverInfos; +import org.gridsuite.ds.server.dto.solver.SimSolverInfos; +import org.gridsuite.ds.server.dto.solver.SolverInfos; + +import java.util.UUID; + +/** + * @author Thang PHAM + */ +@SuppressWarnings("checkstyle:AbstractClassName") +@NoArgsConstructor +@Getter +@Setter +@Entity +@Table(name = "solver_parameters", indexes = @Index(name = "idx_solver_parameters_dynamic_simulation_parameters_id", + columnList = "dynamic_simulation_parameters_id")) +@Inheritance(strategy = InheritanceType.SINGLE_TABLE) +@DiscriminatorColumn(name = "solver_type", discriminatorType = DiscriminatorType.STRING) +public abstract class SolverParametersEntity { + + @Id + @Column(name = "id") + private UUID id; + + @Column(name = "solver_type", insertable = false, updatable = false) + @Enumerated(EnumType.STRING) + private SolverType type; + + // --- Common fields from AbstractSolverInfos --- + @Column(name = "f_norm_tol_alg") + private double fNormTolAlg; + + @Column(name = "initial_add_tol_alg") + private double initialAddTolAlg; + + @Column(name = "sc_step_tol_alg") + private double scStepTolAlg; + + @Column(name = "mx_new_t_step_alg") + private double mxNewTStepAlg; + + @Column(name = "msbset_alg") + private int msbsetAlg; + + @Column(name = "mx_iter_alg") + private int mxIterAlg; + + @Column(name = "print_fl_alg") + private int printFlAlg; + + @Column(name = "f_norm_tol_alg_j") + private double fNormTolAlgJ; + + @Column(name = "initial_add_tol_alg_j") + private double initialAddTolAlgJ; + + @Column(name = "sc_step_tol_alg_j") + private double scStepTolAlgJ; + + @Column(name = "mx_new_t_step_alg_j") + private double mxNewTStepAlgJ; + + @Column(name = "msbset_alg_j") + private int msbsetAlgJ; + + @Column(name = "mx_iter_alg_j") + private int mxIterAlgJ; + + @Column(name = "print_fl_alg_j") + private int printFlAlgJ; + + @Column(name = "f_norm_tol_alg_init") + private double fNormTolAlgInit; + + @Column(name = "initial_add_tol_alg_init") + private double initialAddTolAlgInit; + + @Column(name = "sc_step_tol_alg_init") + private double scStepTolAlgInit; + + @Column(name = "mx_new_t_step_alg_init") + private double mxNewTStepAlgInit; + + @Column(name = "msbset_alg_init") + private int msbsetAlgInit; + + @Column(name = "mx_iter_alg_init") + private int mxIterAlgInit; + + @Column(name = "print_fl_alg_init") + private int printFlAlgInit; + + @Column(name = "max_number_slow_step_increase") + private int maximumNumberSlowStepIncrease; + + @Column(name = "minimal_acceptable_step") + private double minimalAcceptableStep; + + protected void assignAttributes(AbstractSolverInfos solverInfos) { + if (id == null) { + id = UUID.randomUUID(); + } + type = solverInfos.getType(); + fNormTolAlg = solverInfos.getFNormTolAlg(); + initialAddTolAlg = solverInfos.getInitialAddTolAlg(); + scStepTolAlg = solverInfos.getScStepTolAlg(); + mxNewTStepAlg = solverInfos.getMxNewTStepAlg(); + msbsetAlg = solverInfos.getMsbsetAlg(); + mxIterAlg = solverInfos.getMxIterAlg(); + printFlAlg = solverInfos.getPrintFlAlg(); + fNormTolAlgJ = solverInfos.getFNormTolAlgJ(); + initialAddTolAlgJ = solverInfos.getInitialAddTolAlgJ(); + scStepTolAlgJ = solverInfos.getScStepTolAlgJ(); + mxNewTStepAlgJ = solverInfos.getMxNewTStepAlgJ(); + msbsetAlgJ = solverInfos.getMsbsetAlgJ(); + mxIterAlgJ = solverInfos.getMxIterAlgJ(); + printFlAlgJ = solverInfos.getPrintFlAlgJ(); + fNormTolAlgInit = solverInfos.getFNormTolAlgInit(); + initialAddTolAlgInit = solverInfos.getInitialAddTolAlgInit(); + scStepTolAlgInit = solverInfos.getScStepTolAlgInit(); + mxNewTStepAlgInit = solverInfos.getMxNewTStepAlgInit(); + msbsetAlgInit = solverInfos.getMsbsetAlgInit(); + mxIterAlgInit = solverInfos.getMxIterAlgInit(); + printFlAlgInit = solverInfos.getPrintFlAlgInit(); + maximumNumberSlowStepIncrease = solverInfos.getMaximumNumberSlowStepIncrease(); + minimalAcceptableStep = solverInfos.getMinimalAcceptableStep(); + } + + public void update(SolverInfos solverInfos) { + assignAttributes((AbstractSolverInfos) solverInfos); + } + + protected void fillDto(AbstractSolverInfos solverInfos, boolean toDuplicate) { + solverInfos.setId(toDuplicate ? null : id); + solverInfos.setType(type); + solverInfos.setFNormTolAlg(fNormTolAlg); + solverInfos.setInitialAddTolAlg(initialAddTolAlg); + solverInfos.setScStepTolAlg(scStepTolAlg); + solverInfos.setMxNewTStepAlg(mxNewTStepAlg); + solverInfos.setMsbsetAlg(msbsetAlg); + solverInfos.setMxIterAlg(mxIterAlg); + solverInfos.setPrintFlAlg(printFlAlg); + solverInfos.setFNormTolAlgJ(fNormTolAlgJ); + solverInfos.setInitialAddTolAlgJ(initialAddTolAlgJ); + solverInfos.setScStepTolAlgJ(scStepTolAlgJ); + solverInfos.setMxNewTStepAlgJ(mxNewTStepAlgJ); + solverInfos.setMsbsetAlgJ(msbsetAlgJ); + solverInfos.setMxIterAlgJ(mxIterAlgJ); + solverInfos.setPrintFlAlgJ(printFlAlgJ); + solverInfos.setFNormTolAlgInit(fNormTolAlgInit); + solverInfos.setInitialAddTolAlgInit(initialAddTolAlgInit); + solverInfos.setScStepTolAlgInit(scStepTolAlgInit); + solverInfos.setMxNewTStepAlgInit(mxNewTStepAlgInit); + solverInfos.setMsbsetAlgInit(msbsetAlgInit); + solverInfos.setMxIterAlgInit(mxIterAlgInit); + solverInfos.setPrintFlAlgInit(printFlAlgInit); + solverInfos.setMaximumNumberSlowStepIncrease(maximumNumberSlowStepIncrease); + solverInfos.setMinimalAcceptableStep(minimalAcceptableStep); + } + + public abstract SolverInfos toDto(boolean toDuplicate); + + public static SolverParametersEntity fromDto(SolverInfos solverInfos) { + if (solverInfos instanceof IdaSolverInfos idaInfos) { + return new IdaSolverParametersEntity(idaInfos); + } else if (solverInfos instanceof SimSolverInfos simInfos) { + return new SimSolverParametersEntity(simInfos); + } + throw new IllegalArgumentException("Unknown solver type: " + solverInfos.getType()); + } +} diff --git a/src/main/java/org/gridsuite/ds/server/repository/DynamicSimulationParametersRepository.java b/src/main/java/org/gridsuite/ds/server/repository/DynamicSimulationParametersRepository.java new file mode 100644 index 00000000..9ab9a8c6 --- /dev/null +++ b/src/main/java/org/gridsuite/ds/server/repository/DynamicSimulationParametersRepository.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2026, 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.ds.server.repository; + +import org.gridsuite.ds.server.entities.parameters.DynamicSimulationParametersEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.Optional; +import java.util.UUID; + +/** + * @author Thang PHAM + */ +@Repository +public interface DynamicSimulationParametersRepository extends JpaRepository { + + @Query("SELECT params.provider FROM DynamicSimulationParametersEntity params WHERE params.id = :id") + Optional findProviderById(@Param("id") UUID id); +} diff --git a/src/main/java/org/gridsuite/ds/server/repository/ResultRepository.java b/src/main/java/org/gridsuite/ds/server/repository/ResultRepository.java index b4f4a967..1e0a6cab 100644 --- a/src/main/java/org/gridsuite/ds/server/repository/ResultRepository.java +++ b/src/main/java/org/gridsuite/ds/server/repository/ResultRepository.java @@ -7,7 +7,7 @@ package org.gridsuite.ds.server.repository; import org.gridsuite.ds.server.dto.DynamicSimulationStatus; -import org.gridsuite.ds.server.model.ResultEntity; +import org.gridsuite.ds.server.entities.ResultEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/org/gridsuite/ds/server/service/DynamicSimulationResultService.java b/src/main/java/org/gridsuite/ds/server/service/DynamicSimulationResultService.java index 020af336..94c1f42c 100644 --- a/src/main/java/org/gridsuite/ds/server/service/DynamicSimulationResultService.java +++ b/src/main/java/org/gridsuite/ds/server/service/DynamicSimulationResultService.java @@ -5,7 +5,7 @@ import org.gridsuite.computation.service.AbstractComputationResultService; import org.gridsuite.ds.server.dto.DynamicSimulationStatus; import org.gridsuite.ds.server.dto.timeseries.TimeSeriesGroupInfos; -import org.gridsuite.ds.server.model.ResultEntity; +import org.gridsuite.ds.server.entities.ResultEntity; import org.gridsuite.ds.server.repository.ResultRepository; import org.gridsuite.ds.server.service.client.timeseries.TimeSeriesClient; import org.slf4j.Logger; diff --git a/src/main/java/org/gridsuite/ds/server/service/DynamicSimulationWorkerService.java b/src/main/java/org/gridsuite/ds/server/service/DynamicSimulationWorkerService.java index 1df0e501..7aa46648 100644 --- a/src/main/java/org/gridsuite/ds/server/service/DynamicSimulationWorkerService.java +++ b/src/main/java/org/gridsuite/ds/server/service/DynamicSimulationWorkerService.java @@ -179,7 +179,7 @@ public void preRun(DynamicSimulationRunContext runContext) { // at the moment T0 and T1 share the same dynamic model List t0DynamicModel = parametersService.getDynamicModel(inputMapping, runContext.getNetwork()); List t1DynamicModel = parametersService.getDynamicModel(inputMapping, runContext.getNetwork()); - List eventModel = parametersService.getEventModel(parametersInfos.getEvents()); + List eventModel = parametersService.getEventModel(runContext.getEvents()); // set start and stop times t0Parameters.setStartTime(parametersInfos.getStartTime()); diff --git a/src/main/java/org/gridsuite/ds/server/service/contexts/DynamicSimulationResultContext.java b/src/main/java/org/gridsuite/ds/server/service/contexts/DynamicSimulationResultContext.java index 81ecba17..c4deca22 100644 --- a/src/main/java/org/gridsuite/ds/server/service/contexts/DynamicSimulationResultContext.java +++ b/src/main/java/org/gridsuite/ds/server/service/contexts/DynamicSimulationResultContext.java @@ -7,14 +7,17 @@ package org.gridsuite.ds.server.service.contexts; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.gridsuite.computation.dto.ReportInfos; import org.gridsuite.computation.service.AbstractResultContext; import org.gridsuite.ds.server.dto.DynamicSimulationParametersInfos; +import org.gridsuite.ds.server.dto.event.EventInfos; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; import java.io.UncheckedIOException; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.UUID; @@ -28,6 +31,7 @@ public class DynamicSimulationResultContext extends AbstractResultContext { public static final String HEADER_MAPPING = "mapping"; + public static final String HEADER_EVENTS = "events"; public DynamicSimulationResultContext(UUID resultUuid, DynamicSimulationRunContext runContext) { super(resultUuid, runContext); @@ -70,12 +74,27 @@ public static DynamicSimulationResultContext fromMessage(Message message // specific headers for dynamic simulation runContext.setMapping(getNonNullHeader(headers, HEADER_MAPPING)); + String eventsJson = getNonNullHeader(headers, HEADER_EVENTS); + List events; + try { + events = objectMapper.readValue(eventsJson, new TypeReference<>() { }); + } catch (JsonProcessingException e) { + throw new UncheckedIOException(e); + } + runContext.setEvents(events); return new DynamicSimulationResultContext(resultUuid, runContext); } @Override - public Map getSpecificMsgHeaders(ObjectMapper ignoredObjectMapper) { - return Map.of(HEADER_MAPPING, getRunContext().getMapping()); + public Map getSpecificMsgHeaders(ObjectMapper objectMapper) { + String eventsJson; + try { + eventsJson = objectMapper.writeValueAsString(getRunContext().getEvents()); + } catch (JsonProcessingException e) { + throw new UncheckedIOException(e); + } + return Map.of(HEADER_MAPPING, getRunContext().getMapping(), + HEADER_EVENTS, eventsJson); } } diff --git a/src/main/java/org/gridsuite/ds/server/service/contexts/DynamicSimulationRunContext.java b/src/main/java/org/gridsuite/ds/server/service/contexts/DynamicSimulationRunContext.java index ee34d6f7..72c27c9b 100644 --- a/src/main/java/org/gridsuite/ds/server/service/contexts/DynamicSimulationRunContext.java +++ b/src/main/java/org/gridsuite/ds/server/service/contexts/DynamicSimulationRunContext.java @@ -15,6 +15,7 @@ import org.gridsuite.computation.dto.ReportInfos; import org.gridsuite.computation.service.AbstractComputationRunContext; import org.gridsuite.ds.server.dto.DynamicSimulationParametersInfos; +import org.gridsuite.ds.server.dto.event.EventInfos; import java.nio.file.Path; import java.util.List; @@ -28,6 +29,7 @@ public class DynamicSimulationRunContext extends AbstractComputationRunContext { private String mapping; + private List events; // --- Fields which are enriched in worker service --- // diff --git a/src/test/java/org/gridsuite/ds/server/controller/utils/ParameterUtils.java b/src/main/java/org/gridsuite/ds/server/service/parameters/ParameterUtils.java similarity index 56% rename from src/test/java/org/gridsuite/ds/server/controller/utils/ParameterUtils.java rename to src/main/java/org/gridsuite/ds/server/service/parameters/ParameterUtils.java index d0fdb330..f79490cf 100644 --- a/src/test/java/org/gridsuite/ds/server/controller/utils/ParameterUtils.java +++ b/src/main/java/org/gridsuite/ds/server/service/parameters/ParameterUtils.java @@ -1,28 +1,22 @@ -/** - * Copyright (c) 2022, RTE (http://www.rte-france.com) +/* + * Copyright (c) 2026, 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.ds.server.service.parameters; -package org.gridsuite.ds.server.controller.utils; - +import com.powsybl.dynamicsimulation.DynamicSimulationParameters; +import com.powsybl.dynawo.DynawoSimulationParameters; +import com.powsybl.dynawo.DynawoSimulationProvider; import org.gridsuite.ds.server.dto.DynamicSimulationParametersInfos; -import org.gridsuite.ds.server.dto.curve.CurveInfos; -import org.gridsuite.ds.server.dto.event.EventInfos; -import org.gridsuite.ds.server.dto.event.EventPropertyInfos; import org.gridsuite.ds.server.dto.network.NetworkInfos; import org.gridsuite.ds.server.dto.solver.IdaSolverInfos; import org.gridsuite.ds.server.dto.solver.SimSolverInfos; import org.gridsuite.ds.server.dto.solver.SolverInfos; -import org.gridsuite.ds.server.dto.solver.SolverTypeInfos; -import org.gridsuite.ds.server.utils.EquipmentType; -import org.gridsuite.ds.server.utils.PropertyType; import java.util.List; -import static org.gridsuite.ds.server.service.parameters.impl.ParametersServiceImpl.FIELD_STATIC_ID; - /** * @author Thang PHAM */ @@ -31,25 +25,31 @@ private ParameterUtils() { throw new AssertionError("Utility class should not be instantiated"); } - /** - * get default dynamic simulation parameters - * @return a default dynamic simulation parameters - */ - public static DynamicSimulationParametersInfos getDefaultDynamicSimulationParameters() { - IdaSolverInfos idaSolver = getDefaultIdaSolver(); - SimSolverInfos simSolver = getDefaultSimSolver(); + public static DynamicSimulationParametersInfos getDefaultParametersValues() { + DynamicSimulationParameters defaultConfigParameters = DynamicSimulationParameters.load(); + + IdaSolverInfos idaSolver = getDefaultIdaSolverValues(); + SimSolverInfos simSolver = getDefaultSimSolverValues(); List solvers = List.of(idaSolver, simSolver); - NetworkInfos network = getDefaultNetwork(); - return new DynamicSimulationParametersInfos(null, 0.0, 50.0, null, idaSolver.getId(), solvers, network, null, null); + NetworkInfos network = getDefaultNetworkValues(); + + return DynamicSimulationParametersInfos.builder() + .provider(DynawoSimulationProvider.NAME) + .startTime(defaultConfigParameters.getStartTime()) + .stopTime(defaultConfigParameters.getStopTime()) + .solver(DynawoSimulationParameters.SolverType.IDA) + .solvers(solvers) + .network(network) + .build(); } - public static IdaSolverInfos getDefaultIdaSolver() { + public static IdaSolverInfos getDefaultIdaSolverValues() { IdaSolverInfos idaSolver = new IdaSolverInfos(); - // these parameters are taken from solver.par file in dynamic simulation server - idaSolver.setId("IDA"); - idaSolver.setType(SolverTypeInfos.IDA); + // we do not yet support getting values from DynawoSimulationParameters.load() + // due to the lack of deserialization from the solvers.par file to the dto + idaSolver.setType(DynawoSimulationParameters.SolverType.IDA); idaSolver.setOrder(2); idaSolver.setInitStep(1.e-7); idaSolver.setMinStep(1.e-7); @@ -84,11 +84,12 @@ public static IdaSolverInfos getDefaultIdaSolver() { return idaSolver; } - public static SimSolverInfos getDefaultSimSolver() { + public static SimSolverInfos getDefaultSimSolverValues() { SimSolverInfos simSolver = new SimSolverInfos(); - simSolver.setId("SIM"); - simSolver.setType(SolverTypeInfos.SIM); + // we do not yet support getting values from DynawoSimulationParameters.load() + // due to the lack of deserialization from the solvers.par file to the dto + simSolver.setType(DynawoSimulationParameters.SolverType.SIM); simSolver.setHMin(0.001); simSolver.setHMax(1); simSolver.setKReduceStep(0.5); @@ -136,8 +137,11 @@ public static SimSolverInfos getDefaultSimSolver() { return simSolver; } - public static NetworkInfos getDefaultNetwork() { + public static NetworkInfos getDefaultNetworkValues() { NetworkInfos network = new NetworkInfos(); + + // we do not yet support getting values from DynawoSimulationParameters.load() + // due to the lack of deserialization from the network.par file to the dto network.setCapacitorNoReclosingDelay(300); network.setDanglingLineCurrentLimitMaxTimeOperation(240); network.setLineCurrentLimitMaxTimeOperation(240); @@ -161,38 +165,4 @@ public static NetworkInfos getDefaultNetwork() { return network; } - - public static List getCurveInfosList() { - return List.of( - new CurveInfos(EquipmentType.LOAD, "_LOAD___2_EC", "load_PPu"), - new CurveInfos(EquipmentType.LOAD, "_LOAD___2_EC", "load_QPu"), - new CurveInfos(EquipmentType.GENERATOR, "_GEN____3_SM", "generator_omegaPu"), - new CurveInfos(EquipmentType.GENERATOR, "_GEN____3_SM", "generator_PGen"), - new CurveInfos(EquipmentType.GENERATOR, "_GEN____3_SM", "generator_QGen"), - new CurveInfos(EquipmentType.GENERATOR, "_GEN____3_SM", "generator_UStatorPu"), - new CurveInfos(EquipmentType.GENERATOR, "_GEN____3_SM", "voltageRegulator_EfdPu"), - new CurveInfos(EquipmentType.STATIC_VAR_COMPENSATOR, "SVC2", "SVarC_injector_UPu"), - new CurveInfos(EquipmentType.STATIC_VAR_COMPENSATOR, "SVC2", "SVarC_injector_PInjPu"), - new CurveInfos(EquipmentType.STATIC_VAR_COMPENSATOR, "SVC2", "SVarC_injector_QInjPu"), - new CurveInfos(EquipmentType.STATIC_VAR_COMPENSATOR, "SVC2", "SVarC_injector_BPu"), - new CurveInfos(EquipmentType.STATIC_VAR_COMPENSATOR, "SVC2", "SVarC_modeHandling_mode_value") - ); - } - - public static List getEventInfosList() { - return List.of( - new EventInfos(null, null, "_BUS____1-BUS____5-1_AC", null, "Disconnect", List.of( - new EventPropertyInfos(null, FIELD_STATIC_ID, "_BUS____1-BUS____5-1_AC", PropertyType.STRING), - new EventPropertyInfos(null, "startTime", "10", PropertyType.FLOAT), - new EventPropertyInfos(null, "disconnectOnly", "TwoSides.TWO", PropertyType.ENUM) - )), - new EventInfos(null, null, "_BUS____1_TN", null, "FaultNode", List.of( - new EventPropertyInfos(null, FIELD_STATIC_ID, "_BUS____1_TN", PropertyType.STRING), - new EventPropertyInfos(null, "startTime", "20", PropertyType.FLOAT), - new EventPropertyInfos(null, "faultTime", "2", PropertyType.FLOAT), - new EventPropertyInfos(null, "rPu", "23", PropertyType.FLOAT), - new EventPropertyInfos(null, "xPu", "32", PropertyType.FLOAT) - )) - ); - } } diff --git a/src/main/java/org/gridsuite/ds/server/service/parameters/ParametersService.java b/src/main/java/org/gridsuite/ds/server/service/parameters/ParametersService.java index a9dd6a0c..376c3490 100644 --- a/src/main/java/org/gridsuite/ds/server/service/parameters/ParametersService.java +++ b/src/main/java/org/gridsuite/ds/server/service/parameters/ParametersService.java @@ -33,12 +33,29 @@ public interface ParametersService { DynamicSimulationParameters getDynamicSimulationParameters(byte[] dynamicParams, String provider, DynamicSimulationParametersInfos inputParameters); DynamicSimulationRunContext createRunContext(UUID networkUuid, String variantId, String receiver, String provider, String mapping, - ReportInfos reportContext, String userId, DynamicSimulationParametersInfos parameters, boolean debug); + ReportInfos reportContext, String userId, UUID parametersUuid, List events, boolean debug); List getDynamicModel(InputMapping inputMapping, Network network); List getDynamicModel(String mappingName, UUID networkUuid, String variantId); - DynamicSimulationParametersValues getParametersValues(DynamicSimulationParametersInfos parameters, UUID networkUuid, String variantId); + DynamicSimulationParametersValues getParametersValues(UUID parametersUuid, UUID networkUuid, String variantId); + // --- Dynamic simulation parameters related CRUD methods --- // + + List getAllParameters(); + + DynamicSimulationParametersInfos getParameters(UUID parametersUuid); + + String getProvider(UUID parametersUuid); + + UUID createParameters(DynamicSimulationParametersInfos parametersInfos); + + UUID createDefaultParameters(); + + UUID duplicateParameters(UUID sourceParametersUuid); + + void updateParameters(UUID parametersUuid, DynamicSimulationParametersInfos parametersInfos); + + void deleteParameters(UUID parametersUuid); } diff --git a/src/main/java/org/gridsuite/ds/server/service/parameters/impl/ParametersServiceImpl.java b/src/main/java/org/gridsuite/ds/server/service/parameters/impl/ParametersServiceImpl.java index 448a657c..6d6e3c7a 100644 --- a/src/main/java/org/gridsuite/ds/server/service/parameters/impl/ParametersServiceImpl.java +++ b/src/main/java/org/gridsuite/ds/server/service/parameters/impl/ParametersServiceImpl.java @@ -28,6 +28,7 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.gridsuite.computation.dto.ReportInfos; +import org.gridsuite.computation.error.ComputationException; import org.gridsuite.ds.server.dto.DynamicSimulationParametersInfos; import org.gridsuite.ds.server.dto.DynamicSimulationParametersValues; import org.gridsuite.ds.server.dto.XmlSerializableParameter; @@ -39,11 +40,14 @@ import org.gridsuite.ds.server.dto.event.EventInfos; import org.gridsuite.ds.server.dto.network.NetworkInfos; import org.gridsuite.ds.server.dto.solver.SolverInfos; +import org.gridsuite.ds.server.entities.parameters.DynamicSimulationParametersEntity; import org.gridsuite.ds.server.error.DynamicSimulationException; +import org.gridsuite.ds.server.repository.DynamicSimulationParametersRepository; import org.gridsuite.ds.server.service.client.FilterClient; import org.gridsuite.ds.server.service.client.dynamicmapping.DynamicMappingClient; import org.gridsuite.ds.server.service.contexts.DynamicSimulationRunContext; import org.gridsuite.ds.server.service.parameters.CurveGroovyGeneratorService; +import org.gridsuite.ds.server.service.parameters.ParameterUtils; import org.gridsuite.ds.server.service.parameters.ParametersService; import org.gridsuite.ds.server.utils.Utils; import org.gridsuite.filter.expertfilter.ExpertFilter; @@ -57,6 +61,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.server.ResponseStatusException; import javax.xml.stream.XMLStreamException; @@ -66,6 +71,8 @@ import java.util.*; import java.util.stream.Collectors; +import static org.gridsuite.computation.error.ComputationBusinessErrorCode.PARAMETERS_NOT_FOUND; +import static org.gridsuite.ds.server.dto.network.NetworkInfos.NETWORK_ID; import static org.gridsuite.ds.server.error.DynamicSimulationBusinessErrorCode.*; /** @@ -76,7 +83,9 @@ public class ParametersServiceImpl implements ParametersService { private static final Logger LOGGER = LoggerFactory.getLogger(ParametersServiceImpl.class); public static final String FIELD_STATIC_ID = "staticId"; + public static final String MSG_PARAMETERS_UUID_NOT_FOUND = "Parameters uuid not found: "; + private final DynamicSimulationParametersRepository dynamicSimulationParametersRepository; private final NetworkStoreService networkStoreService; private final CurveGroovyGeneratorService curveGroovyGeneratorService; private final DynamicMappingClient dynamicMappingClient; @@ -85,11 +94,13 @@ public class ParametersServiceImpl implements ParametersService { private final String defaultProvider; @Autowired - public ParametersServiceImpl(NetworkStoreService networkStoreService, + public ParametersServiceImpl(DynamicSimulationParametersRepository dynamicSimulationParametersRepository, + NetworkStoreService networkStoreService, CurveGroovyGeneratorService curveGroovyGeneratorService, DynamicMappingClient dynamicMappingClient, FilterClient filterClient, @Value("${dynamic-simulation.default-provider}") String defaultProvider) { + this.dynamicSimulationParametersRepository = dynamicSimulationParametersRepository; this.networkStoreService = networkStoreService; this.curveGroovyGeneratorService = curveGroovyGeneratorService; this.dynamicMappingClient = dynamicMappingClient; @@ -126,12 +137,12 @@ private DynawoSimulationParameters getDynawoSimulationParameters(byte[] dynamicP // --- SOLVER PAR --- // // solver from input parameter - SolverInfos inputSolver = inputParameters.getSolvers().stream().filter(elem -> elem.getId().equals(inputParameters.getSolverId())).findFirst().orElse(null); + SolverInfos inputSolver = inputParameters.getSolvers().stream().filter(elem -> elem.getType() == inputParameters.getSolver()).findFirst().orElse(null); if (inputSolver != null) { ByteArrayOutputStream os = new ByteArrayOutputStream(); XmlSerializableParameter.writeParameter(os, XmlSerializableParameter.PARAMETER_SET, inputSolver); - ParametersSet solverParameters = ParametersXml.load(new ByteArrayInputStream(os.toByteArray()), inputSolver.getId()); - dynawoSimulationParameters.setSolverType(inputSolver.getType().toSolverType()); + ParametersSet solverParameters = ParametersXml.load(new ByteArrayInputStream(os.toByteArray()), inputSolver.getType().name()); + dynawoSimulationParameters.setSolverType(inputSolver.getType()); dynawoSimulationParameters.setSolverParameters(solverParameters); } @@ -141,7 +152,7 @@ private DynawoSimulationParameters getDynawoSimulationParameters(byte[] dynamicP if (network != null) { ByteArrayOutputStream os = new ByteArrayOutputStream(); XmlSerializableParameter.writeParameter(os, XmlSerializableParameter.PARAMETER_SET, network); - ParametersSet networkParameters = ParametersXml.load(new ByteArrayInputStream(os.toByteArray()), network.getId()); + ParametersSet networkParameters = ParametersXml.load(new ByteArrayInputStream(os.toByteArray()), NETWORK_ID); dynawoSimulationParameters.setNetworkParameters(networkParameters); } @@ -170,14 +181,16 @@ public DynamicSimulationParameters getDynamicSimulationParameters(byte[] dynamic @Override public DynamicSimulationRunContext createRunContext(UUID networkUuid, String variantId, String receiver, String provider, String mapping, - ReportInfos reportInfos, String userId, DynamicSimulationParametersInfos parameters, boolean debug) { + ReportInfos reportInfos, String userId, UUID parametersUuid, List events, boolean debug) { + + DynamicSimulationParametersInfos parametersInfos = doGetParameters(parametersUuid); DynamicSimulationRunContext runContext = DynamicSimulationRunContext.builder() .networkUuid(networkUuid) .variantId(variantId) .receiver(receiver) .reportInfos(reportInfos) .userId(userId) - .parameters(parameters) + .parameters(parametersInfos) .debug(debug) .build(); @@ -207,6 +220,9 @@ public DynamicSimulationRunContext createRunContext(UUID networkUuid, String var throw new DynamicSimulationException(MAPPING_NOT_PROVIDED, "Dynamic simulation mapping not provided"); } + // set events for run context + runContext.setEvents(events); + return runContext; } @@ -317,9 +333,90 @@ public List getDynamicModel(String mappingName, UUID network } @Override - public DynamicSimulationParametersValues getParametersValues(DynamicSimulationParametersInfos parametersInfos, UUID networkUuid, String variantId) { + public DynamicSimulationParametersValues getParametersValues(UUID parametersUuid, UUID networkUuid, String variantId) { Network network = getNetwork(networkUuid, variantId); + DynamicSimulationParametersInfos parametersInfos = doGetParameters(parametersUuid); return getParametersValues(parametersInfos, network); } + + // --- Dynamic simulation parameters related CRUD methods --- // + + @Override + @Transactional(readOnly = true) + public List getAllParameters() { + return dynamicSimulationParametersRepository.findAll().stream() + .map(paramsEntity -> paramsEntity.toDto(false)) + .toList(); + } + + @Override + @Transactional(readOnly = true) + public DynamicSimulationParametersInfos getParameters(UUID parametersUuid) { + return doGetParameters(parametersUuid); + } + + private DynamicSimulationParametersInfos doGetParameters(UUID parametersUuid) { + DynamicSimulationParametersEntity entity = dynamicSimulationParametersRepository.findById(parametersUuid) + .orElseThrow(() -> new ComputationException(PARAMETERS_NOT_FOUND, MSG_PARAMETERS_UUID_NOT_FOUND + parametersUuid)); + return entity.toDto(false); + } + + @Override + @Transactional(readOnly = true) + public String getProvider(UUID parametersUuid) { + return dynamicSimulationParametersRepository.findProviderById(parametersUuid) + .orElseThrow(() -> new ComputationException(PARAMETERS_NOT_FOUND, MSG_PARAMETERS_UUID_NOT_FOUND + parametersUuid)); + } + + @Override + @Transactional + public UUID createParameters(DynamicSimulationParametersInfos parametersInfos) { + return doCreateParameters(parametersInfos); + } + + private UUID doCreateParameters(DynamicSimulationParametersInfos parametersInfos) { + return dynamicSimulationParametersRepository.save(new DynamicSimulationParametersEntity(parametersInfos)).getId(); + } + + @Override + @Transactional + public UUID createDefaultParameters() { + DynamicSimulationParametersInfos defaultParametersInfos = getDefaultParametersValues(); + return doCreateParameters(defaultParametersInfos); + } + + private DynamicSimulationParametersInfos getDefaultParametersValues() { + DynamicSimulationParametersInfos defaultConfigParameters = ParameterUtils.getDefaultParametersValues(); + defaultConfigParameters.setProvider(defaultProvider); + return defaultConfigParameters; + } + + @Override + @Transactional + public UUID duplicateParameters(UUID sourceParametersUuid) { + DynamicSimulationParametersEntity entity = dynamicSimulationParametersRepository.findById(sourceParametersUuid) + .orElseThrow(() -> new ComputationException(PARAMETERS_NOT_FOUND, MSG_PARAMETERS_UUID_NOT_FOUND + sourceParametersUuid)); + DynamicSimulationParametersInfos duplicatedParametersInfos = entity.toDto(true); + return doCreateParameters(duplicatedParametersInfos); + } + + @Override + @Transactional + public void updateParameters(UUID parametersUuid, DynamicSimulationParametersInfos parametersInfos) { + DynamicSimulationParametersEntity entity = dynamicSimulationParametersRepository.findById(parametersUuid) + .orElseThrow(() -> new ComputationException(PARAMETERS_NOT_FOUND, MSG_PARAMETERS_UUID_NOT_FOUND + parametersUuid)); + if (parametersInfos == null) { + // if the parameter is null, it means it's a reset to defaultValues + entity.update(getDefaultParametersValues()); + } else { + entity.update(parametersInfos); + } + } + + @Override + @Transactional + public void deleteParameters(UUID parametersUuid) { + dynamicSimulationParametersRepository.deleteById(parametersUuid); + } } diff --git a/src/main/resources/db/changelog/changesets/changelog_20260318T185133Z.xml b/src/main/resources/db/changelog/changesets/changelog_20260318T185133Z.xml new file mode 100644 index 00000000..5076b049 --- /dev/null +++ b/src/main/resources/db/changelog/changesets/changelog_20260318T185133Z.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index 29376b4e..4df11842 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -18,3 +18,7 @@ databaseChangeLog: - include: file: changesets/changelog_20250423T210238Z.xml relativeToChangelogFile: true + - include: + file: changesets/changelog_20260318T185133Z.xml + relativeToChangelogFile: true + diff --git a/src/test/java/org/gridsuite/ds/server/controller/AbstractDynamicSimulationControllerTest.java b/src/test/java/org/gridsuite/ds/server/controller/AbstractDynamicSimulationControllerTest.java index d075b23a..d33606af 100644 --- a/src/test/java/org/gridsuite/ds/server/controller/AbstractDynamicSimulationControllerTest.java +++ b/src/test/java/org/gridsuite/ds/server/controller/AbstractDynamicSimulationControllerTest.java @@ -10,6 +10,7 @@ import org.gridsuite.ds.server.CustomApplicationContextInitializer; import org.gridsuite.ds.server.DynamicSimulationApplication; import org.gridsuite.ds.server.controller.utils.TestUtils; +import org.gridsuite.ds.server.repository.DynamicSimulationParametersRepository; import org.gridsuite.ds.server.service.DynamicSimulationWorkerService; import org.gridsuite.ds.server.service.client.dynamicmapping.DynamicMappingClient; import org.gridsuite.ds.server.service.client.timeseries.TimeSeriesClient; @@ -58,6 +59,9 @@ public abstract class AbstractDynamicSimulationControllerTest extends AbstractDy @MockitoBean protected NetworkStoreService networkStoreClient; + @MockitoBean + protected DynamicSimulationParametersRepository dynamicSimulationParametersRepository; + @MockitoSpyBean protected DynamicSimulationWorkerService dynamicSimulationWorkerService; diff --git a/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerIEEE14Test.java b/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerIEEE14Test.java index 213f5a76..a2e8e815 100644 --- a/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerIEEE14Test.java +++ b/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerIEEE14Test.java @@ -15,6 +15,7 @@ import com.powsybl.dynamicsimulation.DynamicSimulationParameters; import com.powsybl.dynamicsimulation.DynamicSimulationResult; import com.powsybl.dynamicsimulation.json.DynamicSimulationResultDeserializer; +import com.powsybl.dynawo.DynawoSimulationParameters.SolverType; import com.powsybl.dynawo.suppliers.dynamicmodels.DynamicModelConfig; import com.powsybl.dynawo.suppliers.dynamicmodels.DynamicModelConfigJsonUtils; import com.powsybl.iidm.network.Importers; @@ -26,14 +27,16 @@ import com.powsybl.timeseries.TimeSeriesMetadata; import org.apache.commons.collections4.CollectionUtils; import org.gridsuite.ds.server.controller.utils.FileUtils; -import org.gridsuite.ds.server.controller.utils.ParameterUtils; +import org.gridsuite.ds.server.controller.utils.ParameterTestUtils; import org.gridsuite.ds.server.dto.DynamicSimulationParametersInfos; import org.gridsuite.ds.server.dto.curve.CurveInfos; import org.gridsuite.ds.server.dto.dynamicmapping.InputMapping; import org.gridsuite.ds.server.dto.dynamicmapping.ParameterFile; import org.gridsuite.ds.server.dto.event.EventInfos; import org.gridsuite.ds.server.dto.timeseries.TimeSeriesGroupInfos; +import org.gridsuite.ds.server.entities.parameters.DynamicSimulationParametersEntity; import org.gridsuite.ds.server.service.client.timeseries.TimeSeriesClientTest; +import org.gridsuite.ds.server.service.parameters.ParameterUtils; import org.gridsuite.ds.server.utils.Utils; import org.junit.Test; import org.mockito.Mockito; @@ -82,6 +85,8 @@ public class DynamicSimulationControllerIEEE14Test extends AbstractDynamicSimula private static final String VARIANT_1_ID = "variant_1"; private static final String NETWORK_FILE = "IEEE14.iidm"; + private static final UUID PARAMETERS_UUID = UUID.fromString("5170a122-ebe5-4fa2-9cd9-d8f76ce04db3"); + // TODO remove when DynamicSimulationResultDeserializer correct curves by LinkedHashMap private static final Comparator> TIME_SERIES_COMPARATOR = Comparator.comparing(timeSeries -> timeSeries.getMetadata().getName()); @@ -178,26 +183,31 @@ public void tearDown() throws Exception { public void test01GivenCurvesAndEvents() throws Exception { // prepare parameters - DynamicSimulationParametersInfos parameters = ParameterUtils.getDefaultDynamicSimulationParameters(); - + DynamicSimulationParametersInfos parameters = ParameterUtils.getDefaultParametersValues(); + parameters.setStartTime(0d); + parameters.setStopTime(50d); // Test SIM solver (IDA solver will be ignored to test at moment due to the non-determinist on different OSs, Debian vs Ubuntu) - parameters.setSolverId("SIM"); + parameters.setSolver(SolverType.SIM); // given curves - List curveInfosList = ParameterUtils.getCurveInfosList(); + List curveInfosList = ParameterTestUtils.getCurveInfosList(); parameters.setCurves(curveInfosList); // given events - List eventInfosList = ParameterUtils.getEventInfosList(); - parameters.setEvents(eventInfosList); + List eventInfosList = ParameterTestUtils.getEventInfosList(); + + // mock repository for given parameters + DynamicSimulationParametersEntity entity = new DynamicSimulationParametersEntity(parameters); + given(dynamicSimulationParametersRepository.findById(PARAMETERS_UUID)).willReturn(Optional.of(entity)); //run the dynamic simulation (on a specific variant with variantId=" + VARIANT_1_ID + ") MvcResult result = mockMvc.perform( post("/v1/networks/{networkUuid}/run", NETWORK_UUID_STRING) .param("mappingName", MAPPING_NAME_01) + .param("parametersUuid", PARAMETERS_UUID.toString()) .contentType(APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") - .content(objectMapper.writeValueAsString(parameters))) + .content(objectMapper.writeValueAsString(eventInfosList))) .andExpect(status().isOk()) .andReturn(); diff --git a/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerTest.java b/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerTest.java index e23bdaa8..aadc7682 100644 --- a/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerTest.java +++ b/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerTest.java @@ -21,12 +21,15 @@ import com.powsybl.timeseries.*; import org.apache.commons.collections4.CollectionUtils; import org.gridsuite.computation.service.NotificationService; -import org.gridsuite.ds.server.controller.utils.ParameterUtils; +import org.gridsuite.ds.server.controller.utils.ParameterTestUtils; import org.gridsuite.ds.server.dto.DynamicSimulationParametersInfos; import org.gridsuite.ds.server.dto.DynamicSimulationStatus; import org.gridsuite.ds.server.dto.dynamicmapping.ParameterFile; +import org.gridsuite.ds.server.dto.event.EventInfos; import org.gridsuite.ds.server.dto.timeseries.TimeSeriesGroupInfos; +import org.gridsuite.ds.server.entities.parameters.DynamicSimulationParametersEntity; import org.gridsuite.ds.server.service.client.timeseries.TimeSeriesClientTest; +import org.gridsuite.ds.server.service.parameters.ParameterUtils; import org.junit.Before; import org.junit.Test; import org.mockito.MockedStatic; @@ -93,6 +96,8 @@ public class DynamicSimulationControllerTest extends AbstractDynamicSimulationCo private static final String VARIANT_1_ID = "variant_1"; private static final String TEST_FILE = "IEEE14.iidm"; + private static final UUID PARAMETERS_UUID = UUID.fromString("cff95818-bf3f-418f-8f65-ee12c00e90af"); + @Override public OutputDestination getOutputDestination() { return output; @@ -140,10 +145,18 @@ protected void initTimeSeriesServiceMock() { doNothing().when(timeSeriesClient).deleteTimeSeriesGroup(any(UUID.class)); } + private void initParametersRepositoryMock() { + DynamicSimulationParametersInfos params = ParameterUtils.getDefaultParametersValues(); + params.setCurves(List.of()); + DynamicSimulationParametersEntity entity = new DynamicSimulationParametersEntity(params); + given(dynamicSimulationParametersRepository.findById(PARAMETERS_UUID)).willReturn(Optional.of(entity)); + } + @Before @Override public void setUp() throws IOException { super.setUp(); + initParametersRepositoryMock(); } @Override @@ -188,18 +201,19 @@ public void testGivenTimeSeriesAndTimeLine() throws Exception { AbortableInputStream.create(new ByteArrayInputStream("s3 debug file content".getBytes())) )).when(s3Client).getObject(any(GetObjectRequest.class)); - // prepare parameters - DynamicSimulationParametersInfos parameters = ParameterUtils.getDefaultDynamicSimulationParameters(); + // prepare content + List events = List.of(); // test without events //run the dynamic simulation on a specific variant with debug MvcResult result = mockMvc.perform( post("/v1/networks/{networkUuid}/run", NETWORK_UUID_STRING) .param("variantId", VARIANT_1_ID) .param("mappingName", MAPPING_NAME) + .param("parametersUuid", PARAMETERS_UUID.toString()) .param(HEADER_DEBUG, "true") .contentType(APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") - .content(objectMapper.writeValueAsString(parameters))) + .content(objectMapper.writeValueAsString(events))) .andExpect(status().isOk()) .andReturn(); UUID runUuid = objectMapper.readValue(result.getResponse().getContentAsString(), UUID.class); @@ -221,13 +235,17 @@ public void testGivenTimeSeriesAndTimeLine() throws Exception { verify(s3Client, times(1)).putObject(any(PutObjectRequest.class), any(RequestBody.class)); verify(s3Client, times(1)).getObject(any(GetObjectRequest.class)); + // prepare content + events = ParameterTestUtils.getEventInfosList(); // test with events + //run the dynamic simulation on the implicit default variant result = mockMvc.perform( post("/v1/networks/{networkUuid}/run", NETWORK_UUID_STRING) .param("mappingName", MAPPING_NAME) + .param("parametersUuid", PARAMETERS_UUID.toString()) .contentType(APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") - .content(objectMapper.writeValueAsString(parameters))) + .content(objectMapper.writeValueAsString(events))) .andExpect(status().isOk()) .andReturn(); @@ -345,17 +363,18 @@ public void testGivenEmptyTimeSeriesAndTimeLine() throws Exception { doReturn(CompletableFuture.completedFuture(new DynamicSimulationResultImpl(DynamicSimulationResult.Status.SUCCESS, "", curves, finalStateValues, timeLine))) .when(dynamicSimulationWorkerService).getCompletableFuture(any(), any(), any()); - // prepare parameters - DynamicSimulationParametersInfos parameters = ParameterUtils.getDefaultDynamicSimulationParameters(); + // prepare content + List events = List.of(); // test without events //run the dynamic simulation on a specific variant MvcResult result = mockMvc.perform( - post("/v1/networks/{networkUuid}/run", NETWORK_UUID_STRING) - .param("variantId", VARIANT_1_ID) - .param("mappingName", MAPPING_NAME) - .contentType(APPLICATION_JSON) - .header(HEADER_USER_ID, "testUserId") - .content(objectMapper.writeValueAsString(parameters))) + post("/v1/networks/{networkUuid}/run", NETWORK_UUID_STRING) + .param("variantId", VARIANT_1_ID) + .param("mappingName", MAPPING_NAME) + .param("parametersUuid", PARAMETERS_UUID.toString()) + .contentType(APPLICATION_JSON) + .header(HEADER_USER_ID, "testUserId") + .content(objectMapper.writeValueAsString(events))) .andExpect(status().isOk()) .andReturn(); UUID runUuid = objectMapper.readValue(result.getResponse().getContentAsString(), UUID.class); @@ -431,17 +450,18 @@ private void assertRunningStatus(UUID runUuid) throws Exception { } private UUID runAndCancel(CountDownLatch cancelLatch, int cancelDelay) throws Exception { - // prepare parameters - DynamicSimulationParametersInfos parameters = ParameterUtils.getDefaultDynamicSimulationParameters(); + // prepare content + List events = List.of(); // test without events //run the dynamic simulation on a specific variant MvcResult result = mockMvc.perform( - post("/v1/networks/{networkUuid}/run", NETWORK_UUID_STRING) - .param("variantId", VARIANT_1_ID) - .param("mappingName", MAPPING_NAME) - .contentType(APPLICATION_JSON) - .header(HEADER_USER_ID, "testUserId") - .content(objectMapper.writeValueAsString(parameters))) + post("/v1/networks/{networkUuid}/run", NETWORK_UUID_STRING) + .param("variantId", VARIANT_1_ID) + .param("mappingName", MAPPING_NAME) + .param("parametersUuid", PARAMETERS_UUID.toString()) + .contentType(APPLICATION_JSON) + .header(HEADER_USER_ID, "testUserId") + .content(objectMapper.writeValueAsString(events))) .andExpect(status().isOk()) .andReturn(); UUID runUuid = objectMapper.readValue(result.getResponse().getContentAsString(), UUID.class); diff --git a/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationParametersControllerIEEE14Test.java b/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationParametersControllerIEEE14Test.java index 933bd0fc..4d5d9edf 100644 --- a/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationParametersControllerIEEE14Test.java +++ b/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationParametersControllerIEEE14Test.java @@ -12,18 +12,21 @@ import com.powsybl.commons.datasource.ReadOnlyDataSource; import com.powsybl.commons.datasource.ResourceDataSource; import com.powsybl.commons.datasource.ResourceSet; +import com.powsybl.dynawo.DynawoSimulationParameters.SolverType; import com.powsybl.iidm.network.Importers; 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 org.gridsuite.ds.server.DynamicSimulationApplication; -import org.gridsuite.ds.server.controller.utils.ParameterUtils; import org.gridsuite.ds.server.dto.DynamicSimulationParametersInfos; import org.gridsuite.ds.server.dto.DynamicSimulationParametersValues; import org.gridsuite.ds.server.dto.dynamicmapping.InputMapping; import org.gridsuite.ds.server.dto.dynamicmapping.ParameterFile; +import org.gridsuite.ds.server.entities.parameters.DynamicSimulationParametersEntity; +import org.gridsuite.ds.server.repository.DynamicSimulationParametersRepository; import org.gridsuite.ds.server.service.client.dynamicmapping.DynamicMappingClient; +import org.gridsuite.ds.server.service.parameters.ParameterUtils; import org.gridsuite.ds.server.utils.assertions.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -48,7 +51,7 @@ import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** @@ -72,12 +75,17 @@ public class DynamicSimulationParametersControllerIEEE14Test { private static final String VARIANT_1_ID = "variant_1"; private static final String NETWORK_FILE = "IEEE14.iidm"; + private static final UUID PARAMETERS_UUID = UUID.fromString("5a25abdc-c227-4321-9e79-b5347ba7c42e"); + @Autowired private MockMvc mockMvc; @Autowired private ObjectMapper objectMapper; + @MockitoBean + protected DynamicSimulationParametersRepository dynamicSimulationParametersRepository; + @MockitoBean protected DynamicMappingClient dynamicMappingClient; @@ -129,18 +137,20 @@ void setUp() { @Test void testGetParametersValues() throws Exception { // --- Setup --- // - DynamicSimulationParametersInfos parameters = ParameterUtils.getDefaultDynamicSimulationParameters(); - parameters.setSolverId("SIM"); + DynamicSimulationParametersInfos parameters = ParameterUtils.getDefaultParametersValues(); + parameters.setSolver(SolverType.SIM); parameters.setMapping(MAPPING_NAME_01); - String parametersJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(parameters); + DynamicSimulationParametersEntity entity = new DynamicSimulationParametersEntity(parameters); + + // mock repository for given parameters + given(dynamicSimulationParametersRepository.findById(PARAMETERS_UUID)).willReturn(java.util.Optional.of(entity)); // --- Execute --- // - MvcResult result = mockMvc.perform(post("/v1/parameters/values") + MvcResult result = mockMvc.perform(get("/v1/parameters/" + PARAMETERS_UUID.toString() + "/values") .param("networkUuid", NETWORK_UUID_STRING) .param(VARIANT_ID_HEADER, VARIANT_1_ID) - .contentType(MediaType.APPLICATION_JSON) - .content(parametersJson)) + .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn(); diff --git a/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationParametersControllerTest.java b/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationParametersControllerTest.java new file mode 100644 index 00000000..968360f9 --- /dev/null +++ b/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationParametersControllerTest.java @@ -0,0 +1,233 @@ +/** + * Copyright (c) 2026, 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.ds.server.controller; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.gridsuite.ds.server.DynamicSimulationApplication; +import org.gridsuite.ds.server.dto.DynamicSimulationParametersInfos; +import org.gridsuite.ds.server.dto.curve.CurveInfos; +import org.gridsuite.ds.server.entities.parameters.DynamicSimulationParametersEntity; +import org.gridsuite.ds.server.repository.DynamicSimulationParametersRepository; +import org.gridsuite.ds.server.service.parameters.ParameterUtils; +import org.gridsuite.ds.server.utils.EquipmentType; +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.test.context.ContextConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.gridsuite.computation.service.NotificationService.HEADER_USER_ID; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * @author Thang PHAM + */ +@AutoConfigureMockMvc +@SpringBootTest +@ContextConfiguration(classes = {DynamicSimulationApplication.class}) +class DynamicSimulationParametersControllerTest { + + private static final String USER_ID = "userId"; + + @Autowired + MockMvc mockMvc; + + @Autowired + ObjectMapper objectMapper; + + @Autowired + DynamicSimulationParametersRepository parametersRepository; + + @AfterEach + void tearDown() { + parametersRepository.deleteAll(); + } + + private DynamicSimulationParametersInfos newParametersInfos() { + // Keep the DTO minimal and stable for CRUD tests + DynamicSimulationParametersInfos infos = ParameterUtils.getDefaultParametersValues(); + infos.setCurves(List.of()); // make explicit to avoid null handling differences + return infos; + } + + private DynamicSimulationParametersInfos newParametersInfosWithCurves() { + DynamicSimulationParametersInfos infos = ParameterUtils.getDefaultParametersValues(); + + infos.setCurves(List.of( + CurveInfos.builder() + .equipmentType(EquipmentType.LOAD) + .equipmentId("_LOAD___2_EC") + .variableId("load_PPu") + .build(), + CurveInfos.builder() + .equipmentType(EquipmentType.GENERATOR) + .equipmentId("_GEN____3_SM") + .variableId("generator_omegaPu") + .build() + )); + + return infos; + } + + @Test + void testCreateParameters() throws Exception { + DynamicSimulationParametersInfos parametersInfos = newParametersInfos(); + + MvcResult result = mockMvc.perform(post("/v1/parameters") + .contentType(APPLICATION_JSON) + .content(objectMapper.writeValueAsString(parametersInfos))) + .andExpect(status().isOk()) + .andReturn(); + + UUID parametersUuid = objectMapper.readValue(result.getResponse().getContentAsString(), UUID.class); + + Optional entityOpt = parametersRepository.findById(parametersUuid); + assertThat(entityOpt).isPresent(); + + DynamicSimulationParametersInfos resultParametersInfos = entityOpt.get().toDto(true); + + assertThat(resultParametersInfos).usingRecursiveComparison().isEqualTo(parametersInfos); + } + + @Test + void testCreateDefaultParameters() throws Exception { + DynamicSimulationParametersInfos defaultParametersInfos = newParametersInfos(); + + MvcResult result = mockMvc.perform(post("/v1/parameters/default")) + .andExpect(status().isOk()) + .andReturn(); + + UUID parametersUuid = objectMapper.readValue(result.getResponse().getContentAsString(), UUID.class); + + Optional entityOpt = parametersRepository.findById(parametersUuid); + assertThat(entityOpt).isPresent(); + assertThat(entityOpt.get().getProvider()).isEqualTo("Dynawo"); + DynamicSimulationParametersInfos resultParametersInfos = entityOpt.get().toDto(true); + assertThat(resultParametersInfos).usingRecursiveComparison().isEqualTo(defaultParametersInfos); + } + + @Test + void testDuplicateParameters() throws Exception { + DynamicSimulationParametersInfos originalInfos = newParametersInfos(); + UUID originalUuid = parametersRepository.save(new DynamicSimulationParametersEntity(originalInfos)).getId(); + + MvcResult result = mockMvc.perform(post("/v1/parameters") + .param("duplicateFrom", originalUuid.toString())) + .andExpect(status().isOk()) + .andReturn(); + + UUID duplicatedUuid = objectMapper.readValue(result.getResponse().getContentAsString(), UUID.class); + + Optional duplicatedOpt = parametersRepository.findById(duplicatedUuid); + assertThat(duplicatedOpt).isPresent(); + + DynamicSimulationParametersInfos duplicatedInfos = duplicatedOpt.get().toDto(true); + + assertThat(duplicatedInfos).usingRecursiveComparison().isEqualTo(originalInfos); + } + + @Test + void testGetParametersWithCurves() throws Exception { + // --- Setup: persist parameters with curves --- // + DynamicSimulationParametersInfos infos = newParametersInfosWithCurves(); + UUID parametersUuid = parametersRepository.save(new DynamicSimulationParametersEntity(infos)).getId(); + + // --- Execute --- // + MvcResult result = mockMvc.perform(get("/v1/parameters/{uuid}", parametersUuid) + .header(HEADER_USER_ID, USER_ID)) + .andExpect(status().isOk()) + .andReturn(); + + DynamicSimulationParametersInfos returned = + objectMapper.readValue(result.getResponse().getContentAsString(), DynamicSimulationParametersInfos.class); + + // --- Verify --- // + assertThat(returned.getId()).isEqualTo(parametersUuid); + assertThat(returned.getCurves()).hasSize(2); + } + + @Test + void testGetAllParameters() throws Exception { + DynamicSimulationParametersInfos infos = newParametersInfos(); + parametersRepository.saveAll(List.of( + new DynamicSimulationParametersEntity(infos), + new DynamicSimulationParametersEntity(infos) + )); + + MvcResult result = mockMvc.perform(get("/v1/parameters")) + .andExpect(status().isOk()) + .andReturn(); + + List returned = objectMapper.readValue( + result.getResponse().getContentAsString(), + new TypeReference<>() { } + ); + + assertThat(returned).hasSize(2); + assertThat(returned.get(0).getId()).isNotNull(); + assertThat(returned.get(1).getId()).isNotNull(); + } + + @Test + void testUpdateParameters() throws Exception { + DynamicSimulationParametersInfos infos = newParametersInfos(); + UUID parametersUuid = parametersRepository.save(new DynamicSimulationParametersEntity(infos)).getId(); + + DynamicSimulationParametersInfos updatedInfos = newParametersInfos(); + updatedInfos.setStartTime(10d); + updatedInfos.setStopTime(100d); + updatedInfos.getNetwork().setCapacitorNoReclosingDelay(400); // change a field to ensure the update persists + + mockMvc.perform(put("/v1/parameters/{uuid}", parametersUuid) + .contentType(APPLICATION_JSON) + .content(objectMapper.writeValueAsString(updatedInfos))) + .andExpect(status().isOk()); + + Optional entityOpt = parametersRepository.findById(parametersUuid); + assertThat(entityOpt).isPresent(); + + DynamicSimulationParametersInfos persisted = entityOpt.get().toDto(false); + assertThat(persisted.getStartTime()).isEqualTo(10); + assertThat(persisted.getStopTime()).isEqualTo(100); + assertThat(persisted.getNetwork().getCapacitorNoReclosingDelay()).isEqualTo(400); + } + + @Test + void testDeleteParameters() throws Exception { + DynamicSimulationParametersInfos infos = newParametersInfos(); + UUID parametersUuid = parametersRepository.save(new DynamicSimulationParametersEntity(infos)).getId(); + + mockMvc.perform(delete("/v1/parameters/{uuid}", parametersUuid)) + .andExpect(status().isOk()); + + assertThat(parametersRepository.findById(parametersUuid)).isEmpty(); + } + + @Test + void testGetProvider() throws Exception { + DynamicSimulationParametersInfos infos = newParametersInfos(); + infos.setProvider("Dynawo"); + UUID parametersUuid = parametersRepository.save(new DynamicSimulationParametersEntity(infos)).getId(); + + MvcResult result = mockMvc.perform(get("/v1/parameters/{uuid}/provider", parametersUuid)) + .andExpect(status().isOk()) + .andReturn(); + String provider = result.getResponse().getContentAsString(); + assertThat(provider).isEqualTo("Dynawo"); + } +} diff --git a/src/test/java/org/gridsuite/ds/server/controller/utils/ParameterTestUtils.java b/src/test/java/org/gridsuite/ds/server/controller/utils/ParameterTestUtils.java new file mode 100644 index 00000000..8604ca3f --- /dev/null +++ b/src/test/java/org/gridsuite/ds/server/controller/utils/ParameterTestUtils.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2022, 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.ds.server.controller.utils; + +import org.gridsuite.ds.server.dto.curve.CurveInfos; +import org.gridsuite.ds.server.dto.event.EventInfos; +import org.gridsuite.ds.server.dto.event.EventPropertyInfos; +import org.gridsuite.ds.server.utils.EquipmentType; +import org.gridsuite.ds.server.utils.PropertyType; + +import java.util.List; + +import static org.gridsuite.ds.server.service.parameters.impl.ParametersServiceImpl.FIELD_STATIC_ID; + +/** + * @author Thang PHAM + */ +public final class ParameterTestUtils { + private ParameterTestUtils() { + throw new AssertionError("Utility class should not be instantiated"); + } + + public static List getCurveInfosList() { + return List.of( + new CurveInfos(null, EquipmentType.LOAD, "_LOAD___2_EC", "load_PPu"), + new CurveInfos(null, EquipmentType.LOAD, "_LOAD___2_EC", "load_QPu"), + new CurveInfos(null, EquipmentType.GENERATOR, "_GEN____3_SM", "generator_omegaPu"), + new CurveInfos(null, EquipmentType.GENERATOR, "_GEN____3_SM", "generator_PGen"), + new CurveInfos(null, EquipmentType.GENERATOR, "_GEN____3_SM", "generator_QGen"), + new CurveInfos(null, EquipmentType.GENERATOR, "_GEN____3_SM", "generator_UStatorPu"), + new CurveInfos(null, EquipmentType.GENERATOR, "_GEN____3_SM", "voltageRegulator_EfdPu"), + new CurveInfos(null, EquipmentType.STATIC_VAR_COMPENSATOR, "SVC2", "SVarC_injector_UPu"), + new CurveInfos(null, EquipmentType.STATIC_VAR_COMPENSATOR, "SVC2", "SVarC_injector_PInjPu"), + new CurveInfos(null, EquipmentType.STATIC_VAR_COMPENSATOR, "SVC2", "SVarC_injector_QInjPu"), + new CurveInfos(null, EquipmentType.STATIC_VAR_COMPENSATOR, "SVC2", "SVarC_injector_BPu"), + new CurveInfos(null, EquipmentType.STATIC_VAR_COMPENSATOR, "SVC2", "SVarC_modeHandling_mode_value") + ); + } + + public static List getEventInfosList() { + return List.of( + new EventInfos(null, null, "_BUS____1-BUS____5-1_AC", null, "Disconnect", List.of( + new EventPropertyInfos(null, FIELD_STATIC_ID, "_BUS____1-BUS____5-1_AC", PropertyType.STRING), + new EventPropertyInfos(null, "startTime", "10", PropertyType.FLOAT), + new EventPropertyInfos(null, "disconnectOnly", "TwoSides.TWO", PropertyType.ENUM) + )), + new EventInfos(null, null, "_BUS____1_TN", null, "FaultNode", List.of( + new EventPropertyInfos(null, FIELD_STATIC_ID, "_BUS____1_TN", PropertyType.STRING), + new EventPropertyInfos(null, "startTime", "20", PropertyType.FLOAT), + new EventPropertyInfos(null, "faultTime", "2", PropertyType.FLOAT), + new EventPropertyInfos(null, "rPu", "23", PropertyType.FLOAT), + new EventPropertyInfos(null, "xPu", "32", PropertyType.FLOAT) + )) + ); + } +} diff --git a/src/test/java/org/gridsuite/ds/server/dto/XmlSerializableParameterTest.java b/src/test/java/org/gridsuite/ds/server/dto/XmlSerializableParameterTest.java index 048c138d..6e630dc4 100644 --- a/src/test/java/org/gridsuite/ds/server/dto/XmlSerializableParameterTest.java +++ b/src/test/java/org/gridsuite/ds/server/dto/XmlSerializableParameterTest.java @@ -9,11 +9,11 @@ import com.powsybl.commons.exceptions.UncheckedSaxException; import org.gridsuite.ds.server.DynamicSimulationApplication; -import org.gridsuite.ds.server.controller.utils.ParameterUtils; import org.gridsuite.ds.server.dto.network.NetworkInfos; import org.gridsuite.ds.server.dto.solver.IdaSolverInfos; import org.gridsuite.ds.server.dto.solver.SimSolverInfos; import org.gridsuite.ds.server.dto.solver.SolverInfos; +import org.gridsuite.ds.server.service.parameters.ParameterUtils; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; @@ -76,9 +76,9 @@ private void validate(String schemaFile, String expectedXmlFile, Path actualXmlF @Test public void testWriteParameterGivenSolvers() throws IOException, XMLStreamException { - IdaSolverInfos idaSolver = ParameterUtils.getDefaultIdaSolver(); + IdaSolverInfos idaSolver = ParameterUtils.getDefaultIdaSolverValues(); - SimSolverInfos simSolver = ParameterUtils.getDefaultSimSolver(); + SimSolverInfos simSolver = ParameterUtils.getDefaultSimSolverValues(); SolverInfos[] solvers = {idaSolver, simSolver}; @@ -94,7 +94,7 @@ public void testWriteParameterGivenSolvers() throws IOException, XMLStreamExcept @Test public void testWriteParameterGivenNetwork() throws IOException, XMLStreamException { - NetworkInfos network = ParameterUtils.getDefaultNetwork(); + NetworkInfos network = ParameterUtils.getDefaultNetworkValues(); // export network to par file String resultDir = getClass().getResource(DATA_XML + RESOURCE_PATH_DELIMITER + OUTPUT).getPath(); diff --git a/src/test/java/org/gridsuite/ds/server/service/DynamicSimulationResultServiceTest.java b/src/test/java/org/gridsuite/ds/server/service/DynamicSimulationResultServiceTest.java index 67dee24c..7b2bcc6f 100644 --- a/src/test/java/org/gridsuite/ds/server/service/DynamicSimulationResultServiceTest.java +++ b/src/test/java/org/gridsuite/ds/server/service/DynamicSimulationResultServiceTest.java @@ -13,7 +13,7 @@ import org.gridsuite.computation.service.UuidGeneratorService; import org.gridsuite.ds.server.dto.DynamicSimulationStatus; import org.gridsuite.ds.server.dto.timeseries.TimeSeriesGroupInfos; -import org.gridsuite.ds.server.model.ResultEntity; +import org.gridsuite.ds.server.entities.ResultEntity; import org.gridsuite.ds.server.repository.ResultRepository; import org.gridsuite.ds.server.service.client.timeseries.TimeSeriesClient; import org.junit.After; From 5176c3ef1aef5ab2f42a3f624414db4919fa6f0e Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Fri, 20 Mar 2026 17:09:53 +0100 Subject: [PATCH 2/3] remove provider and mapping in request's params Signed-off-by: Thang PHAM --- .../controller/DynamicSimulationController.java | 4 ---- .../service/parameters/ParametersService.java | 4 ++-- .../parameters/impl/ParametersServiceImpl.java | 16 +++++----------- .../DynamicSimulationControllerIEEE14Test.java | 6 ++++-- .../DynamicSimulationControllerTest.java | 5 +---- 5 files changed, 12 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/gridsuite/ds/server/controller/DynamicSimulationController.java b/src/main/java/org/gridsuite/ds/server/controller/DynamicSimulationController.java index a7f736cb..d2e49137 100644 --- a/src/main/java/org/gridsuite/ds/server/controller/DynamicSimulationController.java +++ b/src/main/java/org/gridsuite/ds/server/controller/DynamicSimulationController.java @@ -58,11 +58,9 @@ public DynamicSimulationController(DynamicSimulationService dynamicSimulationSer public ResponseEntity run(@PathVariable("networkUuid") UUID networkUuid, @RequestParam(name = "variantId", required = false) String variantId, @RequestParam(name = "receiver", required = false) String receiver, - @RequestParam(name = "mappingName", required = false) String mappingName, @RequestParam(name = "reportUuid", required = false) UUID reportId, @RequestParam(name = "reporterId", required = false) String reportName, @RequestParam(name = "reportType", required = false, defaultValue = "DynamicSimulation") String reportType, - @RequestParam(name = "provider", required = false) String provider, @RequestParam(name = "debug", required = false, defaultValue = "false") boolean debug, @RequestParam(name = "parametersUuid") UUID parametersUuid, @RequestBody List events, @@ -72,8 +70,6 @@ public ResponseEntity run(@PathVariable("networkUuid") UUID networkUuid, networkUuid, variantId, receiver, - provider, - mappingName, ReportInfos.builder().reportUuid(reportId).reporterId(reportName).computationType(reportType).build(), userId, parametersUuid, diff --git a/src/main/java/org/gridsuite/ds/server/service/parameters/ParametersService.java b/src/main/java/org/gridsuite/ds/server/service/parameters/ParametersService.java index 376c3490..143c58be 100644 --- a/src/main/java/org/gridsuite/ds/server/service/parameters/ParametersService.java +++ b/src/main/java/org/gridsuite/ds/server/service/parameters/ParametersService.java @@ -32,8 +32,8 @@ public interface ParametersService { DynamicSimulationParameters getDynamicSimulationParameters(byte[] dynamicParams, String provider, DynamicSimulationParametersInfos inputParameters); - DynamicSimulationRunContext createRunContext(UUID networkUuid, String variantId, String receiver, String provider, String mapping, - ReportInfos reportContext, String userId, UUID parametersUuid, List events, boolean debug); + DynamicSimulationRunContext createRunContext(UUID networkUuid, String variantId, String receiver, ReportInfos reportContext, + String userId, UUID parametersUuid, List events, boolean debug); List getDynamicModel(InputMapping inputMapping, Network network); diff --git a/src/main/java/org/gridsuite/ds/server/service/parameters/impl/ParametersServiceImpl.java b/src/main/java/org/gridsuite/ds/server/service/parameters/impl/ParametersServiceImpl.java index 6d6e3c7a..fb47f8aa 100644 --- a/src/main/java/org/gridsuite/ds/server/service/parameters/impl/ParametersServiceImpl.java +++ b/src/main/java/org/gridsuite/ds/server/service/parameters/impl/ParametersServiceImpl.java @@ -180,8 +180,9 @@ public DynamicSimulationParameters getDynamicSimulationParameters(byte[] dynamic } @Override - public DynamicSimulationRunContext createRunContext(UUID networkUuid, String variantId, String receiver, String provider, String mapping, - ReportInfos reportInfos, String userId, UUID parametersUuid, List events, boolean debug) { + public DynamicSimulationRunContext createRunContext( + UUID networkUuid, String variantId, String receiver, ReportInfos reportInfos, + String userId, UUID parametersUuid, List events, boolean debug) { DynamicSimulationParametersInfos parametersInfos = doGetParameters(parametersUuid); DynamicSimulationRunContext runContext = DynamicSimulationRunContext.builder() @@ -195,11 +196,7 @@ public DynamicSimulationRunContext createRunContext(UUID networkUuid, String var .build(); // set provider for run context - String providerToUse = provider; - if (providerToUse == null) { - providerToUse = Optional.ofNullable(runContext.getParameters().getProvider()).orElse(defaultProvider); - } - + String providerToUse = Optional.ofNullable(runContext.getParameters().getProvider()).orElse(defaultProvider); runContext.setProvider(providerToUse); // check provider @@ -209,10 +206,7 @@ public DynamicSimulationRunContext createRunContext(UUID networkUuid, String var } // set mapping for run context - String mappingToUse = mapping; - if (mappingToUse == null) { - mappingToUse = runContext.getParameters().getMapping(); - } + String mappingToUse = runContext.getParameters().getMapping(); runContext.setMapping(mappingToUse); // check mapping diff --git a/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerIEEE14Test.java b/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerIEEE14Test.java index a2e8e815..a3b814f5 100644 --- a/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerIEEE14Test.java +++ b/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerIEEE14Test.java @@ -186,7 +186,7 @@ public void test01GivenCurvesAndEvents() throws Exception { DynamicSimulationParametersInfos parameters = ParameterUtils.getDefaultParametersValues(); parameters.setStartTime(0d); parameters.setStopTime(50d); - // Test SIM solver (IDA solver will be ignored to test at moment due to the non-determinist on different OSs, Debian vs Ubuntu) + // Test SIM solver (IDA solver will be ignored to test at the moment due to the non-determinist on different OSs, Debian vs Ubuntu) parameters.setSolver(SolverType.SIM); // given curves @@ -196,6 +196,9 @@ public void test01GivenCurvesAndEvents() throws Exception { // given events List eventInfosList = ParameterTestUtils.getEventInfosList(); + // run with mapping + parameters.setMapping(MAPPING_NAME_01); + // mock repository for given parameters DynamicSimulationParametersEntity entity = new DynamicSimulationParametersEntity(parameters); given(dynamicSimulationParametersRepository.findById(PARAMETERS_UUID)).willReturn(Optional.of(entity)); @@ -203,7 +206,6 @@ public void test01GivenCurvesAndEvents() throws Exception { //run the dynamic simulation (on a specific variant with variantId=" + VARIANT_1_ID + ") MvcResult result = mockMvc.perform( post("/v1/networks/{networkUuid}/run", NETWORK_UUID_STRING) - .param("mappingName", MAPPING_NAME_01) .param("parametersUuid", PARAMETERS_UUID.toString()) .contentType(APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") diff --git a/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerTest.java b/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerTest.java index aadc7682..eedc9d4a 100644 --- a/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerTest.java +++ b/src/test/java/org/gridsuite/ds/server/controller/DynamicSimulationControllerTest.java @@ -148,6 +148,7 @@ protected void initTimeSeriesServiceMock() { private void initParametersRepositoryMock() { DynamicSimulationParametersInfos params = ParameterUtils.getDefaultParametersValues(); params.setCurves(List.of()); + params.setMapping(MAPPING_NAME); DynamicSimulationParametersEntity entity = new DynamicSimulationParametersEntity(params); given(dynamicSimulationParametersRepository.findById(PARAMETERS_UUID)).willReturn(Optional.of(entity)); } @@ -208,7 +209,6 @@ public void testGivenTimeSeriesAndTimeLine() throws Exception { MvcResult result = mockMvc.perform( post("/v1/networks/{networkUuid}/run", NETWORK_UUID_STRING) .param("variantId", VARIANT_1_ID) - .param("mappingName", MAPPING_NAME) .param("parametersUuid", PARAMETERS_UUID.toString()) .param(HEADER_DEBUG, "true") .contentType(APPLICATION_JSON) @@ -241,7 +241,6 @@ public void testGivenTimeSeriesAndTimeLine() throws Exception { //run the dynamic simulation on the implicit default variant result = mockMvc.perform( post("/v1/networks/{networkUuid}/run", NETWORK_UUID_STRING) - .param("mappingName", MAPPING_NAME) .param("parametersUuid", PARAMETERS_UUID.toString()) .contentType(APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") @@ -370,7 +369,6 @@ public void testGivenEmptyTimeSeriesAndTimeLine() throws Exception { MvcResult result = mockMvc.perform( post("/v1/networks/{networkUuid}/run", NETWORK_UUID_STRING) .param("variantId", VARIANT_1_ID) - .param("mappingName", MAPPING_NAME) .param("parametersUuid", PARAMETERS_UUID.toString()) .contentType(APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") @@ -457,7 +455,6 @@ private UUID runAndCancel(CountDownLatch cancelLatch, int cancelDelay) throws Ex MvcResult result = mockMvc.perform( post("/v1/networks/{networkUuid}/run", NETWORK_UUID_STRING) .param("variantId", VARIANT_1_ID) - .param("mappingName", MAPPING_NAME) .param("parametersUuid", PARAMETERS_UUID.toString()) .contentType(APPLICATION_JSON) .header(HEADER_USER_ID, "testUserId") From c362a1ef9572f913e345b87d61f3871ea72e588e Mon Sep 17 00:00:00 2001 From: Thang PHAM Date: Sun, 22 Mar 2026 14:26:22 +0100 Subject: [PATCH 3/3] Fix RabbitMq uses LongString and solver not update Signed-off-by: Thang PHAM --- .../java/org/gridsuite/ds/server/dto/event/EventInfos.java | 5 +++++ .../parameters/solver/IdaSolverParametersEntity.java | 5 +++++ .../parameters/solver/SimSolverParametersEntity.java | 5 +++++ .../entities/parameters/solver/SolverParametersEntity.java | 4 +--- .../service/contexts/DynamicSimulationResultContext.java | 5 +++-- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/gridsuite/ds/server/dto/event/EventInfos.java b/src/main/java/org/gridsuite/ds/server/dto/event/EventInfos.java index d0ba109f..ddf2030f 100644 --- a/src/main/java/org/gridsuite/ds/server/dto/event/EventInfos.java +++ b/src/main/java/org/gridsuite/ds/server/dto/event/EventInfos.java @@ -7,6 +7,7 @@ package org.gridsuite.ds.server.dto.event; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Getter; @@ -27,12 +28,16 @@ public class EventInfos { @JsonProperty("uuid") + @JsonIgnore private UUID id; + @JsonIgnore private UUID nodeId; + @JsonIgnore private String equipmentId; + @JsonIgnore private String equipmentType; private String eventType; diff --git a/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/IdaSolverParametersEntity.java b/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/IdaSolverParametersEntity.java index 236e3e73..1c6e7f4a 100644 --- a/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/IdaSolverParametersEntity.java +++ b/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/IdaSolverParametersEntity.java @@ -57,6 +57,11 @@ public void assignAttributes(IdaSolverInfos solverInfos) { relAccuracy = solverInfos.getRelAccuracy(); } + @Override + public void update(SolverInfos solverInfos) { + assignAttributes((IdaSolverInfos) solverInfos); + } + @Override public SolverInfos toDto(boolean toDuplicate) { IdaSolverInfos dto = IdaSolverInfos.builder() diff --git a/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SimSolverParametersEntity.java b/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SimSolverParametersEntity.java index 884adad3..5b84323a 100644 --- a/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SimSolverParametersEntity.java +++ b/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SimSolverParametersEntity.java @@ -105,6 +105,11 @@ public void assignAttributes(SimSolverInfos solverInfos) { minimumModeChangeTypeForAlgebraicRestorationInit = solverInfos.getMinimumModeChangeTypeForAlgebraicRestorationInit(); } + @Override + public void update(SolverInfos solverInfos) { + assignAttributes((SimSolverInfos) solverInfos); + } + @Override public SolverInfos toDto(boolean toDuplicate) { SimSolverInfos dto = SimSolverInfos.builder() diff --git a/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SolverParametersEntity.java b/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SolverParametersEntity.java index a88f2bf8..bb342b4a 100644 --- a/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SolverParametersEntity.java +++ b/src/main/java/org/gridsuite/ds/server/entities/parameters/solver/SolverParametersEntity.java @@ -140,9 +140,7 @@ protected void assignAttributes(AbstractSolverInfos solverInfos) { minimalAcceptableStep = solverInfos.getMinimalAcceptableStep(); } - public void update(SolverInfos solverInfos) { - assignAttributes((AbstractSolverInfos) solverInfos); - } + public abstract void update(SolverInfos solverInfos); protected void fillDto(AbstractSolverInfos solverInfos, boolean toDuplicate) { solverInfos.setId(toDuplicate ? null : id); diff --git a/src/main/java/org/gridsuite/ds/server/service/contexts/DynamicSimulationResultContext.java b/src/main/java/org/gridsuite/ds/server/service/contexts/DynamicSimulationResultContext.java index c4deca22..4706dcba 100644 --- a/src/main/java/org/gridsuite/ds/server/service/contexts/DynamicSimulationResultContext.java +++ b/src/main/java/org/gridsuite/ds/server/service/contexts/DynamicSimulationResultContext.java @@ -74,10 +74,11 @@ public static DynamicSimulationResultContext fromMessage(Message message // specific headers for dynamic simulation runContext.setMapping(getNonNullHeader(headers, HEADER_MAPPING)); - String eventsJson = getNonNullHeader(headers, HEADER_EVENTS); + // using Object then toString() to avoid casting exception since rabbitmq uses LongString instead of String + Object eventsJson = headers.get(HEADER_EVENTS); List events; try { - events = objectMapper.readValue(eventsJson, new TypeReference<>() { }); + events = objectMapper.readValue(eventsJson.toString(), new TypeReference<>() { }); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); }