From 3da711f330f45b1c9fa15cb3e466432c88af4d54 Mon Sep 17 00:00:00 2001 From: Caroline Jeandat Date: Thu, 5 Feb 2026 10:04:45 +0100 Subject: [PATCH 1/6] draft version --- .../server/SecurityAnalysisController.java | 8 ++--- .../server/dto/ContingencyListsDTO.java | 36 +++++++++++++++++++ .../server/dto/RunContextParametersInfos.java | 3 -- .../dto/SecurityAnalysisParametersDTO.java | 2 ++ .../dto/SecurityAnalysisParametersValues.java | 2 ++ .../server/entities/ContingencyEntity.java | 1 + .../entities/ContingencyListsEmbeddable.java | 34 ++++++++++++++++++ .../SecurityAnalysisParametersEntity.java | 18 ++++++++++ .../server/service/ActionsService.java | 2 +- .../SecurityAnalysisParametersService.java | 12 +++++-- .../SecurityAnalysisResultContext.java | 18 ---------- .../service/SecurityAnalysisRunContext.java | 8 ++--- .../SecurityAnalysisWorkerService.java | 7 ++-- .../server/SecurityAnalysisProviderMock.java | 9 ++--- .../server/service/ActionsServiceTest.java | 6 ++-- 15 files changed, 121 insertions(+), 45 deletions(-) create mode 100644 src/main/java/org/gridsuite/securityanalysis/server/dto/ContingencyListsDTO.java create mode 100644 src/main/java/org/gridsuite/securityanalysis/server/entities/ContingencyListsEmbeddable.java diff --git a/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java b/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java index 4184e694..7b415500 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/SecurityAnalysisController.java @@ -67,7 +67,6 @@ public SecurityAnalysisController(SecurityAnalysisService securityAnalysisServic schema = @Schema(implementation = SecurityAnalysisResult.class))})}) public ResponseEntity run(@Parameter(description = "Network UUID") @PathVariable("networkUuid") UUID networkUuid, @Parameter(description = "Variant Id") @RequestParam(name = "variantId", required = false) String variantId, - @Parameter(description = "Contingency list name") @RequestParam(name = "contingencyListName", required = false) List contigencyListNames, @Parameter(description = "Provider") @RequestParam(name = "provider", required = false) String provider, @Parameter(description = "reportUuid") @RequestParam(name = "reportUuid", required = false) UUID reportUuid, @Parameter(description = "reporterId") @RequestParam(name = "reporterId", required = false) String reporterId, @@ -79,14 +78,14 @@ public ResponseEntity run(@Parameter(description = "Netw securityAnalysisParametersService.createRunContext( networkUuid, variantId, - new RunContextParametersInfos(contigencyListNames, parametersUuid, loadFlowParametersUuid), + new RunContextParametersInfos(parametersUuid, loadFlowParametersUuid), null, new ReportInfos(reportUuid, reporterId, reportType), userId)); return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result); } - @PostMapping(value = "/networks/{networkUuid}/run-and-save", produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE) + @PostMapping(value = "/networks/{networkUuid}/run-and-save", produces = APPLICATION_JSON_VALUE) @Operation(summary = "Run a security analysis on a network and save results in the database") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis has been performed and results have been saved to database", @@ -94,7 +93,6 @@ public ResponseEntity run(@Parameter(description = "Netw schema = @Schema(implementation = SecurityAnalysisResult.class))})}) public ResponseEntity runAndSave(@Parameter(description = "Network UUID") @PathVariable("networkUuid") UUID networkUuid, @Parameter(description = "Variant Id") @RequestParam(name = "variantId", required = false) String variantId, - @Parameter(description = "Contingency list name") @RequestParam(name = "contingencyListName", required = false) List contigencyListNames, @Parameter(description = "Result receiver") @RequestParam(name = "receiver", required = false) String receiver, @Parameter(description = "reportUuid") @RequestParam(name = "reportUuid", required = false) UUID reportUuid, @Parameter(description = "reporterId") @RequestParam(name = "reporterId", required = false) String reporterId, @@ -106,7 +104,7 @@ public ResponseEntity runAndSave(@Parameter(description = "Network UUID") securityAnalysisParametersService.createRunContext( networkUuid, variantId, - new RunContextParametersInfos(contigencyListNames, parametersUuid, loadFlowParametersUuid), + new RunContextParametersInfos(parametersUuid, loadFlowParametersUuid), receiver, new ReportInfos(reportUuid, reporterId, reportType), userId diff --git a/src/main/java/org/gridsuite/securityanalysis/server/dto/ContingencyListsDTO.java b/src/main/java/org/gridsuite/securityanalysis/server/dto/ContingencyListsDTO.java new file mode 100644 index 00000000..0321e6a2 --- /dev/null +++ b/src/main/java/org/gridsuite/securityanalysis/server/dto/ContingencyListsDTO.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2025, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.securityanalysis.server.dto; + +import lombok.*; +import org.gridsuite.securityanalysis.server.entities.ContingencyListsEmbeddable; + +import java.util.UUID; + +/** + * @author Caroline Jeandat {@literal } + */ +@Data +@Builder +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class ContingencyListsDTO { + private UUID id; + private String name; + private boolean activated; + + public ContingencyListsDTO(ContingencyListsEmbeddable contingencyListsEmbeddable) { + this.id = contingencyListsEmbeddable.getId(); + this.name = contingencyListsEmbeddable.getName(); + this.activated = contingencyListsEmbeddable.isActivated(); + } + + public ContingencyListsEmbeddable toEmbeddable() { + return new ContingencyListsEmbeddable(this); + } +} diff --git a/src/main/java/org/gridsuite/securityanalysis/server/dto/RunContextParametersInfos.java b/src/main/java/org/gridsuite/securityanalysis/server/dto/RunContextParametersInfos.java index 75c70925..5061ac6b 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/dto/RunContextParametersInfos.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/dto/RunContextParametersInfos.java @@ -10,7 +10,6 @@ import lombok.AllArgsConstructor; import lombok.Getter; -import java.util.List; import java.util.UUID; /** @@ -20,8 +19,6 @@ @Getter @Schema(description = "to help create a securityAnalysisRunContext") public class RunContextParametersInfos { - private List contingencyListNames; - private UUID securityAnalysisParametersUuid; private UUID loadFlowParametersUuid; diff --git a/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersDTO.java b/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersDTO.java index 1e864d7d..ff68e8cd 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersDTO.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersDTO.java @@ -10,9 +10,11 @@ import lombok.Builder; import java.util.List; +import java.util.UUID; @Builder public record SecurityAnalysisParametersDTO( SecurityAnalysisParameters securityAnalysisParameters, + List contingencyListsUuids, List> limitReductions ) { } diff --git a/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersValues.java b/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersValues.java index 99c2892b..07522b71 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersValues.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersValues.java @@ -36,6 +36,8 @@ public class SecurityAnalysisParametersValues { private double flowProportionalThreshold; + private List contingencyLists; + private List limitReductions; public SecurityAnalysisParametersEntity toEntity() { diff --git a/src/main/java/org/gridsuite/securityanalysis/server/entities/ContingencyEntity.java b/src/main/java/org/gridsuite/securityanalysis/server/entities/ContingencyEntity.java index 2c8f5656..d9bddad7 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/entities/ContingencyEntity.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/entities/ContingencyEntity.java @@ -43,6 +43,7 @@ public ContingencyEntity(String contingencyId, String status, List} + */ +@Getter +@AllArgsConstructor +@NoArgsConstructor +@Embeddable +public class ContingencyListsEmbeddable { + private UUID id; + private String name; + private boolean activated; + + public ContingencyListsEmbeddable(ContingencyListsDTO contingencyListsDTO) { + this.id = contingencyListsDTO.getId(); + this.name = contingencyListsDTO.getName(); + this.activated = contingencyListsDTO.isActivated(); + } +} diff --git a/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisParametersEntity.java b/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisParametersEntity.java index 13aed58d..eb8b76a0 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisParametersEntity.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisParametersEntity.java @@ -55,11 +55,28 @@ public SecurityAnalysisParametersEntity(SecurityAnalysisParametersValues securit @Column(name = "flowProportionalThreshold") private double flowProportionalThreshold; + @ElementCollection + @CollectionTable( + name = "contingency_lists", + joinColumns = @JoinColumn(name = "security_analysis_parameters_id") + ) + private List contingencyLists; + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "security_analysis_parameters_id", foreignKey = @ForeignKey(name = "securityAnalysisParametersEntity_limitReductions_fk")) @OrderColumn(name = "index") private List limitReductions; + public List getActivatedContingencyListUuids() { + if (contingencyLists == null) { + return List.of(); + } + return this.contingencyLists.stream() + .filter(ContingencyListsEmbeddable::isActivated) + .map(ContingencyListsEmbeddable::getId) + .toList(); + } + public List> toLimitReductionsValues() { return this.limitReductions.stream().map(LimitReductionEntity::getReductions).map(ArrayList::new).collect(Collectors.toList()); } @@ -75,6 +92,7 @@ private void assignAttributes(SecurityAnalysisParametersValues securityAnalysisP this.highVoltageProportionalThreshold = securityAnalysisParametersValues.getHighVoltageProportionalThreshold(); this.lowVoltageAbsoluteThreshold = securityAnalysisParametersValues.getLowVoltageAbsoluteThreshold(); this.lowVoltageProportionalThreshold = securityAnalysisParametersValues.getLowVoltageProportionalThreshold(); + this.contingencyLists = securityAnalysisParametersValues.getContingencyLists().stream().map(ContingencyListsEmbeddable::new).toList(); assignLimitReductions(securityAnalysisParametersValues.getLimitReductionsValues()); } diff --git a/src/main/java/org/gridsuite/securityanalysis/server/service/ActionsService.java b/src/main/java/org/gridsuite/securityanalysis/server/service/ActionsService.java index 4e2a8a64..8e686f39 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/service/ActionsService.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/service/ActionsService.java @@ -45,7 +45,7 @@ public ActionsService( this.restTemplate = restTemplate; } - public List getContingencyList(List ids, UUID networkUuid, String variantId) { + public List getContingencyList(List ids, UUID networkUuid, String variantId) { Objects.requireNonNull(ids); Objects.requireNonNull(networkUuid); if (ids.isEmpty()) { diff --git a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisParametersService.java b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisParametersService.java index d2f16aef..e4811486 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisParametersService.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisParametersService.java @@ -41,6 +41,7 @@ public class SecurityAnalysisParametersService { private static final double DEFAULT_HIGH_VOLTAGE_PROPORTIONAL_THRESHOLD = 0.01; // meaning 1.0 % private static final double DEFAULT_LOW_VOLTAGE_ABSOLUTE_THRESHOLD = 1.0; // 1.0 kV private static final double DEFAULT_HIGH_VOLTAGE_ABSOLUTE_THRESHOLD = 1.0; // 1.0 kV + private static final List DEFAULT_CONTINGENCY_LISTS = new ArrayList<>(); public SecurityAnalysisParametersService(@NonNull SecurityAnalysisParametersRepository securityAnalysisParametersRepository, @NonNull LoadFlowService loadFlowService, @Value("${security-analysis.default-provider}") String defaultProvider, @NonNull LimitReductionService limitReductionService) { @@ -69,7 +70,6 @@ public SecurityAnalysisRunContext createRunContext(UUID networkUuid, String vari return new SecurityAnalysisRunContext( networkUuid, variantId, - runContextParametersInfos.getContingencyListNames(), receiver, providerToUse, parameters, @@ -81,18 +81,24 @@ public SecurityAnalysisRunContext createRunContext(UUID networkUuid, String vari public SecurityAnalysisParametersDTO toSecurityAnalysisParameters(SecurityAnalysisParametersEntity entity) { SecurityAnalysisParameters securityAnalysisParameters = SecurityAnalysisParameters.load(); List> limitReductions = new ArrayList<>(); + List activatedContingencyListUuids = new ArrayList<>(); if (entity == null) { // the default values are overloaded securityAnalysisParameters.setIncreasedViolationsParameters(getIncreasedViolationsParameters(DEFAULT_FLOW_PROPORTIONAL_THRESHOLD, DEFAULT_LOW_VOLTAGE_PROPORTIONAL_THRESHOLD, DEFAULT_LOW_VOLTAGE_ABSOLUTE_THRESHOLD, DEFAULT_HIGH_VOLTAGE_PROPORTIONAL_THRESHOLD, DEFAULT_HIGH_VOLTAGE_ABSOLUTE_THRESHOLD)); } else { securityAnalysisParameters.setIncreasedViolationsParameters(getIncreasedViolationsParameters(entity.getFlowProportionalThreshold(), entity.getLowVoltageProportionalThreshold(), entity.getLowVoltageAbsoluteThreshold(), entity.getHighVoltageProportionalThreshold(), entity.getHighVoltageAbsoluteThreshold())); limitReductions = entity.toLimitReductionsValues(); + activatedContingencyListUuids = entity.getActivatedContingencyListUuids(); } if (limitReductions.isEmpty()) { limitReductions = limitReductionService.getDefaultValues(); } - return SecurityAnalysisParametersDTO.builder().securityAnalysisParameters(securityAnalysisParameters).limitReductions(limitReductions).build(); + return SecurityAnalysisParametersDTO.builder() + .securityAnalysisParameters(securityAnalysisParameters) + .contingencyListsUuids(activatedContingencyListUuids) + .limitReductions(limitReductions) + .build(); } public SecurityAnalysisParametersValues toSecurityAnalysisParametersValues(SecurityAnalysisParametersEntity entity) { @@ -103,6 +109,7 @@ public SecurityAnalysisParametersValues toSecurityAnalysisParametersValues(Secur .highVoltageProportionalThreshold(entity.getHighVoltageProportionalThreshold()) .lowVoltageAbsoluteThreshold(entity.getLowVoltageAbsoluteThreshold()) .lowVoltageProportionalThreshold(entity.getLowVoltageProportionalThreshold()) + .contingencyLists(entity.getContingencyLists().stream().map(ContingencyListsDTO::new).toList()) .limitReductions(getLimitReductionsForProvider(entity).orElse(null)) .build(); } @@ -134,6 +141,7 @@ public SecurityAnalysisParametersValues getDefaultSecurityAnalysisParametersValu .highVoltageAbsoluteThreshold(DEFAULT_HIGH_VOLTAGE_ABSOLUTE_THRESHOLD) .highVoltageProportionalThreshold(DEFAULT_HIGH_VOLTAGE_PROPORTIONAL_THRESHOLD) .flowProportionalThreshold(DEFAULT_FLOW_PROPORTIONAL_THRESHOLD) + .contingencyLists(DEFAULT_CONTINGENCY_LISTS) .limitReductions(limitReductionService.createDefaultLimitReductions()) .build(); } diff --git a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisResultContext.java b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisResultContext.java index 8843b37f..a7cc2289 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisResultContext.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisResultContext.java @@ -24,27 +24,16 @@ * @author Geoffroy Jamgotchian */ public class SecurityAnalysisResultContext extends AbstractResultContext { - public static final String CONTINGENCY_LIST_NAMES_HEADER = "contingencyListNames"; - public SecurityAnalysisResultContext(UUID resultUuid, SecurityAnalysisRunContext runContext) { super(resultUuid, runContext); } - private static List getHeaderList(MessageHeaders headers, String name) { - String header = (String) headers.get(name); - if (header == null || header.isEmpty()) { - return Collections.emptyList(); - } - return Arrays.asList(header.split(",")); - } - public static SecurityAnalysisResultContext fromMessage(Message message, ObjectMapper objectMapper) { Objects.requireNonNull(message); MessageHeaders headers = message.getHeaders(); UUID resultUuid = UUID.fromString(getNonNullHeader(headers, HEADER_RESULT_UUID)); UUID networkUuid = UUID.fromString(getNonNullHeader(headers, NETWORK_UUID_HEADER)); String variantId = (String) headers.get(VARIANT_ID_HEADER); - List contingencyListNames = getHeaderList(headers, CONTINGENCY_LIST_NAMES_HEADER); String receiver = (String) headers.get(HEADER_RECEIVER); String provider = (String) headers.get(HEADER_PROVIDER); String userId = (String) headers.get(HEADER_USER_ID); @@ -60,7 +49,6 @@ public static SecurityAnalysisResultContext fromMessage(Message message, SecurityAnalysisRunContext runContext = new SecurityAnalysisRunContext( networkUuid, variantId, - contingencyListNames, receiver, provider, parameters, @@ -69,10 +57,4 @@ public static SecurityAnalysisResultContext fromMessage(Message message, ); return new SecurityAnalysisResultContext(resultUuid, runContext); } - - @Override - protected Map getSpecificMsgHeaders(ObjectMapper ignoredObjectMapper) { - return Map.of( - CONTINGENCY_LIST_NAMES_HEADER, String.join(",", getRunContext().getContingencyListNames())); - } } diff --git a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisRunContext.java b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisRunContext.java index d70bbf19..25fda4d3 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisRunContext.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisRunContext.java @@ -27,18 +27,15 @@ */ @Getter public class SecurityAnalysisRunContext extends AbstractComputationRunContext { - - private final List contingencyListNames; @Setter private List contingencies; - public SecurityAnalysisRunContext(UUID networkUuid, String variantId, List contingencyListNames, + public SecurityAnalysisRunContext(UUID networkUuid, String variantId, String receiver, String provider, SecurityAnalysisParametersDTO parameters, LoadFlowParametersValues loadFlowParametersValues, ReportInfos reportContext, String userId) { this( networkUuid, variantId, - contingencyListNames, receiver, provider, buildParameters(parameters, loadFlowParametersValues, provider), @@ -47,11 +44,10 @@ public SecurityAnalysisRunContext(UUID networkUuid, String variantId, List contingencyListNames, + public SecurityAnalysisRunContext(UUID networkUuid, String variantId, String receiver, String provider, SecurityAnalysisParametersDTO parameters, ReportInfos reportContext, String userId) { super(networkUuid, variantId, receiver, reportContext, userId, provider, parameters); - this.contingencyListNames = Objects.requireNonNull(contingencyListNames); } private static SecurityAnalysisParametersDTO buildParameters(SecurityAnalysisParametersDTO parameters, diff --git a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java index 04eff4bd..a8f4f880 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java @@ -26,7 +26,6 @@ import com.powsybl.network.store.client.PreloadingStrategy; import com.powsybl.security.*; import com.powsybl.security.limitreduction.LimitReduction; -import com.powsybl.ws.commons.LogUtils; import org.gridsuite.computation.service.*; import org.gridsuite.securityanalysis.server.PropertyServerNameProvider; import org.gridsuite.securityanalysis.server.dto.ContingencyInfos; @@ -178,11 +177,13 @@ private LimitReduction createLimitReduction(IdentifiableCriterion voltageLevelCr @Override protected void preRun(SecurityAnalysisRunContext runContext) { - LOGGER.info("Run security analysis on contingency lists: {}", runContext.getContingencyListNames().stream().map(LogUtils::sanitizeParam).toList()); + if (runContext.getParameters().contingencyListsUuids() != null) { + LOGGER.info("Run security analysis on contingency lists: {}", runContext.getParameters().contingencyListsUuids()); //.stream().map(LogUtils::sanitizeParam).toList()); + } List contingencies = observer.observe("contingencies.fetch", runContext, () -> - actionsService.getContingencyList(runContext.getContingencyListNames(), runContext.getNetworkUuid(), runContext.getVariantId()) + actionsService.getContingencyList(runContext.getParameters().contingencyListsUuids(), runContext.getNetworkUuid(), runContext.getVariantId()) ); runContext.setContingencies(contingencies); diff --git a/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisProviderMock.java b/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisProviderMock.java index 2201d464..c3e8e5fd 100644 --- a/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisProviderMock.java +++ b/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisProviderMock.java @@ -22,6 +22,7 @@ import java.util.Comparator; import java.util.List; import java.util.Set; +import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -36,10 +37,10 @@ public class SecurityAnalysisProviderMock implements SecurityAnalysisProvider { private static final Logger LOGGER = LoggerFactory.getLogger(SecurityAnalysisProviderMock.class); - static final String CONTINGENCY_LIST_NAME = "list1"; - static final String CONTINGENCY_LIST2_NAME = "list2"; - static final String CONTINGENCY_LIST_ERROR_NAME = "listError"; - static final String CONTINGENCY_LIST_NAME_VARIANT = "listVariant"; + static final UUID CONTINGENCY_LIST_NAME = UUID.fromString("6afd3d28-3f99-48d7-be9e-e97ffd0b791f"); //"list1"; + static final UUID CONTINGENCY_LIST2_NAME = UUID.fromString("6afd3d28-3f99-48d7-be9e-e97ffd0b791g"); //"list2"; + static final UUID CONTINGENCY_LIST_ERROR_NAME = UUID.fromString("6afd3d28-3f99-48d7-be9e-e97ffd0b791h"); //"listError"; + static final UUID CONTINGENCY_LIST_NAME_VARIANT = UUID.fromString("6afd3d28-3f99-48d7-be9e-e97ffd0b791i"); //"listVariant"; static final List CONTINGENCIES = List.of( new ContingencyInfos(new Contingency("l1", new BranchContingency("l1")), Set.of("wrongId1, wrongId2"), Set.of()), diff --git a/src/test/java/org/gridsuite/securityanalysis/server/service/ActionsServiceTest.java b/src/test/java/org/gridsuite/securityanalysis/server/service/ActionsServiceTest.java index f3ba6b34..b40c39c1 100644 --- a/src/test/java/org/gridsuite/securityanalysis/server/service/ActionsServiceTest.java +++ b/src/test/java/org/gridsuite/securityanalysis/server/service/ActionsServiceTest.java @@ -55,10 +55,10 @@ class ActionsServiceTest { private static final String VARIANT_ID = "variant_id"; - private static final String LIST_NAME = "myList"; - private static final String LIST_NAME_VARIANT = "myListVariant"; + private static final UUID LIST_NAME = UUID.fromString("6afd3d28-3f99-48d7-be9e-e97ffd0b791j"); //"myList"; + private static final UUID LIST_NAME_VARIANT = UUID.fromString("6afd3d28-3f99-48d7-be9e-e97ffd0b791k"); //"myListVariant"; - private static final String VERY_LARGE_LIST_NAME = "veryLargelist"; + private static final UUID VERY_LARGE_LIST_NAME = UUID.fromString("6afd3d28-3f99-48d7-be9e-e97ffd0b791l"); //"veryLargelist"; public static final String WRONG_ID = "wrongID"; private static final ContingencyInfos CONTINGENCY = new ContingencyInfos(new Contingency("c1", new BranchContingency("b1")), Set.of(WRONG_ID), Set.of()); From 357b562503f3504315240e708751b7f346e3bade Mon Sep 17 00:00:00 2001 From: Caroline Jeandat Date: Fri, 6 Feb 2026 18:51:15 +0100 Subject: [PATCH 2/6] add several contingencies for each contingencyList + get contingencies name from directory server --- .../server/dto/ContingencyListsDTO.java | 36 ----------- .../dto/ParametersContingenciesDTO.java | 20 ++++++ .../dto/ParametersContingencyListDTO.java | 24 +++++++ .../dto/SecurityAnalysisParametersDTO.java | 2 +- .../dto/SecurityAnalysisParametersValues.java | 2 +- .../entities/ContingencyListsEmbeddable.java | 34 ---------- .../ParametersContingencyListEntity.java | 49 +++++++++++++++ .../SecurityAnalysisParametersEntity.java | 39 +++++++++--- .../server/service/DirectoryService.java | 63 +++++++++++++++++++ .../ParametersContingenciesService.java | 38 +++++++++++ .../SecurityAnalysisParametersService.java | 16 +++-- .../SecurityAnalysisWorkerService.java | 6 +- src/main/resources/application-local.yaml | 2 + 13 files changed, 242 insertions(+), 89 deletions(-) delete mode 100644 src/main/java/org/gridsuite/securityanalysis/server/dto/ContingencyListsDTO.java create mode 100644 src/main/java/org/gridsuite/securityanalysis/server/dto/ParametersContingenciesDTO.java create mode 100644 src/main/java/org/gridsuite/securityanalysis/server/dto/ParametersContingencyListDTO.java delete mode 100644 src/main/java/org/gridsuite/securityanalysis/server/entities/ContingencyListsEmbeddable.java create mode 100644 src/main/java/org/gridsuite/securityanalysis/server/entities/ParametersContingencyListEntity.java create mode 100644 src/main/java/org/gridsuite/securityanalysis/server/service/DirectoryService.java create mode 100644 src/main/java/org/gridsuite/securityanalysis/server/service/ParametersContingenciesService.java diff --git a/src/main/java/org/gridsuite/securityanalysis/server/dto/ContingencyListsDTO.java b/src/main/java/org/gridsuite/securityanalysis/server/dto/ContingencyListsDTO.java deleted file mode 100644 index 0321e6a2..00000000 --- a/src/main/java/org/gridsuite/securityanalysis/server/dto/ContingencyListsDTO.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2025, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -package org.gridsuite.securityanalysis.server.dto; - -import lombok.*; -import org.gridsuite.securityanalysis.server.entities.ContingencyListsEmbeddable; - -import java.util.UUID; - -/** - * @author Caroline Jeandat {@literal } - */ -@Data -@Builder -@Getter -@NoArgsConstructor -@AllArgsConstructor -public class ContingencyListsDTO { - private UUID id; - private String name; - private boolean activated; - - public ContingencyListsDTO(ContingencyListsEmbeddable contingencyListsEmbeddable) { - this.id = contingencyListsEmbeddable.getId(); - this.name = contingencyListsEmbeddable.getName(); - this.activated = contingencyListsEmbeddable.isActivated(); - } - - public ContingencyListsEmbeddable toEmbeddable() { - return new ContingencyListsEmbeddable(this); - } -} diff --git a/src/main/java/org/gridsuite/securityanalysis/server/dto/ParametersContingenciesDTO.java b/src/main/java/org/gridsuite/securityanalysis/server/dto/ParametersContingenciesDTO.java new file mode 100644 index 00000000..8e17dafc --- /dev/null +++ b/src/main/java/org/gridsuite/securityanalysis/server/dto/ParametersContingenciesDTO.java @@ -0,0 +1,20 @@ +package org.gridsuite.securityanalysis.server.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.UUID; + +/** + * @author Caroline Jeandat {@literal } + */ +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class ParametersContingenciesDTO { + UUID id; + String name; +} diff --git a/src/main/java/org/gridsuite/securityanalysis/server/dto/ParametersContingencyListDTO.java b/src/main/java/org/gridsuite/securityanalysis/server/dto/ParametersContingencyListDTO.java new file mode 100644 index 00000000..4b1e9960 --- /dev/null +++ b/src/main/java/org/gridsuite/securityanalysis/server/dto/ParametersContingencyListDTO.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2025, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.securityanalysis.server.dto; +import lombok.*; + +import java.util.List; + +/** + * @author Caroline Jeandat {@literal } + */ +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Setter +public class ParametersContingencyListDTO { + List contingencies; + String description; + boolean activated; +} diff --git a/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersDTO.java b/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersDTO.java index ff68e8cd..24b68301 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersDTO.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersDTO.java @@ -15,6 +15,6 @@ @Builder public record SecurityAnalysisParametersDTO( SecurityAnalysisParameters securityAnalysisParameters, - List contingencyListsUuids, + List contingencyListUuids, List> limitReductions ) { } diff --git a/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersValues.java b/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersValues.java index 07522b71..20d48738 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersValues.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/dto/SecurityAnalysisParametersValues.java @@ -36,7 +36,7 @@ public class SecurityAnalysisParametersValues { private double flowProportionalThreshold; - private List contingencyLists; + private List contingencyLists; private List limitReductions; diff --git a/src/main/java/org/gridsuite/securityanalysis/server/entities/ContingencyListsEmbeddable.java b/src/main/java/org/gridsuite/securityanalysis/server/entities/ContingencyListsEmbeddable.java deleted file mode 100644 index e2c7a064..00000000 --- a/src/main/java/org/gridsuite/securityanalysis/server/entities/ContingencyListsEmbeddable.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) 2025, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -package org.gridsuite.securityanalysis.server.entities; - -import jakarta.persistence.*; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.gridsuite.securityanalysis.server.dto.ContingencyListsDTO; - -import java.util.UUID; - -/** - * @author Caroline Jeandat {@literal } - */ -@Getter -@AllArgsConstructor -@NoArgsConstructor -@Embeddable -public class ContingencyListsEmbeddable { - private UUID id; - private String name; - private boolean activated; - - public ContingencyListsEmbeddable(ContingencyListsDTO contingencyListsDTO) { - this.id = contingencyListsDTO.getId(); - this.name = contingencyListsDTO.getName(); - this.activated = contingencyListsDTO.isActivated(); - } -} diff --git a/src/main/java/org/gridsuite/securityanalysis/server/entities/ParametersContingencyListEntity.java b/src/main/java/org/gridsuite/securityanalysis/server/entities/ParametersContingencyListEntity.java new file mode 100644 index 00000000..b5c69761 --- /dev/null +++ b/src/main/java/org/gridsuite/securityanalysis/server/entities/ParametersContingencyListEntity.java @@ -0,0 +1,49 @@ +package org.gridsuite.securityanalysis.server.entities; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.List; +import java.util.UUID; + +/** + * @author Caroline Jeandat {@literal } + */ +@Getter +@Setter +@NoArgsConstructor +@Entity +@Table(name = "parameters_contingency_list", indexes = {@Index(name = "idx_security_analysis_parameters_id", columnList = "security_analysis_parameters_id")}) +public class ParametersContingencyListEntity { + + @Id + @GeneratedValue(strategy = GenerationType.UUID) + @Column(name = "contingency_list_id") + private UUID id; + + @ElementCollection + @CollectionTable( + name = "parameters_contingency_list_contingencies", + joinColumns = @JoinColumn(name = "contingency_list_id") + ) + @Column(name = "contingencies_id") + private List contingenciesIds; + + @Column(name = "description") + private String description; + + @Column(name = "activated") + private boolean activated; + + @ManyToOne + @JoinColumn(name = "security_analysis_parameters_id") + private SecurityAnalysisParametersEntity securityAnalysisParameters; + + public ParametersContingencyListEntity(List contingenciesIds, String description, boolean activated) { + this.contingenciesIds = contingenciesIds; + this.description = description; + this.activated = activated; + } +} diff --git a/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisParametersEntity.java b/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisParametersEntity.java index eb8b76a0..ecc287d5 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisParametersEntity.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisParametersEntity.java @@ -8,6 +8,8 @@ import jakarta.persistence.*; import lombok.*; +import org.gridsuite.securityanalysis.server.dto.ParametersContingenciesDTO; +import org.gridsuite.securityanalysis.server.dto.ParametersContingencyListDTO; import org.gridsuite.securityanalysis.server.dto.SecurityAnalysisParametersValues; import org.springframework.lang.Nullable; @@ -55,12 +57,10 @@ public SecurityAnalysisParametersEntity(SecurityAnalysisParametersValues securit @Column(name = "flowProportionalThreshold") private double flowProportionalThreshold; - @ElementCollection - @CollectionTable( - name = "contingency_lists", - joinColumns = @JoinColumn(name = "security_analysis_parameters_id") - ) - private List contingencyLists; + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "securityAnalysisParameters") + @OrderColumn(name = "index") + @Builder.Default + private List contingencyLists = new ArrayList<>(); @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "security_analysis_parameters_id", foreignKey = @ForeignKey(name = "securityAnalysisParametersEntity_limitReductions_fk")) @@ -72,8 +72,8 @@ public List getActivatedContingencyListUuids() { return List.of(); } return this.contingencyLists.stream() - .filter(ContingencyListsEmbeddable::isActivated) - .map(ContingencyListsEmbeddable::getId) + .filter(ParametersContingencyListEntity::isActivated) + .flatMap(contingencyList -> contingencyList.getContingenciesIds().stream()) .toList(); } @@ -92,10 +92,30 @@ private void assignAttributes(SecurityAnalysisParametersValues securityAnalysisP this.highVoltageProportionalThreshold = securityAnalysisParametersValues.getHighVoltageProportionalThreshold(); this.lowVoltageAbsoluteThreshold = securityAnalysisParametersValues.getLowVoltageAbsoluteThreshold(); this.lowVoltageProportionalThreshold = securityAnalysisParametersValues.getLowVoltageProportionalThreshold(); - this.contingencyLists = securityAnalysisParametersValues.getContingencyLists().stream().map(ContingencyListsEmbeddable::new).toList(); + assignContingencyLists(securityAnalysisParametersValues.getContingencyLists()); assignLimitReductions(securityAnalysisParametersValues.getLimitReductionsValues()); } + private void assignContingencyLists(List contingencyListsDTO) { + if (contingencyListsDTO == null) { + return; + } + + List entities = contingencyListsDTO.stream() + .map(dto -> { + ParametersContingencyListEntity entity = new ParametersContingencyListEntity( + dto.getContingencies().stream().map(ParametersContingenciesDTO::getId).toList(), + dto.getDescription(), + dto.isActivated() + ); + entity.setSecurityAnalysisParameters(this); + return entity; + }) + .toList(); + contingencyLists.clear(); + contingencyLists.addAll(entities); + } + private void assignLimitReductions(@Nullable List> values) { if (values == null) { return; @@ -113,4 +133,3 @@ public void updateProvider(String provider) { this.provider = provider; } } - diff --git a/src/main/java/org/gridsuite/securityanalysis/server/service/DirectoryService.java b/src/main/java/org/gridsuite/securityanalysis/server/service/DirectoryService.java new file mode 100644 index 00000000..f2d9ef56 --- /dev/null +++ b/src/main/java/org/gridsuite/securityanalysis/server/service/DirectoryService.java @@ -0,0 +1,63 @@ +package org.gridsuite.securityanalysis.server.service; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import java.net.URI; +import java.util.*; + +/** + * @author Caroline Jeandat {@literal } + */ +@Service +public class DirectoryService { + static final String DIRECTORY_API_VERSION = "v1"; + + private static final String DELIMITER = "/"; + + private String baseUri; + + private RestTemplate restTemplate; + + public void setDirectoryServiceBaseUri(String baseUri) { + this.baseUri = baseUri; + } + + public DirectoryService( + @Value("${gridsuite.services.directory-server.base-uri:http://directory-server}") String baseUri, + RestTemplate restTemplate) { + this.baseUri = baseUri; + this.restTemplate = restTemplate; + } + + public String getContingenciesName(UUID contingenciesId) { + Objects.requireNonNull(contingenciesId); + + URI path = UriComponentsBuilder + .fromPath(DELIMITER + DIRECTORY_API_VERSION + "/elements/{elementUuid}") + .buildAndExpand(contingenciesId) + .toUri(); + + try { + ResponseEntity> response = + restTemplate.exchange( + baseUri + path, + HttpMethod.GET, + null, + new ParameterizedTypeReference<>() { } + ); + + Map responseBody = response.getBody(); + return responseBody != null ? (String) responseBody.get("elementName") : null; + + } catch (HttpClientErrorException.NotFound e) { + return null; + } + } +} diff --git a/src/main/java/org/gridsuite/securityanalysis/server/service/ParametersContingenciesService.java b/src/main/java/org/gridsuite/securityanalysis/server/service/ParametersContingenciesService.java new file mode 100644 index 00000000..ecfadef8 --- /dev/null +++ b/src/main/java/org/gridsuite/securityanalysis/server/service/ParametersContingenciesService.java @@ -0,0 +1,38 @@ +package org.gridsuite.securityanalysis.server.service; + +import org.gridsuite.securityanalysis.server.dto.ParametersContingenciesDTO; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.UUID; + +/** + * @author Caroline Jeandat {@literal } + */ +@Service +public class ParametersContingenciesService { + + private final DirectoryService directoryService; + + public ParametersContingenciesService(DirectoryService directoryService) { + this.directoryService = directoryService; + } + + public List toDTO(List contingenciesIds) { + return contingenciesIds == null ? null : + contingenciesIds.stream() + .map(id -> new ParametersContingenciesDTO(id, getContingenciesName(id))) + .toList(); + } + + public List toUUIDs(List contingenciesDTOs) { + return contingenciesDTOs == null ? null : + contingenciesDTOs.stream() + .map(ParametersContingenciesDTO::getId) + .toList(); + } + + private String getContingenciesName(UUID contingencyId) { + return directoryService.getContingenciesName(contingencyId); + } +} diff --git a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisParametersService.java b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisParametersService.java index e4811486..4c6fee5d 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisParametersService.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisParametersService.java @@ -32,6 +32,8 @@ public class SecurityAnalysisParametersService { private final LoadFlowService loadFlowService; + private final ParametersContingenciesService parametersContingenciesService; + private final String defaultProvider; private final LimitReductionService limitReductionService; @@ -41,12 +43,13 @@ public class SecurityAnalysisParametersService { private static final double DEFAULT_HIGH_VOLTAGE_PROPORTIONAL_THRESHOLD = 0.01; // meaning 1.0 % private static final double DEFAULT_LOW_VOLTAGE_ABSOLUTE_THRESHOLD = 1.0; // 1.0 kV private static final double DEFAULT_HIGH_VOLTAGE_ABSOLUTE_THRESHOLD = 1.0; // 1.0 kV - private static final List DEFAULT_CONTINGENCY_LISTS = new ArrayList<>(); + private static final List DEFAULT_CONTINGENCY_LISTS = new ArrayList<>(); - public SecurityAnalysisParametersService(@NonNull SecurityAnalysisParametersRepository securityAnalysisParametersRepository, @NonNull LoadFlowService loadFlowService, + public SecurityAnalysisParametersService(@NonNull SecurityAnalysisParametersRepository securityAnalysisParametersRepository, @NonNull LoadFlowService loadFlowService, @NonNull ParametersContingenciesService parametersContingenciesService, @Value("${security-analysis.default-provider}") String defaultProvider, @NonNull LimitReductionService limitReductionService) { this.securityAnalysisParametersRepository = Objects.requireNonNull(securityAnalysisParametersRepository); this.loadFlowService = loadFlowService; + this.parametersContingenciesService = parametersContingenciesService; this.defaultProvider = defaultProvider; this.limitReductionService = limitReductionService; } @@ -96,7 +99,7 @@ public SecurityAnalysisParametersDTO toSecurityAnalysisParameters(SecurityAnalys } return SecurityAnalysisParametersDTO.builder() .securityAnalysisParameters(securityAnalysisParameters) - .contingencyListsUuids(activatedContingencyListUuids) + .contingencyListUuids(activatedContingencyListUuids) .limitReductions(limitReductions) .build(); } @@ -109,7 +112,12 @@ public SecurityAnalysisParametersValues toSecurityAnalysisParametersValues(Secur .highVoltageProportionalThreshold(entity.getHighVoltageProportionalThreshold()) .lowVoltageAbsoluteThreshold(entity.getLowVoltageAbsoluteThreshold()) .lowVoltageProportionalThreshold(entity.getLowVoltageProportionalThreshold()) - .contingencyLists(entity.getContingencyLists().stream().map(ContingencyListsDTO::new).toList()) + .contingencyLists(entity.getContingencyLists().stream() + .map(c -> new ParametersContingencyListDTO( + parametersContingenciesService.toDTO(c.getContingenciesIds()), + c.getDescription(), + c.isActivated())) + .toList()) .limitReductions(getLimitReductionsForProvider(entity).orElse(null)) .build(); } diff --git a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java index a8f4f880..d85b3a42 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java @@ -177,13 +177,13 @@ private LimitReduction createLimitReduction(IdentifiableCriterion voltageLevelCr @Override protected void preRun(SecurityAnalysisRunContext runContext) { - if (runContext.getParameters().contingencyListsUuids() != null) { - LOGGER.info("Run security analysis on contingency lists: {}", runContext.getParameters().contingencyListsUuids()); //.stream().map(LogUtils::sanitizeParam).toList()); + if (runContext.getParameters().contingencyListUuids() != null) { + LOGGER.info("Run security analysis on contingency lists: {}", runContext.getParameters().contingencyListUuids()); //.stream().map(LogUtils::sanitizeParam).toList()); } List contingencies = observer.observe("contingencies.fetch", runContext, () -> - actionsService.getContingencyList(runContext.getParameters().contingencyListsUuids(), runContext.getNetworkUuid(), runContext.getVariantId()) + actionsService.getContingencyList(runContext.getParameters().contingencyListUuids(), runContext.getNetworkUuid(), runContext.getVariantId()) ); runContext.setContingencies(contingencies); diff --git a/src/main/resources/application-local.yaml b/src/main/resources/application-local.yaml index a249a4ef..dda0a5f9 100644 --- a/src/main/resources/application-local.yaml +++ b/src/main/resources/application-local.yaml @@ -22,3 +22,5 @@ gridsuite: base-uri: http://localhost:5028 loadflow-server: base-uri: http://localhost:5008 + directory-server: + base-uri: http://localhost:5026 From c3f8d597bd91ec86f275a87b696e6468b7093833 Mon Sep 17 00:00:00 2001 From: Caroline Jeandat Date: Mon, 9 Feb 2026 09:02:48 +0100 Subject: [PATCH 3/6] add changelog --- .../changesets/changelog_20260209T074419Z.xml | 33 +++++++++++++++++++ .../db/changelog/db.changelog-master.yaml | 3 ++ 2 files changed, 36 insertions(+) create mode 100644 src/main/resources/db/changelog/changesets/changelog_20260209T074419Z.xml diff --git a/src/main/resources/db/changelog/changesets/changelog_20260209T074419Z.xml b/src/main/resources/db/changelog/changesets/changelog_20260209T074419Z.xml new file mode 100644 index 00000000..b27f509a --- /dev/null +++ b/src/main/resources/db/changelog/changesets/changelog_20260209T074419Z.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index 2dfde1d1..17f61bcc 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -54,3 +54,6 @@ databaseChangeLog: - include: file: changesets/changelog_20260116T110615Z.xml relativeToChangelogFile: true +# - include: +# file: changesets/changelog_20260209T074419Z.xml +# relativeToChangelogFile: true From c529e1f66e888e1c7c627f44d6cc654f43677772 Mon Sep 17 00:00:00 2001 From: Caroline Jeandat Date: Mon, 9 Feb 2026 09:03:16 +0100 Subject: [PATCH 4/6] add changelog --- src/main/resources/db/changelog/db.changelog-master.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index 17f61bcc..7442be2f 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -54,6 +54,6 @@ databaseChangeLog: - include: file: changesets/changelog_20260116T110615Z.xml relativeToChangelogFile: true -# - include: -# file: changesets/changelog_20260209T074419Z.xml -# relativeToChangelogFile: true + - include: + file: changesets/changelog_20260209T074419Z.xml + relativeToChangelogFile: true From 40863e673d855c49696054bb4cdd33a289fae745 Mon Sep 17 00:00:00 2001 From: Caroline Jeandat Date: Mon, 9 Feb 2026 16:12:21 +0100 Subject: [PATCH 5/6] fix index name --- .../server/entities/ParametersContingencyListEntity.java | 2 +- .../db/changelog/changesets/changelog_20260209T074419Z.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/gridsuite/securityanalysis/server/entities/ParametersContingencyListEntity.java b/src/main/java/org/gridsuite/securityanalysis/server/entities/ParametersContingencyListEntity.java index b5c69761..1d1c7afd 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/entities/ParametersContingencyListEntity.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/entities/ParametersContingencyListEntity.java @@ -15,7 +15,7 @@ @Setter @NoArgsConstructor @Entity -@Table(name = "parameters_contingency_list", indexes = {@Index(name = "idx_security_analysis_parameters_id", columnList = "security_analysis_parameters_id")}) +@Table(name = "parameters_contingency_list", indexes = {@Index(name = "idx_security_analysis_parameters_id_contingency_lists", columnList = "security_analysis_parameters_id")}) public class ParametersContingencyListEntity { @Id diff --git a/src/main/resources/db/changelog/changesets/changelog_20260209T074419Z.xml b/src/main/resources/db/changelog/changesets/changelog_20260209T074419Z.xml index b27f509a..b78fb8f7 100644 --- a/src/main/resources/db/changelog/changesets/changelog_20260209T074419Z.xml +++ b/src/main/resources/db/changelog/changesets/changelog_20260209T074419Z.xml @@ -20,7 +20,7 @@ - + From eea3192b753944fe0c8d486aeccdd4069d1dbbed Mon Sep 17 00:00:00 2001 From: Caroline Jeandat Date: Wed, 11 Feb 2026 15:08:26 +0100 Subject: [PATCH 6/6] fix --- .../SecurityAnalysisParametersEntity.java | 11 +++++++---- .../service/SecurityAnalysisWorkerService.java | 18 +++++++++++------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisParametersEntity.java b/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisParametersEntity.java index ecc287d5..c37c913c 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisParametersEntity.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisParametersEntity.java @@ -59,8 +59,7 @@ public SecurityAnalysisParametersEntity(SecurityAnalysisParametersValues securit @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "securityAnalysisParameters") @OrderColumn(name = "index") - @Builder.Default - private List contingencyLists = new ArrayList<>(); + private List contingencyLists; // = new ArrayList<>(); @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "security_analysis_parameters_id", foreignKey = @ForeignKey(name = "securityAnalysisParametersEntity_limitReductions_fk")) @@ -112,8 +111,12 @@ private void assignContingencyLists(List contingen return entity; }) .toList(); - contingencyLists.clear(); - contingencyLists.addAll(entities); + if (contingencyLists == null) { + contingencyLists = entities; + } else { + contingencyLists.clear(); + contingencyLists.addAll(entities); + } } private void assignLimitReductions(@Nullable List> values) { diff --git a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java index d85b3a42..503cf973 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java @@ -40,6 +40,7 @@ import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; +import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -178,15 +179,18 @@ private LimitReduction createLimitReduction(IdentifiableCriterion voltageLevelCr @Override protected void preRun(SecurityAnalysisRunContext runContext) { if (runContext.getParameters().contingencyListUuids() != null) { - LOGGER.info("Run security analysis on contingency lists: {}", runContext.getParameters().contingencyListUuids()); //.stream().map(LogUtils::sanitizeParam).toList()); + LOGGER.info("Run security analysis on contingency lists: {}", runContext.getParameters().contingencyListUuids()); } - List contingencies = observer.observe("contingencies.fetch", runContext, - () -> - actionsService.getContingencyList(runContext.getParameters().contingencyListUuids(), runContext.getNetworkUuid(), runContext.getVariantId()) - ); - - runContext.setContingencies(contingencies); + try { + List contingencies = observer.observe("contingencies.fetch", runContext, + () -> + actionsService.getContingencyList(runContext.getParameters().contingencyListUuids(), runContext.getNetworkUuid(), runContext.getVariantId()) + ); + runContext.setContingencies(contingencies); + } catch (IllegalArgumentException e) { + throw new InvalidParameterException("No contingency list found in parameters to run the analysis"); + } } @Override