From 4aae9d2fb389b94b01bceb27985edd3fd4f830c9 Mon Sep 17 00:00:00 2001 From: BOUHOURS Antoine Date: Tue, 19 May 2026 11:35:10 +0200 Subject: [PATCH] Temporary fix to handle "null" subject names in security analysis result --- .../SecurityAnalysisResultEntity.java | 7 ++- .../SecurityAnalysisResultEntityTest.java | 49 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisResultEntityTest.java diff --git a/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisResultEntity.java b/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisResultEntity.java index 470fe5fe..a590ccf6 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisResultEntity.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/entities/SecurityAnalysisResultEntity.java @@ -94,9 +94,14 @@ private static List getUniqueSubjectLimitViolations return Stream.concat( securityAnalysisResult.getPostContingencyResults().stream().flatMap(pcr -> pcr.getLimitViolationsResult().getLimitViolations().stream()), securityAnalysisResult.getPreContingencyResult().getLimitViolationsResult().getLimitViolations().stream()) - .map(lm -> new Pair<>(lm.getSubjectId(), lm.getSubjectName())) + .map(lm -> new Pair<>(lm.getSubjectId(), normalizeSubjectName(lm.getSubjectName()))) .distinct() .map(pair -> new SubjectLimitViolationEntity(pair.getFirst(), pair.getSecond())) .toList(); } + + // FIXME: powsybl limit violation detection may expose missing names as "null" instead of null. Method to remove when https://github.com/powsybl/powsybl-core/pull/3922 is merged + private static String normalizeSubjectName(String subjectName) { + return "null".equals(subjectName) ? null : subjectName; + } } diff --git a/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisResultEntityTest.java b/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisResultEntityTest.java new file mode 100644 index 00000000..e97612f0 --- /dev/null +++ b/src/test/java/org/gridsuite/securityanalysis/server/SecurityAnalysisResultEntityTest.java @@ -0,0 +1,49 @@ +/** + * 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.securityanalysis.server; + +import com.powsybl.contingency.violations.LimitViolation; +import com.powsybl.contingency.violations.LimitViolationType; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.TwoSides; +import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; +import com.powsybl.loadflow.LoadFlowResult; +import com.powsybl.network.store.iidm.impl.NetworkFactoryImpl; +import com.powsybl.security.LimitViolationsResult; +import com.powsybl.security.SecurityAnalysisResult; +import org.gridsuite.securityanalysis.server.dto.SecurityAnalysisStatus; +import org.gridsuite.securityanalysis.server.entities.SecurityAnalysisResultEntity; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.UUID; + +import static com.powsybl.iidm.network.test.EurostagTutorialExample1Factory.NHV1_NHV2_1; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Antoine Bouhours + */ +class SecurityAnalysisResultEntityTest { + + @Test + void toEntityNormalizesStringNullSubjectNames() { + Network network = EurostagTutorialExample1Factory.create(new NetworkFactoryImpl()); + SecurityAnalysisResult securityAnalysisResult = new SecurityAnalysisResult( + new LimitViolationsResult(List.of( + new LimitViolation(NHV1_NHV2_1, null, LimitViolationType.CURRENT, "10'", 600, 1000, 1, 1100, TwoSides.ONE), + new LimitViolation(NHV1_NHV2_1, "null", LimitViolationType.CURRENT, "10'", 600, 1000, 1, 1100, TwoSides.ONE) + )), + LoadFlowResult.ComponentResult.Status.CONVERGED, + List.of() + ); + + SecurityAnalysisResultEntity entity = SecurityAnalysisResultEntity.toEntity(network, UUID.randomUUID(), securityAnalysisResult, SecurityAnalysisStatus.CONVERGED); + + assertThat(entity.getSubjectLimitViolations()).hasSize(1); + } +}