diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Importer.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Importer.java index bf18803ba0c..5828fc5dcfa 100644 --- a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Importer.java +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Importer.java @@ -346,4 +346,27 @@ default Network importData(ReadOnlyDataSource dataSource, NetworkFactory network default void copy(ReadOnlyDataSource fromDataSource, DataSource toDataSource) { throw new UnsupportedOperationException("Copy not implemented"); } + + /** + * Update a given network with contents coming from a data source. + * + * @param network network + * @param dataSource data source + * @param parameters some properties to configure the import + * @param reportNode the reportNode used for functional logs + */ + default void update(Network network, ReadOnlyDataSource dataSource, Properties parameters, ReportNode reportNode) { + update(network, dataSource, parameters); + } + + /** + * Update a given network with contents coming from a data source. + * + * @param network network + * @param dataSource data source + * @param parameters some properties to configure the import + */ + default void update(Network network, ReadOnlyDataSource dataSource, Properties parameters) { + throw new UnsupportedOperationException("Importer do not implement updates"); + } } diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Network.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Network.java index 8197882ca70..764c862e2a3 100644 --- a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Network.java +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Network.java @@ -401,6 +401,29 @@ static void readAll(Path dir, Consumer consumer) throws IOException, In readAll(dir, false, LocalComputationManager.getDefault(), ImportConfig.CACHE.get(), consumer); } + default void update(ReadOnlyDataSource dataSource) { + update(dataSource, null); + } + + default void update(ReadOnlyDataSource dataSource, Properties properties) { + update(dataSource, properties, ReportNode.NO_OP); + } + + default void update(ReadOnlyDataSource dataSource, Properties parameters, ReportNode reportNode) { + update(dataSource, LocalComputationManager.getDefault(), ImportConfig.load(), parameters, + new ImportersServiceLoader(), reportNode); + } + + default void update(ReadOnlyDataSource dataSource, ComputationManager computationManager, ImportConfig config, Properties parameters, + ImportersLoader loader, ReportNode reportNode) { + Importer importer = Importer.find(dataSource, loader, computationManager, config); + if (importer != null) { + importer.update(this, dataSource, parameters, reportNode); + } else { + throw new PowsyblException(Importers.UNSUPPORTED_FILE_FORMAT_OR_INVALID_FILE); + } + } + /** * A global bus/breaker view of the network. *

diff --git a/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/ImportersTest.java b/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/ImportersTest.java index 1c9ffe57b63..57812654c29 100644 --- a/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/ImportersTest.java +++ b/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/ImportersTest.java @@ -50,6 +50,7 @@ class ImportersTest extends AbstractConvertersTest { private final NetworkFactory networkFactory = new NetworkFactoryMock(); @BeforeEach + @Override void setUp() throws IOException { super.setUp(); Files.createFile(fileSystem.getPath(WORK_DIR + FOO_TST)); @@ -227,5 +228,18 @@ void loadNetworks() throws InterruptedException, ExecutionException, IOException assertEquals(2, isLoadPresent.size()); isLoadPresent.forEach(Assertions::assertTrue); } + + @Test + void updateNetwork() { + Network network = Network.read(path, computationManager, importConfigMock, null, networkFactory, loader, ReportNode.NO_OP); + assertNotNull(network); + Load load = network.getLoad("LOAD"); + assertNotNull(load); + + // The mocked network simulates P0 is not set in first import, but is read when we call update + assertTrue(Double.isNaN(load.getP0())); + network.update(DataSource.fromPath(path)); + assertEquals(123.0, load.getP0()); + } } diff --git a/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/NetworkFactoryMock.java b/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/NetworkFactoryMock.java index f4eafe5c307..6958187fb7d 100644 --- a/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/NetworkFactoryMock.java +++ b/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/NetworkFactoryMock.java @@ -9,6 +9,11 @@ import java.time.ZoneOffset; import java.time.ZonedDateTime; +import java.util.Properties; + +import com.powsybl.commons.datasource.ReadOnlyDataSource; +import com.powsybl.commons.report.ReportNode; +import com.powsybl.computation.ComputationManager; import org.mockito.Mockito; /** @@ -34,6 +39,33 @@ public Network createNetwork(String id, String sourceFormat) { Mockito.when(load.getLoadType()) .thenAnswer(invocationOnMock -> loadType[0]); + // When called to be updated, rely on default method, that will call importer + Mockito.doCallRealMethod().when(network).update( + Mockito.any(ReadOnlyDataSource.class), + Mockito.any(ComputationManager.class), + Mockito.any(ImportConfig.class), + Mockito.nullable(Properties.class), + Mockito.any(ImportersLoader.class), + Mockito.any(ReportNode.class)); + Mockito.doCallRealMethod().when(network).update( + Mockito.any(ReadOnlyDataSource.class), + Mockito.nullable(Properties.class), + Mockito.any(ReportNode.class)); + Mockito.doCallRealMethod().when(network).update( + Mockito.any(ReadOnlyDataSource.class), + Mockito.nullable(Properties.class)); + Mockito.doCallRealMethod().when(network).update( + Mockito.any(ReadOnlyDataSource.class)); + // Allow setting a value for P0 + double[] loadP = new double[1]; + loadP[0] = Double.NaN; + Mockito.doAnswer(invocationOnMock -> { + loadP[0] = (double) invocationOnMock.getArguments()[0]; + return load; + }).when(load).setP0(Mockito.anyDouble()); + Mockito.when(load.getP0()) + .thenAnswer(invocationOnMock -> loadP[0]); + return network; } diff --git a/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/TestImporter.java b/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/TestImporter.java index 76f2c0b55a5..15ba6d72390 100644 --- a/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/TestImporter.java +++ b/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/TestImporter.java @@ -56,4 +56,19 @@ public Network importData(ReadOnlyDataSource dataSource, NetworkFactory networkF } return networkFactory.createNetwork("mock", "test"); } + + @Override + public void update(Network network, ReadOnlyDataSource dataSource, Properties parameters, ReportNode reportNode) { + if (reportNode != null) { + reportNode.newReportNode() + .withMessageTemplate("test", "Update model ${model}") + .withUntypedValue("model", "eurostagTutorialExample1") + .add(); + } + // Update a load in the network + Load load = network.getLoad("LOAD"); + if (load != null) { + load.setP0(123.0); + } + } }