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/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/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..24b68301 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 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 99c2892b..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,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 +@Setter +@NoArgsConstructor +@Entity +@Table(name = "parameters_contingency_list", indexes = {@Index(name = "idx_security_analysis_parameters_id_contingency_lists", 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 13aed58d..c37c913c 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,11 +57,25 @@ public SecurityAnalysisParametersEntity(SecurityAnalysisParametersValues securit @Column(name = "flowProportionalThreshold") private double flowProportionalThreshold; + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "securityAnalysisParameters") + @OrderColumn(name = "index") + private List contingencyLists; // = new ArrayList<>(); + @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(ParametersContingencyListEntity::isActivated) + .flatMap(contingencyList -> contingencyList.getContingenciesIds().stream()) + .toList(); + } + public List> toLimitReductionsValues() { return this.limitReductions.stream().map(LimitReductionEntity::getReductions).map(ArrayList::new).collect(Collectors.toList()); } @@ -75,9 +91,34 @@ private void assignAttributes(SecurityAnalysisParametersValues securityAnalysisP this.highVoltageProportionalThreshold = securityAnalysisParametersValues.getHighVoltageProportionalThreshold(); this.lowVoltageAbsoluteThreshold = securityAnalysisParametersValues.getLowVoltageAbsoluteThreshold(); this.lowVoltageProportionalThreshold = securityAnalysisParametersValues.getLowVoltageProportionalThreshold(); + 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(); + if (contingencyLists == null) { + contingencyLists = entities; + } else { + contingencyLists.clear(); + contingencyLists.addAll(entities); + } + } + private void assignLimitReductions(@Nullable List> values) { if (values == null) { return; @@ -95,4 +136,3 @@ public void updateProvider(String provider) { this.provider = provider; } } - 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/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 d2f16aef..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,11 +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<>(); - 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; } @@ -69,7 +73,6 @@ public SecurityAnalysisRunContext createRunContext(UUID networkUuid, String vari return new SecurityAnalysisRunContext( networkUuid, variantId, - runContextParametersInfos.getContingencyListNames(), receiver, providerToUse, parameters, @@ -81,18 +84,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) + .contingencyListUuids(activatedContingencyListUuids) + .limitReductions(limitReductions) + .build(); } public SecurityAnalysisParametersValues toSecurityAnalysisParametersValues(SecurityAnalysisParametersEntity entity) { @@ -103,6 +112,12 @@ public SecurityAnalysisParametersValues toSecurityAnalysisParametersValues(Secur .highVoltageProportionalThreshold(entity.getHighVoltageProportionalThreshold()) .lowVoltageAbsoluteThreshold(entity.getLowVoltageAbsoluteThreshold()) .lowVoltageProportionalThreshold(entity.getLowVoltageProportionalThreshold()) + .contingencyLists(entity.getContingencyLists().stream() + .map(c -> new ParametersContingencyListDTO( + parametersContingenciesService.toDTO(c.getContingenciesIds()), + c.getDescription(), + c.isActivated())) + .toList()) .limitReductions(getLimitReductionsForProvider(entity).orElse(null)) .build(); } @@ -134,6 +149,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..503cf973 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; @@ -41,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,14 +178,19 @@ 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()); - - List contingencies = observer.observe("contingencies.fetch", runContext, - () -> - actionsService.getContingencyList(runContext.getContingencyListNames(), runContext.getNetworkUuid(), runContext.getVariantId()) - ); + if (runContext.getParameters().contingencyListUuids() != null) { + LOGGER.info("Run security analysis on contingency lists: {}", runContext.getParameters().contingencyListUuids()); + } - 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 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 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..b78fb8f7 --- /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..7442be2f 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 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());