diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/ValidationUtil.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/ValidationUtil.java index c578d297ab3..9e81b638117 100644 --- a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/ValidationUtil.java +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/ValidationUtil.java @@ -23,6 +23,12 @@ */ public final class ValidationUtil { + public enum ActionOnError { + THROW_EXCEPTION, + LOG_ERROR, + SILENT, + } + private static final Logger LOGGER = LoggerFactory.getLogger(ValidationUtil.class); private static final String ACTIVE_POWER_SETPOINT = "active power setpoint"; @@ -63,33 +69,37 @@ private static void logError(Validable validable, String message, ReportNode rep LOGGER.error("{}{}", validable.getMessageHeader(), message); } - private static void throwExceptionOrLogError(Validable validable, String message, boolean throwException, ReportNode reportNode) { - if (throwException) { + private static void throwExceptionOrLogError(Validable validable, String message, ActionOnError throwException, ReportNode reportNode) { + if (throwException.equals(ActionOnError.THROW_EXCEPTION)) { throw new ValidationException(validable, message); } - logError(validable, message, reportNode); + if (throwException.equals(ActionOnError.LOG_ERROR)) { + logError(validable, message, reportNode); + } } public static void throwExceptionOrLogError(Validable validable, String message, ValidationLevel validationLevel, ReportNode reportNode) { - throwExceptionOrLogError(validable, message, validationLevel == ValidationLevel.STEADY_STATE_HYPOTHESIS, reportNode); + throwExceptionOrLogError(validable, message, checkValidationActionOnError(validationLevel), reportNode); } - private static void throwExceptionOrLogErrorForInvalidValue(Validable validable, double value, String valueName, boolean throwException, ReportNode reportNode) { + private static void throwExceptionOrLogErrorForInvalidValue(Validable validable, double value, String valueName, ActionOnError throwException, ReportNode reportNode) { throwExceptionOrLogErrorForInvalidValue(validable, value, valueName, null, throwException, reportNode); } - private static void throwExceptionOrLogErrorForInvalidValue(Validable validable, double value, String valueName, String reason, boolean throwException, ReportNode reportNode) { - if (throwException) { + private static void throwExceptionOrLogErrorForInvalidValue(Validable validable, double value, String valueName, String reason, ActionOnError throwException, ReportNode reportNode) { + if (throwException.equals(ActionOnError.THROW_EXCEPTION)) { throw createInvalidValueException(validable, value, valueName, reason); } - logError(validable, createInvalidValueMessage(value, valueName, reason), reportNode); + if (throwException.equals(ActionOnError.LOG_ERROR)) { + logError(validable, createInvalidValueMessage(value, valueName, reason), reportNode); + } } public static ValidationLevel checkActivePowerSetpoint(Validable validable, double activePowerSetpoint, ValidationLevel validationLevel, ReportNode reportNode) { - return checkActivePowerSetpoint(validable, activePowerSetpoint, validationLevel == ValidationLevel.STEADY_STATE_HYPOTHESIS, reportNode); + return checkActivePowerSetpoint(validable, activePowerSetpoint, checkValidationActionOnError(validationLevel), reportNode); } - private static ValidationLevel checkActivePowerSetpoint(Validable validable, double activePowerSetpoint, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkActivePowerSetpoint(Validable validable, double activePowerSetpoint, ActionOnError throwException, ReportNode reportNode) { if (Double.isNaN(activePowerSetpoint)) { throwExceptionOrLogErrorForInvalidValue(validable, activePowerSetpoint, ACTIVE_POWER_SETPOINT, throwException, reportNode); return ValidationLevel.EQUIPMENT; @@ -98,10 +108,10 @@ private static ValidationLevel checkActivePowerSetpoint(Validable validable, dou } public static ValidationLevel checkHvdcActivePowerSetpoint(Validable validable, double activePowerSetpoint, ValidationLevel validationLevel, ReportNode reportNode) { - return checkHvdcActivePowerSetpoint(validable, activePowerSetpoint, checkValidationLevel(validationLevel), reportNode); + return checkHvdcActivePowerSetpoint(validable, activePowerSetpoint, checkValidationActionOnError(validationLevel), reportNode); } - private static ValidationLevel checkHvdcActivePowerSetpoint(Validable validable, double activePowerSetpoint, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkHvdcActivePowerSetpoint(Validable validable, double activePowerSetpoint, ActionOnError throwException, ReportNode reportNode) { if (Double.isNaN(activePowerSetpoint)) { throwExceptionOrLogErrorForInvalidValue(validable, activePowerSetpoint, ACTIVE_POWER_SETPOINT, throwException, reportNode); return ValidationLevel.EQUIPMENT; @@ -118,10 +128,10 @@ public static void checkActivePowerLimits(Validable validable, double minP, doub } public static ValidationLevel checkTargetDeadband(Validable validable, String validableType, boolean regulating, double targetDeadband, ValidationLevel validationLevel, ReportNode reportNode) { - return checkTargetDeadband(validable, validableType, regulating, targetDeadband, checkValidationLevel(validationLevel), reportNode); + return checkTargetDeadband(validable, validableType, regulating, targetDeadband, checkValidationActionOnError(validationLevel), reportNode); } - private static ValidationLevel checkTargetDeadband(Validable validable, String validableType, boolean regulating, double targetDeadband, boolean throwsException, ReportNode reportNode) { + private static ValidationLevel checkTargetDeadband(Validable validable, String validableType, boolean regulating, double targetDeadband, ActionOnError throwsException, ReportNode reportNode) { if (regulating && Double.isNaN(targetDeadband)) { throwExceptionOrLogError(validable, "Undefined value for target deadband of regulating " + validableType, throwsException, reportNode); return ValidationLevel.EQUIPMENT; @@ -133,10 +143,10 @@ private static ValidationLevel checkTargetDeadband(Validable validable, String v } public static ValidationLevel checkVoltageControl(Validable validable, boolean voltageRegulatorOn, double voltageSetpoint, ValidationLevel validationLevel, ReportNode reportNode) { - return checkVoltageControl(validable, voltageRegulatorOn, voltageSetpoint, checkValidationLevel(validationLevel), reportNode); + return checkVoltageControl(validable, voltageRegulatorOn, voltageSetpoint, checkValidationActionOnError(validationLevel), reportNode); } - private static ValidationLevel checkVoltageControl(Validable validable, boolean voltageRegulatorOn, double voltageSetpoint, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkVoltageControl(Validable validable, boolean voltageRegulatorOn, double voltageSetpoint, ActionOnError throwException, ReportNode reportNode) { if (voltageRegulatorOn) { if (Double.isNaN(voltageSetpoint)) { throwExceptionOrLogErrorForInvalidValue(validable, voltageSetpoint, VOLTAGE_SETPOINT, VOLTAGE_REGULATOR_ON, throwException, reportNode); @@ -150,10 +160,10 @@ private static ValidationLevel checkVoltageControl(Validable validable, boolean } public static ValidationLevel checkVoltageControl(Validable validable, Boolean voltageRegulatorOn, double voltageSetpoint, double reactivePowerSetpoint, ValidationLevel validationLevel, ReportNode reportNode) { - return checkVoltageControl(validable, voltageRegulatorOn, voltageSetpoint, reactivePowerSetpoint, checkValidationLevel(validationLevel), reportNode); + return checkVoltageControl(validable, voltageRegulatorOn, voltageSetpoint, reactivePowerSetpoint, checkValidationActionOnError(validationLevel), reportNode); } - private static ValidationLevel checkVoltageControl(Validable validable, Boolean voltageRegulatorOn, double voltageSetpoint, double reactivePowerSetpoint, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkVoltageControl(Validable validable, Boolean voltageRegulatorOn, double voltageSetpoint, double reactivePowerSetpoint, ActionOnError throwException, ReportNode reportNode) { if (voltageRegulatorOn == null) { throw new ValidationException(validable, "voltage regulator status is not set"); } @@ -217,10 +227,10 @@ public static void checkLoadType(Validable validable, LoadType loadType) { } public static ValidationLevel checkP0(Validable validable, double p0, ValidationLevel validationLevel, ReportNode reportNode) { - return checkP0(validable, p0, checkValidationLevel(validationLevel), reportNode); + return checkP0(validable, p0, checkValidationActionOnError(validationLevel), reportNode); } - private static ValidationLevel checkP0(Validable validable, double p0, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkP0(Validable validable, double p0, ActionOnError throwException, ReportNode reportNode) { if (Double.isNaN(p0)) { throwExceptionOrLogError(validable, "p0 is invalid", throwException, reportNode); return ValidationLevel.EQUIPMENT; @@ -229,10 +239,10 @@ private static ValidationLevel checkP0(Validable validable, double p0, boolean t } public static ValidationLevel checkQ0(Validable validable, double q0, ValidationLevel validationLevel, ReportNode reportNode) { - return checkQ0(validable, q0, validationLevel == ValidationLevel.STEADY_STATE_HYPOTHESIS, reportNode); + return checkQ0(validable, q0, checkValidationActionOnError(validationLevel), reportNode); } - private static ValidationLevel checkQ0(Validable validable, double q0, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkQ0(Validable validable, double q0, ActionOnError throwException, ReportNode reportNode) { if (Double.isNaN(q0)) { throwExceptionOrLogError(validable, "q0 is invalid", throwException, reportNode); return ValidationLevel.EQUIPMENT; @@ -339,10 +349,10 @@ public static void checkMaximumSectionCount(Validable validable, int maximumSect } public static ValidationLevel checkSections(Validable validable, Integer currentSectionCount, int maximumSectionCount, ValidationLevel validationLevel, ReportNode reportNode) { - return checkSections(validable, currentSectionCount, maximumSectionCount, checkValidationLevel(validationLevel), reportNode); + return checkSections(validable, currentSectionCount, maximumSectionCount, checkValidationActionOnError(validationLevel), reportNode); } - private static ValidationLevel checkSections(Validable validable, Integer currentSectionCount, int maximumSectionCount, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkSections(Validable validable, Integer currentSectionCount, int maximumSectionCount, ActionOnError throwException, ReportNode reportNode) { checkMaximumSectionCount(validable, maximumSectionCount); if (currentSectionCount == null) { throwExceptionOrLogError(validable, "the current number of section is undefined", throwException, reportNode); @@ -377,11 +387,11 @@ public static void checkRatedU2(Validable validable, double ratedU2) { public static ValidationLevel checkSvcRegulator(Validable validable, double voltageSetpoint, double reactivePowerSetpoint, StaticVarCompensator.RegulationMode regulationMode, ValidationLevel validationLevel, ReportNode reportNode) { - return checkSvcRegulator(validable, voltageSetpoint, reactivePowerSetpoint, regulationMode, checkValidationLevel(validationLevel), reportNode); + return checkSvcRegulator(validable, voltageSetpoint, reactivePowerSetpoint, regulationMode, checkValidationActionOnError(validationLevel), reportNode); } private static ValidationLevel checkSvcRegulator(Validable validable, double voltageSetpoint, double reactivePowerSetpoint, - StaticVarCompensator.RegulationMode regulationMode, boolean throwException, ReportNode reportNode) { + StaticVarCompensator.RegulationMode regulationMode, ActionOnError throwException, ReportNode reportNode) { if (regulationMode == null) { throwExceptionOrLogError(validable, "Regulation mode is invalid", throwException, reportNode); return ValidationLevel.EQUIPMENT; @@ -418,7 +428,7 @@ public static void checkBmax(Validable validable, double bMax) { } } - private static ValidationLevel errorOrWarningForRtc(Validable validable, boolean loadTapChangingCapabilities, String message, boolean throwException, ReportNode reportNode) { + private static ValidationLevel errorOrWarningForRtc(Validable validable, boolean loadTapChangingCapabilities, String message, ActionOnError throwException, ReportNode reportNode) { if (loadTapChangingCapabilities) { throwExceptionOrLogError(validable, message, throwException, reportNode); return ValidationLevel.EQUIPMENT; @@ -434,12 +444,12 @@ private static ValidationLevel errorOrWarningForRtc(Validable validable, boolean public static ValidationLevel checkRatioTapChangerRegulation(Validable validable, boolean regulating, boolean loadTapChangingCapabilities, Terminal regulationTerminal, RatioTapChanger.RegulationMode regulationMode, double regulationValue, Network network, ValidationLevel validationLevel, ReportNode reportNode) { - return checkRatioTapChangerRegulation(validable, regulating, loadTapChangingCapabilities, regulationTerminal, regulationMode, regulationValue, network, checkValidationLevel(validationLevel), reportNode); + return checkRatioTapChangerRegulation(validable, regulating, loadTapChangingCapabilities, regulationTerminal, regulationMode, regulationValue, network, checkValidationActionOnError(validationLevel), reportNode); } private static ValidationLevel checkRatioTapChangerRegulation(Validable validable, boolean regulating, boolean loadTapChangingCapabilities, Terminal regulationTerminal, RatioTapChanger.RegulationMode regulationMode, - double regulationValue, Network network, boolean throwException, + double regulationValue, Network network, ActionOnError throwException, ReportNode reportNode) { ValidationLevel validationLevel = ValidationLevel.STEADY_STATE_HYPOTHESIS; if (regulating) { @@ -466,12 +476,12 @@ public static ValidationLevel checkPhaseTapChangerRegulation(Validable validable double regulationValue, boolean regulating, Terminal regulationTerminal, Network network, ValidationLevel validationLevel, ReportNode reportNode) { return checkPhaseTapChangerRegulation(validable, regulationMode, regulationValue, regulating, regulationTerminal, - network, checkValidationLevel(validationLevel), reportNode); + network, checkValidationActionOnError(validationLevel), reportNode); } private static ValidationLevel checkPhaseTapChangerRegulation(Validable validable, PhaseTapChanger.RegulationMode regulationMode, double regulationValue, boolean regulating, Terminal regulationTerminal, - Network network, boolean throwException, ReportNode reportNode) { + Network network, ActionOnError throwException, ReportNode reportNode) { ValidationLevel validationLevel = ValidationLevel.STEADY_STATE_HYPOTHESIS; if (regulationMode == null) { throwExceptionOrLogError(validable, "phase regulation mode is not set", throwException, reportNode); @@ -499,11 +509,11 @@ private static ValidationLevel checkPhaseTapChangerRegulation(Validable validabl public static ValidationLevel checkOnlyOneTapChangerRegulatingEnabled(Validable validable, Set> tapChangersNotIncludingTheModified, boolean regulating, ValidationLevel validationLevel, ReportNode reportNode) { - return checkOnlyOneTapChangerRegulatingEnabled(validable, tapChangersNotIncludingTheModified, regulating, checkValidationLevel(validationLevel), reportNode); + return checkOnlyOneTapChangerRegulatingEnabled(validable, tapChangersNotIncludingTheModified, regulating, checkValidationActionOnError(validationLevel), reportNode); } private static ValidationLevel checkOnlyOneTapChangerRegulatingEnabled(Validable validable, Set> tapChangersNotIncludingTheModified, - boolean regulating, boolean throwException, ReportNode reportNode) { + boolean regulating, ActionOnError throwException, ReportNode reportNode) { if (regulating && tapChangersNotIncludingTheModified.stream().anyMatch(TapChanger::isRegulating)) { throwExceptionOrLogError(validable, UNIQUE_REGULATING_TAP_CHANGER_MSG, throwException, reportNode); return ValidationLevel.EQUIPMENT; @@ -513,11 +523,11 @@ private static ValidationLevel checkOnlyOneTapChangerRegulatingEnabled(Validable public static ValidationLevel checkConvertersMode(Validable validable, HvdcLine.ConvertersMode converterMode, ValidationLevel validationLevel, ReportNode reportNode) { - return checkConvertersMode(validable, converterMode, checkValidationLevel(validationLevel), reportNode); + return checkConvertersMode(validable, converterMode, checkValidationActionOnError(validationLevel), reportNode); } private static ValidationLevel checkConvertersMode(Validable validable, HvdcLine.ConvertersMode converterMode, - boolean throwException, ReportNode reportNode) { + ActionOnError throwException, ReportNode reportNode) { if (converterMode == null) { throwExceptionOrLogError(validable, "converter mode is invalid", throwException, reportNode); return ValidationLevel.EQUIPMENT; @@ -535,11 +545,11 @@ public static void checkPowerFactor(Validable validable, double powerFactor) { public static ValidationLevel checkLoadingLimits(Validable validable, double permanentLimit, Collection temporaryLimits, ValidationLevel validationLevel, ReportNode reportNode) { - return checkLoadingLimits(validable, permanentLimit, temporaryLimits, checkValidationLevel(validationLevel), reportNode); + return checkLoadingLimits(validable, permanentLimit, temporaryLimits, checkValidationActionOnError(validationLevel), reportNode); } private static ValidationLevel checkLoadingLimits(Validable validable, double permanentLimit, Collection temporaryLimits, - boolean throwException, ReportNode reportNode) { + ActionOnError throwException, ReportNode reportNode) { ValidationLevel validationLevel = ValidationUtil.checkPermanentLimit(validable, permanentLimit, temporaryLimits, throwException, reportNode); ValidationUtil.checkTemporaryLimits(validable, permanentLimit, temporaryLimits); return validationLevel; @@ -547,11 +557,11 @@ private static ValidationLevel checkLoadingLimits(Validable validable, double pe public static ValidationLevel checkPermanentLimit(Validable validable, double permanentLimit, Collection temporaryLimits, ValidationLevel validationLevel, ReportNode reportNode) { - return checkPermanentLimit(validable, permanentLimit, temporaryLimits, checkValidationLevel(validationLevel), reportNode); + return checkPermanentLimit(validable, permanentLimit, temporaryLimits, checkValidationActionOnError(validationLevel), reportNode); } private static ValidationLevel checkPermanentLimit(Validable validable, double permanentLimit, Collection temporaryLimits, - boolean throwException, ReportNode reportNode) { + ActionOnError throwException, ReportNode reportNode) { ValidationLevel validationLevel = ValidationLevel.STEADY_STATE_HYPOTHESIS; if (Double.isNaN(permanentLimit) && !temporaryLimits.isEmpty()) { throwExceptionOrLogError(validable, "permanent limit must be defined if temporary limits are present", throwException, reportNode); @@ -588,10 +598,10 @@ private static void checkTemporaryLimits(Validable validable, double permanentLi } public static ValidationLevel checkLossFactor(Validable validable, float lossFactor, ValidationLevel validationLevel, ReportNode reportNode) { - return checkLossFactor(validable, lossFactor, checkValidationLevel(validationLevel), reportNode); + return checkLossFactor(validable, lossFactor, checkValidationActionOnError(validationLevel), reportNode); } - private static ValidationLevel checkLossFactor(Validable validable, float lossFactor, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkLossFactor(Validable validable, float lossFactor, ActionOnError throwException, ReportNode reportNode) { ValidationLevel validationLevel = ValidationLevel.STEADY_STATE_HYPOTHESIS; if (Double.isNaN(lossFactor)) { throwExceptionOrLogError(validable, "loss factor is invalid is undefined", throwException, reportNode); @@ -602,7 +612,7 @@ private static ValidationLevel checkLossFactor(Validable validable, float lossFa return validationLevel; } - private static ValidationLevel checkRtc(Validable validable, RatioTapChanger rtc, Network network, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkRtc(Validable validable, RatioTapChanger rtc, Network network, ActionOnError throwException, ReportNode reportNode) { ValidationLevel validationLevel = ValidationLevel.STEADY_STATE_HYPOTHESIS; if (rtc.findTapPosition().isEmpty()) { throwExceptionOrLogError(validable, "tap position is not set", throwException, reportNode); @@ -613,7 +623,7 @@ private static ValidationLevel checkRtc(Validable validable, RatioTapChanger rtc return validationLevel; } - private static ValidationLevel checkPtc(Validable validable, PhaseTapChanger ptc, Network network, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkPtc(Validable validable, PhaseTapChanger ptc, Network network, ActionOnError throwException, ReportNode reportNode) { ValidationLevel validationLevel = ValidationLevel.STEADY_STATE_HYPOTHESIS; if (ptc.findTapPosition().isEmpty()) { throwExceptionOrLogError(validable, "tap position is not set", throwException, reportNode); @@ -624,7 +634,7 @@ private static ValidationLevel checkPtc(Validable validable, PhaseTapChanger ptc return validationLevel; } - private static ValidationLevel checkThreeWindingsTransformer(Validable validable, ThreeWindingsTransformer twt, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkThreeWindingsTransformer(Validable validable, ThreeWindingsTransformer twt, ActionOnError throwException, ReportNode reportNode) { ValidationLevel validationLevel = ValidationLevel.STEADY_STATE_HYPOTHESIS; for (ThreeWindingsTransformer.Leg leg : twt.getLegs()) { if (leg.hasRatioTapChanger()) { @@ -653,7 +663,7 @@ private static ValidationLevel checkThreeWindingsTransformer(Validable validable return validationLevel; } - private static ValidationLevel checkTwoWindingsTransformer(Validable validable, TwoWindingsTransformer twt, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkTwoWindingsTransformer(Validable validable, TwoWindingsTransformer twt, ActionOnError throwException, ReportNode reportNode) { ValidationLevel validationLevel = ValidationLevel.STEADY_STATE_HYPOTHESIS; if (twt.hasRatioTapChanger()) { validationLevel = ValidationLevel.min(validationLevel, checkRtc(validable, twt.getRatioTapChanger(), twt.getNetwork(), throwException, reportNode)); @@ -670,7 +680,7 @@ private static ValidationLevel checkTwoWindingsTransformer(Validable validable, return validationLevel; } - private static ValidationLevel checkIdentifiable(Identifiable identifiable, ValidationLevel previous, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkIdentifiable(Identifiable identifiable, ValidationLevel previous, ActionOnError throwException, ReportNode reportNode) { ValidationLevel validationLevel = previous; if (identifiable instanceof Validable validable) { if (identifiable instanceof Battery battery) { @@ -710,7 +720,7 @@ private static ValidationLevel checkIdentifiable(Identifiable identifiable, V return validationLevel; } - private static ValidationLevel checkGenerationOnDanglingLine(ValidationLevel previous, Validable validable, DanglingLine danglingLine, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkGenerationOnDanglingLine(ValidationLevel previous, Validable validable, DanglingLine danglingLine, ActionOnError throwException, ReportNode reportNode) { ValidationLevel validationLevel = previous; DanglingLine.Generation generation = danglingLine.getGeneration(); if (generation != null) { @@ -724,7 +734,7 @@ private static Integer getSectionCount(ShuntCompensator shunt) { return shunt.findSectionCount().isPresent() ? shunt.getSectionCount() : null; } - private static ValidationLevel checkOperationalLimitsGroups(Validable validable, Collection operationalLimitsGroupCollection, ValidationLevel previous, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkOperationalLimitsGroups(Validable validable, Collection operationalLimitsGroupCollection, ValidationLevel previous, ActionOnError throwException, ReportNode reportNode) { ValidationLevel validationLevel = previous; for (OperationalLimitsGroup group : operationalLimitsGroupCollection) { validationLevel = checkOperationalLimitsGroup(validable, group, validationLevel, throwException, reportNode); @@ -732,7 +742,7 @@ private static ValidationLevel checkOperationalLimitsGroups(Validable validable, return validationLevel; } - private static ValidationLevel checkOperationalLimitsGroup(Validable validable, OperationalLimitsGroup operationalLimitsGroup, ValidationLevel previous, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkOperationalLimitsGroup(Validable validable, OperationalLimitsGroup operationalLimitsGroup, ValidationLevel previous, ActionOnError throwException, ReportNode reportNode) { ValidationLevel[] validationLevel = new ValidationLevel[1]; validationLevel[0] = previous; operationalLimitsGroup.getCurrentLimits().ifPresent(l -> validationLevel[0] = checkLoadingLimits(validable, l, validationLevel[0], throwException, reportNode)); @@ -741,11 +751,11 @@ private static ValidationLevel checkOperationalLimitsGroup(Validable validable, return validationLevel[0]; } - private static ValidationLevel checkLoadingLimits(Validable validable, LoadingLimits limits, ValidationLevel validationLevel, boolean throwException, ReportNode reportNode) { + private static ValidationLevel checkLoadingLimits(Validable validable, LoadingLimits limits, ValidationLevel validationLevel, ActionOnError throwException, ReportNode reportNode) { return ValidationLevel.min(validationLevel, checkLoadingLimits(validable, limits.getPermanentLimit(), limits.getTemporaryLimits(), throwException, reportNode)); } - public static ValidationLevel validate(Collection> identifiables, boolean allChecks, boolean throwException, ValidationLevel previous, ReportNode reportNode) { + public static ValidationLevel validate(Collection> identifiables, boolean allChecks, ActionOnError throwException, ValidationLevel previous, ReportNode reportNode) { Objects.requireNonNull(identifiables); Objects.requireNonNull(previous); Objects.requireNonNull(reportNode); @@ -766,4 +776,8 @@ private static boolean checkValidationLevel(ValidationLevel validationLevel) { return validationLevel.compareTo(ValidationLevel.STEADY_STATE_HYPOTHESIS) >= 0; } + private static ActionOnError checkValidationActionOnError(ValidationLevel validationLevel) { + return validationLevel.compareTo(ValidationLevel.STEADY_STATE_HYPOTHESIS) >= 0 ? ActionOnError.THROW_EXCEPTION : ActionOnError.SILENT; + } + } diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NetworkImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NetworkImpl.java index d131eedeacb..48ac9739269 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NetworkImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NetworkImpl.java @@ -1247,14 +1247,14 @@ public ValidationLevel runValidationChecks(boolean throwsException, ReportNode r .withUntypedValue("networkId", id) .add(); validationLevel = ValidationUtil.validate(Collections.unmodifiableCollection(index.getAll()), - true, throwsException, validationLevel != null ? validationLevel : minValidationLevel, readReportNode); + true, throwsException ? ValidationUtil.ActionOnError.THROW_EXCEPTION : ValidationUtil.ActionOnError.LOG_ERROR, validationLevel != null ? validationLevel : minValidationLevel, readReportNode); return validationLevel; } @Override public ValidationLevel getValidationLevel() { if (validationLevel == null) { - validationLevel = ValidationUtil.validate(Collections.unmodifiableCollection(index.getAll()), false, false, minValidationLevel, ReportNode.NO_OP); + validationLevel = ValidationUtil.validate(Collections.unmodifiableCollection(index.getAll()), false, ValidationUtil.ActionOnError.SILENT, minValidationLevel, ReportNode.NO_OP); } return validationLevel; } diff --git a/iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/ValidationLevelLogsTest.java b/iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/ValidationLevelLogsTest.java new file mode 100644 index 00000000000..1c9b56882af --- /dev/null +++ b/iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/ValidationLevelLogsTest.java @@ -0,0 +1,106 @@ +/** + * 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/. + * SPDX-License-Identifier: MPL-2.0 + */ + +package com.powsybl.iidm.network.impl; + +import com.powsybl.commons.report.ReportNode; +import com.powsybl.commons.test.TestUtil; +import com.powsybl.iidm.network.*; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.StringWriter; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Luma Zamarreño {@literal } + * @author José Antonio Marqués {@literal } + */ + +class ValidationLevelLogsTest { + + @Test + void equipmentAndSteadyStateTest() throws IOException { + // create a network associated with a reportNode + ReportNode reportNode = ReportNode.newRootReportNode() + .withMessageTemplate("testValidationLevelLogs", "Test validationLevel Logs") + .withUntypedValue("name", "test") + .build(); + + Network network = NetworkFactory.findDefault().createNetwork("oneLoad", "test"); + ReportNodeContext reportNodeContext = network.getReportNodeContext(); + reportNodeContext.pushReportNode(reportNode); + + // Define the network model + network.setMinimumAcceptableValidationLevel(ValidationLevel.EQUIPMENT); + createNetworkWithEquipmentValidationLevel(network); + + // We check that the SILENT option for action on error works + // While creating only network equipment if we have established validation level to EQUIPMENT, + // We should not see anything reported + assertTrue(checkReportNode(""" + Test validationLevel Logs + """, network.getReportNodeContext().getReportNode())); + + network.runValidationChecks(false, network.getReportNodeContext().getReportNode()); + + assertTrue(checkReportNode(""" + + Test validationLevel Logs + + Running validation checks on IIDM network oneLoad + p0 is invalid + p0 is invalid + """, network.getReportNodeContext().getReportNode())); + + ValidationException e = assertThrows(ValidationException.class, () -> network.setMinimumAcceptableValidationLevel(ValidationLevel.STEADY_STATE_HYPOTHESIS)); + assertTrue(e.getMessage().contains("Network 'oneLoad': Network should be corrected in order to correspond to validation level STEADY_STATE_HYPOTHESIS")); + + // Define the steady-state attributes + network.getLoads().iterator().next().setP0(10.0).setQ0(-5.0); + network.runValidationChecks(false, network.getReportNodeContext().getReportNode()); + + assertTrue(checkReportNode(""" + + Test validationLevel Logs + + Running validation checks on IIDM network oneLoad + p0 is invalid + p0 is invalid + Running validation checks on IIDM network oneLoad + """, network.getReportNodeContext().getReportNode())); + + assertEquals(ValidationLevel.STEADY_STATE_HYPOTHESIS, network.getValidationLevel()); + } + + private static boolean checkReportNode(String expected, ReportNode reportNode) throws IOException { + StringWriter sw = new StringWriter(); + reportNode.print(sw); + assertEquals(expected, TestUtil.normalizeLineSeparator(sw.toString())); + return true; + } + + public static void createNetworkWithEquipmentValidationLevel(Network network) { + Substation s1 = network.newSubstation() + .setId("S1") + .setCountry(Country.FR) + .setTso("RTE") + .setGeographicalTags("A") + .add(); + VoltageLevel vl1 = s1.newVoltageLevel() + .setId("VL1") + .setNominalV(24.0) + .setTopologyKind(TopologyKind.BUS_BREAKER) + .add(); + Bus loadBus = vl1.getBusBreakerView().newBus() + .setId("LoadBus") + .add(); + vl1.newLoad() + .setId("LOAD") + .setBus(loadBus.getId()) + .setConnectableBus(loadBus.getId()) + .add(); + } +}