Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.powsybl.commons.report.ReportNode;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -33,6 +34,9 @@
@ModificationErrorTypeName("COMPOSITE_MODIFICATION_ERROR")
public class CompositeModificationInfos extends ModificationInfos {

@Schema(description = "composite modification name")
private String compositeName;

@Schema(description = "composite modification list")
@JsonInclude(JsonInclude.Include.NON_NULL)
private List<ModificationInfos> modifications;
Expand All @@ -41,4 +45,12 @@ public class CompositeModificationInfos extends ModificationInfos {
public AbstractModification toModification() {
return new CompositeModification(this);
}

@Override
public ReportNode createSubReportNode(ReportNode reportNode) {
return reportNode.newReportNode()
.withMessageTemplate("network.modification.composite")
.withUntypedValue("modificationName", getCompositeName())
.add();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,44 @@
package org.gridsuite.modification.modifications;

import com.powsybl.commons.report.ReportNode;
import com.powsybl.commons.report.TypedValue;
import com.powsybl.iidm.network.Network;
import org.gridsuite.modification.dto.CompositeModificationInfos;
import org.gridsuite.modification.report.NetworkModificationReportResourceBundle;

import static org.gridsuite.modification.modifications.byfilter.AbstractModificationByAssignment.VALUE_KEY_ERROR_MESSAGE;

/**
* @author Ghazwa Rehili <ghazwa.rehili at rte-france.com>
*/
public class CompositeModification extends AbstractModification {

private final CompositeModificationInfos compositeModificationInfos;

public CompositeModification(CompositeModificationInfos compositeModificationInfos) {
this.compositeModificationInfos = compositeModificationInfos;
}

@Override
public void apply(Network network, ReportNode subReportNode) {
throw new UnsupportedOperationException();
compositeModificationInfos.getModifications().forEach(
modif -> {
ReportNode modifNode = modif.createSubReportNode(subReportNode);
try {
modif.toModification().apply(network, modifNode);
} catch (Exception e) {
// in case of error in a network modification, the composite modification doesn't interrupt its execution :
// the following modifications will be carried out
modifNode.newReportNode()
.withResourceBundles(NetworkModificationReportResourceBundle.BASE_NAME)
.withMessageTemplate("network.modification.compositeReportException")
.withUntypedValue("modificationName", modif.toModification().getName())
.withUntypedValue(VALUE_KEY_ERROR_MESSAGE, e.getMessage())
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
}
);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ network.modification.noLimitSetSelectedOnSide1 = No limit set selected on side 1
network.modification.noLimitSetSelectedOnSide2 = No limit set selected on side 2
network.modification.limitSetAbsentOnSide1 = limit set '${selectedOperationalLimitsGroup}' on side 1 does not exist
network.modification.limitSetAbsentOnSide2 = limit set '${selectedOperationalLimitsGroup}' on side 2 does not exist
network.modification.composite = Composite modification : '${modificationName}'
network.modification.compositeReportException = Cannot execute ${modificationName} : ${errorMessage}
network.modification.applicabilityChanged = limit set ${operationalLimitsGroupName} applicability changed to ${applicability}
network.modification.limits = Limits
network.modification.activeLimitsSets = Active limits sets
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@
*/
package org.gridsuite.modification.modifications;

import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.iidm.network.Generator;
import com.powsybl.iidm.network.LoadType;
import com.powsybl.iidm.network.Network;

import org.gridsuite.modification.ModificationType;
import org.gridsuite.modification.dto.CompositeModificationInfos;
import org.gridsuite.modification.dto.ModificationInfos;
import org.gridsuite.modification.dto.*;
import org.gridsuite.modification.report.NetworkModificationReportResourceBundle;
import org.gridsuite.modification.utils.ModificationCreation;
import org.gridsuite.modification.utils.NetworkCreation;
import java.util.List;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.gridsuite.modification.utils.TestUtils.*;
import static org.junit.jupiter.api.Assertions.*;

/**
* @author Ghazwa Rehili <ghazwa.rehili at rte-france.com>
Expand All @@ -27,13 +31,48 @@ class CompositeModificationsTest extends AbstractNetworkModificationTest {

@Override
public void checkModification() {
Network network = getNetwork();
CompositeModificationInfos compositeModificationInfos = (CompositeModificationInfos) buildModification();

// checks that the sub sub sub netmod is executed at the right depth
ReportNode report = compositeModificationInfos.createSubReportNode(ReportNode.newRootReportNode()
.withResourceBundles(NetworkModificationReportResourceBundle.BASE_NAME)
.withMessageTemplate("test")
.build());
CompositeModification netmod = (CompositeModification) compositeModificationInfos.toModification();
assertDoesNotThrow(() -> netmod.apply(network, report));
assertLogMessageAtDepth(
"Generator with id=idGenerator modified :",
"network.modification.generatorModification",
report,
4
);
assertLogMessageAtDepth(
"Composite modification : 'sub sub composite'",
"network.modification.composite",
report,
2
);

// regular throwing exception netmod
GeneratorCreation throwingExceptionNetMod = (GeneratorCreation) buildThrowingModification().toModification();
assertThrows(PowsyblException.class, () -> throwingExceptionNetMod.apply(network));
// but doesn't throw once inside a composite modification
compositeModificationInfos.setModifications(List.of(buildThrowingModification()));
CompositeModification netmodContainingError = (CompositeModification) compositeModificationInfos.toModification();
assertDoesNotThrow(() -> netmodContainingError.apply(network, report));
// but the thrown message is inside the report :
assertLogMessageWithoutRank(
"Cannot execute GeneratorCreation : The network " + getNetwork().getId() + " already contains an object 'GeneratorImpl' with the id 'idGenerator'",
"network.modification.compositeReportException",
report
);
}

@Override
public void testApply() throws Exception {
CompositeModificationInfos compositeModificationInfos = (CompositeModificationInfos) buildModification();
compositeModificationInfos.getModifications().forEach(modificationInfos -> modificationInfos.toModification().apply(getNetwork()));
assertAfterNetworkModificationApplication();
private GeneratorCreationInfos buildThrowingModification() {
return ModificationCreation.getCreationGenerator(
"v1", "idGenerator", "nameGenerator", "1B", "v2load", "LOAD", "v1"
);
}

@Override
Expand All @@ -44,19 +83,44 @@ protected Network createNetwork(UUID networkUuid) {
@Override
protected ModificationInfos buildModification() {
List<ModificationInfos> modifications = List.of(
ModificationCreation.getCreationGenerator("v1", "idGenerator", "nameGenerator", "1B", "v2load", "LOAD",
"v1"),
CompositeModificationInfos.builder()
.compositeName("sub composite 1")
.modifications(
List.of(
ModificationCreation.getModificationGenerator("idGenerator", "other idGenerator name"),
// this should throw an error but not stop the execution of the composite modification and all the other content
buildThrowingModification()
)
).build(),
ModificationCreation.getModificationGenerator("idGenerator", "new idGenerator name"),
ModificationCreation.getCreationLoad("v1", "idLoad", "nameLoad", "1.1", LoadType.UNDEFINED),
ModificationCreation.getCreationBattery("v1", "idBattery", "nameBattry", "1.1"));
ModificationCreation.getCreationBattery("v1", "idBattery", "nameBattery", "1.1"),
// test of a composite modification inside a composite modification inside a composite modification
CompositeModificationInfos.builder()
.compositeName("sub composite 2")
.modifications(
List.of(
CompositeModificationInfos.builder()
.compositeName("sub sub composite")
.modifications(
List.of(ModificationCreation.getModificationGenerator("idGenerator", "other idGenerator name again"))
).build(),
ModificationCreation.getModificationGenerator("idGenerator", "even newer idGenerator name")
)
).build()
);
return CompositeModificationInfos.builder()
.compositeName("main composite")
.modifications(modifications)
.stashed(false)
.build();
}

@Override
protected void assertAfterNetworkModificationApplication() {
assertNotNull(getNetwork().getGenerator("idGenerator"));
Generator gen = getNetwork().getGenerator("idGenerator");
assertNotNull(gen);
assertEquals("even newer idGenerator name", gen.getOptionalName().orElseThrow());
assertNotNull(getNetwork().getLoad("idLoad"));
assertNotNull(getNetwork().getBattery("idBattery"));
}
Expand Down
28 changes: 28 additions & 0 deletions src/test/java/org/gridsuite/modification/utils/TestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ public static void assertLogNthMessage(String expectedMessage, String reportKey,
assertEquals(expectedMessage, message.get().trim());
}

public static void assertLogMessageAtDepth(String expectedMessage, String reportKey, ReportNode reportNode, int depth) {
Optional<String> message = getMessageFromReporterAtDepth(reportKey, reportNode, 1, depth);
assertTrue(message.isPresent());
assertEquals(expectedMessage, message.get().trim());
}

public static void assertLogMessage(String expectedMessage, String reportKey, ReportNode reportNode) {
assertLogNthMessage(expectedMessage, reportKey, reportNode, 1);
}
Expand Down Expand Up @@ -85,6 +91,28 @@ private static boolean assertMessageFoundFromReporter(String expectedMessage, St
return foundInSubReporters;
}

private static Optional<String> getMessageFromReporterAtDepth(String reportKey, ReportNode reporterModel, int currentDepth, int expectedDepth) {
Optional<String> message = Optional.empty();

Iterator<ReportNode> reportersIterator = reporterModel.getChildren().iterator();
while (message.isEmpty() && reportersIterator.hasNext() && currentDepth < expectedDepth) {
message = getMessageFromReporterAtDepth(reportKey, reportersIterator.next(), currentDepth + 1, expectedDepth);
}

Iterator<ReportNode> reportsIterator = reporterModel.getChildren().iterator();
while (message.isEmpty() && reportsIterator.hasNext()) {
ReportNode report = reportsIterator.next();
if (currentDepth == expectedDepth && report.getMessageKey().equals(reportKey)) {
message = Optional.of(formatReportMessage(report, reporterModel));
}
}

return message;
}

/**
* @param rank order position inside reporterModel
*/
private static Optional<String> getMessageFromReporter(String reportKey, ReportNode reporterModel, int rank) {
Optional<String> message = Optional.empty();

Expand Down