From c16c77da4d0527e0f4132610eeb1e172f62cb9a9 Mon Sep 17 00:00:00 2001 From: phiedw Date: Mon, 18 Dec 2023 09:54:08 +0100 Subject: [PATCH] Move virtual-hubs to farao-core (#851) * moved virtual-hubs to farao-core * cleaned up a pom Signed-off-by: Philippe Edwards * added security around xml import of virtual hubs * fixes after review --------- Signed-off-by: Philippe Edwards Co-authored-by: OpenSuze <40593901+OpenSuze@users.noreply.github.com> --- data/crac-io/pom.xml | 2 +- data/glsk/glsk-virtual-hubs/pom.xml | 5 +- data/pom.xml | 3 +- data/virtual-hubs/pom.xml | 25 ++ data/virtual-hubs/virtual-hubs-api/pom.xml | 20 ++ .../farao/virtual_hubs/MarketArea.java | 38 +++ .../farao/virtual_hubs/VirtualHub.java | 50 ++++ .../VirtualHubsConfiguration.java | 37 +++ .../farao/virtual_hubs/MarketAreaTest.java | 49 +++ .../farao/virtual_hubs/VirtualHubTest.java | 79 +++++ .../VirtualHubsConfigurationTest.java | 51 ++++ data/virtual-hubs/virtual-hubs-json/pom.xml | 32 ++ .../json/JsonVirtualHubsConfiguration.java | 63 ++++ ...ConfigurationDeserializationException.java | 20 ++ .../VirtualHubsConfigurationDeserializer.java | 113 +++++++ .../VirtualHubsConfigurationJsonModule.java | 21 ++ ...bsConfigurationSerializationException.java | 20 ++ .../VirtualHubsConfigurationSerializer.java | 65 ++++ .../JsonVirtualHubsConfigurationTest.java | 89 ++++++ .../test/resources/invalidConfiguration.json | 3 + .../src/test/resources/invalidMarketArea.json | 7 + .../src/test/resources/invalidVirtualHub.json | 7 + .../virtualHubsConfigurationFile.json | 49 +++ .../virtual-hubs-network-assigner/pom.xml | 63 ++++ .../VirtualHubAssigner.java | 92 ++++++ .../VirtualHubAssignerTest.java | 97 ++++++ .../test/resources/12Nodes_with_Xnodes.xiidm | 283 ++++++++++++++++++ .../virtual-hubs-network-extension/pom.xml | 49 +++ .../network_extension/AssignedVirtualHub.java | 31 ++ .../AssignedVirtualHubAdder.java | 31 ++ .../AssignedVirtualHubAdderImpl.java | 56 ++++ .../AssignedVirtualHubAdderImplProvider.java | 35 +++ .../AssignedVirtualHubImpl.java | 53 ++++ .../AssignedVirtualHubXmlSerializer.java | 63 ++++ .../main/resources/xsd/assignedVirtualHub.xsd | 22 ++ .../AssignedVirtualHubTest.java | 78 +++++ .../AssignedVirtualHubXmlSerializerTest.java | 76 +++++ .../test/resources/12Nodes_with_Xnodes.xiidm | 283 ++++++++++++++++++ data/virtual-hubs/virtual-hubs-xml/pom.xml | 29 ++ .../VirtualHubsConfigProcessingException.java | 16 + .../xml/VirtualHubsConfigurationImporter.java | 68 +++++ .../xml/XmlVirtualHubsConfiguration.java | 27 ++ .../VirtualHubsConfigurationImporterTest.java | 49 +++ .../src/test/resources/truncatedFile.xml | 12 + .../virtualHubsConfigurationFile.xml | 18 ++ loopflow-computation/pom.xml | 4 - pom.xml | 11 - 47 files changed, 2373 insertions(+), 21 deletions(-) create mode 100755 data/virtual-hubs/pom.xml create mode 100755 data/virtual-hubs/virtual-hubs-api/pom.xml create mode 100644 data/virtual-hubs/virtual-hubs-api/src/main/java/com/farao_community/farao/virtual_hubs/MarketArea.java create mode 100644 data/virtual-hubs/virtual-hubs-api/src/main/java/com/farao_community/farao/virtual_hubs/VirtualHub.java create mode 100644 data/virtual-hubs/virtual-hubs-api/src/main/java/com/farao_community/farao/virtual_hubs/VirtualHubsConfiguration.java create mode 100644 data/virtual-hubs/virtual-hubs-api/src/test/java/com/farao_community/farao/virtual_hubs/MarketAreaTest.java create mode 100644 data/virtual-hubs/virtual-hubs-api/src/test/java/com/farao_community/farao/virtual_hubs/VirtualHubTest.java create mode 100644 data/virtual-hubs/virtual-hubs-api/src/test/java/com/farao_community/farao/virtual_hubs/VirtualHubsConfigurationTest.java create mode 100644 data/virtual-hubs/virtual-hubs-json/pom.xml create mode 100644 data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/JsonVirtualHubsConfiguration.java create mode 100644 data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationDeserializationException.java create mode 100644 data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationDeserializer.java create mode 100644 data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationJsonModule.java create mode 100644 data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationSerializationException.java create mode 100644 data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationSerializer.java create mode 100644 data/virtual-hubs/virtual-hubs-json/src/test/java/com/farao_community/farao/virtual_hubs/json/JsonVirtualHubsConfigurationTest.java create mode 100644 data/virtual-hubs/virtual-hubs-json/src/test/resources/invalidConfiguration.json create mode 100644 data/virtual-hubs/virtual-hubs-json/src/test/resources/invalidMarketArea.json create mode 100644 data/virtual-hubs/virtual-hubs-json/src/test/resources/invalidVirtualHub.json create mode 100644 data/virtual-hubs/virtual-hubs-json/src/test/resources/virtualHubsConfigurationFile.json create mode 100755 data/virtual-hubs/virtual-hubs-network-assigner/pom.xml create mode 100644 data/virtual-hubs/virtual-hubs-network-assigner/src/main/java/com/farao_community/farao/virtual_hubs/network_extension_builder/VirtualHubAssigner.java create mode 100644 data/virtual-hubs/virtual-hubs-network-assigner/src/test/java/com/farao_community/farao/virtual_hubs/network_extension_builder/VirtualHubAssignerTest.java create mode 100644 data/virtual-hubs/virtual-hubs-network-assigner/src/test/resources/12Nodes_with_Xnodes.xiidm create mode 100755 data/virtual-hubs/virtual-hubs-network-extension/pom.xml create mode 100644 data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHub.java create mode 100644 data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubAdder.java create mode 100644 data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubAdderImpl.java create mode 100644 data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubAdderImplProvider.java create mode 100644 data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubImpl.java create mode 100644 data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubXmlSerializer.java create mode 100644 data/virtual-hubs/virtual-hubs-network-extension/src/main/resources/xsd/assignedVirtualHub.xsd create mode 100644 data/virtual-hubs/virtual-hubs-network-extension/src/test/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubTest.java create mode 100644 data/virtual-hubs/virtual-hubs-network-extension/src/test/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubXmlSerializerTest.java create mode 100644 data/virtual-hubs/virtual-hubs-network-extension/src/test/resources/12Nodes_with_Xnodes.xiidm create mode 100644 data/virtual-hubs/virtual-hubs-xml/pom.xml create mode 100644 data/virtual-hubs/virtual-hubs-xml/src/main/java/com/farao_community/farao/virtual_hubs/xml/VirtualHubsConfigProcessingException.java create mode 100644 data/virtual-hubs/virtual-hubs-xml/src/main/java/com/farao_community/farao/virtual_hubs/xml/VirtualHubsConfigurationImporter.java create mode 100644 data/virtual-hubs/virtual-hubs-xml/src/main/java/com/farao_community/farao/virtual_hubs/xml/XmlVirtualHubsConfiguration.java create mode 100644 data/virtual-hubs/virtual-hubs-xml/src/test/java/com/farao_community/farao/virtual_hubs/xml/VirtualHubsConfigurationImporterTest.java create mode 100644 data/virtual-hubs/virtual-hubs-xml/src/test/resources/truncatedFile.xml create mode 100644 data/virtual-hubs/virtual-hubs-xml/src/test/resources/virtualHubsConfigurationFile.xml diff --git a/data/crac-io/pom.xml b/data/crac-io/pom.xml index 0c5f9ace02..22a002f499 100644 --- a/data/crac-io/pom.xml +++ b/data/crac-io/pom.xml @@ -20,4 +20,4 @@ crac-io-api crac-io-json - \ No newline at end of file + diff --git a/data/glsk/glsk-virtual-hubs/pom.xml b/data/glsk/glsk-virtual-hubs/pom.xml index ff4890e1b9..a098c6dd53 100644 --- a/data/glsk/glsk-virtual-hubs/pom.xml +++ b/data/glsk/glsk-virtual-hubs/pom.xml @@ -26,13 +26,10 @@ farao-reference-program ${project.version} - - ${project.groupId} - farao-virtual-hubs-network-extension - ${project.groupId} farao-virtual-hubs-api + ${project.version} com.powsybl diff --git a/data/pom.xml b/data/pom.xml index ac66f4bc91..6f571d6258 100755 --- a/data/pom.xml +++ b/data/pom.xml @@ -25,5 +25,6 @@ rao-result result-exporter refprog + virtual-hubs - \ No newline at end of file + diff --git a/data/virtual-hubs/pom.xml b/data/virtual-hubs/pom.xml new file mode 100755 index 0000000000..ddc36f34ab --- /dev/null +++ b/data/virtual-hubs/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + + com.farao-community.farao + farao-data + 4.7.0-SNAPSHOT + + + farao-virtual-hubs + pom + FARAO virtual hubs + Virtual hubs management for FARAO framework + + + virtual-hubs-api + virtual-hubs-json + virtual-hubs-network-assigner + virtual-hubs-network-extension + virtual-hubs-xml + + + diff --git a/data/virtual-hubs/virtual-hubs-api/pom.xml b/data/virtual-hubs/virtual-hubs-api/pom.xml new file mode 100755 index 0000000000..5bd0a98aaa --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-api/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + + com.farao-community.farao + farao-virtual-hubs + 4.7.0-SNAPSHOT + + farao-virtual-hubs-api + + + org.junit.jupiter + junit-jupiter + + + + diff --git a/data/virtual-hubs/virtual-hubs-api/src/main/java/com/farao_community/farao/virtual_hubs/MarketArea.java b/data/virtual-hubs/virtual-hubs-api/src/main/java/com/farao_community/farao/virtual_hubs/MarketArea.java new file mode 100644 index 0000000000..70eed8af1f --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-api/src/main/java/com/farao_community/farao/virtual_hubs/MarketArea.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs; + +import java.util.Objects; + +/** + * Market area description POJO + * + * @author Sebastien Murgey {@literal } + */ +public class MarketArea { + private final String code; + private final String eic; + private final boolean isMcParticipant; + + public MarketArea(String code, String eic, boolean isMcParticipant) { + this.code = Objects.requireNonNull(code, "MarketArea creation does not allow null code"); + this.eic = Objects.requireNonNull(eic, "MarketArea creation does not allow null eic"); + this.isMcParticipant = isMcParticipant; + } + + public String getCode() { + return code; + } + + public String getEic() { + return eic; + } + + public boolean isMcParticipant() { + return isMcParticipant; + } +} diff --git a/data/virtual-hubs/virtual-hubs-api/src/main/java/com/farao_community/farao/virtual_hubs/VirtualHub.java b/data/virtual-hubs/virtual-hubs-api/src/main/java/com/farao_community/farao/virtual_hubs/VirtualHub.java new file mode 100644 index 0000000000..de8b4a2dcc --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-api/src/main/java/com/farao_community/farao/virtual_hubs/VirtualHub.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs; + +import java.util.Objects; + +/** + * Virtual hub description POJO + * + * @author Sebastien Murgey {@literal } + */ +public class VirtualHub { + private final String code; + private final String eic; + private final boolean isMcParticipant; + private final String nodeName; + private final MarketArea relatedMa; + + public VirtualHub(String code, String eic, boolean isMcParticipant, String nodeName, MarketArea relatedMa) { + this.code = Objects.requireNonNull(code, "VirtualHub creation does not allow null code"); + this.eic = Objects.requireNonNull(eic, "VirtualHub creation does not allow null eic"); + this.isMcParticipant = isMcParticipant; + this.nodeName = Objects.requireNonNull(nodeName, "VirtualHub creation does not allow null nodeName"); + this.relatedMa = Objects.requireNonNull(relatedMa, "VirtualHub creation does not allow null relatedMa"); + } + + public String getCode() { + return code; + } + + public String getEic() { + return eic; + } + + public boolean isMcParticipant() { + return isMcParticipant; + } + + public String getNodeName() { + return nodeName; + } + + public MarketArea getRelatedMa() { + return relatedMa; + } +} diff --git a/data/virtual-hubs/virtual-hubs-api/src/main/java/com/farao_community/farao/virtual_hubs/VirtualHubsConfiguration.java b/data/virtual-hubs/virtual-hubs-api/src/main/java/com/farao_community/farao/virtual_hubs/VirtualHubsConfiguration.java new file mode 100644 index 0000000000..11fe642541 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-api/src/main/java/com/farao_community/farao/virtual_hubs/VirtualHubsConfiguration.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Virtual hubs configuration POJO + * + * @author Sebastien Murgey {@literal } + */ +public class VirtualHubsConfiguration { + private final List marketAreas = new ArrayList<>(); + private final List virtualHubs = new ArrayList<>(); + + public void addMarketArea(MarketArea marketArea) { + marketAreas.add(Objects.requireNonNull(marketArea, "Virtual hubs configuration does not allow adding null market area")); + } + + public void addVirtualHub(VirtualHub virtualHub) { + virtualHubs.add(Objects.requireNonNull(virtualHub, "Virtual hubs configuration does not allow adding null virtual hub")); + } + + public List getMarketAreas() { + return marketAreas; + } + + public List getVirtualHubs() { + return virtualHubs; + } +} diff --git a/data/virtual-hubs/virtual-hubs-api/src/test/java/com/farao_community/farao/virtual_hubs/MarketAreaTest.java b/data/virtual-hubs/virtual-hubs-api/src/test/java/com/farao_community/farao/virtual_hubs/MarketAreaTest.java new file mode 100644 index 0000000000..82dd6d4e0e --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-api/src/test/java/com/farao_community/farao/virtual_hubs/MarketAreaTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Sebastien Murgey {@literal } + */ +class MarketAreaTest { + @Test + public void checkThatMarketAreaIsCorrectlyCreated() { + MarketArea myMarketArea = new MarketArea("AreaCode", "AreaEic", true); + assertEquals("AreaCode", myMarketArea.getCode()); + assertEquals("AreaEic", myMarketArea.getEic()); + assertTrue(myMarketArea.isMcParticipant()); + + MarketArea myOtherMarketArea = new MarketArea("OtherAreaCode", "OtherAreaEic", false); + assertEquals("OtherAreaCode", myOtherMarketArea.getCode()); + assertEquals("OtherAreaEic", myOtherMarketArea.getEic()); + assertFalse(myOtherMarketArea.isMcParticipant()); + } + + @Test + public void checkThatMarketAreaCreationThrowsWhenCodeIsNull() { + NullPointerException thrown = assertThrows( + NullPointerException.class, + () -> new MarketArea(null, "AreaEic", true), + "Null code in MarketArea creation should throw but does not" + ); + assertEquals("MarketArea creation does not allow null code", thrown.getMessage()); + } + + @Test + public void checkThatMarketAreaCreationThrowsWhenEicIsNull() { + NullPointerException thrown = assertThrows( + NullPointerException.class, + () -> new MarketArea("AreaCode", null, true), + "Null eic in MarketArea creation should throw but does not" + ); + assertEquals("MarketArea creation does not allow null eic", thrown.getMessage()); + } +} diff --git a/data/virtual-hubs/virtual-hubs-api/src/test/java/com/farao_community/farao/virtual_hubs/VirtualHubTest.java b/data/virtual-hubs/virtual-hubs-api/src/test/java/com/farao_community/farao/virtual_hubs/VirtualHubTest.java new file mode 100644 index 0000000000..67c638035f --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-api/src/test/java/com/farao_community/farao/virtual_hubs/VirtualHubTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Sebastien Murgey {@literal } + */ +class VirtualHubTest { + @Test + public void checkThatVirtualHubIsCorrectlyCreated() { + MarketArea marketArea = new MarketArea("AreaCode", "AreaEic", true); + VirtualHub myVirtualHub = new VirtualHub("HubCode", "HubEic", true, "HubNodeName", marketArea); + assertEquals("HubCode", myVirtualHub.getCode()); + assertEquals("HubEic", myVirtualHub.getEic()); + assertTrue(myVirtualHub.isMcParticipant()); + assertEquals("HubNodeName", myVirtualHub.getNodeName()); + assertEquals(marketArea, myVirtualHub.getRelatedMa()); + + MarketArea otherMarketArea = new MarketArea("OtherAreaCode", "OtherAreaEic", false); + VirtualHub myOtherVirtualHub = new VirtualHub("OtherHubCode", "OtherHubEic", false, "OtherHubNodeName", otherMarketArea); + assertEquals("OtherHubCode", myOtherVirtualHub.getCode()); + assertEquals("OtherHubEic", myOtherVirtualHub.getEic()); + assertFalse(myOtherVirtualHub.isMcParticipant()); + assertEquals("OtherHubNodeName", myOtherVirtualHub.getNodeName()); + assertEquals(otherMarketArea, myOtherVirtualHub.getRelatedMa()); + } + + @Test + public void checkThatVirtualHubCreationThrowsWhenCodeIsNull() { + MarketArea marketArea = new MarketArea("AreaCode", "AreaEic", true); + NullPointerException thrown = assertThrows( + NullPointerException.class, + () -> new VirtualHub(null, "HubEic", true, "HubNodeName", marketArea), + "Null code in VirtualHub creation should throw but does not" + ); + assertEquals("VirtualHub creation does not allow null code", thrown.getMessage()); + } + + @Test + public void checkThatVirtualHubCreationThrowsWhenEicIsNull() { + MarketArea marketArea = new MarketArea("AreaCode", "AreaEic", true); + NullPointerException thrown = assertThrows( + NullPointerException.class, + () -> new VirtualHub("HubCode", null, true, "HubNodeName", marketArea), + "Null code in VirtualHub creation should throw but does not" + ); + assertEquals("VirtualHub creation does not allow null eic", thrown.getMessage()); + } + + @Test + public void checkThatVirtualHubCreationThrowsWhenNodeNameIsNull() { + MarketArea marketArea = new MarketArea("AreaCode", "AreaEic", true); + NullPointerException thrown = assertThrows( + NullPointerException.class, + () -> new VirtualHub("HubCode", "HubEic", true, null, marketArea), + "Null nodeName in VirtualHub creation should throw but does not" + ); + assertEquals("VirtualHub creation does not allow null nodeName", thrown.getMessage()); + } + + @Test + public void checkThatVirtualHubCreationThrowsWhenMarketAreaIsNull() { + NullPointerException thrown = assertThrows( + NullPointerException.class, + () -> new VirtualHub("HubCode", "HubEic", true, "HubNodeName", null), + "Null relatedMa in VirtualHub creation should throw but does not" + ); + assertEquals("VirtualHub creation does not allow null relatedMa", thrown.getMessage()); + } + +} diff --git a/data/virtual-hubs/virtual-hubs-api/src/test/java/com/farao_community/farao/virtual_hubs/VirtualHubsConfigurationTest.java b/data/virtual-hubs/virtual-hubs-api/src/test/java/com/farao_community/farao/virtual_hubs/VirtualHubsConfigurationTest.java new file mode 100644 index 0000000000..bf9fc8ec31 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-api/src/test/java/com/farao_community/farao/virtual_hubs/VirtualHubsConfigurationTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Sebastien Murgey {@literal } + */ +class VirtualHubsConfigurationTest { + @Test + public void checkThatConfigurationManipulationWorksAsExpected() { + VirtualHubsConfiguration configuration = new VirtualHubsConfiguration(); + MarketArea marketArea = new MarketArea("AreaCode", "AreaEic", true); + configuration.addMarketArea(marketArea); + configuration.addMarketArea(new MarketArea("OtherAreaCode", "OtherAreaEic", false)); + configuration.addVirtualHub(new VirtualHub("HubCode", "HubEic", true, "HibNodeName", marketArea)); + + assertEquals(2, configuration.getMarketAreas().size()); + assertEquals(1, configuration.getVirtualHubs().size()); + assertTrue(configuration.getMarketAreas().contains(marketArea)); + } + + @Test + public void checkThatAddingNullMarketAreaInConfigurationThrows() { + VirtualHubsConfiguration configuration = new VirtualHubsConfiguration(); + NullPointerException thrown = assertThrows( + NullPointerException.class, + () -> configuration.addMarketArea(null), + "Null market area addition in configuration should throw but does not" + ); + assertEquals("Virtual hubs configuration does not allow adding null market area", thrown.getMessage()); + } + + @Test + public void checkThatAddingNullVirtualHubInConfigurationThrows() { + VirtualHubsConfiguration configuration = new VirtualHubsConfiguration(); + NullPointerException thrown = assertThrows( + NullPointerException.class, + () -> configuration.addVirtualHub(null), + "Null virtual hub addition in configuration should throw but does not" + ); + assertEquals("Virtual hubs configuration does not allow adding null virtual hub", thrown.getMessage()); + } +} diff --git a/data/virtual-hubs/virtual-hubs-json/pom.xml b/data/virtual-hubs/virtual-hubs-json/pom.xml new file mode 100644 index 0000000000..18bc556e70 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-json/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + + com.farao-community.farao + farao-virtual-hubs + 4.7.0-SNAPSHOT + + + farao-virtual-hubs-json + + + + ${project.groupId} + farao-virtual-hubs-api + ${project.version} + + + com.fasterxml.jackson.core + jackson-databind + + + org.junit.jupiter + junit-jupiter + test + + + + diff --git a/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/JsonVirtualHubsConfiguration.java b/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/JsonVirtualHubsConfiguration.java new file mode 100644 index 0000000000..8173fc8c22 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/JsonVirtualHubsConfiguration.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.json; + +import com.farao_community.farao.virtual_hubs.VirtualHubsConfiguration; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Writer; +import java.util.Objects; + +/** + * @author Sebastien Murgey {@literal } + */ +public final class JsonVirtualHubsConfiguration { + private JsonVirtualHubsConfiguration() { + throw new AssertionError("Utility class should not be instantiated"); + } + + public static VirtualHubsConfiguration importConfiguration(InputStream inputStream) { + Objects.requireNonNull(inputStream, "Virtual hubs configuration import on null input stream is invalid"); + try { + ObjectMapper objectMapper = preparedObjectMapper(); + return objectMapper.readValue(inputStream, VirtualHubsConfiguration.class); + } catch (IOException e) { + throw new VirtualHubsConfigurationDeserializationException(e); + } + } + + public static void exportConfiguration(OutputStream outputStream, VirtualHubsConfiguration configuration) { + Objects.requireNonNull(outputStream, "Virtual hubs configuration export on null output stream is invalid"); + Objects.requireNonNull(configuration, "Virtual hubs configuration export on null configuration is invalid"); + try { + ObjectMapper objectMapper = preparedObjectMapper(); + objectMapper.writeValue(outputStream, configuration); + } catch (IOException e) { + throw new VirtualHubsConfigurationSerializationException(e); + } + } + + public static void exportConfiguration(Writer writer, VirtualHubsConfiguration configuration) { + Objects.requireNonNull(writer, "Virtual hubs configuration export on null writer is invalid"); + Objects.requireNonNull(configuration, "Virtual hubs configuration export on null configuration is invalid"); + try { + ObjectMapper objectMapper = preparedObjectMapper(); + objectMapper.writeValue(writer, configuration); + } catch (IOException e) { + throw new VirtualHubsConfigurationSerializationException(e); + } + } + + private static ObjectMapper preparedObjectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.registerModule(new VirtualHubsConfigurationJsonModule()); + return objectMapper; + } +} diff --git a/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationDeserializationException.java b/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationDeserializationException.java new file mode 100644 index 0000000000..ce6e3433d7 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationDeserializationException.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.json; + +/** + * @author Sebastien Murgey {@literal } + */ +class VirtualHubsConfigurationDeserializationException extends RuntimeException { + public VirtualHubsConfigurationDeserializationException(String message) { + super(message); + } + + public VirtualHubsConfigurationDeserializationException(Throwable cause) { + super(cause); + } +} diff --git a/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationDeserializer.java b/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationDeserializer.java new file mode 100644 index 0000000000..c4c88c1b5d --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationDeserializer.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.json; + +import com.farao_community.farao.virtual_hubs.MarketArea; +import com.farao_community.farao.virtual_hubs.VirtualHub; +import com.farao_community.farao.virtual_hubs.VirtualHubsConfiguration; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Sebastien Murgey {@literal } + */ +class VirtualHubsConfigurationDeserializer extends JsonDeserializer { + @Override + public VirtualHubsConfiguration deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + Map marketAreas = new HashMap<>(); + VirtualHubsConfiguration configuration = new VirtualHubsConfiguration(); + + while (!jsonParser.nextToken().isStructEnd()) { + switch (jsonParser.getCurrentName()) { + case "marketAreas": + deserializeMarketAreas(jsonParser, configuration, marketAreas); + break; + case "virtualHubs": + deserializeVirtualHubs(jsonParser, configuration, marketAreas); + break; + default: + throw new VirtualHubsConfigurationDeserializationException(String.format("Attribute '%s' invalid for configuration", jsonParser.getCurrentName())); + } + } + return configuration; + } + + private void deserializeMarketAreas(JsonParser jsonParser, VirtualHubsConfiguration configuration, Map marketAreas) throws IOException { + jsonParser.nextToken(); // Enter inside list and iterate on all market areas + while (!jsonParser.nextToken().isStructEnd()) { + deserializeMarketArea(jsonParser, configuration, marketAreas); + } + } + + private void deserializeVirtualHubs(JsonParser jsonParser, VirtualHubsConfiguration configuration, Map marketAreas) throws IOException { + jsonParser.nextToken(); // Enter inside list and iterate on all virtual hubs + while (!jsonParser.nextToken().isStructEnd()) { + deserializeVirtualHub(jsonParser, configuration, marketAreas); + } + } + + private void deserializeMarketArea(JsonParser jsonParser, VirtualHubsConfiguration configuration, Map marketAreas) throws IOException { + String code = null; + String eic = null; + Boolean isMcParticipant = null; + while (!jsonParser.nextToken().isStructEnd()) { + switch (jsonParser.getCurrentName()) { + case "code": + code = jsonParser.nextTextValue(); + break; + case "eic": + eic = jsonParser.nextTextValue(); + break; + case "isMcParticipant": + isMcParticipant = jsonParser.nextBooleanValue(); + break; + default: + throw new VirtualHubsConfigurationDeserializationException(String.format("Attribute '%s' invalid for market area", jsonParser.getCurrentName())); + } + } + MarketArea marketArea = new MarketArea(code, eic, isMcParticipant); + marketAreas.put(code, marketArea); + configuration.addMarketArea(marketArea); + } + + private void deserializeVirtualHub(JsonParser jsonParser, VirtualHubsConfiguration configuration, Map marketAreas) throws IOException { + String code = null; + String eic = null; + Boolean isMcParticipant = null; + String nodeName = null; + MarketArea marketArea = null; + while (!jsonParser.nextToken().isStructEnd()) { + switch (jsonParser.getCurrentName()) { + case "code": + code = jsonParser.nextTextValue(); + break; + case "eic": + eic = jsonParser.nextTextValue(); + break; + case "isMcParticipant": + isMcParticipant = jsonParser.nextBooleanValue(); + break; + case "nodeName": + nodeName = jsonParser.nextTextValue(); + break; + case "marketArea": + String marketAreaCode = jsonParser.nextTextValue(); + marketArea = marketAreas.get(marketAreaCode); + break; + default: + throw new VirtualHubsConfigurationDeserializationException(String.format("Attribute '%s' invalid for virtual hub", jsonParser.getCurrentName())); + } + } + configuration.addVirtualHub(new VirtualHub(code, eic, isMcParticipant, nodeName, marketArea)); + } +} diff --git a/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationJsonModule.java b/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationJsonModule.java new file mode 100644 index 0000000000..7006f7c66e --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationJsonModule.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.json; + +import com.farao_community.farao.virtual_hubs.VirtualHubsConfiguration; +import com.fasterxml.jackson.databind.module.SimpleModule; + +/** + * @author Sebastien Murgey {@literal } + */ +class VirtualHubsConfigurationJsonModule extends SimpleModule { + public VirtualHubsConfigurationJsonModule() { + super(); + addSerializer(VirtualHubsConfiguration.class, new VirtualHubsConfigurationSerializer()); + addDeserializer(VirtualHubsConfiguration.class, new VirtualHubsConfigurationDeserializer()); + } +} diff --git a/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationSerializationException.java b/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationSerializationException.java new file mode 100644 index 0000000000..d6cad9a9d1 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationSerializationException.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.json; + +/** + * @author Sebastien Murgey {@literal } + */ +class VirtualHubsConfigurationSerializationException extends RuntimeException { + public VirtualHubsConfigurationSerializationException(String message) { + super(message); + } + + public VirtualHubsConfigurationSerializationException(Throwable cause) { + super(cause); + } +} diff --git a/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationSerializer.java b/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationSerializer.java new file mode 100644 index 0000000000..c49ac32a4a --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-json/src/main/java/com/farao_community/farao/virtual_hubs/json/VirtualHubsConfigurationSerializer.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.json; + +import com.farao_community.farao.virtual_hubs.MarketArea; +import com.farao_community.farao.virtual_hubs.VirtualHub; +import com.farao_community.farao.virtual_hubs.VirtualHubsConfiguration; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +/** + * @author Sebastien Murgey {@literal } + */ +class VirtualHubsConfigurationSerializer extends JsonSerializer { + @Override + public void serialize(VirtualHubsConfiguration virtualHubsConfiguration, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeStartObject(); + serializeMarketAreas(virtualHubsConfiguration, jsonGenerator); + serializeVirtualHubs(virtualHubsConfiguration, jsonGenerator); + jsonGenerator.writeEndObject(); + } + + private void serializeMarketAreas(VirtualHubsConfiguration virtualHubsConfiguration, JsonGenerator jsonGenerator) throws IOException { + jsonGenerator.writeFieldName("marketAreas"); + jsonGenerator.writeStartArray(); + for (MarketArea marketArea : virtualHubsConfiguration.getMarketAreas()) { + serializeMarketArea(marketArea, jsonGenerator); + } + jsonGenerator.writeEndArray(); + } + + private void serializeMarketArea(MarketArea marketArea, JsonGenerator jsonGenerator) throws IOException { + jsonGenerator.writeStartObject(); + jsonGenerator.writeStringField("code", marketArea.getCode()); + jsonGenerator.writeStringField("eic", marketArea.getEic()); + jsonGenerator.writeBooleanField("isMcParticipant", marketArea.isMcParticipant()); + jsonGenerator.writeEndObject(); + } + + private void serializeVirtualHubs(VirtualHubsConfiguration virtualHubsConfiguration, JsonGenerator jsonGenerator) throws IOException { + jsonGenerator.writeFieldName("virtualHubs"); + jsonGenerator.writeStartArray(); + for (VirtualHub virtualHub : virtualHubsConfiguration.getVirtualHubs()) { + serializeVirtualHub(virtualHub, jsonGenerator); + } + jsonGenerator.writeEndArray(); + } + + private void serializeVirtualHub(VirtualHub virtualHub, JsonGenerator jsonGenerator) throws IOException { + jsonGenerator.writeStartObject(); + jsonGenerator.writeStringField("code", virtualHub.getCode()); + jsonGenerator.writeStringField("eic", virtualHub.getEic()); + jsonGenerator.writeBooleanField("isMcParticipant", virtualHub.isMcParticipant()); + jsonGenerator.writeStringField("nodeName", virtualHub.getNodeName()); + jsonGenerator.writeStringField("marketArea", virtualHub.getRelatedMa().getCode()); + jsonGenerator.writeEndObject(); + } +} diff --git a/data/virtual-hubs/virtual-hubs-json/src/test/java/com/farao_community/farao/virtual_hubs/json/JsonVirtualHubsConfigurationTest.java b/data/virtual-hubs/virtual-hubs-json/src/test/java/com/farao_community/farao/virtual_hubs/json/JsonVirtualHubsConfigurationTest.java new file mode 100644 index 0000000000..955e7e373f --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-json/src/test/java/com/farao_community/farao/virtual_hubs/json/JsonVirtualHubsConfigurationTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.json; + +import com.farao_community.farao.virtual_hubs.MarketArea; +import com.farao_community.farao.virtual_hubs.VirtualHub; +import com.farao_community.farao.virtual_hubs.VirtualHubsConfiguration; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.StringWriter; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Sebastien Murgey {@literal } + */ +class JsonVirtualHubsConfigurationTest { + @Test + public void checkThatCorrectConfigurationFileImportsCorrectly() { + VirtualHubsConfiguration configuration = JsonVirtualHubsConfiguration.importConfiguration(getClass().getResourceAsStream("/virtualHubsConfigurationFile.json")); + + assertEquals(3, configuration.getMarketAreas().size()); + assertEquals(4, configuration.getVirtualHubs().size()); + } + + @Test + public void checkThatConfigurationExportsCorrectlyOnOutputStream() { + VirtualHubsConfiguration configuration = new VirtualHubsConfiguration(); + MarketArea marketArea = new MarketArea("AreaCode", "AreaEic", true); + configuration.addMarketArea(marketArea); + configuration.addMarketArea(new MarketArea("OtherAreaCode", "OtherAreaEic", false)); + configuration.addVirtualHub(new VirtualHub("HubCode", "HubEic", true, "HubNodeName", marketArea)); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + JsonVirtualHubsConfiguration.exportConfiguration(baos, configuration); + + assertEquals("{\"marketAreas\":[{\"code\":\"AreaCode\",\"eic\":\"AreaEic\",\"isMcParticipant\":true},{\"code\":\"OtherAreaCode\",\"eic\":\"OtherAreaEic\",\"isMcParticipant\":false}],\"virtualHubs\":[{\"code\":\"HubCode\",\"eic\":\"HubEic\",\"isMcParticipant\":true,\"nodeName\":\"HubNodeName\",\"marketArea\":\"AreaCode\"}]}", new String(baos.toByteArray())); + } + + @Test + public void checkThatConfigurationExportsCorrectlyOnWriter() { + VirtualHubsConfiguration configuration = new VirtualHubsConfiguration(); + MarketArea marketArea = new MarketArea("AreaCode", "AreaEic", true); + configuration.addMarketArea(marketArea); + configuration.addMarketArea(new MarketArea("OtherAreaCode", "OtherAreaEic", false)); + configuration.addVirtualHub(new VirtualHub("HubCode", "HubEic", true, "HubNodeName", marketArea)); + + StringWriter writer = new StringWriter(); + JsonVirtualHubsConfiguration.exportConfiguration(writer, configuration); + + assertEquals("{\"marketAreas\":[{\"code\":\"AreaCode\",\"eic\":\"AreaEic\",\"isMcParticipant\":true},{\"code\":\"OtherAreaCode\",\"eic\":\"OtherAreaEic\",\"isMcParticipant\":false}],\"virtualHubs\":[{\"code\":\"HubCode\",\"eic\":\"HubEic\",\"isMcParticipant\":true,\"nodeName\":\"HubNodeName\",\"marketArea\":\"AreaCode\"}]}", writer.toString()); + } + + @Test + public void checkThatIncorrectConfigurationImportThrows() { + VirtualHubsConfigurationDeserializationException thrown = assertThrows( + VirtualHubsConfigurationDeserializationException.class, + () -> JsonVirtualHubsConfiguration.importConfiguration(getClass().getResourceAsStream("/invalidConfiguration.json")), + "Invalid parameter in configuration should throw" + ); + assertEquals("Attribute 'brokenParam' invalid for configuration", thrown.getMessage()); + } + + @Test + public void checkThatIncorrectMarketAreaImportThrows() { + VirtualHubsConfigurationDeserializationException thrown = assertThrows( + VirtualHubsConfigurationDeserializationException.class, + () -> JsonVirtualHubsConfiguration.importConfiguration(getClass().getResourceAsStream("/invalidMarketArea.json")), + "Invalid parameter in market area should throw" + ); + assertEquals("Attribute 'brokenParam' invalid for market area", thrown.getMessage()); + + } + + @Test + public void checkThatIncorrectVirtualHubImportThrows() { + VirtualHubsConfigurationDeserializationException thrown = assertThrows( + VirtualHubsConfigurationDeserializationException.class, + () -> JsonVirtualHubsConfiguration.importConfiguration(getClass().getResourceAsStream("/invalidVirtualHub.json")), + "Invalid parameter in virtual hub should throw" + ); + assertEquals("Attribute 'brokenParam' invalid for virtual hub", thrown.getMessage()); + } +} diff --git a/data/virtual-hubs/virtual-hubs-json/src/test/resources/invalidConfiguration.json b/data/virtual-hubs/virtual-hubs-json/src/test/resources/invalidConfiguration.json new file mode 100644 index 0000000000..54d94ee4d0 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-json/src/test/resources/invalidConfiguration.json @@ -0,0 +1,3 @@ +{ + "brokenParam" : [] +} diff --git a/data/virtual-hubs/virtual-hubs-json/src/test/resources/invalidMarketArea.json b/data/virtual-hubs/virtual-hubs-json/src/test/resources/invalidMarketArea.json new file mode 100644 index 0000000000..41a7cd444d --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-json/src/test/resources/invalidMarketArea.json @@ -0,0 +1,7 @@ +{ + "marketAreas": [ + { + "brokenParam": true + } + ] +} diff --git a/data/virtual-hubs/virtual-hubs-json/src/test/resources/invalidVirtualHub.json b/data/virtual-hubs/virtual-hubs-json/src/test/resources/invalidVirtualHub.json new file mode 100644 index 0000000000..04f15f838a --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-json/src/test/resources/invalidVirtualHub.json @@ -0,0 +1,7 @@ +{ + "virtualHubs": [ + { + "brokenParam": true + } + ] +} diff --git a/data/virtual-hubs/virtual-hubs-json/src/test/resources/virtualHubsConfigurationFile.json b/data/virtual-hubs/virtual-hubs-json/src/test/resources/virtualHubsConfigurationFile.json new file mode 100644 index 0000000000..57f58d46a1 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-json/src/test/resources/virtualHubsConfigurationFile.json @@ -0,0 +1,49 @@ +{ + "marketAreas" : [ + { + "code" : "BE", + "eic" : "10YBE----------2", + "isMcParticipant": false + }, + { + "code" : "ES", + "eic" : "10YES-REE------0", + "isMcParticipant": true + }, + { + "code" : "FR", + "eic" : "10YFR-RTE------C", + "isMcParticipant": true + } + ], + "virtualHubs" : [ + { + "code" : "Virtual_Hub_FR_1", + "eic" : "17Y000000930814J", + "isMcParticipant" : true, + "nodeName" : "XFR_ES11", + "marketArea" : "FR" + }, + { + "code" : "Virtual_Hub_FR_2", + "eic" : "17Y000000930814E", + "isMcParticipant" : false, + "nodeName" : "XFR_BE11", + "marketArea" : "FR" + }, + { + "code" : "Virtual_Hub_ES_FR", + "eic" : "17Y000000930808E", + "isMcParticipant" : true, + "nodeName" : "EFR_ES11", + "marketArea" : "ES" + }, + { + "code": "Virtual_Hub_ES_MA", + "eic": "17Y0000009308082", + "isMcParticipant": false, + "nodeName": "XMA_ES11", + "marketArea": "ES" + } + ] +} diff --git a/data/virtual-hubs/virtual-hubs-network-assigner/pom.xml b/data/virtual-hubs/virtual-hubs-network-assigner/pom.xml new file mode 100755 index 0000000000..25795c8a7d --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-assigner/pom.xml @@ -0,0 +1,63 @@ + + + 4.0.0 + + + com.farao-community.farao + farao-virtual-hubs + 4.7.0-SNAPSHOT + + + farao-virtual-hubs-network-assigner + + + + + ${project.groupId} + farao-virtual-hubs-api + ${project.version} + + + ${project.groupId} + farao-virtual-hubs-network-extension + ${project.version} + + + com.powsybl + powsybl-commons + + + com.powsybl + powsybl-iidm-api + + + org.slf4j + slf4j-api + + + + + com.powsybl + powsybl-config-test + test + + + com.powsybl + powsybl-iidm-impl + test + + + com.powsybl + powsybl-iidm-xml-converter + test + + + org.junit.jupiter + junit-jupiter + test + + + + diff --git a/data/virtual-hubs/virtual-hubs-network-assigner/src/main/java/com/farao_community/farao/virtual_hubs/network_extension_builder/VirtualHubAssigner.java b/data/virtual-hubs/virtual-hubs-network-assigner/src/main/java/com/farao_community/farao/virtual_hubs/network_extension_builder/VirtualHubAssigner.java new file mode 100644 index 0000000000..0c23e2e772 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-assigner/src/main/java/com/farao_community/farao/virtual_hubs/network_extension_builder/VirtualHubAssigner.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.network_extension_builder; + +import com.farao_community.farao.virtual_hubs.VirtualHub; +import com.farao_community.farao.virtual_hubs.network_extension.AssignedVirtualHubAdder; +import com.powsybl.iidm.network.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +/** + * @author Baptiste Seguinot {@literal } + */ +public class VirtualHubAssigner { + + private static final Logger LOGGER = LoggerFactory.getLogger(VirtualHubAssigner.class); + private List virtualHubs; + + public VirtualHubAssigner(List virtualHubs) { + this.virtualHubs = virtualHubs; + } + + public void addVirtualLoads(Network network) { + virtualHubs.forEach(vh -> addVirtualLoad(network, vh)); + } + + private void addVirtualLoad(Network network, VirtualHub virtualHub) { + + Optional bus = findBusById(network, virtualHub.getNodeName()); + if (bus.isPresent()) { + // virtual hub is on a real network node + addVirtualHubOnNewFictitiousLoad(bus.get(), virtualHub); + return; + } + + Optional danglingLine = findDanglingLineWithXNode(network, virtualHub.getNodeName()); + if (danglingLine.isPresent()) { + // virtual hub is on a Xnode which has been merged in a dangling line during network import + if (danglingLine.get().getTerminal().isConnected()) { + addVirtualHubOnNewFictitiousLoad(danglingLine.get().getTerminal().getBusBreakerView().getConnectableBus(), virtualHub); + } else { + LOGGER.warn("Virtual hub {} was not assigned on node {} as it is disconnected from the main network", virtualHub.getEic(), virtualHub.getNodeName()); + } + return; + } + + LOGGER.warn("Virtual hub {} cannot be assigned on node {} as it was not found in the network", virtualHub.getEic(), virtualHub.getNodeName()); + } + + private void addVirtualHubOnNewFictitiousLoad(Bus bus, VirtualHub virtualHub) { + // add a fictitious load to this bus + Load load = bus.getVoltageLevel().newLoad() + .setBus(bus.getId()) + .setId(virtualHub.getEic() + "_virtualLoad") + .setEnsureIdUnicity(true) + .setLoadType(LoadType.FICTITIOUS) + .setP0(0.).setQ0(0.) + .add(); + + // the virtual hub is assigned on this load + load.newExtension(AssignedVirtualHubAdder.class) + .withCode(virtualHub.getCode()) + .withEic(virtualHub.getEic()) + .withMcParticipant(virtualHub.isMcParticipant()) + .withNodeName(virtualHub.getNodeName()) + .withRelatedMa(Objects.isNull(virtualHub.getRelatedMa()) ? null : virtualHub.getRelatedMa().getCode()) + .add(); + + LOGGER.info("A fictitious load {} has been added to {} in order to assign the virtual hub {}", load.getId(), bus.getId(), virtualHub.getEic()); + } + + private Optional findBusById(Network network, String id) { + return network.getVoltageLevelStream() + .flatMap(vl -> vl.getBusBreakerView().getBusStream()) + .filter(bus -> bus.getId().equals(id)) + .findFirst(); + } + + private Optional findDanglingLineWithXNode(Network network, String xNodeId) { + return network.getDanglingLineStream() + .filter(danglingLine -> danglingLine.getPairingKey().equals(xNodeId)) + .findFirst(); + } +} diff --git a/data/virtual-hubs/virtual-hubs-network-assigner/src/test/java/com/farao_community/farao/virtual_hubs/network_extension_builder/VirtualHubAssignerTest.java b/data/virtual-hubs/virtual-hubs-network-assigner/src/test/java/com/farao_community/farao/virtual_hubs/network_extension_builder/VirtualHubAssignerTest.java new file mode 100644 index 0000000000..665fe649c2 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-assigner/src/test/java/com/farao_community/farao/virtual_hubs/network_extension_builder/VirtualHubAssignerTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.network_extension_builder; + +import com.farao_community.farao.virtual_hubs.MarketArea; +import com.farao_community.farao.virtual_hubs.VirtualHub; +import com.farao_community.farao.virtual_hubs.network_extension.AssignedVirtualHub; +import com.powsybl.iidm.network.Load; +import com.powsybl.iidm.network.Network; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Baptiste Seguinot {@literal } + */ +class VirtualHubAssignerTest { + + private Network network; + private List virtualHubs; + + @BeforeEach + void setUp() { + network = Network.read("12Nodes_with_Xnodes.xiidm", getClass().getResourceAsStream("/" + "12Nodes_with_Xnodes.xiidm")); + virtualHubs = new ArrayList<>(); + } + + @Test + void testAssignerOnRealNode() { + virtualHubs.add(new VirtualHub("code_vh1", "eic_vh1", true, "NNL2AA1 ", new MarketArea("NL", "eic_nl", true))); + new VirtualHubAssigner(virtualHubs).addVirtualLoads(network); + + Optional load = network.getLoadStream().filter(l -> l.getExtension(AssignedVirtualHub.class) != null).findFirst(); + assertTrue(load.isPresent()); + assertEquals("eic_vh1_virtualLoad", load.get().getId()); + + AssignedVirtualHub virtualHub = load.get().getExtension(AssignedVirtualHub.class); + assertEquals("eic_vh1", virtualHub.getEic()); + assertEquals("NNL2AA1 ", virtualHub.getNodeName()); + } + + @Test + void testAssignerOnXNode() { + virtualHubs.add(new VirtualHub("code_vh2", "eic_vh2", true, "X_GBFR1 ", new MarketArea("FR", "eic_fr", true))); + new VirtualHubAssigner(virtualHubs).addVirtualLoads(network); + + Optional load = network.getLoadStream().filter(l -> l.getExtension(AssignedVirtualHub.class) != null).findFirst(); + assertTrue(load.isPresent()); + assertEquals("eic_vh2_virtualLoad", load.get().getId()); + + AssignedVirtualHub virtualHub = load.get().getExtension(AssignedVirtualHub.class); + assertEquals("eic_vh2", virtualHub.getEic()); + assertEquals("X_GBFR1 ", virtualHub.getNodeName()); + } + + @Test + void testAssignerDisconnectedXNode() { + + network.getDanglingLine("FFR1AA1 X_GBFR1 1").getTerminal().disconnect(); + + virtualHubs.add(new VirtualHub("code_vh2", "eic_vh2", true, "X_GBFR1 ", new MarketArea("FR", "eic_fr", true))); + new VirtualHubAssigner(virtualHubs).addVirtualLoads(network); + + Optional load = network.getLoadStream().filter(l -> l.getExtension(AssignedVirtualHub.class) != null).findFirst(); + assertTrue(load.isEmpty()); + assertNull(network.getLoad("eic_vh2_virtualLoad")); + } + + @Test + void testAssignerOnSeveralNodes() { + virtualHubs.add(new VirtualHub("code_vh1", "eic_vh1", true, "NNL2AA1 ", new MarketArea("NL", "eic_nl", true))); + virtualHubs.add(new VirtualHub("code_vh2", "eic_vh2", true, "X_GBFR1 ", new MarketArea("FR", "eic_fr", true))); + + new VirtualHubAssigner(virtualHubs).addVirtualLoads(network); + + assertEquals(2L, network.getLoadStream().filter(l -> l.getExtension(AssignedVirtualHub.class) != null).count()); + } + + @Test + void testAssignerOnNonExistingNode() { + virtualHubs.add(new VirtualHub("code_vh3", "eic_vh3", true, "UNKNOWN_", new MarketArea("FR", "eic_fr", true))); + + new VirtualHubAssigner(virtualHubs).addVirtualLoads(network); + + Optional load = network.getLoadStream().filter(l -> l.getExtension(AssignedVirtualHub.class) != null).findFirst(); + assertFalse(load.isPresent()); + } +} diff --git a/data/virtual-hubs/virtual-hubs-network-assigner/src/test/resources/12Nodes_with_Xnodes.xiidm b/data/virtual-hubs/virtual-hubs-network-assigner/src/test/resources/12Nodes_with_Xnodes.xiidm new file mode 100644 index 0000000000..acdf6ceced --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-assigner/src/test/resources/12Nodes_with_Xnodes.xiidm @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/virtual-hubs/virtual-hubs-network-extension/pom.xml b/data/virtual-hubs/virtual-hubs-network-extension/pom.xml new file mode 100755 index 0000000000..039b1d13bf --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-extension/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + + com.farao-community.farao + farao-virtual-hubs + 4.7.0-SNAPSHOT + + + farao-virtual-hubs-network-extension + + + + + com.powsybl + powsybl-commons + + + com.powsybl + powsybl-iidm-api + + + + + com.powsybl + powsybl-config-test + test + + + com.powsybl + powsybl-iidm-impl + test + + + com.powsybl + powsybl-iidm-xml-converter + test + + + org.junit.jupiter + junit-jupiter + test + + + + diff --git a/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHub.java b/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHub.java new file mode 100644 index 0000000000..c7553a8097 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHub.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.network_extension; + +import com.powsybl.commons.extensions.Extension; +import com.powsybl.iidm.network.Injection; + +/** + * @author Baptiste Seguinot {@literal } + */ +public interface AssignedVirtualHub> extends Extension { + + @Override + default String getName() { + return "assignedVirtualHub"; + } + + String getCode(); + + String getEic(); + + boolean isMcParticipant(); + + String getNodeName(); + + String getRelatedMa(); +} diff --git a/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubAdder.java b/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubAdder.java new file mode 100644 index 0000000000..741830f40b --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubAdder.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.network_extension; + +import com.powsybl.commons.extensions.ExtensionAdder; +import com.powsybl.iidm.network.Injection; + +/** + * @author Baptiste Seguinot {@literal } + */ +public interface AssignedVirtualHubAdder> extends ExtensionAdder> { + + @Override + default Class getExtensionClass() { + return AssignedVirtualHub.class; + } + + AssignedVirtualHubAdder withCode(String code); + + AssignedVirtualHubAdder withEic(String eic); + + AssignedVirtualHubAdder withMcParticipant(boolean isMcParticipant); + + AssignedVirtualHubAdder withNodeName(String nodeName); + + AssignedVirtualHubAdder withRelatedMa(String relatedMa); +} diff --git a/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubAdderImpl.java b/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubAdderImpl.java new file mode 100644 index 0000000000..7083ed5240 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubAdderImpl.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.network_extension; + +import com.powsybl.commons.extensions.AbstractExtensionAdder; +import com.powsybl.iidm.network.Injection; + +/** + * @author Baptiste Seguinot {@literal } + */ +public class AssignedVirtualHubAdderImpl> extends AbstractExtensionAdder> implements AssignedVirtualHubAdder { + + private String code; + private String eic; + private boolean isMcParticipant; + private String nodeName; + private String relatedMa; + + public AssignedVirtualHubAdderImpl(T extendable) { + super(extendable); + } + + public AssignedVirtualHubAdder withCode(String code) { + this.code = code; + return this; + } + + public AssignedVirtualHubAdder withEic(String eic) { + this.eic = eic; + return this; + } + + public AssignedVirtualHubAdder withMcParticipant(boolean isMcParticipant) { + this.isMcParticipant = isMcParticipant; + return this; + } + + public AssignedVirtualHubAdder withNodeName(String nodeName) { + this.nodeName = nodeName; + return this; + } + + public AssignedVirtualHubAdder withRelatedMa(String relatedMa) { + this.relatedMa = relatedMa; + return this; + } + + @Override + public AssignedVirtualHubImpl createExtension(T extendable) { + return new AssignedVirtualHubImpl<>(code, eic, isMcParticipant, nodeName, relatedMa); + } +} diff --git a/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubAdderImplProvider.java b/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubAdderImplProvider.java new file mode 100644 index 0000000000..f6269c13a2 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubAdderImplProvider.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ + +package com.farao_community.farao.virtual_hubs.network_extension; + +import com.google.auto.service.AutoService; +import com.powsybl.commons.extensions.ExtensionAdderProvider; +import com.powsybl.iidm.network.Injection; + +/** + * @author Baptiste Seguinot {@literal } + */ +@AutoService(ExtensionAdderProvider.class) +public class AssignedVirtualHubAdderImplProvider> implements ExtensionAdderProvider, AssignedVirtualHubAdderImpl> { + + @Override + public String getImplementationName() { + return "Default"; + } + + @Override + public Class getAdderClass() { + return AssignedVirtualHubAdderImpl.class; + } + + @Override + public AssignedVirtualHubAdderImpl newAdder(T extendable) { + return new AssignedVirtualHubAdderImpl<>(extendable); + } + +} diff --git a/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubImpl.java b/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubImpl.java new file mode 100644 index 0000000000..4cde6342fa --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubImpl.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.network_extension; + +import com.powsybl.commons.extensions.AbstractExtension; +import com.powsybl.iidm.network.Injection; + +import java.util.Objects; + +/** + * @author Baptiste Seguinot {@literal } + */ +public class AssignedVirtualHubImpl> extends AbstractExtension implements AssignedVirtualHub { + + private final String code; + private final String eic; + private final boolean isMcParticipant; + private final String nodeName; + private final String relatedMa; + + public AssignedVirtualHubImpl(String code, String eic, boolean isMcParticipant, String nodeName, String relatedMa) { + this.code = code; + this.eic = Objects.requireNonNull(eic, "AssignedVirtualHubImpl creation does not allow null eic"); + this.isMcParticipant = isMcParticipant; + this.nodeName = nodeName; + this.relatedMa = relatedMa; + } + + public String getCode() { + return code; + } + + public String getEic() { + return eic; + } + + public boolean isMcParticipant() { + return isMcParticipant; + } + + public String getNodeName() { + return nodeName; + } + + public String getRelatedMa() { + return relatedMa; + } + +} diff --git a/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubXmlSerializer.java b/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubXmlSerializer.java new file mode 100644 index 0000000000..7580a0f928 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-extension/src/main/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubXmlSerializer.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.network_extension; + +import com.google.auto.service.AutoService; +import com.powsybl.commons.extensions.AbstractExtensionXmlSerializer; +import com.powsybl.commons.extensions.ExtensionXmlSerializer; +import com.powsybl.commons.xml.XmlReaderContext; +import com.powsybl.commons.xml.XmlWriterContext; +import com.powsybl.iidm.network.Injection; + +import javax.xml.stream.XMLStreamException; +import java.util.Objects; + +/** + * @author Baptiste Seguinot {@literal } + */ +@AutoService(ExtensionXmlSerializer.class) +public class AssignedVirtualHubXmlSerializer> extends AbstractExtensionXmlSerializer> { + + public AssignedVirtualHubXmlSerializer() { + super("assignedVirtualHub", "network", AssignedVirtualHub.class, false, + "assignedVirtualHub.xsd", + "https://farao-community.github.io/schema/iidm/ext/virtual_hub_extension/1_0", "farao"); + } + + @Override + public void write(AssignedVirtualHub assignedVirtualHub, XmlWriterContext context) throws XMLStreamException { + if (!Objects.isNull(assignedVirtualHub.getCode())) { + context.getExtensionsWriter().writeAttribute("code", assignedVirtualHub.getCode()); + } + context.getExtensionsWriter().writeAttribute("eic", assignedVirtualHub.getEic()); + context.getExtensionsWriter().writeAttribute("isMcParticipant", Boolean.toString(assignedVirtualHub.isMcParticipant())); + + if (!Objects.isNull(assignedVirtualHub.getNodeName())) { + context.getExtensionsWriter().writeAttribute("nodeName", assignedVirtualHub.getNodeName()); + } + if (!Objects.isNull(assignedVirtualHub.getRelatedMa())) { + context.getExtensionsWriter().writeAttribute("relatedMa", assignedVirtualHub.getRelatedMa()); + } + } + + @Override + public AssignedVirtualHub read(T extendable, XmlReaderContext context) { + String code = context.getReader().getAttributeValue(null, "code"); + String eic = context.getReader().getAttributeValue(null, "eic"); + String isMcParticipantAsString = context.getReader().getAttributeValue(null, "isMcParticipant"); + String nodeName = context.getReader().getAttributeValue(null, "nodeName"); + String relatedMa = context.getReader().getAttributeValue(null, "relatedMa"); + + boolean isMcParticipant = false; + if (isMcParticipantAsString.equals(Boolean.toString(true))) { + isMcParticipant = true; + } + + extendable.newExtension(AssignedVirtualHubAdder.class).withCode(code).withEic(eic).withMcParticipant(isMcParticipant).withNodeName(nodeName).withRelatedMa(relatedMa).add(); + return extendable.getExtension(AssignedVirtualHub.class); + } +} diff --git a/data/virtual-hubs/virtual-hubs-network-extension/src/main/resources/xsd/assignedVirtualHub.xsd b/data/virtual-hubs/virtual-hubs-network-extension/src/main/resources/xsd/assignedVirtualHub.xsd new file mode 100644 index 0000000000..8086bf7ee3 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-extension/src/main/resources/xsd/assignedVirtualHub.xsd @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/data/virtual-hubs/virtual-hubs-network-extension/src/test/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubTest.java b/data/virtual-hubs/virtual-hubs-network-extension/src/test/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubTest.java new file mode 100644 index 0000000000..4168b3e618 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-extension/src/test/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.network_extension; + +import com.powsybl.iidm.network.DanglingLine; +import com.powsybl.iidm.network.Generator; +import com.powsybl.iidm.network.Network; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Baptiste Seguinot {@literal } + */ +class AssignedVirtualHubTest { + + private static final String SMALL_NETWORK_FILE_NAME = "12Nodes_with_Xnodes.xiidm"; + + @Test + void testConstructor() { + AssignedVirtualHub virtualHub = new AssignedVirtualHubImpl("code", "10XAAAUDHGKAAAAS", false, "12345678", "FR"); + assertEquals("code", virtualHub.getCode()); + assertEquals("10XAAAUDHGKAAAAS", virtualHub.getEic()); + assertFalse(virtualHub.isMcParticipant()); + assertEquals("12345678", virtualHub.getNodeName()); + assertEquals("FR", virtualHub.getRelatedMa()); + } + + @Test + void testExtensionAdderOnGenerator() { + Network network = Network.read(SMALL_NETWORK_FILE_NAME, getClass().getResourceAsStream("/" + SMALL_NETWORK_FILE_NAME)); + Generator anyGenerator = network.getGenerators().iterator().next(); + + anyGenerator.newExtension(AssignedVirtualHubAdder.class) + .withCode("CODE__") + .withEic("19VDUEGOLKAAAAS") + .withMcParticipant(true) + .withNodeName("") + .withRelatedMa("BE") + .add(); + + AssignedVirtualHub virtualHub = anyGenerator.getExtension(AssignedVirtualHub.class); + + assertNotNull(virtualHub); + assertEquals("CODE__", virtualHub.getCode()); + assertEquals("19VDUEGOLKAAAAS", virtualHub.getEic()); + assertTrue(virtualHub.isMcParticipant()); + assertEquals("", virtualHub.getNodeName()); + assertEquals("BE", virtualHub.getRelatedMa()); + } + + @Test + void testExtensionAdderOnDanglingLine() { + Network network = Network.read(SMALL_NETWORK_FILE_NAME, getClass().getResourceAsStream("/" + SMALL_NETWORK_FILE_NAME)); + DanglingLine anyDanglingLine = network.getDanglingLines().iterator().next(); + + anyDanglingLine.newExtension(AssignedVirtualHubAdder.class) + .withCode("__CODE") + .withEic("19VDUEGOLKAAAAS") + .withMcParticipant(true) + .withNodeName("UCTENODE") + .withRelatedMa(null) + .add(); + + AssignedVirtualHub virtualHub = anyDanglingLine.getExtension(AssignedVirtualHub.class); + + assertNotNull(virtualHub); + assertEquals("__CODE", virtualHub.getCode()); + assertEquals("19VDUEGOLKAAAAS", virtualHub.getEic()); + assertTrue(virtualHub.isMcParticipant()); + assertEquals("UCTENODE", virtualHub.getNodeName()); + assertNull(virtualHub.getRelatedMa()); + } +} diff --git a/data/virtual-hubs/virtual-hubs-network-extension/src/test/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubXmlSerializerTest.java b/data/virtual-hubs/virtual-hubs-network-extension/src/test/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubXmlSerializerTest.java new file mode 100644 index 0000000000..3aef1ce369 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-extension/src/test/java/com/farao_community/farao/virtual_hubs/network_extension/AssignedVirtualHubXmlSerializerTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.network_extension; + +import com.powsybl.iidm.network.DanglingLine; +import com.powsybl.iidm.network.Generator; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.xml.NetworkXml; +import org.junit.jupiter.api.Test; + +import java.io.*; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Baptiste Seguinot {@literal } + */ +class AssignedVirtualHubXmlSerializerTest { + + private static final String SMALL_NETWORK_FILE_NAME = "12Nodes_with_Xnodes.xiidm"; + + @Test + void roundTripTest() { + // load network + Network originalNetwork = Network.read(SMALL_NETWORK_FILE_NAME, getClass().getResourceAsStream("/" + SMALL_NETWORK_FILE_NAME)); + + // add extensions + DanglingLine dl = originalNetwork.getDanglingLine("FFR1AA1 X_GBFR1 1"); + Generator g = originalNetwork.getGenerator("NNL1AA1 _generator"); + + dl.newExtension(AssignedVirtualHubAdder.class). + withCode("code1"). + withEic("17YXTYUDHGKAAAAS"). + withMcParticipant(true). + withNodeName("X_GBFR1 "). + withRelatedMa("FR"). + add(); + + g.newExtension(AssignedVirtualHubAdder.class). + withCode("code2"). + withEic("15XGDYRHKLKAAAAS"). + withMcParticipant(false). + withNodeName("NNL3AA1 "). + withRelatedMa(null). + add(); + + // round trip + ByteArrayOutputStream os = new ByteArrayOutputStream(); + NetworkXml.write(originalNetwork, os); + ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); + Network roundTripedNetwork = NetworkXml.read(is); + + // check results + AssignedVirtualHub avh1 = roundTripedNetwork.getDanglingLine("FFR1AA1 X_GBFR1 1").getExtension(AssignedVirtualHub.class); + AssignedVirtualHub avh2 = originalNetwork.getGenerator("NNL1AA1 _generator").getExtension(AssignedVirtualHub.class); + + assertNotNull(avh1); + assertEquals("code1", avh1.getCode()); + assertEquals("17YXTYUDHGKAAAAS", avh1.getEic()); + assertTrue(avh1.isMcParticipant()); + assertEquals("X_GBFR1 ", avh1.getNodeName()); + assertEquals("FR", avh1.getRelatedMa()); + + assertNotNull(avh2); + assertEquals("code2", avh2.getCode()); + assertEquals("15XGDYRHKLKAAAAS", avh2.getEic()); + assertFalse(avh2.isMcParticipant()); + assertEquals("NNL3AA1 ", avh2.getNodeName()); + assertNull(avh2.getRelatedMa()); + } +} + diff --git a/data/virtual-hubs/virtual-hubs-network-extension/src/test/resources/12Nodes_with_Xnodes.xiidm b/data/virtual-hubs/virtual-hubs-network-extension/src/test/resources/12Nodes_with_Xnodes.xiidm new file mode 100644 index 0000000000..acdf6ceced --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-network-extension/src/test/resources/12Nodes_with_Xnodes.xiidm @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/virtual-hubs/virtual-hubs-xml/pom.xml b/data/virtual-hubs/virtual-hubs-xml/pom.xml new file mode 100644 index 0000000000..f1c4a646df --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-xml/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + + + com.farao-community.farao + farao-virtual-hubs + 4.7.0-SNAPSHOT + + + farao-virtual-hubs-xml + + + + ${project.groupId} + farao-virtual-hubs-api + ${project.version} + + + + org.junit.jupiter + junit-jupiter-api + test + + + + diff --git a/data/virtual-hubs/virtual-hubs-xml/src/main/java/com/farao_community/farao/virtual_hubs/xml/VirtualHubsConfigProcessingException.java b/data/virtual-hubs/virtual-hubs-xml/src/main/java/com/farao_community/farao/virtual_hubs/xml/VirtualHubsConfigProcessingException.java new file mode 100644 index 0000000000..f67cd0e314 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-xml/src/main/java/com/farao_community/farao/virtual_hubs/xml/VirtualHubsConfigProcessingException.java @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.xml; + +/** + * @author Sebastien Murgey {@literal } + */ +class VirtualHubsConfigProcessingException extends RuntimeException { + public VirtualHubsConfigProcessingException(Throwable cause) { + super(cause); + } +} diff --git a/data/virtual-hubs/virtual-hubs-xml/src/main/java/com/farao_community/farao/virtual_hubs/xml/VirtualHubsConfigurationImporter.java b/data/virtual-hubs/virtual-hubs-xml/src/main/java/com/farao_community/farao/virtual_hubs/xml/VirtualHubsConfigurationImporter.java new file mode 100644 index 0000000000..4b687b4c94 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-xml/src/main/java/com/farao_community/farao/virtual_hubs/xml/VirtualHubsConfigurationImporter.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.xml; + +import com.farao_community.farao.virtual_hubs.MarketArea; +import com.farao_community.farao.virtual_hubs.VirtualHub; +import com.farao_community.farao.virtual_hubs.VirtualHubsConfiguration; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.Objects; +import java.util.TreeMap; + +/** + * @author Sebastien Murgey {@literal } + */ +class VirtualHubsConfigurationImporter { + public VirtualHubsConfiguration importConfiguration(InputStream inputStream) { + Objects.requireNonNull(inputStream, "Cannot import configuration from null input stream"); + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.parse(inputStream); + Element configurationEl = document.getDocumentElement(); + NodeList marketAreas = configurationEl.getElementsByTagName("MarketArea"); + NodeList virtualHubs = configurationEl.getElementsByTagName("VirtualHub"); + Map marketAreasMap = new TreeMap<>(); + + VirtualHubsConfiguration configuration = new VirtualHubsConfiguration(); + + for (int i = 0; i < marketAreas.getLength(); i++) { + Node node = marketAreas.item(i); + String code = node.getAttributes().getNamedItem("Code").getNodeValue(); + String eic = node.getAttributes().getNamedItem("Eic").getNodeValue(); + boolean isMcParticipant = Boolean.parseBoolean(node.getAttributes().getNamedItem("MCParticipant").getNodeValue()); + MarketArea marketArea = new MarketArea(code, eic, isMcParticipant); + marketAreasMap.put(code, marketArea); + configuration.addMarketArea(marketArea); + } + for (int i = 0; i < virtualHubs.getLength(); i++) { + Node node = virtualHubs.item(i); + String code = node.getAttributes().getNamedItem("Code").getNodeValue(); + String eic = node.getAttributes().getNamedItem("Eic").getNodeValue(); + boolean isMcParticipant = Boolean.parseBoolean(node.getAttributes().getNamedItem("MCParticipant").getNodeValue()); + String nodeName = node.getAttributes().getNamedItem("NodeName").getNodeValue(); + MarketArea marketArea = marketAreasMap.get(node.getAttributes().getNamedItem("RelatedMA").getNodeValue()); + configuration.addVirtualHub(new VirtualHub(code, eic, isMcParticipant, nodeName, marketArea)); + } + return configuration; + } catch (ParserConfigurationException | SAXException | IOException e) { + throw new VirtualHubsConfigProcessingException(e); + } + } +} diff --git a/data/virtual-hubs/virtual-hubs-xml/src/main/java/com/farao_community/farao/virtual_hubs/xml/XmlVirtualHubsConfiguration.java b/data/virtual-hubs/virtual-hubs-xml/src/main/java/com/farao_community/farao/virtual_hubs/xml/XmlVirtualHubsConfiguration.java new file mode 100644 index 0000000000..d02f4ceda7 --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-xml/src/main/java/com/farao_community/farao/virtual_hubs/xml/XmlVirtualHubsConfiguration.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.xml; + +import com.farao_community.farao.virtual_hubs.VirtualHubsConfiguration; + +import java.io.InputStream; +import java.util.Objects; + +/** + * @author Sebastien Murgey {@literal } + */ +public final class XmlVirtualHubsConfiguration { + private XmlVirtualHubsConfiguration() { + throw new AssertionError("Utility class should not be instantiated"); + } + + public static VirtualHubsConfiguration importConfiguration(InputStream inputStream) { + Objects.requireNonNull(inputStream, "Virtual hubs configuration import on null input stream is invalid"); + VirtualHubsConfigurationImporter importer = new VirtualHubsConfigurationImporter(); + return importer.importConfiguration(inputStream); + } +} diff --git a/data/virtual-hubs/virtual-hubs-xml/src/test/java/com/farao_community/farao/virtual_hubs/xml/VirtualHubsConfigurationImporterTest.java b/data/virtual-hubs/virtual-hubs-xml/src/test/java/com/farao_community/farao/virtual_hubs/xml/VirtualHubsConfigurationImporterTest.java new file mode 100644 index 0000000000..fb88f6ebea --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-xml/src/test/java/com/farao_community/farao/virtual_hubs/xml/VirtualHubsConfigurationImporterTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020, 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 https://mozilla.org/MPL/2.0/. + */ +package com.farao_community.farao.virtual_hubs.xml; + +import com.farao_community.farao.virtual_hubs.VirtualHubsConfiguration; +import org.junit.jupiter.api.Test; +import org.xml.sax.SAXException; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Sebastien Murgey {@literal } + */ +class VirtualHubsConfigurationImporterTest { + @Test + public void checkThatConfigurationFileIsCorrectlyImported() { + VirtualHubsConfigurationImporter importer = new VirtualHubsConfigurationImporter(); + VirtualHubsConfiguration configuration = importer.importConfiguration(getClass().getResourceAsStream("/virtualHubsConfigurationFile.xml")); + + assertEquals(3, configuration.getMarketAreas().size()); + assertEquals(4, configuration.getVirtualHubs().size()); + } + + @Test + public void checkThatConfigurationImportWithNullInputStreamThrows() { + VirtualHubsConfigurationImporter importer = new VirtualHubsConfigurationImporter(); + NullPointerException thrown = assertThrows( + NullPointerException.class, + () -> importer.importConfiguration(null), + "Null input stream as importConfiguration input should throw but does not" + ); + assertEquals("Cannot import configuration from null input stream", thrown.getMessage()); + } + + @Test + public void checkThatInvalidInputStreamThrowsException() { + VirtualHubsConfigurationImporter importer = new VirtualHubsConfigurationImporter(); + VirtualHubsConfigProcessingException thrown = assertThrows( + VirtualHubsConfigProcessingException.class, + () -> importer.importConfiguration(getClass().getResourceAsStream("/truncatedFile.xml")), + "Errors in XML processing should be thrown as VirtualHubsConfigProcessingException" + ); + assertTrue(thrown.getCause() instanceof SAXException); + } +} diff --git a/data/virtual-hubs/virtual-hubs-xml/src/test/resources/truncatedFile.xml b/data/virtual-hubs/virtual-hubs-xml/src/test/resources/truncatedFile.xml new file mode 100644 index 0000000000..361116bbfc --- /dev/null +++ b/data/virtual-hubs/virtual-hubs-xml/src/test/resources/truncatedFile.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/loopflow-computation/pom.xml b/loopflow-computation/pom.xml index 9921a8b904..d1a7255b46 100644 --- a/loopflow-computation/pom.xml +++ b/loopflow-computation/pom.xml @@ -36,10 +36,6 @@ farao-sensitivity-analysis ${project.version} - - ${project.groupId} - farao-virtual-hubs-network-extension - com.powsybl powsybl-glsk-commons diff --git a/pom.xml b/pom.xml index 91ddb87b65..9ef7c4a686 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,6 @@ 3.13.0 2.11.0 - 0.0.9 1.1.1 32.0.0-jre 9.5.2237 @@ -394,16 +393,6 @@ guava ${google.guava.version} - - ${project.groupId} - farao-virtual-hubs-network-extension - ${farao.virtualhubs.version} - - - ${project.groupId} - farao-virtual-hubs-api - ${farao.virtualhubs.version} - com.google.ortools ortools-java