From f62ee89f6a16b2e58a010ac4181e6a0f55966b64 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Tue, 24 Aug 2021 11:49:47 +0200 Subject: [PATCH 01/29] Fix Switch type mapping. Signed-off-by: Dennis Labordus --- MAPPING.md | 51 +++++++++++++++++-- .../cim/mapping/mapper/CimToSclMapper.java | 14 ++++- .../compas/cim/mapping/model/SwitchType.java | 8 +-- .../service/CompasCimMappingService.java | 2 +- .../mapping/mapper/CimToSclMapperTest.java | 35 +++++++++++-- .../cim/mapping/model/SwitchTypeTest.java | 2 +- 6 files changed, 93 insertions(+), 19 deletions(-) diff --git a/MAPPING.md b/MAPPING.md index 3634531..a16cd16 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -24,12 +24,14 @@ There is an IEC document describing the mapping, namely IEC/TS 62361-102, but no | -------------------------------- | -------------------------------- | --------- | | *cim:VoltageLevel* | *TVoltageLevel* | | | name or id | name | | +| '0' | nomFreq | (1) | | nominalV | voltage.value | | | 'k' | voltage.multiplier | | | 'V' | voltage.unit | | -| List<Bay> | List<TBay> | (1) | +| List<Bay> | List<TBay> | (2) | -(1): The list of Bays that belong to the VoltageLevel. +(1): The nomFreq will be set to 0 if there is a Switch connected to it of the type 'DCLineSegment'. +(2): The list of Bays that belong to the VoltageLevel. | CIM Class | IEC Class | Remark | | -------------------------------- | -------------------------------- | --------- | @@ -62,8 +64,9 @@ ConnectivityNode. | List<cim:Terminal> | List<TTerminal> | (3) | (1): Switches in IEC CIM can be the following types, cim:Switch cim:Breaker cim:Disconnector cim:LoadBreakSwitch cim: -ProtectedSwitch.These classes are all mapped in the same way on IEC 61850 -(2): The mapping between types is described in 5.6.2 of IEC/TS 62361-102. +ProtectedSwitch.These classes are all mapped in the same way on IEC 61850 +(2): The mapping between types is described in 5.6.2 of IEC/TS 62361-102. Below is a table describing how the mapper +implements this mapping. (3): The list of Terminal that belong to the Switch. | CIM Class | IEC Class | Remark | @@ -75,3 +78,43 @@ ProtectedSwitch.These classes are all mapped in the same way on IEC 61850 (1): Use the ID of the ConnectivityNode to find the name or pathName of that ConnectivityNode. A map is saved of all ConnectivityNode that are processed for each Bay. + +## Mapping from Cim Switch Type to IEC TConductingEquipment + +| IEC 61850 Type | CIM Type | +| --------------- | --------------------- | +| BSH | Connector | +| CAB | ACLineSegment | +| CAB | DCLineSegment | +| CAP | ShuntCompensator | +| CAP | SeriesCompensator | +| CBR | ProtectedSwitch | +| CBR | Breaker | +| CBR | Recloser | +| CON | FrequencyConverter | +| CTR | CurrentTransformer | +| DIS | Switch | +| DIS | Disconnector | +| DIS | Fuse | +| DIS | Jumper | +| DIS | LoadBreakSwitch | +| DIS | GroundDisconnector | +| DIS | Sectionaliser | +| EFN | PetersenCoil | +| GEN | GeneratingUnit | +| LTC | TapChanger | +| LTC | RatioTapChanger | +| LTC | PhaseTapChanger | +| MOT | AsynchronousMachine | +| PSH | GroundingImpedance | +| PTR | PowerTransformer | +| PTW | TransformerEnd | +| PTW | PowerTransformerEnd | +| PTW | TransformerTankEnd | +| RES | EarthFaultCompensator | +| SAR | SurgeArrester | +| SCR | ACDCConverter | +| SMC | SynchronousMachine | +| TCR | StaticVarCompensator | +| TNK | TransformerTank | +| VTR | PotentialTransformer | diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java index 8115496..c00a375 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java @@ -10,6 +10,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.math.BigDecimal; import java.util.Optional; /** @@ -78,7 +79,7 @@ protected void afterVoltageLevelToTVoltageLevel(CgmesVoltageLevel cgmesVoltageLe // The bays need to be mapped in a special way, because IIDM doesn't know them. context.getBaysByVoltageLevel(cgmesVoltageLevel.getId()) .stream() - .map(bay -> mapBayToTBay(bay, cgmesVoltageLevel, context)) + .map(bay -> mapBayToTBay(bay, cgmesVoltageLevel, tVoltageLevel, context)) .forEach(tBay -> tVoltageLevel.getBay().add(tBay)); } @@ -92,12 +93,14 @@ protected void beforeBayToTBay(@MappingTarget TBay tBay, @Mapping(target = "name", source = "nameOrId") protected abstract TBay mapBayToTBay(CgmesBay cgmesBay, @Context CgmesVoltageLevel cgmesVoltageLevel, + @Context TVoltageLevel tVoltageLevel, @Context CimToSclMapperContext context); @AfterMapping protected void afterBayToTBay(CgmesBay cgmesBay, @MappingTarget TBay tBay, @Context CgmesVoltageLevel cgmesVoltageLevel, + @Context TVoltageLevel tVoltageLevel, @Context CimToSclMapperContext context) { // First we will process the Connectivity Nodes, because their path names are needed in the Terminal // of a Conduction Equipment. @@ -110,7 +113,7 @@ protected void afterBayToTBay(CgmesBay cgmesBay, // Now we can process the Conduction Equipment with their terminals. context.getSwitches(cgmesBay.getId()) .stream() - .map(cgmesSwitch -> mapSwitchToTConductingEquipment(cgmesSwitch, context)) + .map(cgmesSwitch -> mapSwitchToTConductingEquipment(cgmesSwitch, tVoltageLevel, context)) .forEach(tConductingEquipment -> tBay.getConductingEquipment().add(tConductingEquipment)); } @@ -130,12 +133,19 @@ protected void afterConnectivityNodeToTConnectivityNode(CgmesConnectivityNode cg @Mapping(target = "name", source = "nameOrId") @Mapping(target = "type", expression = "java( org.lfenergy.compas.cim.mapping.model.SwitchType.convertSwitchType(cgmesSwitch.getType()).name() )") protected abstract TConductingEquipment mapSwitchToTConductingEquipment(CgmesSwitch cgmesSwitch, + @Context TVoltageLevel tVoltageLevel, @Context CimToSclMapperContext context); @AfterMapping protected void afterSwitchToTConductingEquipment(CgmesSwitch cgmesSwitch, @MappingTarget TConductingEquipment tConductingEquipment, + @Context TVoltageLevel tVoltageLevel, @Context CimToSclMapperContext context) { + // For DCLineSegment the nomFreq from the Voltage Level to 0 + if ("DCLineSegment".equals(cgmesSwitch.getType())) { + tVoltageLevel.setNomFreq(BigDecimal.ZERO); + } + context.getTerminals(cgmesSwitch.getId()) .stream() .map(cgmesTerminal -> mapTerminalToTTerminal(cgmesTerminal, context)) diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/model/SwitchType.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/model/SwitchType.java index d70ab36..e3292b1 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/model/SwitchType.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/model/SwitchType.java @@ -17,7 +17,7 @@ */ public enum SwitchType { BSH("Connector"), - // CAB("ACLineSegment", "DCLineSegment"), + CAB("ACLineSegment", "DCLineSegment"), CAP("ShuntCompensator", "SeriesCompensator"), CBR("ProtectedSwitch", "Breaker", "Recloser"), CON("FrequencyConverter"), @@ -25,21 +25,15 @@ public enum SwitchType { DIS("Switch", "Disconnector", "Fuse", "Jumper", "LoadBreakSwitch", "GroundDisconnector", "Sectionaliser"), EFN("PetersenCoil"), GEN("GeneratingUnit"), - // GIL("ACLineSegment", "DCLineSegment"), - IFL("ACLineSegment", "DCLineSegment", "EquivalentBranch"), - // LIN("ACLineSegment", "DCLineSegment"), LTC("TapChanger", "RatioTapChanger", "PhaseTapChanger"), MOT("AsynchronousMachine"), PSH("GroundingImpedance"), PTR("PowerTransformer"), PTW("TransformerEnd", "PowerTransformerEnd", "TransformerTankEnd"), - // REA("ShuntCompensator", "SeriesCompensator"), RES("EarthFaultCompensator"), - // RRC("SynchronousMachine"), SAR("SurgeArrester"), SCR("ACDCConverter"), SMC("SynchronousMachine"), - // TCF("FrequencyConverter"), TCR("StaticVarCompensator"), TNK("TransformerTank"), VTR("PotentialTransformer"); diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java index e425459..b56b829 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java @@ -65,7 +65,7 @@ public SCL map(List cimData, Principal principal) { * @return The created SCL Model. */ SCL createBasicSCL(List cimData, Principal principal) { - SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss"); + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssXXX"); ObjectFactory factory = new ObjectFactory(); // Create the SCL and set some default values. diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java index b025940..94fcc83 100644 --- a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java @@ -11,6 +11,7 @@ import org.lfenergy.compas.core.commons.ElementConverter; import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.scl2007b4.model.TConnectivityNode; +import org.lfenergy.compas.scl2007b4.model.TVoltageLevel; import org.mapstruct.factory.Mappers; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -46,6 +47,9 @@ class CimToSclMapperTest { @Mock private CgmesTerminal cgmesTerminal; + @Mock + private TVoltageLevel tVoltageLevel; + private CimToSclMapper mapper; @BeforeEach @@ -78,6 +82,7 @@ void map_WhenWithCimData_ThenSclMapped() throws IOException { var voltageLevel = substation.getVoltageLevel().get(0); assertEquals("S1 380kV", voltageLevel.getName()); assertNotNull(voltageLevel.getVoltage()); + assertNull(voltageLevel.getNomFreq()); assertEquals(BigDecimal.valueOf(380.0), voltageLevel.getVoltage().getValue()); assertEquals("k", voltageLevel.getVoltage().getMultiplier()); assertEquals("V", voltageLevel.getVoltage().getUnit()); @@ -154,7 +159,7 @@ void mapBayToTBay_WhenCalledWithCgmesBay_ThenPropertiesMappedToTBay() { when(cgmesBay.getNameOrId()).thenReturn(expectedName); - var sclBay = mapper.mapBayToTBay(cgmesBay, cgmesVoltageLevel, context); + var sclBay = mapper.mapBayToTBay(cgmesBay, cgmesVoltageLevel, tVoltageLevel, context); assertNotNull(sclBay); assertEquals(expectedName, sclBay.getName()); @@ -187,21 +192,43 @@ void mapConnectivityNodeToTConnectivityNode_WhenCalledWithCgmesConnectivityNode_ } @Test - void mapSwitchToTConductingEquipment_WhenCalledWithCgmesSwitch_ThenPropertiesMappedToTConductingEquipment() { + void mapSwitchToTConductingEquipment_WhenCalledWithCgmesSwitchOtherType_ThenPropertiesMappedToTConductingEquipment() { var expectedName = "TheName"; var expectedType = SwitchType.CBR.name(); when(cgmesSwitch.getNameOrId()).thenReturn(expectedName); when(cgmesSwitch.getType()).thenReturn(SwitchType.CBR.getCimTypes().get(0)); - var sclConductingEquipment = mapper.mapSwitchToTConductingEquipment(cgmesSwitch, context); + var sclConductingEquipment = mapper.mapSwitchToTConductingEquipment(cgmesSwitch, tVoltageLevel, context); + + assertNotNull(sclConductingEquipment); + assertEquals(expectedName, sclConductingEquipment.getName()); + assertEquals(expectedType, sclConductingEquipment.getType()); + verify(cgmesSwitch, times(1)).getId(); + verify(cgmesSwitch, times(1)).getNameOrId(); + verify(cgmesSwitch, times(2)).getType(); + verify(tVoltageLevel, never()).setNomFreq(any(BigDecimal.class)); + verify(context, times(1)).addLast(sclConductingEquipment); + verifyNoMoreInteractions(cgmesSwitch); + } + + @Test + void mapSwitchToTConductingEquipment_WhenCalledWithCgmesSwitchDCLineSegment_ThenPropertiesMappedToTConductingEquipment() { + var expectedName = "TheName"; + var expectedType = SwitchType.CAB.name(); + + when(cgmesSwitch.getNameOrId()).thenReturn(expectedName); + when(cgmesSwitch.getType()).thenReturn("DCLineSegment"); + + var sclConductingEquipment = mapper.mapSwitchToTConductingEquipment(cgmesSwitch, tVoltageLevel, context); assertNotNull(sclConductingEquipment); assertEquals(expectedName, sclConductingEquipment.getName()); assertEquals(expectedType, sclConductingEquipment.getType()); verify(cgmesSwitch, times(1)).getId(); verify(cgmesSwitch, times(1)).getNameOrId(); - verify(cgmesSwitch, times(1)).getType(); + verify(cgmesSwitch, times(2)).getType(); + verify(tVoltageLevel, times(1)).setNomFreq(BigDecimal.ZERO); verify(context, times(1)).addLast(sclConductingEquipment); verifyNoMoreInteractions(cgmesSwitch); } diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/model/SwitchTypeTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/model/SwitchTypeTest.java index db1e179..221b9d3 100644 --- a/service/src/test/java/org/lfenergy/compas/cim/mapping/model/SwitchTypeTest.java +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/model/SwitchTypeTest.java @@ -16,7 +16,7 @@ class SwitchTypeTest { @Test void convertSwitchType_WhenCalledWithKnownCimType_ThenSCLTypeIsReturned() { - var expectedType = SwitchType.IFL; + var expectedType = SwitchType.CAB; var result = SwitchType.convertSwitchType(expectedType.getCimTypes().get(0)); assertEquals(expectedType, result); From 9f989883546dcf8d6816b04857269e518de67082 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Tue, 24 Aug 2021 11:54:51 +0200 Subject: [PATCH 02/29] Fix Switch type mapping. Signed-off-by: Dennis Labordus --- .../org/lfenergy/compas/cim/mapping/CimMappingConstants.java | 2 ++ .../lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java | 4 +++- .../org/lfenergy/compas/cim/mapping/model/SwitchType.java | 3 ++- .../compas/cim/mapping/mapper/CimToSclMapperTest.java | 3 ++- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/CimMappingConstants.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/CimMappingConstants.java index c912645..9463d5d 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/CimMappingConstants.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/CimMappingConstants.java @@ -13,4 +13,6 @@ public class CimMappingConstants { public static final String SCL_NS_URI = "http://www.iec.ch/61850/2003/SCL"; public static final String RDF_NS_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; + public static final String DC_LINE_SEGMENT_TYPE = "DCLineSegment"; + } diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java index c00a375..84da458 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java @@ -13,6 +13,8 @@ import java.math.BigDecimal; import java.util.Optional; +import static org.lfenergy.compas.cim.mapping.CimMappingConstants.DC_LINE_SEGMENT_TYPE; + /** * Interface for MapStruct to configure how a Cim Model is Mapped to a SCL IEC Model, * including the objects, like Substation, VoltageLevel and more. @@ -142,7 +144,7 @@ protected void afterSwitchToTConductingEquipment(CgmesSwitch cgmesSwitch, @Context TVoltageLevel tVoltageLevel, @Context CimToSclMapperContext context) { // For DCLineSegment the nomFreq from the Voltage Level to 0 - if ("DCLineSegment".equals(cgmesSwitch.getType())) { + if (DC_LINE_SEGMENT_TYPE.equals(cgmesSwitch.getType())) { tVoltageLevel.setNomFreq(BigDecimal.ZERO); } diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/model/SwitchType.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/model/SwitchType.java index e3292b1..ff62284 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/model/SwitchType.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/model/SwitchType.java @@ -8,6 +8,7 @@ import java.util.Arrays; import java.util.List; +import static org.lfenergy.compas.cim.mapping.CimMappingConstants.DC_LINE_SEGMENT_TYPE; import static org.lfenergy.compas.cim.mapping.exception.CompasCimMappingErrorCode.UNKNOWN_TYPE_ERROR_CODE; /** @@ -17,7 +18,7 @@ */ public enum SwitchType { BSH("Connector"), - CAB("ACLineSegment", "DCLineSegment"), + CAB("ACLineSegment", DC_LINE_SEGMENT_TYPE), CAP("ShuntCompensator", "SeriesCompensator"), CBR("ProtectedSwitch", "Breaker", "Recloser"), CON("FrequencyConverter"), diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java index 94fcc83..4d84221 100644 --- a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java @@ -26,6 +26,7 @@ import static java.util.Objects.requireNonNull; import static org.junit.jupiter.api.Assertions.*; +import static org.lfenergy.compas.cim.mapping.CimMappingConstants.DC_LINE_SEGMENT_TYPE; import static org.lfenergy.compas.cim.mapping.CimMappingConstants.RDF_NS_URI; import static org.mockito.Mockito.*; @@ -218,7 +219,7 @@ void mapSwitchToTConductingEquipment_WhenCalledWithCgmesSwitchDCLineSegment_Then var expectedType = SwitchType.CAB.name(); when(cgmesSwitch.getNameOrId()).thenReturn(expectedName); - when(cgmesSwitch.getType()).thenReturn("DCLineSegment"); + when(cgmesSwitch.getType()).thenReturn(DC_LINE_SEGMENT_TYPE); var sclConductingEquipment = mapper.mapSwitchToTConductingEquipment(cgmesSwitch, tVoltageLevel, context); From 706bff6d44b92aaa9d044066a07bb9d8ed9c9a08 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 26 Aug 2021 13:40:39 +0200 Subject: [PATCH 03/29] Added DependaBot configuration + Fixed some known issues. Signed-off-by: Dennis Labordus --- .github/dependabot.yml | 29 +++++++++++++++++++++++ .github/workflows/build-project.yml | 5 ++-- .github/workflows/release-project.yml | 5 ++-- .github/workflows/sonarcloud-analysis.yml | 11 +++++---- 4 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..d29de45 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,29 @@ +# SPDX-FileCopyrightText: 2021 Alliander N.V. +# +# SPDX-License-Identifier: Apache-2.0 + +version: 2 + +registries: + maven-github: + type: maven-repository + url: https://maven.pkg.github.com/com-pas/* + username: OWNER + password: ${{ secrets.DB_GITHUB_PACKAGES }} + +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + open-pull-requests-limit: 5 + + # Maintain dependencies for Maven + - package-ecosystem: "maven" + directory: "/" + registries: + - maven-github + schedule: + interval: "daily" + open-pull-requests-limit: 5 diff --git a/.github/workflows/build-project.yml b/.github/workflows/build-project.yml index d108fe8..34b8858 100644 --- a/.github/workflows/build-project.yml +++ b/.github/workflows/build-project.yml @@ -15,9 +15,10 @@ jobs: steps: - uses: actions/checkout@v2 - name: Set up JDK 1.11 - uses: actions/setup-java@v1 + uses: actions/setup-java@v2.3.0 with: - java-version: 1.11 + distribution: 'zulu' + java-version: '11' - name: Create custom Maven Settings.xml uses: whelk-io/maven-settings-xml-action@v18 with: diff --git a/.github/workflows/release-project.yml b/.github/workflows/release-project.yml index 9aa0de7..f875e11 100644 --- a/.github/workflows/release-project.yml +++ b/.github/workflows/release-project.yml @@ -24,10 +24,11 @@ jobs: shell: bash # Extra the tagname form the git reference, value of GITHUB_REF will be something like refs/tags/. run: echo "##[set-output name=tagname;]$(echo ${GITHUB_REF##*/})" - - uses: actions/setup-java@v2 + - name: Set up JDK 1.11 + uses: actions/setup-java@v2.3.0 with: + distribution: 'zulu' java-version: '11' - distribution: 'adopt' - name: Create custom Maven Settings.xml uses: whelk-io/maven-settings-xml-action@v18 with: diff --git a/.github/workflows/sonarcloud-analysis.yml b/.github/workflows/sonarcloud-analysis.yml index 69223d9..503f044 100644 --- a/.github/workflows/sonarcloud-analysis.yml +++ b/.github/workflows/sonarcloud-analysis.yml @@ -16,18 +16,19 @@ jobs: - uses: actions/checkout@v2 with: fetch-depth: 0 - - name: Set up JDK 11 - uses: actions/setup-java@v1 + - name: Set up JDK 1.11 + uses: actions/setup-java@v2.3.0 with: - java-version: 1.11 + distribution: 'zulu' + java-version: '11' - name: Cache SonarCloud packages - uses: actions/cache@v1 + uses: actions/cache@v2.1.6 with: path: ~/.sonar/cache key: ${{ runner.os }}-sonar restore-keys: ${{ runner.os }}-sonar - name: Cache Maven packages - uses: actions/cache@v1 + uses: actions/cache@v2.1.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From 407d22eb76ab666bbc416bdbda640cc304412079 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Aug 2021 12:49:20 +0000 Subject: [PATCH 04/29] Bump slf4j.version from 1.7.31 to 1.7.32 Bumps `slf4j.version` from 1.7.31 to 1.7.32. Updates `slf4j-api` from 1.7.31 to 1.7.32 - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.31...v_1.7.32) Updates `slf4j-simple` from 1.7.31 to 1.7.32 - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.31...v_1.7.32) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.slf4j:slf4j-simple dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b1e9634..6c8b360 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ SPDX-License-Identifier: Apache-2.0 0.2.0 2.0.2 - 1.7.31 + 1.7.32 4.3.1 1.4.2.Final From 3529aa22d795d99cab4d6c239dd7ac963ff1cb7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Aug 2021 12:49:27 +0000 Subject: [PATCH 05/29] Bump hibernate-validator from 6.2.0.Final to 7.0.1.Final Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.2.0.Final to 7.0.1.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/main/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.2.0.Final...7.0.1.Final) --- updated-dependencies: - dependency-name: org.hibernate.validator:hibernate-validator dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b1e9634..6ba9b2f 100644 --- a/pom.xml +++ b/pom.xml @@ -150,7 +150,7 @@ SPDX-License-Identifier: Apache-2.0 org.hibernate.validator hibernate-validator - 6.2.0.Final + 7.0.1.Final test From 7eb73f5f182875ebcc62a5ba58e325d601f576ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Aug 2021 12:49:29 +0000 Subject: [PATCH 06/29] Bump jakarta.el from 3.0.3 to 4.0.1 Bumps [jakarta.el](https://github.com/eclipse-ee4j/el-ri) from 3.0.3 to 4.0.1. - [Release notes](https://github.com/eclipse-ee4j/el-ri/releases) - [Commits](https://github.com/eclipse-ee4j/el-ri/commits) --- updated-dependencies: - dependency-name: org.glassfish:jakarta.el dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b1e9634..bdbedc1 100644 --- a/pom.xml +++ b/pom.xml @@ -156,7 +156,7 @@ SPDX-License-Identifier: Apache-2.0 org.glassfish jakarta.el - 3.0.3 + 4.0.1 test From 63b74af016508ddaae057472d08ba954fda2a049 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Aug 2021 12:49:33 +0000 Subject: [PATCH 07/29] Bump jacoco-maven-plugin from 0.8.6 to 0.8.7 Bumps [jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.6 to 0.8.7. - [Release notes](https://github.com/jacoco/jacoco/releases) - [Commits](https://github.com/jacoco/jacoco/compare/v0.8.6...v0.8.7) --- updated-dependencies: - dependency-name: org.jacoco:jacoco-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b1e9634..5560b94 100644 --- a/pom.xml +++ b/pom.xml @@ -211,7 +211,7 @@ SPDX-License-Identifier: Apache-2.0 java - 0.8.6 + 0.8.7 jacoco target/site/jacoco/jacoco.xml, From b539c6fd0a607b22ad6479172e30508bb6e7fdb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Aug 2021 13:09:10 +0000 Subject: [PATCH 08/29] Bump maven-source-plugin from 3.2.0 to 3.2.1 Bumps [maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.2.0 to 3.2.1. - [Release notes](https://github.com/apache/maven-source-plugin/releases) - [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.2.0...maven-source-plugin-3.2.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-source-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3fe445e..e96c91d 100644 --- a/pom.xml +++ b/pom.xml @@ -265,7 +265,7 @@ SPDX-License-Identifier: Apache-2.0 org.apache.maven.plugins maven-source-plugin - 3.2.0 + 3.2.1 attach-sources From 2662b40798a5437c0932c995ffe6ffd414d94549 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Aug 2021 13:09:18 +0000 Subject: [PATCH 09/29] Bump compas.core.version from 0.2.0 to 0.2.1 Bumps `compas.core.version` from 0.2.0 to 0.2.1. Updates `scl2007b4` from 0.2.0 to 0.2.1 Updates `commons` from 0.2.0 to 0.2.1 Updates `rest-commons` from 0.2.0 to 0.2.1 --- updated-dependencies: - dependency-name: org.lfenergy.compas.core:scl2007b4 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.lfenergy.compas.core:commons dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.lfenergy.compas.core:rest-commons dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3fe445e..ff35eea 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ SPDX-License-Identifier: Apache-2.0 3.0.0-M5 3.2.0 - 0.2.0 + 0.2.1 2.0.2 1.7.32 4.3.1 From ae16207f5d41fb851fc848c28f292c64243e829f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Aug 2021 13:16:32 +0000 Subject: [PATCH 10/29] Bump quarkus.platform.version from 2.0.0.Final to 2.1.3.Final Bumps `quarkus.platform.version` from 2.0.0.Final to 2.1.3.Final. Updates `quarkus-universe-bom` from 2.0.0.Final to 2.1.3.Final - [Release notes](https://github.com/quarkusio/quarkus-platform/releases) - [Commits](https://github.com/quarkusio/quarkus-platform/compare/2.0.0.Final...2.1.3.Final) Updates `quarkus-maven-plugin` from 2.0.0.Final to 2.1.3.Final --- updated-dependencies: - dependency-name: io.quarkus:quarkus-universe-bom dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.quarkus:quarkus-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pom.xml b/app/pom.xml index 526f267..9dd5e29 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 jar - 2.0.0.Final + 2.1.3.Final From f27983a914812edd443985e7ea7c4de5c98d175a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Aug 2021 13:16:39 +0000 Subject: [PATCH 11/29] Bump mockito-junit-jupiter from 3.11.2 to 3.12.4 Bumps [mockito-junit-jupiter](https://github.com/mockito/mockito) from 3.11.2 to 3.12.4. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.11.2...v3.12.4) --- updated-dependencies: - dependency-name: org.mockito:mockito-junit-jupiter dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3fe445e..535e79b 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ SPDX-License-Identifier: Apache-2.0 3.0.0-M5 3.2.0 - 0.2.0 + 0.2.1 2.0.2 1.7.32 4.3.1 @@ -32,7 +32,7 @@ SPDX-License-Identifier: Apache-2.0 5.7.2 - 3.11.2 + 3.12.4 0.9.1 From d2597532de2b7e310fecced88bbf6e820826d200 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Aug 2021 13:24:03 +0000 Subject: [PATCH 12/29] Bump quarkus.platform.version from 2.0.0.Final to 2.1.4.Final Bumps `quarkus.platform.version` from 2.0.0.Final to 2.1.4.Final. Updates `quarkus-universe-bom` from 2.0.0.Final to 2.1.4.Final - [Release notes](https://github.com/quarkusio/quarkus-platform/releases) - [Commits](https://github.com/quarkusio/quarkus-platform/compare/2.0.0.Final...2.1.4.Final) Updates `quarkus-maven-plugin` from 2.0.0.Final to 2.1.4.Final --- updated-dependencies: - dependency-name: io.quarkus:quarkus-universe-bom dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.quarkus:quarkus-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pom.xml b/app/pom.xml index 526f267..e525c52 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 jar - 2.0.0.Final + 2.1.4.Final From a208fff5cf625d1ae09edabc8887b5ee51e481a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Aug 2021 13:38:01 +0000 Subject: [PATCH 13/29] Bump jandex-maven-plugin from 1.1.0 to 1.1.1 Bumps [jandex-maven-plugin](https://github.com/wildfly/jandex-maven-plugin) from 1.1.0 to 1.1.1. - [Release notes](https://github.com/wildfly/jandex-maven-plugin/releases) - [Commits](https://github.com/wildfly/jandex-maven-plugin/compare/1.1.0...1.1.1) --- updated-dependencies: - dependency-name: org.jboss.jandex:jandex-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 208d2a5..4d068ed 100644 --- a/pom.xml +++ b/pom.xml @@ -183,7 +183,7 @@ SPDX-License-Identifier: Apache-2.0 org.jboss.jandex jandex-maven-plugin - 1.1.0 + 1.1.1 make-index From f826e4cb51ddae2b27eaee1609a0bcf6ae1cce28 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Mon, 30 Aug 2021 07:45:28 +0200 Subject: [PATCH 14/29] Fixed version, because Quarkus still uses EL 2.x Signed-off-by: Dennis Labordus --- .github/dependabot.yml | 6 ++++++ pom.xml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d29de45..4eb5a68 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -27,3 +27,9 @@ updates: schedule: interval: "daily" open-pull-requests-limit: 5 + allow: + # Next two dependencies shouldn't be upgrade, because RestEasy isn't using newer version. (2.3.X) + - dependency-name: org.hibernate.validator:hibernate-validator + versions: [ "6.x" ] + - dependency-name: org.glassfish:jakarta.el + versions: [ "3.x" ] diff --git a/pom.xml b/pom.xml index 6ba9b2f..b1e9634 100644 --- a/pom.xml +++ b/pom.xml @@ -150,7 +150,7 @@ SPDX-License-Identifier: Apache-2.0 org.hibernate.validator hibernate-validator - 7.0.1.Final + 6.2.0.Final test From 7df61c56b3a1626dea061e6c74149cb7847644aa Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Mon, 30 Aug 2021 07:52:06 +0200 Subject: [PATCH 15/29] Fixed version, because Quarkus still uses EL 3.x Signed-off-by: Dennis Labordus --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7e13a07..4d068ed 100644 --- a/pom.xml +++ b/pom.xml @@ -156,7 +156,7 @@ SPDX-License-Identifier: Apache-2.0 org.glassfish jakarta.el - 4.0.1 + 3.0.3 test From 21e16b9a59e02dc2cebb5f5bcab840442739d8e0 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Mon, 30 Aug 2021 08:04:02 +0200 Subject: [PATCH 16/29] Fixed version, because Quarkus still uses EL 3.x Signed-off-by: Dennis Labordus --- .github/dependabot.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 4eb5a68..b08d22c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -27,9 +27,9 @@ updates: schedule: interval: "daily" open-pull-requests-limit: 5 - allow: - # Next two dependencies shouldn't be upgrade, because RestEasy isn't using newer version. (2.3.X) + ignore: + # Next two dependencies shouldn't be upgrade, because Quarkus isn't using newer version of EL. - dependency-name: org.hibernate.validator:hibernate-validator - versions: [ "6.x" ] + versions: [ "7.x" ] - dependency-name: org.glassfish:jakarta.el - versions: [ "3.x" ] + versions: [ "4.x" ] From 88bd46fc03e5935fa9fe984e5197e6f415d19325 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Mon, 30 Aug 2021 08:40:01 +0200 Subject: [PATCH 17/29] Fixed version, because Quarkus still uses EL 3.x Signed-off-by: Dennis Labordus --- .github/dependabot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b08d22c..0e10dd9 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -30,6 +30,6 @@ updates: ignore: # Next two dependencies shouldn't be upgrade, because Quarkus isn't using newer version of EL. - dependency-name: org.hibernate.validator:hibernate-validator - versions: [ "7.x" ] + versions: [ "[7.0,)" ] - dependency-name: org.glassfish:jakarta.el - versions: [ "4.x" ] + versions: [ "[4.0,)" ] From 53249828414ed3327c14aaa69bae882cd9a169bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Aug 2021 06:55:40 +0000 Subject: [PATCH 18/29] Bump jakarta.el from 3.0.3 to 3.0.4 Bumps [jakarta.el](https://github.com/eclipse-ee4j/el-ri) from 3.0.3 to 3.0.4. - [Release notes](https://github.com/eclipse-ee4j/el-ri/releases) - [Commits](https://github.com/eclipse-ee4j/el-ri/commits) --- updated-dependencies: - dependency-name: org.glassfish:jakarta.el dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4d068ed..2e4d55c 100644 --- a/pom.xml +++ b/pom.xml @@ -156,7 +156,7 @@ SPDX-License-Identifier: Apache-2.0 org.glassfish jakarta.el - 3.0.3 + 3.0.4 test From 06894ddb16b1fee4039f743ec2cb5bc4f93c3c25 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Mon, 30 Aug 2021 15:00:45 +0200 Subject: [PATCH 19/29] Added mapping of PowerTransformer from CIM to 61850. Signed-off-by: Dennis Labordus --- .../cim/mapping/cgmes/CgmesCimReader.java | 4 +- .../cim/mapping/mapper/CimToSclMapper.java | 27 ++++++++++-- .../mapping/mapper/CimToSclMapperContext.java | 43 +++++++++++++++---- .../cim/mapping/model/CgmesTransformer.java | 21 +++++++++ .../service/CompasCimMappingService.java | 2 +- .../mapper/CimToSclMapperContextTest.java | 35 +++++++++++++++ .../mapping/mapper/CimToSclMapperTest.java | 34 +++++++++++++-- .../mapping/model/CgmesTransformerTest.java | 11 +++++ 8 files changed, 159 insertions(+), 18 deletions(-) create mode 100644 service/src/main/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformer.java create mode 100644 service/src/test/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformerTest.java diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/cgmes/CgmesCimReader.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/cgmes/CgmesCimReader.java index 593fc91..c59c69a 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/cgmes/CgmesCimReader.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/cgmes/CgmesCimReader.java @@ -36,11 +36,11 @@ public CgmesCimReader(ElementConverter converter) { } /** - * Use PowSyBl to convert a CIM XML InputStream to the PowSyBl IIDM Model. + * Use PowSyBl to convert a CIM XML InputStream to the PowSyBl Cgmes Model. * Multiple InputStream Objects can be passed if needed. * * @param cimData The different InputStream Objects that combined define the CIM Model. - * @return The IIDM Network model that can be used to convert further to IEC 61850. + * @return The Cgmes Model that can be used to convert further to IEC 61850. */ public CgmesModel readModel(List cimData) { LOGGER.debug("Create a ReadOnlyDataSource from the input data."); diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java index 84da458..35ec7f8 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java @@ -30,7 +30,7 @@ public abstract class CimToSclMapper { /** * Top level mapping method to start the mapping of all known elements from Cgmes Model - * and IIDM Network Model to the IEC SCL Model. + * to the IEC SCL Model. * * @param context Holding all data from which the SCL (also passed) needs to be filled. */ @@ -59,12 +59,16 @@ protected abstract TSubstation mapSubstationToTSubstation(CgmesSubstation substa protected void afterSubstationToTSubstation(CgmesSubstation substation, @MappingTarget TSubstation tSubstation, @Context CimToSclMapperContext context) { - // The bays need to be mapped in a special way, because IIDM doesn't know them. context.getVoltageLevelsBySubstation(substation.getId()) .stream() .map(voltageLevel -> mapVoltageLevelToTVoltageLevel(voltageLevel, context)) .forEach(tVoltageLevel -> tSubstation.getVoltageLevel().add(tVoltageLevel)); + // PowerTransformers coupled to the Bay Level. + context.getTransformers(substation.getId()) + .stream() + .map(transformer -> mapTransformerToTPowerTransformer(transformer, context)) + .forEach(tPowerTransformer -> tSubstation.getPowerTransformer().add(tPowerTransformer)); } @Mapping(target = "name", source = "nameOrId") @@ -78,11 +82,16 @@ protected abstract TVoltageLevel mapVoltageLevelToTVoltageLevel(CgmesVoltageLeve protected void afterVoltageLevelToTVoltageLevel(CgmesVoltageLevel cgmesVoltageLevel, @MappingTarget TVoltageLevel tVoltageLevel, @Context CimToSclMapperContext context) { - // The bays need to be mapped in a special way, because IIDM doesn't know them. context.getBaysByVoltageLevel(cgmesVoltageLevel.getId()) .stream() .map(bay -> mapBayToTBay(bay, cgmesVoltageLevel, tVoltageLevel, context)) .forEach(tBay -> tVoltageLevel.getBay().add(tBay)); + + // PowerTransformers coupled to the Bay Level. + context.getTransformers(cgmesVoltageLevel.getId()) + .stream() + .map(transformer -> mapTransformerToTPowerTransformer(transformer, context)) + .forEach(tPowerTransformer -> tVoltageLevel.getPowerTransformer().add(tPowerTransformer)); } @BeforeMapping @@ -117,8 +126,20 @@ protected void afterBayToTBay(CgmesBay cgmesBay, .stream() .map(cgmesSwitch -> mapSwitchToTConductingEquipment(cgmesSwitch, tVoltageLevel, context)) .forEach(tConductingEquipment -> tBay.getConductingEquipment().add(tConductingEquipment)); + + // PowerTransformers coupled to the Bay Level. + context.getTransformers(cgmesBay.getId()) + .stream() + .map(transformer -> mapTransformerToTPowerTransformer(transformer, context)) + .forEach(tPowerTransformer -> tBay.getPowerTransformer().add(tPowerTransformer)); } + @Mapping(target = "name", source = "nameOrId") + @Mapping(target = "desc", source = "description") + @Mapping(target = "type", constant = "PTR") + protected abstract TPowerTransformer mapTransformerToTPowerTransformer(CgmesTransformer transformer, + @Context CimToSclMapperContext context); + @Mapping(target = "name", source = "nameOrId") protected abstract TConnectivityNode mapConnectivityNodeToTConnectivityNode(CgmesConnectivityNode cgmesConnectivityNode, @Context CimToSclMapperContext context); diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContext.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContext.java index a715b09..72f2b11 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContext.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContext.java @@ -58,19 +58,44 @@ public List getVoltageLevelsBySubstation(String substationId) */ public List getBaysByVoltageLevel(String voltageLevelId) { return cgmesModel.tripleStore().query( - "SELECT *\n" + - "WHERE {\n" + - "GRAPH ?graph {\n" + - " ?Bay\n" + - " a cim:Bay ;\n" + - " cim:IdentifiedObject.name ?name ;\n" + - " cim:Bay.VoltageLevel ?VoltageLevel ;\n" + - " FILTER (str(?VoltageLevel) = \"http://default-cgmes-model/#" + voltageLevelId + "\") " + - "}}").stream() + "SELECT *\n" + + "WHERE {\n" + + "GRAPH ?graph {\n" + + " ?Bay\n" + + " a cim:Bay ;\n" + + " cim:IdentifiedObject.name ?name ;\n" + + " cim:Bay.VoltageLevel ?VoltageLevel ;\n" + + " FILTER (str(?VoltageLevel) = \"http://default-cgmes-model/#" + voltageLevelId + "\") " + + "}}").stream() .map(bag -> new CgmesBay(bag.getId("Bay"), bag.get("name"))) .collect(Collectors.toList()); } + /** + * Search the CGMES Model for Power-Transformers that below to a specific container. + * + * @param containerId The ID of the Container. + * @return The List of converted CGMES Power-Transformers that were found. + */ + public List getTransformers(String containerId) { + return cgmesModel.tripleStore().query( + "SELECT *\n" + + "{ GRAPH ?graph {\n" + + " ?PowerTransformer\n" + + " a cim:PowerTransformer ;\n" + + " cim:IdentifiedObject.name ?name ;\n" + + " cim:IdentifiedObject.description ?description ;\n" + + " cim:Equipment.EquipmentContainer ?EquipmentContainer .\n" + + "}}") + .stream() + .filter(propertyBag -> containerId.equals(propertyBag.getId("EquipmentContainer"))) + .map(propertyBag -> new CgmesTransformer( + propertyBag.getId("PowerTransformer"), + propertyBag.get("name"), + propertyBag.get("description"))) + .collect(Collectors.toList()); + } + /** * Search the CGMES Model for Connectivity Nodes that below to a specific container. * diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformer.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformer.java new file mode 100644 index 0000000..e2390b1 --- /dev/null +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformer.java @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2021 Alliander N.V. +// +// SPDX-License-Identifier: Apache-2.0 +package org.lfenergy.compas.cim.mapping.model; + +public class CgmesTransformer extends AbstractCgmesEntity { + private String description; + + public CgmesTransformer(String id, String name, String description) { + super(id, name); + this.description = description; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java index b56b829..5a23f75 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java @@ -22,7 +22,7 @@ import java.util.stream.Collectors; /** - * Mapping Service to process the passed CIM XML(s) (RDF Format) and convert these to a IIDM Model + * Mapping Service to process the passed CIM XML(s) (RDF Format) and convert these to a Cgmes Model * that is used to create a IEC SCL Model, including some basic data being filled in the Header. */ @ApplicationScoped diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContextTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContextTest.java index f08c514..9e7223b 100644 --- a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContextTest.java +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContextTest.java @@ -104,6 +104,41 @@ void getBaysByVoltageLevel_WhenSparQLReturnsBags_ThenPropertyBagIsConvertedToCgm assertEquals(bayName, bay.getName()); } + @Test + void getTransformers_WhenSparQLReturnsBags_ThenPropertyBagIsConvertedToCgmesTransformer() { + var pwId = "PowertransformerId"; + var pwName = "Name Powertransformer"; + var pwDesc = "Desc Powertransformer"; + var pwContainerId = "Known Container ID"; + var bags = new PropertyBags(); + var bag = new PropertyBag(List.of("PowerTransformer", "name", "description", "EquipmentContainer")); + bag.put("PowerTransformer", pwId); + bag.put("name", pwName); + bag.put("description", pwDesc); + bag.put("EquipmentContainer", pwContainerId); + bags.add(bag); + + bag = new PropertyBag(List.of("PowerTransformer", "name", "description", "EquipmentContainer")); + bag.put("PowerTransformer", "Other ID"); + bag.put("name", "Other name"); + bag.put("description", "Other desc"); + bag.put("EquipmentContainer", "Unknown Container ID"); + bags.add(bag); + + var tripleStore = mock(TripleStore.class); + when(cgmesModel.tripleStore()).thenReturn(tripleStore); + when(tripleStore.query(anyString())).thenReturn(bags); + + var result = context.getTransformers(pwContainerId); + + assertNotNull(result); + assertEquals(1, result.size()); + var transformer = result.get(0); + assertEquals(pwId, transformer.getId()); + assertEquals(pwName, transformer.getName()); + assertEquals(pwDesc, transformer.getDescription()); + } + @Test void getConnectivityNode_WhenCalledWithKnownId_ThenPropertyBagsIsFilteredOnIdAndConvertedToCgmesConnectivityNode() { var ccnId = "CcnId"; diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java index 4d84221..0225ccf 100644 --- a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java @@ -11,6 +11,7 @@ import org.lfenergy.compas.core.commons.ElementConverter; import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.scl2007b4.model.TConnectivityNode; +import org.lfenergy.compas.scl2007b4.model.TPowerTransformerEnum; import org.lfenergy.compas.scl2007b4.model.TVoltageLevel; import org.mapstruct.factory.Mappers; import org.mockito.Mock; @@ -42,6 +43,8 @@ class CimToSclMapperTest { @Mock private CgmesBay cgmesBay; @Mock + private CgmesTransformer cgmesTransformer; + @Mock private CgmesConnectivityNode cgmesConnectivityNode; @Mock private CgmesSwitch cgmesSwitch; @@ -79,6 +82,12 @@ void map_WhenWithCimData_ThenSclMapped() throws IOException { assertEquals("_af9a4ae3-ba2e-4c34-8e47-5af894ee20f4", substation.getName()); assertEquals("Sub1", substation.getDesc()); + assertEquals(1, substation.getPowerTransformer().size()); + var powerTransformer = substation.getPowerTransformer().get(0); + assertEquals("T3", powerTransformer.getName()); + assertEquals(TPowerTransformerEnum.PTR, powerTransformer.getType()); + assertEquals("Trafo-5", powerTransformer.getDesc()); + assertEquals(3, substation.getVoltageLevel().size()); var voltageLevel = substation.getVoltageLevel().get(0); assertEquals("S1 380kV", voltageLevel.getName()); @@ -128,7 +137,7 @@ void mapSubstationToTSubstation_WhenCalledWithSubstation_ThenPropertiesMappedToT assertNotNull(sclSubstation); assertEquals(expectedId, sclSubstation.getName()); assertEquals(expectedDesc, sclSubstation.getDesc()); - verify(cgmesSubstation, times(2)).getId(); + verify(cgmesSubstation, times(3)).getId(); verify(cgmesSubstation, times(1)).getOptionalName(); verify(context, times(1)).addLast(sclSubstation); verifyNoMoreInteractions(cgmesSubstation); @@ -147,7 +156,7 @@ void mapVoltageLevelToTVoltageLevel_WhenCalledWithVoltageLevel_ThenPropertiesMap assertNotNull(sclVoltageLevel); assertEquals(expectedName, sclVoltageLevel.getName()); assertEquals(expectedVoltage, sclVoltageLevel.getVoltage().getValue()); - verify(cgmesVoltageLevel, times(1)).getId(); + verify(cgmesVoltageLevel, times(2)).getId(); verify(cgmesVoltageLevel, times(1)).getNameOrId(); verify(cgmesVoltageLevel, times(1)).getNominalV(); verify(context, times(1)).addLast(sclVoltageLevel); @@ -164,12 +173,31 @@ void mapBayToTBay_WhenCalledWithCgmesBay_ThenPropertiesMappedToTBay() { assertNotNull(sclBay); assertEquals(expectedName, sclBay.getName()); - verify(cgmesBay, times(2)).getId(); + verify(cgmesBay, times(3)).getId(); verify(cgmesBay, times(1)).getNameOrId(); verify(context, times(1)).addLast(sclBay); verifyNoMoreInteractions(cgmesBay); } + @Test + void mapTransformerToTPowerTransformer_WhenCalledWithCgmesTransformer_ThenPropertiesMappedToTPowerTransformer() { + var expectedName = "TheName"; + var expectedDesc = "Desc"; + + when(cgmesTransformer.getNameOrId()).thenReturn(expectedName); + when(cgmesTransformer.getDescription()).thenReturn(expectedDesc); + + var sclPowerTransformer = mapper.mapTransformerToTPowerTransformer(cgmesTransformer, context); + + assertNotNull(sclPowerTransformer); + assertEquals(expectedName, sclPowerTransformer.getName()); + assertEquals(expectedDesc, sclPowerTransformer.getDesc()); + assertEquals(TPowerTransformerEnum.PTR, sclPowerTransformer.getType()); + verify(cgmesTransformer, times(1)).getNameOrId(); + verify(cgmesTransformer, times(1)).getDescription(); + verifyNoMoreInteractions(cgmesTransformer); + } + @Test void mapConnectivityNodeToTConnectivityNode_WhenCalledWithCgmesConnectivityNode_ThenPropertiesMappedToTConnectivityNode() { var expectedId = "Id"; diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformerTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformerTest.java new file mode 100644 index 0000000..e62822f --- /dev/null +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformerTest.java @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: 2021 Alliander N.V. +// +// SPDX-License-Identifier: Apache-2.0 +package org.lfenergy.compas.cim.mapping.model; + +class CgmesTransformerTest extends AbstractPojoTester { + @Override + protected Class getClassToBeTested() { + return CgmesTransformer.class; + } +} From f7c59ca2f04f8dfa682acfa142ae9d35373f3da8 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Mon, 30 Aug 2021 16:08:37 +0200 Subject: [PATCH 20/29] Improved test. Signed-off-by: Dennis Labordus --- .../mapping/mapper/CimToSclMapperTest.java | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java index 0225ccf..20f587a 100644 --- a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java @@ -9,10 +9,7 @@ import org.lfenergy.compas.cim.mapping.cgmes.CgmesCimReader; import org.lfenergy.compas.cim.mapping.model.*; import org.lfenergy.compas.core.commons.ElementConverter; -import org.lfenergy.compas.scl2007b4.model.SCL; -import org.lfenergy.compas.scl2007b4.model.TConnectivityNode; -import org.lfenergy.compas.scl2007b4.model.TPowerTransformerEnum; -import org.lfenergy.compas.scl2007b4.model.TVoltageLevel; +import org.lfenergy.compas.scl2007b4.model.*; import org.mapstruct.factory.Mappers; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -83,10 +80,7 @@ void map_WhenWithCimData_ThenSclMapped() throws IOException { assertEquals("Sub1", substation.getDesc()); assertEquals(1, substation.getPowerTransformer().size()); - var powerTransformer = substation.getPowerTransformer().get(0); - assertEquals("T3", powerTransformer.getName()); - assertEquals(TPowerTransformerEnum.PTR, powerTransformer.getType()); - assertEquals("Trafo-5", powerTransformer.getDesc()); + assertPowerTransformer(substation.getPowerTransformer().get(0)); assertEquals(3, substation.getVoltageLevel().size()); var voltageLevel = substation.getVoltageLevel().get(0); @@ -102,17 +96,33 @@ void map_WhenWithCimData_ThenSclMapped() throws IOException { assertEquals("BAY_T4_2", bay.getName()); assertEquals(4, bay.getConnectivityNode().size()); - var connectivityNode = bay.getConnectivityNode().get(0); - assertEquals("CONNECTIVITY_NODE82", connectivityNode.getName()); - assertEquals("_af9a4ae3-ba2e-4c34-8e47-5af894ee20f4/S1 380kV/BAY_T4_2/CONNECTIVITY_NODE82", connectivityNode.getPathName()); + assertConnectivityNode(bay.getConnectivityNode().get(0)); assertEquals(3, bay.getConductingEquipment().size()); var conductingEquipment = bay.getConductingEquipment().get(0); + assertConductingEquipment(conductingEquipment); + + assertEquals(2, conductingEquipment.getTerminal().size()); + assertTerminal(conductingEquipment.getTerminal().get(0)); + } + + private void assertPowerTransformer(TPowerTransformer powerTransformer) { + assertEquals("T3", powerTransformer.getName()); + assertEquals(TPowerTransformerEnum.PTR, powerTransformer.getType()); + assertEquals("Trafo-5", powerTransformer.getDesc()); + } + + private void assertConnectivityNode(TConnectivityNode connectivityNode) { + assertEquals("CONNECTIVITY_NODE82", connectivityNode.getName()); + assertEquals("_af9a4ae3-ba2e-4c34-8e47-5af894ee20f4/S1 380kV/BAY_T4_2/CONNECTIVITY_NODE82", connectivityNode.getPathName()); + } + + private void assertConductingEquipment(TConductingEquipment conductingEquipment) { assertEquals("BREAKER25", conductingEquipment.getName()); assertEquals("CBR", conductingEquipment.getType()); + } - assertEquals(2, conductingEquipment.getTerminal().size()); - var terminal = conductingEquipment.getTerminal().get(0); + private void assertTerminal(TTerminal terminal) { assertEquals("T4_2_ADDB1", terminal.getName()); assertEquals("CONNECTIVITY_NODE83", terminal.getCNodeName()); assertEquals("_af9a4ae3-ba2e-4c34-8e47-5af894ee20f4/S1 380kV/BAY_T4_2/CONNECTIVITY_NODE83", terminal.getConnectivityNode()); From 3fd49d102b16927fc63347d3daa637fd442ae349 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Tue, 31 Aug 2021 10:43:15 +0200 Subject: [PATCH 21/29] Added mapping of PowerTransformerEnd from CIM to 61850. Signed-off-by: Dennis Labordus --- MAPPING.md | 25 ++++++- README.md | 14 ++++ .../cim/mapping/mapper/CimToSclMapper.java | 48 +++++++++---- .../mapping/mapper/CimToSclMapperContext.java | 34 ++++++++++ .../mapping/model/AbstractCgmesEntity.java | 8 +-- .../mapping/model/CgmesTransformerEnd.java | 21 ++++++ .../mapper/CimToSclMapperContextTest.java | 63 +++++++++++++++++ .../mapping/mapper/CimToSclMapperTest.java | 68 ++++++++++++------- .../model/AbstractCgmesEntityTest.java | 23 +------ .../model/CgmesTransformerEndTest.java | 11 +++ 10 files changed, 244 insertions(+), 71 deletions(-) create mode 100644 service/src/main/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformerEnd.java create mode 100644 service/src/test/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformerEndTest.java diff --git a/MAPPING.md b/MAPPING.md index a16cd16..cf1860f 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -17,6 +17,7 @@ There is an IEC document describing the mapping, namely IEC/TS 62361-102, but no | id | name | | | name | desc | | | List<cim:VoltageLevel> | List<TVoltageLevel> | (1) | +| List<*PowerTransformer*> | List<TPowerTransformer> | | (1): The list of VoltageLevels that belong to the Substation. @@ -29,6 +30,7 @@ There is an IEC document describing the mapping, namely IEC/TS 62361-102, but no | 'k' | voltage.multiplier | | | 'V' | voltage.unit | | | List<Bay> | List<TBay> | (2) | +| List<*PowerTransformer*> | List<TPowerTransformer> | | (1): The nomFreq will be set to 0 if there is a Switch connected to it of the type 'DCLineSegment'. (2): The list of Bays that belong to the VoltageLevel. @@ -39,6 +41,7 @@ There is an IEC document describing the mapping, namely IEC/TS 62361-102, but no | name or id | name | | | List<cim:ConnectivityNode> | List<TConnectivityNode> | (1) | | List<*Switches*> | List<TConductingEquipment> | (2) | +| List<*PowerTransformer*> | List<TPowerTransformer> | | (1): ConnectivityNode in IEC CIM can be linked to a Bay, but also to the VoltageLevel. In IEC 61850 a ConnectivityNode can only be added to a Bay, so also the ConnectivityNode from the VoltageLevel are added to the Bay. This causes those @@ -48,7 +51,23 @@ ProtectedSwitch.These classes are all mapped in the same way on IEC 61850 | CIM Class | IEC Class | Remark | | -------------------------------- | -------------------------------- | --------- | -| *cim:ConnectivityNode* | *TConnectivityNode | | +| *cim:PowerTransformer* | *TPowerTransformer* | | +| name or id | name | | +| description | desc | | +| 'PTR' | type | | + +| CIM Class | IEC Class | Remark | +| -------------------------------- | -------------------------------- | --------- | +| *cim:PowerTransformerEnd* | *TTransformerWinding* | | +| name or id | name | | +| 'PTW' | type | | +| Terminal | List<TTerminal> | (1) | + +(1): The terminal found in IEC CIM will be added as List to IEC 61850. + +| CIM Class | IEC Class | Remark | +| -------------------------------- | -------------------------------- | --------- | +| *cim:ConnectivityNode* | *TConnectivityNode* | | | name or id | name | | | - | pathName | (1) | @@ -58,7 +77,7 @@ ConnectivityNode. | CIM Class | IEC Class | Remark | | -------------------------------- | -------------------------------- | --------- | -| *Switches* | *TConductingEquipment | (1) | +| *Switches* | *TConductingEquipment* | (1) | | name or id | name | | | type | type | (2) | | List<cim:Terminal> | List<TTerminal> | (3) | @@ -71,7 +90,7 @@ implements this mapping. | CIM Class | IEC Class | Remark | | -------------------------------- | -------------------------------- | --------- | -| *cim:Terminal* | *TTerminal | | +| *cim:Terminal* | *TTerminal* | | | name or id | name | | | - | connectivityNode | (1) | | - | CNodeName | (1) | diff --git a/README.md b/README.md index 9699662..2f70720 100644 --- a/README.md +++ b/README.md @@ -63,3 +63,17 @@ You can then execute your native executable with: `./app/target/code-with-quarku If you want to learn more about building native executables, please consult https://quarkus.io/guides/maven-tooling.html . + +## Security + +To use most of the endpoints the users needs to be authenticated using JWT in the authorization header. There are 4 +environment variables that can be set in the container to configure the validation/processing of the JWT. + +| Environment variable | Java Property | Description | Example | +| -------------------------------- | -------------------------------- | -------------------------------------------------- | ---------------------------------------------------------------------- | +| JWT_VERIFY_KEY | smallrye.jwt.verify.key.location | Location of certificates to verify the JWT. | http://localhost:8089/auth/realms/compas/protocol/openid-connect/certs | +| JWT_VERIFY_ISSUER | mp.jwt.verify.issuer | The issuer of the JWT. | http://localhost:8089/auth/realms/compas | +| JWT_VERIFY_CLIENT_ID | mp.jwt.verify.audiences | The Client ID that should be in the "aud" claim. | cim-mapping | +| JWT_GROUPS_PATH | smallrye.jwt.path.groups | The JSON Path where to find the roles of the user. | resource_access/cim-mapping/roles | + +There are no roles defined in this service, only need to be authenticated. diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java index 35ec7f8..c6566f8 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java @@ -11,7 +11,6 @@ import org.slf4j.LoggerFactory; import java.math.BigDecimal; -import java.util.Optional; import static org.lfenergy.compas.cim.mapping.CimMappingConstants.DC_LINE_SEGMENT_TYPE; @@ -50,8 +49,15 @@ protected void beforeTNaming(@MappingTarget TNaming tNaming, context.addLast(tNaming); } + @BeforeMapping + protected void beforeSubstationToTSubstation(@MappingTarget TSubstation tSubstation, + @Context CimToSclMapperContext context) { + // Reset the Map of ConnectivityNodes, because we only need them inside processing of the Substation. + context.resetTConnectivityNodeMap(); + } + @Mapping(target = "name", source = "id") - @Mapping(target = "desc", source = "optionalName") + @Mapping(target = "desc", source = "name") protected abstract TSubstation mapSubstationToTSubstation(CgmesSubstation substation, @Context CimToSclMapperContext context); @@ -94,13 +100,6 @@ protected void afterVoltageLevelToTVoltageLevel(CgmesVoltageLevel cgmesVoltageLe .forEach(tPowerTransformer -> tVoltageLevel.getPowerTransformer().add(tPowerTransformer)); } - @BeforeMapping - protected void beforeBayToTBay(@MappingTarget TBay tBay, - @Context CimToSclMapperContext context) { - // Reset the Map of ConnectivityNodes, because we only need them inside processing of the Bay. - context.resetTConnectivityNodeMap(); - } - @Mapping(target = "name", source = "nameOrId") protected abstract TBay mapBayToTBay(CgmesBay cgmesBay, @Context CgmesVoltageLevel cgmesVoltageLevel, @@ -140,6 +139,33 @@ protected void afterBayToTBay(CgmesBay cgmesBay, protected abstract TPowerTransformer mapTransformerToTPowerTransformer(CgmesTransformer transformer, @Context CimToSclMapperContext context); + @AfterMapping + protected void afterTransformerToTPowerTransformer(CgmesTransformer transformer, + @MappingTarget TPowerTransformer tPowerTransformer, + @Context CimToSclMapperContext context) { + // PowerTransformer Ends coupled to the PowerTransformer. + context.getTransformerEnds(transformer.getId()) + .stream() + .map(transformerEnd -> mapTransformerEndToTTransformerWinding(transformerEnd, context)) + .forEach(tTransformerWinding -> tPowerTransformer.getTransformerWinding().add(tTransformerWinding)); + } + + @Mapping(target = "name", source = "nameOrId") + @Mapping(target = "type", constant = "PTW") + protected abstract TTransformerWinding mapTransformerEndToTTransformerWinding(CgmesTransformerEnd transformerEnd, + @Context CimToSclMapperContext context); + + @AfterMapping + protected void afterTransformerEndToTTransformerWinding(CgmesTransformerEnd transformerEnd, + @MappingTarget TTransformerWinding tTransformerWinding, + @Context CimToSclMapperContext context) { + context.getTerminal(transformerEnd.getTerminalId()) + .ifPresent(cgmesTerminal -> { + var tTerminal = mapTerminalToTTerminal(cgmesTerminal, context); + tTransformerWinding.getTerminal().add(tTerminal); + }); + } + @Mapping(target = "name", source = "nameOrId") protected abstract TConnectivityNode mapConnectivityNodeToTConnectivityNode(CgmesConnectivityNode cgmesConnectivityNode, @Context CimToSclMapperContext context); @@ -182,10 +208,6 @@ protected void afterSwitchToTConductingEquipment(CgmesSwitch cgmesSwitch, protected abstract TTerminal mapTerminalToTTerminal(CgmesTerminal cgmesTerminal, @Context CimToSclMapperContext context); - protected String optionalString(Optional value) { - return value.orElse(null); - } - @AfterMapping protected void afterTNaming(@MappingTarget TNaming tNaming, @Context CimToSclMapperContext context) { diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContext.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContext.java index 72f2b11..346eb17 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContext.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContext.java @@ -96,6 +96,23 @@ public List getTransformers(String containerId) { .collect(Collectors.toList()); } + /** + * Search the CGMES Model for Power-Transformer Ends that below to a specific Power-Transformer. + * + * @param powerTransformerId The ID of the Power-Transformer. + * @return The List of converted CGMES Power-Transformer Ends that were found. + */ + public List getTransformerEnds(String powerTransformerId) { + return cgmesModel.transformerEnds() + .stream() + .filter(propertyBag -> powerTransformerId.equals(propertyBag.getId("PowerTransformer"))) + .map(propertyBag -> new CgmesTransformerEnd( + propertyBag.getId("TransformerEnd"), + propertyBag.get("name"), + propertyBag.getId("Terminal"))) + .collect(Collectors.toList()); + } + /** * Search the CGMES Model for Connectivity Nodes that below to a specific container. * @@ -148,6 +165,23 @@ public List getTerminals(String conductingEquipmentId) { .collect(Collectors.toList()); } + /** + * Search the CGMES Model for a Terminal with a specific ID. + * + * @param terminalId The ID of the Terminal. + * @return The converted CGMES Terminal that is found. + */ + public Optional getTerminal(String terminalId) { + return cgmesModel.terminals() + .stream() + .filter(propertyBag -> terminalId.equals(propertyBag.getId("Terminal"))) + .map(propertyBag -> new CgmesTerminal( + propertyBag.getId("Terminal"), + propertyBag.get("name"), + propertyBag.getId("ConnectivityNode"))) + .findFirst(); + } + /* * Below part contains methods to keep track of all the naming elements passed. * At the end this list is used to create a PathName for the ConnectivityNode. diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/model/AbstractCgmesEntity.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/model/AbstractCgmesEntity.java index 42959c6..c134728 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/model/AbstractCgmesEntity.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/model/AbstractCgmesEntity.java @@ -3,8 +3,6 @@ // SPDX-License-Identifier: Apache-2.0 package org.lfenergy.compas.cim.mapping.model; -import java.util.Optional; - public abstract class AbstractCgmesEntity { private String id; private String name; @@ -30,11 +28,7 @@ public void setName(String name) { this.name = name; } - public Optional getOptionalName() { - return Optional.ofNullable(getName()); - } - public String getNameOrId() { - return getOptionalName().orElseGet(this::getId); + return getName() != null ? getName() : getId(); } } diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformerEnd.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformerEnd.java new file mode 100644 index 0000000..33ff12f --- /dev/null +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformerEnd.java @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2021 Alliander N.V. +// +// SPDX-License-Identifier: Apache-2.0 +package org.lfenergy.compas.cim.mapping.model; + +public class CgmesTransformerEnd extends AbstractCgmesEntity { + private String terminalId; + + public CgmesTransformerEnd(String id, String name, String terminalId) { + super(id, name); + this.terminalId = terminalId; + } + + public String getTerminalId() { + return terminalId; + } + + public void setTerminalId(String terminalId) { + this.terminalId = terminalId; + } +} diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContextTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContextTest.java index 9e7223b..2a797db 100644 --- a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContextTest.java +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContextTest.java @@ -139,6 +139,38 @@ void getTransformers_WhenSparQLReturnsBags_ThenPropertyBagIsConvertedToCgmesTran assertEquals(pwDesc, transformer.getDescription()); } + @Test + void getTransformerEnds_WhenCalledWithKnownId_ThenPropertyBagsIsFilteredOnIdAndConvertedToCgmesTransformerEnd() { + var tfeId = "TfeId"; + var tfeName = "Name Tfe"; + var terminalId = "Known Terminal ID"; + var tfId = "Known Transformer ID"; + var bags = new PropertyBags(); + var bag = new PropertyBag(List.of("TransformerEnd", "name", "PowerTransformer", "Terminal")); + bag.put("TransformerEnd", tfeId); + bag.put("name", tfeName); + bag.put("PowerTransformer", tfId); + bag.put("Terminal", terminalId); + bags.add(bag); + + bag = new PropertyBag(List.of("TransformerEnd", "name", "PowerTransformer", "Terminal")); + bag.put("TransformerEnd", "Other ID"); + bag.put("name", "Other Name"); + bag.put("PowerTransformer", "Unknown Transformer ID"); + bag.put("Terminal", "Other Terminal ID"); + bags.add(bag); + + when(cgmesModel.transformerEnds()).thenReturn(bags); + + var result = context.getTransformerEnds(tfId); + assertNotNull(result); + assertEquals(1, result.size()); + var ccn = result.get(0); + assertEquals(tfeId, ccn.getId()); + assertEquals(tfeName, ccn.getName()); + assertEquals(terminalId, ccn.getTerminalId()); + } + @Test void getConnectivityNode_WhenCalledWithKnownId_ThenPropertyBagsIsFilteredOnIdAndConvertedToCgmesConnectivityNode() { var ccnId = "CcnId"; @@ -231,6 +263,37 @@ void getTerminals_WhenCalledWithKnownId_ThenPropertyBagsIsFilteredOnIdAndConvert assertEquals(ccnNode, terminal.getConnectivityNodeId()); } + @Test + void getTerminal_WhenCalledWithKnownId_ThenPropertyBagsIsFilteredOnIdAndConvertedToCgmesTerminal() { + var terminalId = "TerminalId"; + var terminalName = "Name Terminal"; + var ccnNode = "Connectivity Node ID"; + var containerId = "Known Container ID"; + var bags = new PropertyBags(); + var bag = new PropertyBag(List.of("Terminal", "name", "ConnectivityNode", "ConductingEquipment")); + bag.put("Terminal", terminalId); + bag.put("name", terminalName); + bag.put("ConnectivityNode", ccnNode); + bag.put("ConductingEquipment", containerId); + bags.add(bag); + + bag = new PropertyBag(List.of("Terminal", "name", "ConnectivityNode", "ConductingEquipment")); + bag.put("Terminal", "Other ID"); + bag.put("name", "Other Name"); + bag.put("ConnectivityNode", "Some Other ID"); + bag.put("ConductingEquipment", "Unknown Container ID"); + bags.add(bag); + + when(cgmesModel.terminals()).thenReturn(bags); + + var result = context.getTerminal(terminalId); + assertNotNull(result); + var terminal = result.get(); + assertEquals(terminalId, terminal.getId()); + assertEquals(terminalName, terminal.getName()); + assertEquals(ccnNode, terminal.getConnectivityNodeId()); + } + @Test void createPathName_WhenCalledWithNoStack_ThenEmptyStringIsReturned() { assertEquals("", context.createPathName()); diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java index 20f587a..4dd1271 100644 --- a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java @@ -42,6 +42,8 @@ class CimToSclMapperTest { @Mock private CgmesTransformer cgmesTransformer; @Mock + private CgmesTransformerEnd cgmesTransformerEnd; + @Mock private CgmesConnectivityNode cgmesConnectivityNode; @Mock private CgmesSwitch cgmesSwitch; @@ -80,7 +82,14 @@ void map_WhenWithCimData_ThenSclMapped() throws IOException { assertEquals("Sub1", substation.getDesc()); assertEquals(1, substation.getPowerTransformer().size()); - assertPowerTransformer(substation.getPowerTransformer().get(0)); + var powerTransformer = substation.getPowerTransformer().get(0); + assertPowerTransformer(powerTransformer); + + assertEquals(3, powerTransformer.getTransformerWinding().size()); + var powerTransformerEnd = powerTransformer.getTransformerWinding().get(0); + assertTransformerWinding(powerTransformerEnd); + assertTerminal(powerTransformerEnd.getTerminal(), 1, "T3_0", "CONNECTIVITY_NODE88", + "_af9a4ae3-ba2e-4c34-8e47-5af894ee20f4/S1 380kV/BAY_T3_0/CONNECTIVITY_NODE88"); assertEquals(3, substation.getVoltageLevel().size()); var voltageLevel = substation.getVoltageLevel().get(0); @@ -102,8 +111,8 @@ void map_WhenWithCimData_ThenSclMapped() throws IOException { var conductingEquipment = bay.getConductingEquipment().get(0); assertConductingEquipment(conductingEquipment); - assertEquals(2, conductingEquipment.getTerminal().size()); - assertTerminal(conductingEquipment.getTerminal().get(0)); + assertTerminal(conductingEquipment.getTerminal(), 2, "T4_2_ADDB1", "CONNECTIVITY_NODE83", + "_af9a4ae3-ba2e-4c34-8e47-5af894ee20f4/S1 380kV/BAY_T4_2/CONNECTIVITY_NODE83"); } private void assertPowerTransformer(TPowerTransformer powerTransformer) { @@ -112,6 +121,11 @@ private void assertPowerTransformer(TPowerTransformer powerTransformer) { assertEquals("Trafo-5", powerTransformer.getDesc()); } + private void assertTransformerWinding(TTransformerWinding powerTransformerEnd) { + assertEquals("T3", powerTransformerEnd.getName()); + assertEquals(TTransformerWindingEnum.PTW, powerTransformerEnd.getType()); + } + private void assertConnectivityNode(TConnectivityNode connectivityNode) { assertEquals("CONNECTIVITY_NODE82", connectivityNode.getName()); assertEquals("_af9a4ae3-ba2e-4c34-8e47-5af894ee20f4/S1 380kV/BAY_T4_2/CONNECTIVITY_NODE82", connectivityNode.getPathName()); @@ -122,10 +136,12 @@ private void assertConductingEquipment(TConductingEquipment conductingEquipment) assertEquals("CBR", conductingEquipment.getType()); } - private void assertTerminal(TTerminal terminal) { - assertEquals("T4_2_ADDB1", terminal.getName()); - assertEquals("CONNECTIVITY_NODE83", terminal.getCNodeName()); - assertEquals("_af9a4ae3-ba2e-4c34-8e47-5af894ee20f4/S1 380kV/BAY_T4_2/CONNECTIVITY_NODE83", terminal.getConnectivityNode()); + private void assertTerminal(List terminals, int size, String name, String nodeName, String connectivityNode) { + assertEquals(size, terminals.size()); + var terminal = terminals.get(0); + assertEquals(name, terminal.getName()); + assertEquals(nodeName, terminal.getCNodeName()); + assertEquals(connectivityNode, terminal.getConnectivityNode()); } private String readFile() throws IOException { @@ -140,7 +156,7 @@ void mapSubstationToTSubstation_WhenCalledWithSubstation_ThenPropertiesMappedToT var expectedDesc = "Some description"; when(cgmesSubstation.getId()).thenReturn(expectedId); - when(cgmesSubstation.getOptionalName()).thenReturn(Optional.of(expectedDesc)); + when(cgmesSubstation.getName()).thenReturn(expectedDesc); var sclSubstation = mapper.mapSubstationToTSubstation(cgmesSubstation, context); @@ -148,7 +164,7 @@ void mapSubstationToTSubstation_WhenCalledWithSubstation_ThenPropertiesMappedToT assertEquals(expectedId, sclSubstation.getName()); assertEquals(expectedDesc, sclSubstation.getDesc()); verify(cgmesSubstation, times(3)).getId(); - verify(cgmesSubstation, times(1)).getOptionalName(); + verify(cgmesSubstation, times(1)).getName(); verify(context, times(1)).addLast(sclSubstation); verifyNoMoreInteractions(cgmesSubstation); } @@ -203,11 +219,28 @@ void mapTransformerToTPowerTransformer_WhenCalledWithCgmesTransformer_ThenProper assertEquals(expectedName, sclPowerTransformer.getName()); assertEquals(expectedDesc, sclPowerTransformer.getDesc()); assertEquals(TPowerTransformerEnum.PTR, sclPowerTransformer.getType()); + verify(cgmesTransformer, times(1)).getId(); verify(cgmesTransformer, times(1)).getNameOrId(); verify(cgmesTransformer, times(1)).getDescription(); verifyNoMoreInteractions(cgmesTransformer); } + @Test + void mapTransformerEndToTTransformerWinding_WhenCalledWithCgmesTransformerEnd_ThenPropertiesMappedToTTransformerWinding() { + var expectedName = "TheName"; + + when(cgmesTransformerEnd.getNameOrId()).thenReturn(expectedName); + + var sclTransformerWinding = mapper.mapTransformerEndToTTransformerWinding(cgmesTransformerEnd, context); + + assertNotNull(sclTransformerWinding); + assertEquals(expectedName, sclTransformerWinding.getName()); + assertEquals(TTransformerWindingEnum.PTW, sclTransformerWinding.getType()); + verify(cgmesTransformerEnd, times(1)).getNameOrId(); + verify(cgmesTransformerEnd, times(1)).getTerminalId(); + verifyNoMoreInteractions(cgmesTransformerEnd); + } + @Test void mapConnectivityNodeToTConnectivityNode_WhenCalledWithCgmesConnectivityNode_ThenPropertiesMappedToTConnectivityNode() { var expectedId = "Id"; @@ -295,22 +328,5 @@ void mapTerminalToTTerminal_WhenCalledWithCgmesTerminal_ThenPropertiesMappedToTT verify(context, times(1)).getPathnameFromConnectivityNode(expectedConnectivityNode); verify(context, times(1)).getNameFromConnectivityNode(expectedConnectivityNode); verifyNoMoreInteractions(cgmesTerminal, context); - - } - - @Test - void optionalString_WhenCalledWithFilledOptional_ThenStringValueReturned() { - var expectedValue = "Some string"; - - var value = mapper.optionalString(Optional.of(expectedValue)); - - assertEquals(expectedValue, value); - } - - @Test - void optionalString_WhenCalledWithEmptyOptional_ThenBlankStringReturned() { - var value = mapper.optionalString(Optional.empty()); - - assertNull(value); } } \ No newline at end of file diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/model/AbstractCgmesEntityTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/model/AbstractCgmesEntityTest.java index c3fbc47..58de8e1 100644 --- a/service/src/test/java/org/lfenergy/compas/cim/mapping/model/AbstractCgmesEntityTest.java +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/model/AbstractCgmesEntityTest.java @@ -5,7 +5,7 @@ import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; class AbstractCgmesEntityTest extends AbstractPojoTester { @Override @@ -13,32 +13,12 @@ protected Class getClassToBeTested() { return AbstractCgmesEntity.class; } - @Test - void getOptionalName_WhenCalledWithName_ThenOptionalWithNameReturned() { - var id = "id"; - var name = "name"; - var model = new CgmesBay(id, name); - - assertNotNull(model.getOptionalName()); - assertEquals(name, model.getOptionalName().get()); - } - - @Test - void getOptionalName_WhenCalledWithoutName_ThenOptionalEmptyReturned() { - var id = "id"; - var model = new CgmesBay(id, null); - - assertNotNull(model.getOptionalName()); - assertFalse(model.getOptionalName().isPresent()); - } - @Test void getNameOrId_WhenCalledWithName_ThenNameReturned() { var id = "id"; var name = "name"; var model = new CgmesBay(id, name); - assertNotNull(model.getOptionalName()); assertEquals(name, model.getNameOrId()); } @@ -47,7 +27,6 @@ void getNameOrId_WhenCalledWithoutName_ThenIdReturned() { var id = "id"; var model = new CgmesBay(id, null); - assertNotNull(model.getOptionalName()); assertEquals(id, model.getNameOrId()); } } diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformerEndTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformerEndTest.java new file mode 100644 index 0000000..3086085 --- /dev/null +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/model/CgmesTransformerEndTest.java @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: 2021 Alliander N.V. +// +// SPDX-License-Identifier: Apache-2.0 +package org.lfenergy.compas.cim.mapping.model; + +class CgmesTransformerEndTest extends AbstractPojoTester { + @Override + protected Class getClassToBeTested() { + return CgmesTransformerEnd.class; + } +} From b4f79450ee64e6e6ebe5670de1b8f14ff358c016 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Tue, 31 Aug 2021 13:25:16 +0200 Subject: [PATCH 22/29] Added mapping of TapChanger from CIM to 61850. Signed-off-by: Dennis Labordus --- .../cim/mapping/mapper/CimToSclMapper.java | 13 ++ .../mapping/mapper/CimToSclMapperContext.java | 130 +++++++---- .../cim/mapping/model/CgmesTapChanger.java | 10 + .../mapper/CimToSclMapperContextTest.java | 205 +++++++++++------- .../mapping/mapper/CimToSclMapperTest.java | 39 +++- .../mapping/model/CgmesTapChangerTest.java | 11 + 6 files changed, 284 insertions(+), 124 deletions(-) create mode 100644 service/src/main/java/org/lfenergy/compas/cim/mapping/model/CgmesTapChanger.java create mode 100644 service/src/test/java/org/lfenergy/compas/cim/mapping/model/CgmesTapChangerTest.java diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java index c6566f8..2bb7085 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapper.java @@ -159,13 +159,26 @@ protected abstract TTransformerWinding mapTransformerEndToTTransformerWinding(Cg protected void afterTransformerEndToTTransformerWinding(CgmesTransformerEnd transformerEnd, @MappingTarget TTransformerWinding tTransformerWinding, @Context CimToSclMapperContext context) { + // Convert the Ratio-/PhaseTapChanger from IEC CIM to IEC 61850. + context.getTapChanger(transformerEnd.getId()) + .ifPresent(cgmesTapChanger -> { + var tTapChanger = mapTapChangerToTTapChanger(cgmesTapChanger, context); + tTransformerWinding.setTapChanger(tTapChanger); + }); + context.getTerminal(transformerEnd.getTerminalId()) .ifPresent(cgmesTerminal -> { var tTerminal = mapTerminalToTTerminal(cgmesTerminal, context); tTransformerWinding.getTerminal().add(tTerminal); }); + } + @Mapping(target = "name", source = "nameOrId") + @Mapping(target = "type", constant = "LTC") + protected abstract TTapChanger mapTapChangerToTTapChanger(CgmesTapChanger tapChanger, + @Context CimToSclMapperContext context); + @Mapping(target = "name", source = "nameOrId") protected abstract TConnectivityNode mapConnectivityNodeToTConnectivityNode(CgmesConnectivityNode cgmesConnectivityNode, @Context CimToSclMapperContext context); diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContext.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContext.java index 346eb17..c31a35e 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContext.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContext.java @@ -4,6 +4,7 @@ package org.lfenergy.compas.cim.mapping.mapper; import com.powsybl.cgmes.model.CgmesModel; +import com.powsybl.triplestore.api.PropertyBags; import org.lfenergy.compas.cim.mapping.model.*; import org.lfenergy.compas.scl2007b4.model.TConnectivityNode; import org.lfenergy.compas.scl2007b4.model.TNaming; @@ -12,6 +13,26 @@ import java.util.stream.Collectors; public class CimToSclMapperContext { + public static final String SUBSTATION_PROP = "Substation"; + public static final String VOLTAGE_LEVEL_PROP = "VoltageLevel"; + public static final String BAY_PROP = "Bay"; + public static final String POWER_TRANSFORMER_PROP = "PowerTransformer"; + public static final String TRANSFORMER_END_PROP = "TransformerEnd"; + public static final String RATIO_TAP_CHANGER_PROP = "RatioTapChanger"; + public static final String PHASE_TAP_CHANGER_PROP = "PhaseTapChanger"; + public static final String SWITCH_PROP = "Switch"; + public static final String TERMINAL_PROP = "Terminal"; + public static final String CONNECTIVITY_NODE_PROP = "ConnectivityNode"; + public static final String CONNECTIVITY_NODE_CONTAINER_PROP = "ConnectivityNodeContainer"; + public static final String CONDUCTING_EQUIPMENT_PROP = "ConductingEquipment"; + public static final String EQUIPMENT_CONTAINER_PROP = "EquipmentContainer"; + public static final String NAME_PROP = "name"; + public static final String DESCRIPTION_PROP = "description"; + public static final String NOMINAL_VOLTAGE_PROP = "nominalVoltage"; + public static final String TYPE_PROP = "type"; + public static final String TERMINAL_1_PROP = "Terminal1"; + public static final String TERMINAL_2_PROP = "Terminal2"; + private final CgmesModel cgmesModel; public CimToSclMapperContext(CgmesModel cgmesModel) { @@ -19,7 +40,7 @@ public CimToSclMapperContext(CgmesModel cgmesModel) { } /** - * Search the CGMES Model for all Substations that below to the network. + * Search the CGMES Model for all Substations. * * @return The List of converted CGMES Substations that were found. */ @@ -27,13 +48,13 @@ public List getSubstations() { return cgmesModel.substations() .stream() .map(propertyBag -> new CgmesSubstation( - propertyBag.getId("Substation"), - propertyBag.get("name"))) + propertyBag.getId(SUBSTATION_PROP), + propertyBag.get(NAME_PROP))) .collect(Collectors.toList()); } /** - * Search the CGMES Model for VoltageLevels that below to a specific substation. + * Search the CGMES Model for VoltageLevels that are coupled to a specific substation. * * @param substationId The ID of the Substation. * @return The List of converted CGMES VoltageLevels that were found. @@ -41,16 +62,16 @@ public List getSubstations() { public List getVoltageLevelsBySubstation(String substationId) { return cgmesModel.voltageLevels() .stream() - .filter(propertyBag -> substationId.equals(propertyBag.getId("Substation"))) + .filter(propertyBag -> substationId.equals(propertyBag.getId(SUBSTATION_PROP))) .map(propertyBag -> new CgmesVoltageLevel( - propertyBag.getId("VoltageLevel"), - propertyBag.get("name"), - propertyBag.asDouble("nominalVoltage"))) + propertyBag.getId(VOLTAGE_LEVEL_PROP), + propertyBag.get(NAME_PROP), + propertyBag.asDouble(NOMINAL_VOLTAGE_PROP))) .collect(Collectors.toList()); } /** - * Search for bays that belong to a specific Voltage Level. Because CGMES Model doesn't support this + * Search for bays that are coupled to a specific Voltage Level. Because CGMES Model doesn't support this, * a SparQL is executed against the TripleStore. * * @param voltageLevelId The ID of the Voltage Level to filter on. @@ -67,12 +88,13 @@ public List getBaysByVoltageLevel(String voltageLevelId) { " cim:Bay.VoltageLevel ?VoltageLevel ;\n" + " FILTER (str(?VoltageLevel) = \"http://default-cgmes-model/#" + voltageLevelId + "\") " + "}}").stream() - .map(bag -> new CgmesBay(bag.getId("Bay"), bag.get("name"))) + .map(bag -> new CgmesBay(bag.getId(BAY_PROP), bag.get(NAME_PROP))) .collect(Collectors.toList()); } /** - * Search the CGMES Model for Power-Transformers that below to a specific container. + * Search the CGMES Model for Power-Transformers that are coupled to a specific container. Because CGMES Model + * doesn't support filtering on Container ID, a SparQL is executed against the TripleStore. * * @param containerId The ID of the Container. * @return The List of converted CGMES Power-Transformers that were found. @@ -84,20 +106,20 @@ public List getTransformers(String containerId) { " ?PowerTransformer\n" + " a cim:PowerTransformer ;\n" + " cim:IdentifiedObject.name ?name ;\n" + - " cim:IdentifiedObject.description ?description ;\n" + " cim:Equipment.EquipmentContainer ?EquipmentContainer .\n" + + " OPTIONAL { ?PowerTransformer cim:IdentifiedObject.description ?description } \n" + + " FILTER (str(?EquipmentContainer) = \"http://default-cgmes-model/#" + containerId + "\") " + "}}") .stream() - .filter(propertyBag -> containerId.equals(propertyBag.getId("EquipmentContainer"))) .map(propertyBag -> new CgmesTransformer( - propertyBag.getId("PowerTransformer"), - propertyBag.get("name"), - propertyBag.get("description"))) + propertyBag.getId(POWER_TRANSFORMER_PROP), + propertyBag.get(NAME_PROP), + propertyBag.get(DESCRIPTION_PROP))) .collect(Collectors.toList()); } /** - * Search the CGMES Model for Power-Transformer Ends that below to a specific Power-Transformer. + * Search the CGMES Model for Power-Transformer Ends that are coupled to a specific Power-Transformer. * * @param powerTransformerId The ID of the Power-Transformer. * @return The List of converted CGMES Power-Transformer Ends that were found. @@ -105,16 +127,42 @@ public List getTransformers(String containerId) { public List getTransformerEnds(String powerTransformerId) { return cgmesModel.transformerEnds() .stream() - .filter(propertyBag -> powerTransformerId.equals(propertyBag.getId("PowerTransformer"))) + .filter(propertyBag -> powerTransformerId.equals(propertyBag.getId(POWER_TRANSFORMER_PROP))) .map(propertyBag -> new CgmesTransformerEnd( - propertyBag.getId("TransformerEnd"), - propertyBag.get("name"), - propertyBag.getId("Terminal"))) + propertyBag.getId(TRANSFORMER_END_PROP), + propertyBag.get(NAME_PROP), + propertyBag.getId(TERMINAL_PROP))) .collect(Collectors.toList()); } /** - * Search the CGMES Model for Connectivity Nodes that below to a specific container. + * Search the CGMES Model for a RatioTapChanger or PhaseTapChanger that are coupled to a Power-Transformer End. + * + * @param powerTransformerEndId The ID of the Power-Transformer End. + * @return The converted CGMEs TapChanger found, or Empty Optional if non. + */ + public Optional getTapChanger(String powerTransformerEndId) { + // Convert all the RatioTapChangers from CIM. + var tapChanger = getTapChanger(cgmesModel.ratioTapChangers(), powerTransformerEndId, RATIO_TAP_CHANGER_PROP); + if (!tapChanger.isPresent()) { + // Convert all the PhaseTapChangers from CIM. + tapChanger = getTapChanger(cgmesModel.phaseTapChangers(), powerTransformerEndId, PHASE_TAP_CHANGER_PROP); + } + return tapChanger; + } + + private Optional getTapChanger(PropertyBags tapChangers, String powerTransformerEndId, String idName) { + return tapChangers + .stream() + .filter(propertyBag -> powerTransformerEndId.equals(propertyBag.getId(TRANSFORMER_END_PROP))) + .map(propertyBag -> new CgmesTapChanger( + propertyBag.getId(idName), + propertyBag.get(NAME_PROP))) + .findFirst(); + } + + /** + * Search the CGMES Model for Connectivity Nodes that are coupled to a specific container. * * @param containerId The ID of the Container. * @return The List of converted CGMES Connectivity Nodes that were found. @@ -122,15 +170,15 @@ public List getTransformerEnds(String powerTransformerId) { public List getConnectivityNode(String containerId) { return cgmesModel.connectivityNodes() .stream() - .filter(propertyBag -> containerId.equals(propertyBag.getId("ConnectivityNodeContainer"))) + .filter(propertyBag -> containerId.equals(propertyBag.getId(CONNECTIVITY_NODE_CONTAINER_PROP))) .map(propertyBag -> new CgmesConnectivityNode( - propertyBag.getId("ConnectivityNode"), - propertyBag.get("name"))) + propertyBag.getId(CONNECTIVITY_NODE_PROP), + propertyBag.get(NAME_PROP))) .collect(Collectors.toList()); } /** - * Search the CGMES Model for Switches (Breakers, Disconnector and more) that below to a specific container. + * Search the CGMES Model for Switches (Breakers, Disconnector and more) that are coupled to a specific container. * * @param containerId The ID of the Container. * @return The List of converted CGMES Switches that were found. @@ -138,18 +186,18 @@ public List getConnectivityNode(String containerId) { public List getSwitches(String containerId) { return cgmesModel.switches() .stream() - .filter(propertyBag -> containerId.equals(propertyBag.getId("EquipmentContainer"))) + .filter(propertyBag -> containerId.equals(propertyBag.getId(EQUIPMENT_CONTAINER_PROP))) .map(propertyBag -> new CgmesSwitch( - propertyBag.getId("Switch"), - propertyBag.get("name"), - propertyBag.getLocal("type"), - propertyBag.getId("Terminal1"), - propertyBag.getId("Terminal2"))) + propertyBag.getId(SWITCH_PROP), + propertyBag.get(NAME_PROP), + propertyBag.getLocal(TYPE_PROP), + propertyBag.getId(TERMINAL_1_PROP), + propertyBag.getId(TERMINAL_2_PROP))) .collect(Collectors.toList()); } /** - * Search the CGMES Model for Terminals that below to a specific Conducting Equipment. + * Search the CGMES Model for Terminals that are coupled to a specific Conducting Equipment. * * @param conductingEquipmentId The ID of the Conducting Equipment. * @return The List of converted CGMES Terminals that were found. @@ -157,11 +205,11 @@ public List getSwitches(String containerId) { public List getTerminals(String conductingEquipmentId) { return cgmesModel.terminals() .stream() - .filter(propertyBag -> conductingEquipmentId.equals(propertyBag.getId("ConductingEquipment"))) + .filter(propertyBag -> conductingEquipmentId.equals(propertyBag.getId(CONDUCTING_EQUIPMENT_PROP))) .map(propertyBag -> new CgmesTerminal( - propertyBag.getId("Terminal"), - propertyBag.get("name"), - propertyBag.getId("ConnectivityNode"))) + propertyBag.getId(TERMINAL_PROP), + propertyBag.get(NAME_PROP), + propertyBag.getId(CONNECTIVITY_NODE_PROP))) .collect(Collectors.toList()); } @@ -174,11 +222,11 @@ public List getTerminals(String conductingEquipmentId) { public Optional getTerminal(String terminalId) { return cgmesModel.terminals() .stream() - .filter(propertyBag -> terminalId.equals(propertyBag.getId("Terminal"))) + .filter(propertyBag -> terminalId.equals(propertyBag.getId(TERMINAL_PROP))) .map(propertyBag -> new CgmesTerminal( - propertyBag.getId("Terminal"), - propertyBag.get("name"), - propertyBag.getId("ConnectivityNode"))) + propertyBag.getId(TERMINAL_PROP), + propertyBag.get(NAME_PROP), + propertyBag.getId(CONNECTIVITY_NODE_PROP))) .findFirst(); } diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/model/CgmesTapChanger.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/model/CgmesTapChanger.java new file mode 100644 index 0000000..e087b06 --- /dev/null +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/model/CgmesTapChanger.java @@ -0,0 +1,10 @@ +// SPDX-FileCopyrightText: 2021 Alliander N.V. +// +// SPDX-License-Identifier: Apache-2.0 +package org.lfenergy.compas.cim.mapping.model; + +public class CgmesTapChanger extends AbstractCgmesEntity { + public CgmesTapChanger(String id, String name) { + super(id, name); + } +} diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContextTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContextTest.java index 2a797db..2295905 100644 --- a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContextTest.java +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperContextTest.java @@ -19,6 +19,7 @@ import java.util.List; import static org.junit.jupiter.api.Assertions.*; +import static org.lfenergy.compas.cim.mapping.mapper.CimToSclMapperContext.*; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -36,9 +37,9 @@ void getSubstations_WhenCalled_ThenPropertyBagsIsConvertedToCgmesSubstation() { var substationId = "SubstationId"; var substationName = "Name Substation"; var bags = new PropertyBags(); - var bag = new PropertyBag(List.of("Substation", "name")); - bag.put("Substation", substationId); - bag.put("name", substationName); + var bag = new PropertyBag(List.of(SUBSTATION_PROP, NAME_PROP)); + bag.put(SUBSTATION_PROP, substationId); + bag.put(NAME_PROP, substationName); bags.add(bag); when(cgmesModel.substations()).thenReturn(bags); @@ -57,18 +58,18 @@ void getVoltageLevelsBySubstation_WhenCalledWithKnownId_ThenPropertyBagsIsFilter var voltageLevelName = "Name VoltageLevel"; var substationId = "Known Substation ID"; var bags = new PropertyBags(); - var bag = new PropertyBag(List.of("VoltageLevel", "name", "nominalVoltage", "Substation")); - bag.put("VoltageLevel", voltageLevelId); - bag.put("name", voltageLevelName); - bag.put("nominalVoltage", "1.0"); - bag.put("Substation", substationId); + var bag = new PropertyBag(List.of(VOLTAGE_LEVEL_PROP, NAME_PROP, NOMINAL_VOLTAGE_PROP, SUBSTATION_PROP)); + bag.put(VOLTAGE_LEVEL_PROP, voltageLevelId); + bag.put(NAME_PROP, voltageLevelName); + bag.put(NOMINAL_VOLTAGE_PROP, "1.0"); + bag.put(SUBSTATION_PROP, substationId); bags.add(bag); - bag = new PropertyBag(List.of("VoltageLevel", "name", "nominalVoltage", "Substation")); - bag.put("VoltageLevel", "Other ID"); - bag.put("name", "Other Name"); - bag.put("nominalVoltage", "1.1"); - bag.put("Substation", "Unknown Container ID"); + bag = new PropertyBag(List.of(VOLTAGE_LEVEL_PROP, NAME_PROP, NOMINAL_VOLTAGE_PROP, SUBSTATION_PROP)); + bag.put(VOLTAGE_LEVEL_PROP, "Other ID"); + bag.put(NAME_PROP, "Other Name"); + bag.put(NOMINAL_VOLTAGE_PROP, "1.1"); + bag.put(SUBSTATION_PROP, "Unknown Container ID"); bags.add(bag); when(cgmesModel.voltageLevels()).thenReturn(bags); @@ -86,9 +87,9 @@ void getBaysByVoltageLevel_WhenSparQLReturnsBags_ThenPropertyBagIsConvertedToCgm var bayId = "BayId"; var bayName = "Name Bay"; var bags = new PropertyBags(); - var bag = new PropertyBag(List.of("Bay", "name")); - bag.put("Bay", bayId); - bag.put("name", bayName); + var bag = new PropertyBag(List.of(BAY_PROP, NAME_PROP)); + bag.put(BAY_PROP, bayId); + bag.put(NAME_PROP, bayName); bags.add(bag); var tripleStore = mock(TripleStore.class); @@ -111,18 +112,11 @@ void getTransformers_WhenSparQLReturnsBags_ThenPropertyBagIsConvertedToCgmesTran var pwDesc = "Desc Powertransformer"; var pwContainerId = "Known Container ID"; var bags = new PropertyBags(); - var bag = new PropertyBag(List.of("PowerTransformer", "name", "description", "EquipmentContainer")); - bag.put("PowerTransformer", pwId); - bag.put("name", pwName); - bag.put("description", pwDesc); - bag.put("EquipmentContainer", pwContainerId); - bags.add(bag); - - bag = new PropertyBag(List.of("PowerTransformer", "name", "description", "EquipmentContainer")); - bag.put("PowerTransformer", "Other ID"); - bag.put("name", "Other name"); - bag.put("description", "Other desc"); - bag.put("EquipmentContainer", "Unknown Container ID"); + var bag = new PropertyBag(List.of(POWER_TRANSFORMER_PROP, NAME_PROP, DESCRIPTION_PROP, EQUIPMENT_CONTAINER_PROP)); + bag.put(POWER_TRANSFORMER_PROP, pwId); + bag.put(NAME_PROP, pwName); + bag.put(DESCRIPTION_PROP, pwDesc); + bag.put(EQUIPMENT_CONTAINER_PROP, pwContainerId); bags.add(bag); var tripleStore = mock(TripleStore.class); @@ -146,18 +140,18 @@ void getTransformerEnds_WhenCalledWithKnownId_ThenPropertyBagsIsFilteredOnIdAndC var terminalId = "Known Terminal ID"; var tfId = "Known Transformer ID"; var bags = new PropertyBags(); - var bag = new PropertyBag(List.of("TransformerEnd", "name", "PowerTransformer", "Terminal")); - bag.put("TransformerEnd", tfeId); - bag.put("name", tfeName); - bag.put("PowerTransformer", tfId); - bag.put("Terminal", terminalId); + var bag = new PropertyBag(List.of(TRANSFORMER_END_PROP, NAME_PROP, POWER_TRANSFORMER_PROP, TERMINAL_PROP)); + bag.put(TRANSFORMER_END_PROP, tfeId); + bag.put(NAME_PROP, tfeName); + bag.put(POWER_TRANSFORMER_PROP, tfId); + bag.put(TERMINAL_PROP, terminalId); bags.add(bag); - bag = new PropertyBag(List.of("TransformerEnd", "name", "PowerTransformer", "Terminal")); - bag.put("TransformerEnd", "Other ID"); - bag.put("name", "Other Name"); - bag.put("PowerTransformer", "Unknown Transformer ID"); - bag.put("Terminal", "Other Terminal ID"); + bag = new PropertyBag(List.of(TRANSFORMER_END_PROP, NAME_PROP, POWER_TRANSFORMER_PROP, TERMINAL_PROP)); + bag.put(TRANSFORMER_END_PROP, "Other ID"); + bag.put(NAME_PROP, "Other Name"); + bag.put(POWER_TRANSFORMER_PROP, "Unknown Transformer ID"); + bag.put(TERMINAL_PROP, "Other Terminal ID"); bags.add(bag); when(cgmesModel.transformerEnds()).thenReturn(bags); @@ -171,22 +165,77 @@ void getTransformerEnds_WhenCalledWithKnownId_ThenPropertyBagsIsFilteredOnIdAndC assertEquals(terminalId, ccn.getTerminalId()); } + @Test + void getTapChanger_WhenNoTapChangersFound_ThenEmptyOptionalReturned() { + var tfeId = "Known Transformer End ID"; + + when(cgmesModel.ratioTapChangers()).thenReturn(new PropertyBags()); + when(cgmesModel.phaseTapChangers()).thenReturn(new PropertyBags()); + + var result = context.getTapChanger(tfeId); + assertFalse(result.isPresent()); + } + + @Test + void getTapChanger_WhenRatioTapChangersFound_ThenConvertedRatioTapChangerReturned() { + var tcId = "TapChangerId"; + var tcName = "Name TapChanger"; + var tfeId = "Known Transformer End ID"; + + var bags = new PropertyBags(); + var bag = new PropertyBag(List.of(RATIO_TAP_CHANGER_PROP, NAME_PROP, TRANSFORMER_END_PROP)); + bag.put(RATIO_TAP_CHANGER_PROP, tcId); + bag.put(NAME_PROP, tcName); + bag.put(TRANSFORMER_END_PROP, tfeId); + bags.add(bag); + when(cgmesModel.ratioTapChangers()).thenReturn(bags); + + var result = context.getTapChanger(tfeId); + assertTrue(result.isPresent()); + var tapChanger = result.get(); + assertEquals(tcId, tapChanger.getId()); + assertEquals(tcName, tapChanger.getName()); + } + + @Test + void getTapChanger_WhenNoRatioTapChangerFoundButPhaseTapChangersFound_ThenConvertedPhaseTapChangerReturned() { + var tcId = "TapChangerId"; + var tcName = "Name TapChanger"; + var tfeId = "Known Transformer End ID"; + + when(cgmesModel.ratioTapChangers()).thenReturn(new PropertyBags()); + + var bags = new PropertyBags(); + var bag = new PropertyBag(List.of(PHASE_TAP_CHANGER_PROP, NAME_PROP, TRANSFORMER_END_PROP)); + bag.put(PHASE_TAP_CHANGER_PROP, tcId); + bag.put(NAME_PROP, tcName); + bag.put(TRANSFORMER_END_PROP, tfeId); + bags.add(bag); + when(cgmesModel.phaseTapChangers()).thenReturn(bags); + + var result = context.getTapChanger(tfeId); + assertTrue(result.isPresent()); + var tapChanger = result.get(); + assertEquals(tcId, tapChanger.getId()); + assertEquals(tcName, tapChanger.getName()); + } + @Test void getConnectivityNode_WhenCalledWithKnownId_ThenPropertyBagsIsFilteredOnIdAndConvertedToCgmesConnectivityNode() { var ccnId = "CcnId"; var ccnName = "Name Ccn"; var ccnContainerId = "Known Container ID"; var bags = new PropertyBags(); - var bag = new PropertyBag(List.of("ConnectivityNode", "name", "ConnectivityNodeContainer")); - bag.put("ConnectivityNode", ccnId); - bag.put("name", ccnName); - bag.put("ConnectivityNodeContainer", ccnContainerId); + var bag = new PropertyBag(List.of(CONNECTIVITY_NODE_PROP, NAME_PROP, CONNECTIVITY_NODE_CONTAINER_PROP)); + bag.put(CONNECTIVITY_NODE_PROP, ccnId); + bag.put(NAME_PROP, ccnName); + bag.put(CONNECTIVITY_NODE_CONTAINER_PROP, ccnContainerId); bags.add(bag); - bag = new PropertyBag(List.of("ConnectivityNode", "name", "ConnectivityNodeContainer")); - bag.put("ConnectivityNode", "Other ID"); - bag.put("name", "Other Name"); - bag.put("ConnectivityNodeContainer", "Unknown Container ID"); + bag = new PropertyBag(List.of(CONNECTIVITY_NODE_PROP, NAME_PROP, CONNECTIVITY_NODE_CONTAINER_PROP)); + bag.put(CONNECTIVITY_NODE_PROP, "Other ID"); + bag.put(NAME_PROP, "Other Name"); + bag.put(CONNECTIVITY_NODE_CONTAINER_PROP, "Unknown Container ID"); bags.add(bag); when(cgmesModel.connectivityNodes()).thenReturn(bags); @@ -205,20 +254,20 @@ void getSwitches_WhenCalledWithKnownId_ThenPropertyBagsIsFilteredOnIdAndConverte var switchName = "Name Switch"; var containerId = "Known Container ID"; var bags = new PropertyBags(); - var bag = new PropertyBag(List.of("Switch", "name", "type", "EquipmentContainer", "Terminal1", "Terminal2")); - bag.put("Switch", switchId); - bag.put("name", switchName); - bag.put("type", "Breaker"); - bag.put("EquipmentContainer", containerId); - bag.put("Terminal1", "Terminal1 ID"); - bag.put("Terminal2", "Terminal2 ID"); + var bag = new PropertyBag(List.of(SWITCH_PROP, NAME_PROP, TYPE_PROP, EQUIPMENT_CONTAINER_PROP, TERMINAL_1_PROP, TERMINAL_2_PROP)); + bag.put(SWITCH_PROP, switchId); + bag.put(NAME_PROP, switchName); + bag.put(TYPE_PROP, "Breaker"); + bag.put(EQUIPMENT_CONTAINER_PROP, containerId); + bag.put(TERMINAL_1_PROP, "Terminal1 ID"); + bag.put(TERMINAL_2_PROP, "Terminal2 ID"); bags.add(bag); - bag = new PropertyBag(List.of("Switch", "name", "type", "EquipmentContainer", "Terminal1", "Terminal2")); - bag.put("Switch", "Other ID"); - bag.put("name", "Other Name"); - bag.put("type", "Breaker"); - bag.put("EquipmentContainer", "Unknown Container ID"); + bag = new PropertyBag(List.of(SWITCH_PROP, NAME_PROP, TYPE_PROP, EQUIPMENT_CONTAINER_PROP, TERMINAL_1_PROP, TERMINAL_2_PROP)); + bag.put(SWITCH_PROP, "Other ID"); + bag.put(NAME_PROP, "Other Name"); + bag.put(TYPE_PROP, "Breaker"); + bag.put(EQUIPMENT_CONTAINER_PROP, "Unknown Container ID"); bags.add(bag); when(cgmesModel.switches()).thenReturn(bags); @@ -238,18 +287,18 @@ void getTerminals_WhenCalledWithKnownId_ThenPropertyBagsIsFilteredOnIdAndConvert var ccnNode = "Connectivity Node ID"; var containerId = "Known Container ID"; var bags = new PropertyBags(); - var bag = new PropertyBag(List.of("Terminal", "name", "ConnectivityNode", "ConductingEquipment")); - bag.put("Terminal", terminalId); - bag.put("name", terminalName); - bag.put("ConnectivityNode", ccnNode); - bag.put("ConductingEquipment", containerId); + var bag = new PropertyBag(List.of(TERMINAL_PROP, NAME_PROP, CONNECTIVITY_NODE_PROP, CONDUCTING_EQUIPMENT_PROP)); + bag.put(TERMINAL_PROP, terminalId); + bag.put(NAME_PROP, terminalName); + bag.put(CONNECTIVITY_NODE_PROP, ccnNode); + bag.put(CONDUCTING_EQUIPMENT_PROP, containerId); bags.add(bag); - bag = new PropertyBag(List.of("Terminal", "name", "ConnectivityNode", "ConductingEquipment")); - bag.put("Terminal", "Other ID"); - bag.put("name", "Other Name"); - bag.put("ConnectivityNode", "Some Other ID"); - bag.put("ConductingEquipment", "Unknown Container ID"); + bag = new PropertyBag(List.of(TERMINAL_PROP, NAME_PROP, CONNECTIVITY_NODE_PROP, CONDUCTING_EQUIPMENT_PROP)); + bag.put(TERMINAL_PROP, "Other ID"); + bag.put(NAME_PROP, "Other Name"); + bag.put(CONNECTIVITY_NODE_PROP, "Some Other ID"); + bag.put(CONDUCTING_EQUIPMENT_PROP, "Unknown Container ID"); bags.add(bag); when(cgmesModel.terminals()).thenReturn(bags); @@ -270,18 +319,18 @@ void getTerminal_WhenCalledWithKnownId_ThenPropertyBagsIsFilteredOnIdAndConverte var ccnNode = "Connectivity Node ID"; var containerId = "Known Container ID"; var bags = new PropertyBags(); - var bag = new PropertyBag(List.of("Terminal", "name", "ConnectivityNode", "ConductingEquipment")); - bag.put("Terminal", terminalId); - bag.put("name", terminalName); - bag.put("ConnectivityNode", ccnNode); - bag.put("ConductingEquipment", containerId); + var bag = new PropertyBag(List.of(TERMINAL_PROP, NAME_PROP, CONNECTIVITY_NODE_PROP, CONDUCTING_EQUIPMENT_PROP)); + bag.put(TERMINAL_PROP, terminalId); + bag.put(NAME_PROP, terminalName); + bag.put(CONNECTIVITY_NODE_PROP, ccnNode); + bag.put(CONDUCTING_EQUIPMENT_PROP, containerId); bags.add(bag); - bag = new PropertyBag(List.of("Terminal", "name", "ConnectivityNode", "ConductingEquipment")); - bag.put("Terminal", "Other ID"); - bag.put("name", "Other Name"); - bag.put("ConnectivityNode", "Some Other ID"); - bag.put("ConductingEquipment", "Unknown Container ID"); + bag = new PropertyBag(List.of(TERMINAL_PROP, NAME_PROP, CONNECTIVITY_NODE_PROP, CONDUCTING_EQUIPMENT_PROP)); + bag.put(TERMINAL_PROP, "Other ID"); + bag.put(NAME_PROP, "Other Name"); + bag.put(CONNECTIVITY_NODE_PROP, "Some Other ID"); + bag.put(CONDUCTING_EQUIPMENT_PROP, "Unknown Container ID"); bags.add(bag); when(cgmesModel.terminals()).thenReturn(bags); diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java index 4dd1271..f591c1c 100644 --- a/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/mapper/CimToSclMapperTest.java @@ -44,6 +44,8 @@ class CimToSclMapperTest { @Mock private CgmesTransformerEnd cgmesTransformerEnd; @Mock + private CgmesTapChanger cgmesTapChanger; + @Mock private CgmesConnectivityNode cgmesConnectivityNode; @Mock private CgmesSwitch cgmesSwitch; @@ -81,14 +83,15 @@ void map_WhenWithCimData_ThenSclMapped() throws IOException { assertEquals("_af9a4ae3-ba2e-4c34-8e47-5af894ee20f4", substation.getName()); assertEquals("Sub1", substation.getDesc()); - assertEquals(1, substation.getPowerTransformer().size()); - var powerTransformer = substation.getPowerTransformer().get(0); + assertEquals(2, substation.getPowerTransformer().size()); + var powerTransformer = substation.getPowerTransformer().get(1); assertPowerTransformer(powerTransformer); assertEquals(3, powerTransformer.getTransformerWinding().size()); - var powerTransformerEnd = powerTransformer.getTransformerWinding().get(0); - assertTransformerWinding(powerTransformerEnd); - assertTerminal(powerTransformerEnd.getTerminal(), 1, "T3_0", "CONNECTIVITY_NODE88", + var transformerWinding = powerTransformer.getTransformerWinding().get(0); + assertTransformerWinding(transformerWinding); + assertTapChanger(transformerWinding.getTapChanger()); + assertTerminal(transformerWinding.getTerminal(), 1, "T3_0", "CONNECTIVITY_NODE88", "_af9a4ae3-ba2e-4c34-8e47-5af894ee20f4/S1 380kV/BAY_T3_0/CONNECTIVITY_NODE88"); assertEquals(3, substation.getVoltageLevel().size()); @@ -116,26 +119,36 @@ void map_WhenWithCimData_ThenSclMapped() throws IOException { } private void assertPowerTransformer(TPowerTransformer powerTransformer) { + assertNotNull(powerTransformer); assertEquals("T3", powerTransformer.getName()); assertEquals(TPowerTransformerEnum.PTR, powerTransformer.getType()); assertEquals("Trafo-5", powerTransformer.getDesc()); } private void assertTransformerWinding(TTransformerWinding powerTransformerEnd) { + assertNotNull(powerTransformerEnd); assertEquals("T3", powerTransformerEnd.getName()); assertEquals(TTransformerWindingEnum.PTW, powerTransformerEnd.getType()); } private void assertConnectivityNode(TConnectivityNode connectivityNode) { + assertNotNull(connectivityNode); assertEquals("CONNECTIVITY_NODE82", connectivityNode.getName()); assertEquals("_af9a4ae3-ba2e-4c34-8e47-5af894ee20f4/S1 380kV/BAY_T4_2/CONNECTIVITY_NODE82", connectivityNode.getPathName()); } private void assertConductingEquipment(TConductingEquipment conductingEquipment) { + assertNotNull(conductingEquipment); assertEquals("BREAKER25", conductingEquipment.getName()); assertEquals("CBR", conductingEquipment.getType()); } + private void assertTapChanger(TTapChanger tapChanger) { + assertNotNull(tapChanger); + assertEquals("T3", tapChanger.getName()); + assertEquals("LTC", tapChanger.getType()); + } + private void assertTerminal(List terminals, int size, String name, String nodeName, String connectivityNode) { assertEquals(size, terminals.size()); var terminal = terminals.get(0); @@ -236,11 +249,27 @@ void mapTransformerEndToTTransformerWinding_WhenCalledWithCgmesTransformerEnd_Th assertNotNull(sclTransformerWinding); assertEquals(expectedName, sclTransformerWinding.getName()); assertEquals(TTransformerWindingEnum.PTW, sclTransformerWinding.getType()); + verify(cgmesTransformerEnd, times(1)).getId(); verify(cgmesTransformerEnd, times(1)).getNameOrId(); verify(cgmesTransformerEnd, times(1)).getTerminalId(); verifyNoMoreInteractions(cgmesTransformerEnd); } + @Test + void mapTapChangerToTTapChanger_WhenCalledWithCgmesTapChanger_ThenPropertiesMappedToTTapChanger() { + var expectedName = "TheName"; + + when(cgmesTapChanger.getNameOrId()).thenReturn(expectedName); + + var sclTapChanger = mapper.mapTapChangerToTTapChanger(cgmesTapChanger, context); + + assertNotNull(sclTapChanger); + assertEquals(expectedName, sclTapChanger.getName()); + assertEquals("LTC", sclTapChanger.getType()); + verify(cgmesTapChanger, times(1)).getNameOrId(); + verifyNoMoreInteractions(cgmesTapChanger); + } + @Test void mapConnectivityNodeToTConnectivityNode_WhenCalledWithCgmesConnectivityNode_ThenPropertiesMappedToTConnectivityNode() { var expectedId = "Id"; diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/model/CgmesTapChangerTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/model/CgmesTapChangerTest.java new file mode 100644 index 0000000..1cb3fd9 --- /dev/null +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/model/CgmesTapChangerTest.java @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: 2021 Alliander N.V. +// +// SPDX-License-Identifier: Apache-2.0 +package org.lfenergy.compas.cim.mapping.model; + +class CgmesTapChangerTest extends AbstractPojoTester { + @Override + protected Class getClassToBeTested() { + return CgmesTapChanger.class; + } +} From fa7de1f2a4f335da6f17867ee9e5447bd2f6c0a7 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Tue, 31 Aug 2021 13:32:31 +0200 Subject: [PATCH 23/29] Added mapping of TapChanger from CIM to 61850. Signed-off-by: Dennis Labordus --- MAPPING.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAPPING.md b/MAPPING.md index cf1860f..0121f02 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -65,6 +65,13 @@ ProtectedSwitch.These classes are all mapped in the same way on IEC 61850 (1): The terminal found in IEC CIM will be added as List to IEC 61850. +| CIM Class | IEC Class | Remark | +| -------------------------------- | -------------------------------- | --------- | +| *cim:RatioTapChanger* | *TTapChanger* | | +| *cim:PhaseTapChanger* | *TTapChanger* | | +| name or id | name | | +| 'LTC' | type | | + | CIM Class | IEC Class | Remark | | -------------------------------- | -------------------------------- | --------- | | *cim:ConnectivityNode* | *TConnectivityNode* | | From 94ddc3e38d04542cea8e8dbcbb3320ebf0eb3c9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Aug 2021 15:17:32 +0000 Subject: [PATCH 24/29] Bump quarkus.platform.version from 2.1.4.Final to 2.2.1.Final Bumps `quarkus.platform.version` from 2.1.4.Final to 2.2.1.Final. Updates `quarkus-universe-bom` from 2.1.4.Final to 2.2.1.Final - [Release notes](https://github.com/quarkusio/quarkus-platform/releases) - [Commits](https://github.com/quarkusio/quarkus-platform/compare/2.1.4.Final...2.2.1.Final) Updates `quarkus-maven-plugin` from 2.1.4.Final to 2.2.1.Final --- updated-dependencies: - dependency-name: io.quarkus:quarkus-universe-bom dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.quarkus:quarkus-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pom.xml b/app/pom.xml index e525c52..02b9a8f 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 jar - 2.1.4.Final + 2.2.1.Final From 056423d23339d624c32b2e09778516e8551bb807 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Wed, 1 Sep 2021 08:53:17 +0200 Subject: [PATCH 25/29] Make configurable which claim to use for Who. Signed-off-by: Dennis Labordus --- README.md | 9 +++++++++ app/pom.xml | 2 +- .../compas/cim/mapping/rest/UserInfoProperties.java | 13 +++++++++++++ .../mapping/rest/v1/CompasCimMappingResource.java | 12 +++++++++--- app/src/main/resources/application.properties | 2 ++ .../rest/v1/CompasCimMappingResourceTest.java | 11 ++++++++--- .../mapping/service/CompasCimMappingService.java | 9 ++++----- .../service/CompasCimMappingServiceTest.java | 12 ++++-------- 8 files changed, 50 insertions(+), 20 deletions(-) create mode 100644 app/src/main/java/org/lfenergy/compas/cim/mapping/rest/UserInfoProperties.java diff --git a/README.md b/README.md index 2f70720..1691206 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,15 @@ You can then execute your native executable with: `./app/target/code-with-quarku If you want to learn more about building native executables, please consult https://quarkus.io/guides/maven-tooling.html . +## Environment variables + +Below environment variable(s) can be used to configure which claims are used to fill user information, for instance Who +in History Record. + +| Environment variable | Java Property | Description | Example | +| -------------------------------- | ------------------------------ | --------------------------------------------- | ---------------- | +| USERINFO_WHO_CLAIMNAME | compas.userinfo.who.claimname | The Name of the user use in the WHo History. | name | + ## Security To use most of the endpoints the users needs to be authenticated using JWT in the authorization header. There are 4 diff --git a/app/pom.xml b/app/pom.xml index e525c52..c8a6152 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -94,7 +94,7 @@ SPDX-License-Identifier: Apache-2.0 io.quarkus - quarkus-test-security + quarkus-test-security-jwt test diff --git a/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/UserInfoProperties.java b/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/UserInfoProperties.java new file mode 100644 index 0000000..b800ecb --- /dev/null +++ b/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/UserInfoProperties.java @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2021 Alliander N.V. +// +// SPDX-License-Identifier: Apache-2.0 +package org.lfenergy.compas.cim.mapping.rest; + +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithName; + +@ConfigMapping(prefix = "compas.userinfo") +public interface UserInfoProperties { + @WithName("who.claimname") + String who(); +} diff --git a/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResource.java b/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResource.java index 5efa426..149cb05 100644 --- a/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResource.java +++ b/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResource.java @@ -4,7 +4,8 @@ package org.lfenergy.compas.cim.mapping.rest.v1; import io.quarkus.security.Authenticated; -import io.quarkus.security.identity.SecurityIdentity; +import org.eclipse.microprofile.jwt.JsonWebToken; +import org.lfenergy.compas.cim.mapping.rest.UserInfoProperties; import org.lfenergy.compas.cim.mapping.rest.v1.model.MapRequest; import org.lfenergy.compas.cim.mapping.rest.v1.model.MapResponse; import org.lfenergy.compas.cim.mapping.service.CompasCimMappingService; @@ -25,7 +26,10 @@ public class CompasCimMappingResource { private CompasCimMappingService compasCimMappingService; @Inject - SecurityIdentity securityIdentity; + JsonWebToken jsonWebToken; + + @Inject + UserInfoProperties userInfoProperties; @Inject public CompasCimMappingResource(CompasCimMappingService compasCimMappingService) { @@ -37,8 +41,10 @@ public CompasCimMappingResource(CompasCimMappingService compasCimMappingService) @Consumes(MediaType.APPLICATION_XML) @Produces(MediaType.APPLICATION_XML) public MapResponse mapCimToScl(@Valid MapRequest request) { + String username = jsonWebToken.getClaim(userInfoProperties.who()); + var response = new MapResponse(); - response.setScl(compasCimMappingService.map(request.getCimData(), securityIdentity.getPrincipal())); + response.setScl(compasCimMappingService.map(request.getCimData(), username)); return response; } } \ No newline at end of file diff --git a/app/src/main/resources/application.properties b/app/src/main/resources/application.properties index fbfa191..2f841a2 100644 --- a/app/src/main/resources/application.properties +++ b/app/src/main/resources/application.properties @@ -2,6 +2,8 @@ # # SPDX-License-Identifier: Apache-2.0 +compas.userinfo.who.claimname = ${USERINFO_WHO_CLAIMNAME:name} + quarkus.http.cors = false quarkus.http.root-path = /compas-cim-mapping/ quarkus.http.limits.max-body-size = 150M diff --git a/app/src/test/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResourceTest.java b/app/src/test/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResourceTest.java index 793c8b2..04d25c6 100644 --- a/app/src/test/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResourceTest.java +++ b/app/src/test/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResourceTest.java @@ -7,6 +7,8 @@ import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.mockito.InjectMock; import io.quarkus.test.security.TestSecurity; +import io.quarkus.test.security.jwt.Claim; +import io.quarkus.test.security.jwt.JwtSecurity; import io.restassured.http.ContentType; import org.junit.jupiter.api.Test; import org.lfenergy.compas.cim.mapping.model.CimData; @@ -18,7 +20,6 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; -import java.security.Principal; import java.util.List; import static io.restassured.RestAssured.given; @@ -32,6 +33,10 @@ @QuarkusTest @TestHTTPEndpoint(CompasCimMappingResource.class) @TestSecurity(user = "test-mapper") +@JwtSecurity(claims = { + // Default the claim "name" is configured for Who, so we will set this claim for the test. + @Claim(key = "name", value = "Test User") +}) class CompasCimMappingResourceTest { @InjectMock private CompasCimMappingService compasCimMappingService; @@ -47,7 +52,7 @@ void mapCimToScl_WhenCalled_ThenCorrectMessageIsRetrieved() throws IOException { var scl = new SCL(); scl.setVersion("2007"); - when(compasCimMappingService.map(any(), any(Principal.class))).thenReturn(scl); + when(compasCimMappingService.map(any(), eq("Test User"))).thenReturn(scl); var response = given() .contentType(ContentType.XML) @@ -65,7 +70,7 @@ void mapCimToScl_WhenCalled_ThenCorrectMessageIsRetrieved() throws IOException { var sclVersion = xmlPath.getString("cms:MapResponse.scl:SCL.@version"); assertNotNull(sclVersion); assertEquals("2007", sclVersion); - verify(compasCimMappingService, times(1)).map(any(), any(Principal.class)); + verify(compasCimMappingService, times(1)).map(any(), eq("Test User")); } private String readFile() throws IOException { diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java index 5a23f75..25353f3 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java @@ -14,7 +14,6 @@ import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; -import java.security.Principal; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; @@ -47,8 +46,8 @@ public CompasCimMappingService(CgmesCimReader cgmesCimReader, * @param principal * @return The created SCL Model. */ - public SCL map(List cimData, Principal principal) { - var scl = createBasicSCL(cimData, principal); + public SCL map(List cimData, String who) { + var scl = createBasicSCL(cimData, who); if (cimData != null && !cimData.isEmpty()) { // Convert the Data to the Network Model from PowSyBl @@ -64,7 +63,7 @@ public SCL map(List cimData, Principal principal) { * * @return The created SCL Model. */ - SCL createBasicSCL(List cimData, Principal principal) { + SCL createBasicSCL(List cimData, String who) { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssXXX"); ObjectFactory factory = new ObjectFactory(); @@ -87,7 +86,7 @@ SCL createBasicSCL(List cimData, Principal principal) { item.setVersion(INITIAL_VERSION); item.setRevision(INITIAL_REVISION); item.setWhen(formatter.format(new Date())); - item.setWho(principal.getName()); + item.setWho(who); // Add all CIM filenames that where used to create the SCL Content. String what = "SCL created from CIM File(s)"; diff --git a/service/src/test/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingServiceTest.java b/service/src/test/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingServiceTest.java index 008eb1f..fc0ce54 100644 --- a/service/src/test/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingServiceTest.java +++ b/service/src/test/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingServiceTest.java @@ -15,7 +15,6 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import java.security.Principal; import java.util.Collections; import java.util.List; @@ -27,8 +26,6 @@ class CompasCimMappingServiceTest { @Mock private CgmesModel cgmesModel; - @Mock - private Principal principal; @Mock private CgmesCimReader cgmesCimReader; @@ -43,7 +40,7 @@ void map_WhenCalledWithData_ThenReaderAndMapperAreCalled() { when(cgmesCimReader.readModel(any())).thenReturn(cgmesModel); var cimDataList = List.of(new CimData()); - var scl = compasCimMappingService.map(cimDataList, principal); + var scl = compasCimMappingService.map(cimDataList, "username"); assertNotNull(scl); verify(cgmesCimReader, times(1)).readModel(cimDataList); @@ -53,7 +50,7 @@ void map_WhenCalledWithData_ThenReaderAndMapperAreCalled() { @Test void map_WhenCalledWithoutData_ThenReaderAndMapperAreNotCalled() { - var scl = compasCimMappingService.map(Collections.emptyList(), principal); + var scl = compasCimMappingService.map(Collections.emptyList(), "username"); assertNotNull(scl); verifyNoInteractions(cgmesCimReader, cimToSclMapper); @@ -61,7 +58,7 @@ void map_WhenCalledWithoutData_ThenReaderAndMapperAreNotCalled() { @Test void map_WhenCalledWithNullValue_ThenReaderAndMapperAreNotCalled() { - var scl = compasCimMappingService.map(null, principal); + var scl = compasCimMappingService.map(null, "username"); assertNotNull(scl); verifyNoInteractions(cgmesCimReader, cimToSclMapper); @@ -88,9 +85,8 @@ void createBasicSCL_WhenCalledWithNullValue_ThenNewSCLInstanceReturnedWithPartsF private void createBasicSCL_WhenCalled_ThenExpectedName(List cimDataList) { var expectedName = "Mr. Name"; - when(principal.getName()).thenReturn(expectedName); - var scl = compasCimMappingService.createBasicSCL(cimDataList, principal); + var scl = compasCimMappingService.createBasicSCL(cimDataList, expectedName); assertNotNull(scl); assertEquals("2007", scl.getVersion()); From 5bf348ed95b1ebb229d32d2a496a41c8cbe62518 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Wed, 1 Sep 2021 08:55:08 +0200 Subject: [PATCH 26/29] Make configurable which claim to use for Who. Signed-off-by: Dennis Labordus --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1691206..5f6f07e 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ in History Record. | Environment variable | Java Property | Description | Example | | -------------------------------- | ------------------------------ | --------------------------------------------- | ---------------- | -| USERINFO_WHO_CLAIMNAME | compas.userinfo.who.claimname | The Name of the user use in the WHo History. | name | +| USERINFO_WHO_CLAIMNAME | compas.userinfo.who.claimname | The Name of the user used in the Who History. | name | ## Security From 7da131552890fa64037be244cb5548f74cf75666 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Wed, 1 Sep 2021 08:56:46 +0200 Subject: [PATCH 27/29] Make configurable which claim to use for Who. Signed-off-by: Dennis Labordus --- .../compas/cim/mapping/rest/v1/CompasCimMappingResource.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResource.java b/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResource.java index 149cb05..5402494 100644 --- a/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResource.java +++ b/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResource.java @@ -9,6 +9,8 @@ import org.lfenergy.compas.cim.mapping.rest.v1.model.MapRequest; import org.lfenergy.compas.cim.mapping.rest.v1.model.MapResponse; import org.lfenergy.compas.cim.mapping.service.CompasCimMappingService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; @@ -23,6 +25,8 @@ @RequestScoped @Path("/cim/v1/") public class CompasCimMappingResource { + private static final Logger LOGGER = LoggerFactory.getLogger(CompasCimMappingResource.class); + private CompasCimMappingService compasCimMappingService; @Inject @@ -42,6 +46,7 @@ public CompasCimMappingResource(CompasCimMappingService compasCimMappingService) @Produces(MediaType.APPLICATION_XML) public MapResponse mapCimToScl(@Valid MapRequest request) { String username = jsonWebToken.getClaim(userInfoProperties.who()); + LOGGER.trace("Username used for Who {}", username); var response = new MapResponse(); response.setScl(compasCimMappingService.map(request.getCimData(), username)); From c9ee01fea13210ff203df06260d3b582c431b55f Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Wed, 1 Sep 2021 13:23:14 +0200 Subject: [PATCH 28/29] Make configurable which claim to use for Who. Signed-off-by: Dennis Labordus --- .../cim/mapping/service/CompasCimMappingService.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java b/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java index 25353f3..c20047e 100644 --- a/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java +++ b/service/src/main/java/org/lfenergy/compas/cim/mapping/service/CompasCimMappingService.java @@ -42,8 +42,8 @@ public CompasCimMappingService(CgmesCimReader cgmesCimReader, /** * Map the passed CIM XML to IEC SCL Model. * - * @param cimData The CIM XML Data. - * @param principal + * @param cimData The CIM XML Data. + * @param who The name of the user who created the SCL from the CIM Data. * @return The created SCL Model. */ public SCL map(List cimData, String who) { @@ -59,8 +59,10 @@ public SCL map(List cimData, String who) { } /** - * Create a basic SCL Obejct with common values filled. + * Create a basic SCL Object with common values filled. * + * @param cimData The CIM XML Data. + * @param who The name of the user who created the SCL from the CIM Data. * @return The created SCL Model. */ SCL createBasicSCL(List cimData, String who) { From 4363833cdb966bd1e6a1a7b0ba7235f54cce7d5e Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Wed, 1 Sep 2021 13:28:59 +0200 Subject: [PATCH 29/29] Make configurable which claim to use for Who. Signed-off-by: Dennis Labordus --- .../cim/mapping/rest/v1/CompasCimMappingResource.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResource.java b/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResource.java index 5402494..1cd1893 100644 --- a/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResource.java +++ b/app/src/main/java/org/lfenergy/compas/cim/mapping/rest/v1/CompasCimMappingResource.java @@ -45,11 +45,11 @@ public CompasCimMappingResource(CompasCimMappingService compasCimMappingService) @Consumes(MediaType.APPLICATION_XML) @Produces(MediaType.APPLICATION_XML) public MapResponse mapCimToScl(@Valid MapRequest request) { - String username = jsonWebToken.getClaim(userInfoProperties.who()); - LOGGER.trace("Username used for Who {}", username); + String who = jsonWebToken.getClaim(userInfoProperties.who()); + LOGGER.trace("Username used for Who {}", who); var response = new MapResponse(); - response.setScl(compasCimMappingService.map(request.getCimData(), username)); + response.setScl(compasCimMappingService.map(request.getCimData(), who)); return response; } } \ No newline at end of file