From 9fc367cfbe7d13aecb0c19f9c072b44ac644fa84 Mon Sep 17 00:00:00 2001 From: aDiaite <62600667+AliouDIAITE@users.noreply.github.com> Date: Wed, 22 Jun 2022 10:31:02 +0200 Subject: [PATCH] Release 0.0.4 (#103) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [#65] : correcting history for automation service Signed-off-by: Aliou DIAITE * [#65 ==> 95] : correcting history for automation service: add test Signed-off-by: Aliou DIAITE * Update SCL communication import method to allow the import of the att… (#91) * Update SCL communication import method to allow the import of the attributes Address et PhysConn if present. Signed-off-by: SAINTIER FRANCOIS * [#66] : WIP Signed-off-by: Aliou DIAITE * [#66] : WIP to be refactored Signed-off-by: Aliou DIAITE * Update SCL communication import method to allow the import of the att… (#91) * Update SCL communication import method to allow the import of the attributes Address et PhysConn if present. Signed-off-by: SAINTIER FRANCOIS Signed-off-by: Aliou DIAITE * [#65] : correcting history for automation service Signed-off-by: Aliou DIAITE * [#65 ==> 95] : correcting history for automation service: add test Signed-off-by: Aliou DIAITE * [#66] : WIP refactoring and test needed Signed-off-by: Aliou DIAITE * [#66] : WIP add files and tests, refactoring Signed-off-by: Aliou DIAITE * [#66] : moving code to subnetwork and refactoring Signed-off-by: Aliou DIAITE * [#66] : delete not yet used code Signed-off-by: Aliou DIAITE * [#66] : WIP Signed-off-by: Aliou DIAITE * [#66] : WIP to be refactored Signed-off-by: Aliou DIAITE * [#66] : refactoring after remarks for pull request Signed-off-by: Aliou DIAITE * [#66] : delete commented code and update pom.xml Signed-off-by: Aliou DIAITE * Added CII Best Practices Badge + removed unused LFX Security Tool badge Signed-off-by: Flurb * [#88] : add private COMPAS_SCL_FILE_TYPE in created SCD (#102) [#88] : add private COMPAS_SCL_FILE_TYPE in created SCD Signed-off-by: Aliou DIAITE * [#70] : all updatable DA should be returned Signed-off-by: massifben <105049157+massifben@users.noreply.github.com> Co-authored-by: SaintierFr <99645240+SaintierFr@users.noreply.github.com> Co-authored-by: Flurb Co-authored-by: massifben <105049157+massifben@users.noreply.github.com> --- README.md | 1 + pom.xml | 13 +- sct-app/pom.xml | 35 +- .../compas/sct/app/SclAutomationService.java | 17 +- .../SclAutomationServiceTest.java | 27 +- sct-app/src/test/resources/std_1.xml | 344 ++++++++++++++ sct-app/src/test/resources/std_2.xml | 344 ++++++++++++++ sct-app/src/test/resources/std_3.xml | 344 ++++++++++++++ sct-commons/pom.xml | 64 ++- .../compas/sct/commons/CommonConstants.java | 16 + .../sct/commons/dto/ConnectedApDTO.java | 5 +- .../compas/sct/commons/dto/DaTypeName.java | 32 +- .../compas/sct/commons/dto/DataTypeName.java | 41 +- .../compas/sct/commons/dto/DoTypeName.java | 20 +- .../compas/sct/commons/dto/LNodeDTO.java | 12 +- .../sct/commons/dto/ResumedDataTemplate.java | 60 ++- .../compas/sct/commons/dto/SubNetworkDTO.java | 31 +- .../compas/sct/commons/scl/SclService.java | 246 +++++++--- .../commons/scl/com/CommunicationAdapter.java | 11 +- .../commons/scl/com/ConnectedAPAdapter.java | 19 + .../sct/commons/scl/dtt/DATypeAdapter.java | 43 +- .../sct/commons/scl/dtt/DOTypeAdapter.java | 85 ++-- .../sct/commons/scl/dtt/LNodeTypeAdapter.java | 33 +- .../commons/scl/ied/AbstractLNAdapter.java | 122 +++-- .../sct/commons/scl/ied/IEDAdapter.java | 7 + .../sct/commons/scl/ied/LDeviceAdapter.java | 8 +- .../lfenergy/compas/sct/commons/dto/DTO.java | 8 + .../sct/commons/dto/DaTypeNameTest.java | 132 ++++-- .../sct/commons/dto/DoTypeNameTest.java | 116 ++++- .../compas/sct/commons/dto/LNodeDTOTest.java | 60 +-- .../commons/dto/ResumedDataTemplateTest.java | 100 +++- .../sct/commons/dto/SubNetworkDTOTest.java | 29 ++ .../sct/commons/scl/SclServiceTest.java | 428 +++++++++++++++--- .../scl/com/ConnectedAPAdapterTest.java | 69 ++- .../commons/scl/dtt/DATypeAdapterTest.java | 7 +- .../commons/scl/dtt/DOTypeAdapterTest.java | 30 +- .../sct/commons/scl/ied/LN0AdapterTest.java | 4 +- .../commons/testhelpers/DataTypeUtils.java | 34 ++ .../testhelpers/MarshallerWrapper.java | 6 +- .../scd-ied-dtt-com-import-stds/scd.xml | 35 ++ .../scd_lnode_with_many_compas_icdheader.xml | 41 ++ .../scd-ied-dtt-com-import-stds/ssd.xml | 26 ++ .../scd-ied-dtt-com-import-stds/std.xml | 344 ++++++++++++++ .../std_SITESITE1GTW1.xml | 344 ++++++++++++++ .../std_SITESITE1GTW2.xml | 344 ++++++++++++++ .../std_with_same_ICDSystemVersionUUID.xml | 344 ++++++++++++++ .../ied_test_aggregate_DAI.xml | 87 ++++ .../ied_test_updatable_DAI.xml | 257 +++++++++++ .../ied_with_filled_communication.xml | 111 +++++ sct-coverage/pom.xml | 6 + 50 files changed, 4416 insertions(+), 526 deletions(-) create mode 100644 sct-app/src/test/resources/std_1.xml create mode 100644 sct-app/src/test/resources/std_2.xml create mode 100644 sct-app/src/test/resources/std_3.xml create mode 100644 sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/DataTypeUtils.java create mode 100644 sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/scd.xml create mode 100644 sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/scd_lnode_with_many_compas_icdheader.xml create mode 100644 sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/ssd.xml create mode 100644 sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std.xml create mode 100644 sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std_SITESITE1GTW1.xml create mode 100644 sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std_SITESITE1GTW2.xml create mode 100644 sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std_with_same_ICDSystemVersionUUID.xml create mode 100644 sct-commons/src/test/resources/scl-srv-import-ieds/ied_test_aggregate_DAI.xml create mode 100644 sct-commons/src/test/resources/scl-srv-import-ieds/ied_test_updatable_DAI.xml create mode 100644 sct-commons/src/test/resources/scl-srv-import-ieds/ied_with_filled_communication.xml diff --git a/README.md b/README.md index d453ed604..2258900c2 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ SPDX-License-Identifier: Apache-2.0 --> [![REUSE status](https://api.reuse.software/badge/github.com/com-pas/compas-sct)](https://api.reuse.software/info/github.com/com-pas/compas-sct) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5925/badge)](https://bestpractices.coreinfrastructure.org/projects/5925) # System Configuration Tool (SCT) components diff --git a/pom.xml b/pom.xml index 8b5b10e77..769f09f99 100644 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,7 @@ org.projectlombok lombok - 1.18.20 + 1.18.24 org.junit.jupiter @@ -68,6 +68,11 @@ scl2007b4 0.2.1 + + org.lfenergy.compas.core + scl-extension + 0.8.0 + ch.qos.logback logback-classic @@ -80,6 +85,10 @@ org.lfenergy.compas.core scl2007b4 + + org.lfenergy.compas.core + scl-extension + ch.qos.logback logback-classic @@ -132,4 +141,4 @@ - \ No newline at end of file + diff --git a/sct-app/pom.xml b/sct-app/pom.xml index 98b1a8459..d8a715842 100644 --- a/sct-app/pom.xml +++ b/sct-app/pom.xml @@ -56,6 +56,12 @@ junit-jupiter-engine test + + org.mockito + mockito-core + 3.6.28 + test + @@ -67,12 +73,29 @@ 11 - org.apache.maven.plugins maven-surefire-plugin - + + org.jacoco + jacoco-maven-plugin + + + default-prepare-agent + + prepare-agent + + + + report + test + + report + + + + org.apache.maven.plugins maven-dependency-plugin @@ -83,21 +106,25 @@ unpack - + **/SCL2007B4/*.xsd, **/SCL_CoMPAS.xsd org.lfenergy.compas.xsd compas-scl-xsd 0.0.4 + + org.lfenergy.compas.core + scl-extension + 0.8.0 + ${project.build.directory} - \ No newline at end of file diff --git a/sct-app/src/main/java/org/lfenergy/compas/sct/app/SclAutomationService.java b/sct-app/src/main/java/org/lfenergy/compas/sct/app/SclAutomationService.java index 7751c3b7c..b8840930a 100644 --- a/sct-app/src/main/java/org/lfenergy/compas/sct/app/SclAutomationService.java +++ b/sct-app/src/main/java/org/lfenergy/compas/sct/app/SclAutomationService.java @@ -6,27 +6,34 @@ import lombok.NonNull; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.sct.commons.dto.HeaderDTO; +import org.lfenergy.compas.sct.commons.dto.SubNetworkDTO; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; import org.lfenergy.compas.sct.commons.scl.SclService; -import java.util.Optional; +import java.util.*; @Slf4j public class SclAutomationService { + private static final Map, List> comMap = Map.of( + Pair.of("RSPACE_PROCESS_NETWORK", SubNetworkDTO.SubnetworkType.MMS.toString()), Arrays.asList("PROCESS_AP", "TOTO_AP_GE"), + Pair.of("RSPACE_ADMIN_NETWORK", SubNetworkDTO.SubnetworkType.IP.toString()), Arrays.asList("ADMIN_AP","TATA_AP_EFFACEC")); + private SclAutomationService(){throw new IllegalStateException("SclAutomationService class"); } - public static SclRootAdapter createSCD(@NonNull SCL ssd, @NonNull HeaderDTO headerDTO) throws ScdException { + public static SclRootAdapter createSCD(@NonNull SCL ssd, @NonNull HeaderDTO headerDTO, Set stds) throws ScdException { SclRootAdapter scdAdapter = SclService.initScl(Optional.ofNullable(headerDTO.getId()), headerDTO.getVersion(),headerDTO.getRevision()); if(!headerDTO.getHistoryItems().isEmpty()) { - headerDTO.getHistoryItems().forEach(hItem -> - SclService.addHistoryItem(scdAdapter.getCurrentElem(), hItem.getWho(), hItem.getWhat(), hItem.getWhy())); + HeaderDTO.HistoryItem hItem = headerDTO.getHistoryItems().get(0); + SclService.addHistoryItem(scdAdapter.getCurrentElem(), hItem.getWho(), hItem.getWhat(), hItem.getWhy()); } - SclService.addSubstation(scdAdapter.getCurrentElem(), ssd); + SclService.addSubstation(scdAdapter.getCurrentElem(), ssd); + SclService.importSTDElementsInSCD(scdAdapter, stds, comMap); return scdAdapter; } } diff --git a/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceTest.java b/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceTest.java index 4732a918a..6aecfd219 100644 --- a/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceTest.java +++ b/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceTest.java @@ -13,6 +13,8 @@ import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; import static org.junit.jupiter.api.Assertions.*; @@ -29,11 +31,15 @@ void init(){ @Test void createSCD() throws Exception { - SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml"); - SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO); + SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd.xml"); + SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); + SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO, Set.of(std)); assertNotNull(expectedSCD.getCurrentElem().getHeader().getId()); assertNull(expectedSCD.getCurrentElem().getHeader().getHistory()); assertEquals(1, expectedSCD.getCurrentElem().getSubstation().size()); + assertEquals(1, expectedSCD.getCurrentElem().getIED().size()); + assertNotNull(expectedSCD.getCurrentElem().getDataTypeTemplates()); + assertEquals(2, expectedSCD.getCurrentElem().getCommunication().getSubNetwork().size()); } @Test @@ -44,7 +50,10 @@ void createSCD_With_HItem() throws Exception { historyItem.setWhy("because"); headerDTO.getHistoryItems().add(historyItem); SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml"); - SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO); + SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml"); + SCL std2 = SclTestMarshaller.getSCLFromFile("/std_2.xml"); + SCL std3 = SclTestMarshaller.getSCLFromFile("/std_3.xml"); + SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO, Set.of(std1, std2, std3)); assertNotNull(expectedSCD.getCurrentElem().getHeader().getId()); assertEquals(1 ,expectedSCD.getCurrentElem().getHeader().getHistory().getHitem().size()); assertEquals(1, expectedSCD.getCurrentElem().getSubstation().size()); @@ -62,16 +71,20 @@ void createSCD_With_HItems() throws Exception { historyItemBis.setWhy("because bis"); headerDTO.getHistoryItems().addAll(Arrays.asList(historyItem, historyItemBis)); SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml"); - SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO); + SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml"); + SCL std2 = SclTestMarshaller.getSCLFromFile("/std_2.xml"); + SCL std3 = SclTestMarshaller.getSCLFromFile("/std_3.xml"); + SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO,Set.of(std1, std2, std3)); assertNotNull(expectedSCD.getCurrentElem().getHeader().getId()); - assertEquals(2 ,expectedSCD.getCurrentElem().getHeader().getHistory().getHitem().size()); + assertEquals(1, expectedSCD.getCurrentElem().getHeader().getHistory().getHitem().size()); + assertEquals("what", expectedSCD.getCurrentElem().getHeader().getHistory().getHitem().get(0).getWhat()); } - @Test void createSCD_SSD_Without_Substation() throws Exception { SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd_without_substations.xml"); assertThrows(ScdException.class, - () -> SclAutomationService.createSCD(ssd, headerDTO) ); + () -> SclAutomationService.createSCD(ssd, headerDTO, new HashSet<>()) ); } + } \ No newline at end of file diff --git a/sct-app/src/test/resources/std_1.xml b/sct-app/src/test/resources/std_1.xml new file mode 100644 index 000000000..a844f0fc6 --- /dev/null +++ b/sct-app/src/test/resources/std_1.xml @@ -0,0 +1,344 @@ + + + + +
+ + + +
+ + + +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + Phase 1_Pilotes + 9d13ab59-1ec8-4c46-91c8-0326e6a5408e + 1 + 1.0 + + + + Ldevice current status + + + + + off + + + 1000 + + + Activation_deactivation command + + + + + + + + m + + + A + + + + + 10 + + + + + 20 + + + + + 20 + + + + + 10 + + + + Rated Input Current High + + + + + + + + + + + + + + + + + + + + 4800 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IEC 61850-8-1:2003 + + + + + + + + + IEC 61850-8-1:2003 + + + on + blocked + test + test/blocked + off + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + + status-only + direct-with-enhanced-security + + + + m + kg + s + A + K + mol + cd + deg + rad + sr + Gy + Bq + °C + Sv + F + C + S + H + V + ohm + J + N + Hz + lx + Lm + Wb + T + W + Pa + + + m/s + m/s² + m³/s + m/m³ + M + kg/m³ + m²/s + W/m K + J/K + ppm + 1/s + rad/s + W/m² + J/m² + S/m + K/s + Pa/s + J/kg K + VA + Watts + VAr + phi + cos(phi) + Vs + + As + + A²t + VAh + Wh + VArh + V/Hz + Hz/s + char + char/s + kgm² + dB + J/Wh + W/s + l/s + dBm + h + min + Ohm/m + percent/s + A/V + A/Vs + + + y + z + a + f + p + n + µ + m + c + d + + da + h + k + M + G + T + P + E + Z + Y + + +
\ No newline at end of file diff --git a/sct-app/src/test/resources/std_2.xml b/sct-app/src/test/resources/std_2.xml new file mode 100644 index 000000000..42228c889 --- /dev/null +++ b/sct-app/src/test/resources/std_2.xml @@ -0,0 +1,344 @@ + + + + +
+ + + +
+ + + +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + Phase 1_Pilotes + 9d13ab59-1ec8-4c46-91c8-0326e6a5408e + 1 + 1.0 + + + + Ldevice current status + + + + + off + + + 1000 + + + Activation_deactivation command + + + + + + + + m + + + A + + + + + 10 + + + + + 20 + + + + + 20 + + + + + 10 + + + + Rated Input Current High + + + + + + + + + + + + + + + + + + + + 4800 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IEC 61850-8-1:2003 + + + + + + + + + IEC 61850-8-1:2003 + + + on + blocked + test + test/blocked + off + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + + status-only + direct-with-enhanced-security + + + + m + kg + s + A + K + mol + cd + deg + rad + sr + Gy + Bq + °C + Sv + F + C + S + H + V + ohm + J + N + Hz + lx + Lm + Wb + T + W + Pa + + + m/s + m/s² + m³/s + m/m³ + M + kg/m³ + m²/s + W/m K + J/K + ppm + 1/s + rad/s + W/m² + J/m² + S/m + K/s + Pa/s + J/kg K + VA + Watts + VAr + phi + cos(phi) + Vs + + As + + A²t + VAh + Wh + VArh + V/Hz + Hz/s + char + char/s + kgm² + dB + J/Wh + W/s + l/s + dBm + h + min + Ohm/m + percent/s + A/V + A/Vs + + + y + z + a + f + p + n + µ + m + c + d + + da + h + k + M + G + T + P + E + Z + Y + + +
\ No newline at end of file diff --git a/sct-app/src/test/resources/std_3.xml b/sct-app/src/test/resources/std_3.xml new file mode 100644 index 000000000..38ce30c55 --- /dev/null +++ b/sct-app/src/test/resources/std_3.xml @@ -0,0 +1,344 @@ + + + + +
+ + + +
+ + + +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + Phase 1_Pilotes + 9d13ab59-1ec8-4c46-91c8-0326e6a5408e + 1 + 1.0 + + + + Ldevice current status + + + + + off + + + 1000 + + + Activation_deactivation command + + + + + + + + m + + + A + + + + + 10 + + + + + 20 + + + + + 20 + + + + + 10 + + + + Rated Input Current High + + + + + + + + + + + + + + + + + + + + 4800 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IEC 61850-8-1:2003 + + + + + + + + + IEC 61850-8-1:2003 + + + on + blocked + test + test/blocked + off + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + + status-only + direct-with-enhanced-security + + + + m + kg + s + A + K + mol + cd + deg + rad + sr + Gy + Bq + °C + Sv + F + C + S + H + V + ohm + J + N + Hz + lx + Lm + Wb + T + W + Pa + + + m/s + m/s² + m³/s + m/m³ + M + kg/m³ + m²/s + W/m K + J/K + ppm + 1/s + rad/s + W/m² + J/m² + S/m + K/s + Pa/s + J/kg K + VA + Watts + VAr + phi + cos(phi) + Vs + + As + + A²t + VAh + Wh + VArh + V/Hz + Hz/s + char + char/s + kgm² + dB + J/Wh + W/s + l/s + dBm + h + min + Ohm/m + percent/s + A/V + A/Vs + + + y + z + a + f + p + n + µ + m + c + d + + da + h + k + M + G + T + P + E + Z + Y + + +
\ No newline at end of file diff --git a/sct-commons/pom.xml b/sct-commons/pom.xml index 19512bad9..1eaf5f727 100644 --- a/sct-commons/pom.xml +++ b/sct-commons/pom.xml @@ -13,14 +13,14 @@ local-SNAPSHOT - org.lfenergy.compas sct-commons local-SNAPSHOT SCT-COMMONS - ${basedir}/${aggregate.report.dir} + **/scl2007b4/**/* + 3.22.0 @@ -105,6 +105,12 @@ 2.3.1 compile + + org.assertj + assertj-core + ${assertJ.version} + test + @@ -116,12 +122,34 @@ 11 - org.apache.maven.plugins maven-surefire-plugin - + + org.jacoco + jacoco-maven-plugin + + + **/scl2007b4/**/* + + + + + default-prepare-agent + + prepare-agent + + + + report + test + + report + + + + org.apache.maven.plugins maven-dependency-plugin @@ -132,20 +160,46 @@ unpack - + **/SCL2007B4/*.xsd, **/SCL_CoMPAS.xsd org.lfenergy.compas.xsd compas-scl-xsd 0.0.4 + + org.lfenergy.compas.core + scl-extension + 0.8.0 + ${project.build.directory} + + org.codehaus.mojo + jaxb2-maven-plugin + 2.5.0 + + + xjc + + xjc + + + + + + ${project.build.directory}/xsd/SCL2007B4/SCL.xsd + ${project.build.directory}/xsd/SCL_CoMPAS.xsd + + org.lfenergy.compas.scl2007b4.model + true + + org.apache.maven.plugins maven-jar-plugin diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/CommonConstants.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/CommonConstants.java index 01f29cbf4..90dcd01b9 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/CommonConstants.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/CommonConstants.java @@ -12,4 +12,20 @@ public class CommonConstants { public static final String XML_DEFAULT_NS_PREFIX = "scl"; public static final String XML_DEFAULT_NS_URI = "http://www.iec.ch/61850/2003/SCL"; public static final String XML_DEFAULT_XSD_PATH = "classpath:schema/SCL.xsd"; + + public static final String COMPAS_SCL_FILE_TYPE = "COMPAS-SclFileType"; + public static final String SCL_FILE_TYPE = "SclFileType"; + public static final String COMPAS_ICDHEADER = "COMPAS-ICDHeader"; + public static final String ICD_SYSTEM_VERSION_UUID = "ICDSystemVersionUUID"; + public static final String IED_NAME = "IEDName"; + public static final String HEADER_ID = "headerId"; + public static final String HEADER_VERSION = "headerVersion"; + public static final String HEADER_REVISION = "headerRevision"; + public static final String IED_TYPE = "IEDType"; + public static final String VENDOR_NAME = "VendorName"; + public static final String IED_REDUNDANCY = "IEDredundancy"; + public static final String IED_MODEL = "IEDmodel"; + public static final String HW_REV = "hwRev"; + public static final String SW_REV = "swRev"; + } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ConnectedApDTO.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ConnectedApDTO.java index 837738aca..1104525a7 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ConnectedApDTO.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ConnectedApDTO.java @@ -5,17 +5,16 @@ package org.lfenergy.compas.sct.commons.dto; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import org.lfenergy.compas.scl2007b4.model.TConnectedAP; import org.lfenergy.compas.sct.commons.scl.com.ConnectedAPAdapter; -import java.util.Objects; - @Setter @Getter @NoArgsConstructor +@AllArgsConstructor public class ConnectedApDTO { private String iedName; private String apName; diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DaTypeName.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DaTypeName.java index 28015bdd5..ce5166612 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DaTypeName.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DaTypeName.java @@ -4,10 +4,7 @@ package org.lfenergy.compas.sct.commons.dto; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -18,12 +15,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.stream.Collectors; @Getter @Setter @NoArgsConstructor +@EqualsAndHashCode(callSuper = true) public class DaTypeName extends DataTypeName{ public static final String VALIDATION_REGEX = "[a-zA-Z][a-zA-Z0-9]*(\\([0-9]+\\))?(\\.[a-zA-Z][a-zA-Z0-9]*(\\([0-9]+\\))?)*"; @@ -37,6 +34,10 @@ public DaTypeName(String daName) { super(daName); } + public DaTypeName(String name, String names) { + super(name, names); + } + public static DaTypeName from(DaTypeName dataName){ DaTypeName daTypeName = new DaTypeName(dataName.toString()); if(dataName.isDefined()) { @@ -50,11 +51,6 @@ public static DaTypeName from(DaTypeName dataName){ return daTypeName; } - - public DaTypeName(String name, String names) { - super(name, names); - } - public boolean isValImport(){ return valImport; } @@ -94,22 +90,6 @@ public void addDaiValue(Long sg, String val) { } } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || o.getClass() != getClass()) return false; - if (!super.equals(o)) return false; - DaTypeName that = (DaTypeName) o; - return fc == that.fc && - Objects.equals(bType, that.bType) && - Objects.equals(type, that.type); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), fc, bType, type); - } - public void merge(DaTypeName daName) { if(!isDefined()) return; fc = daName.fc; diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DataTypeName.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DataTypeName.java index 25f593173..0a09e5e1c 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DataTypeName.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DataTypeName.java @@ -5,25 +5,22 @@ package org.lfenergy.compas.sct.commons.dto; import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.NonNull; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import java.util.stream.Stream; @Getter @Setter @Slf4j @NoArgsConstructor +@EqualsAndHashCode public class DataTypeName { protected String name = ""; // dataName or DataAttributeName @@ -31,13 +28,18 @@ public class DataTypeName { public DataTypeName(String dataName){ if(dataName == null) return; - String[] tokens = dataName.split("\\."); name = tokens[0]; if(tokens.length > 1){ - int idx = dataName.indexOf("."); - tokens = dataName.substring(idx + 1).split("\\."); - structNames = Stream.of(tokens).collect(Collectors.toList()); + structNames.addAll(List.of(tokens).subList(1, tokens.length)); + } + } + + public DataTypeName(String name, String names){ + if(name == null) return; + this.name = name; + if (StringUtils.isNotBlank(names)){ + structNames.addAll(List.of(names.split("\\."))); } } @@ -49,12 +51,6 @@ public boolean isDefined(){ return !StringUtils.isBlank(name); } - public DataTypeName(String name, @NonNull String names){ - this.name = name; - String[] tokens = names.split("\\."); - structNames = Stream.of(tokens).collect(Collectors.toList()); - } - @Override public String toString(){ StringBuilder stringBuilder = new StringBuilder(); @@ -66,21 +62,6 @@ public String toString(){ return stringBuilder.toString(); } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o==null || o.getClass() != getClass()) return false; - DataTypeName that = (DataTypeName) o; - return Objects.equals(name, that.name) && - Arrays.equals(structNames.toArray(new String[0]), - that.structNames.toArray(new String[0])); - } - - @Override - public int hashCode() { - return Objects.hash(name, structNames); - } - public void addStructName(String structName) { structNames.add(structName); } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DoTypeName.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DoTypeName.java index c91301caa..c75e512f3 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DoTypeName.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DoTypeName.java @@ -4,18 +4,16 @@ package org.lfenergy.compas.sct.commons.dto; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import org.lfenergy.compas.scl2007b4.model.TPredefinedCDCEnum; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - @Getter @Setter @NoArgsConstructor +@EqualsAndHashCode(callSuper = true) public class DoTypeName extends DataTypeName { public static final String VALIDATION_REGEX = "[A-Z][0-9A-Za-z]{0,11}(\\.[a-z][0-9A-Za-z]*(\\([0-9]+\\))?)?"; private TPredefinedCDCEnum cdc; @@ -35,20 +33,6 @@ public static DoTypeName from(DoTypeName dataName){ return doTypeName; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || o.getClass() !=getClass()) return false; - if (!super.equals(o)) return false; - DoTypeName that = (DoTypeName) o; - return cdc == that.cdc; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), cdc); - } - public void merge(DoTypeName doName) { if(!isDefined()) return; if(cdc == null) diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/LNodeDTO.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/LNodeDTO.java index a3add7184..3892277b9 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/LNodeDTO.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/LNodeDTO.java @@ -10,8 +10,6 @@ import org.lfenergy.compas.scl2007b4.model.TAnyLN; import org.lfenergy.compas.scl2007b4.model.TExtRef; import org.lfenergy.compas.sct.commons.Utils; -import org.lfenergy.compas.sct.commons.exception.ScdException; -import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; import org.lfenergy.compas.sct.commons.scl.dtt.DataTypeTemplateAdapter; import org.lfenergy.compas.sct.commons.scl.dtt.LNodeTypeAdapter; import org.lfenergy.compas.sct.commons.scl.ied.AbstractLNAdapter; @@ -92,11 +90,11 @@ public static LNodeDTO from(AbstractLNAdapter nodeAdapter, ) ) ); - ResumedDataTemplate filter = new ResumedDataTemplate(); - filter.setLnInst(nodeAdapter.getLNInst()); - filter.setLnClass(nodeAdapter.getLNClass()); - filter.setPrefix(nodeAdapter.getPrefix()); - filter.setLnType(nodeAdapter.getLnType()); + ResumedDataTemplate filter = ResumedDataTemplate.builder() + .lnInst(nodeAdapter.getLNInst()) + .lnClass(nodeAdapter.getLNClass()) + .prefix(nodeAdapter.getPrefix()) + .lnType(nodeAdapter.getLnType()).build(); List resumedDataTemplateList = lNodeTypeAdapter.getResumedDTTs(filter); lNodeDTO.addAllResumedDataTemplate(resumedDataTemplateList); } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplate.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplate.java index add107dba..a52514f76 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplate.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplate.java @@ -5,27 +5,30 @@ package org.lfenergy.compas.sct.commons.dto; import com.fasterxml.jackson.annotation.JsonIgnore; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.lfenergy.compas.scl2007b4.model.TFCEnum; -import org.lfenergy.compas.scl2007b4.model.TLLN0Enum; -import org.lfenergy.compas.scl2007b4.model.TPredefinedBasicTypeEnum; -import org.lfenergy.compas.scl2007b4.model.TPredefinedCDCEnum; -import org.lfenergy.compas.scl2007b4.model.TVal; +import lombok.*; +import org.lfenergy.compas.scl2007b4.model.*; + +import java.util.ArrayList; +import java.util.List; -import java.util.*; @Setter @Getter +@AllArgsConstructor @NoArgsConstructor +@EqualsAndHashCode +@Builder(toBuilder = true) public class ResumedDataTemplate { private String prefix; private String lnType; private String lnClass; private String lnInst; + @Builder.Default + @NonNull private DoTypeName doName = new DoTypeName(""); + @Builder.Default + @NonNull private DaTypeName daName = new DaTypeName(""); public static ResumedDataTemplate copyFrom(ResumedDataTemplate dtt){ @@ -41,27 +44,29 @@ public static ResumedDataTemplate copyFrom(ResumedDataTemplate dtt){ } public boolean isUpdatable(){ - return daName.isDefined() && daName.isUpdatable(); + return daName.isDefined() && daName.isUpdatable(); } @JsonIgnore public String getObjRef(String iedName, String ldInst){ - StringBuilder stringBuilder = new StringBuilder(); //LDName - stringBuilder.append(iedName) - .append(ldInst) - .append("/"); + return iedName + ldInst + "/" + getLNRef(); + } + + @JsonIgnore + public String getLNRef(){ + StringBuilder stringBuilder = new StringBuilder(); if(TLLN0Enum.LLN_0.value().equals(lnClass)){ stringBuilder.append(TLLN0Enum.LLN_0.value()); } else { stringBuilder.append(prefix) - .append(lnClass) - .append(lnInst); + .append(lnClass) + .append(lnInst); } stringBuilder.append('.') - .append(getDoRef()) - .append('.') - .append(getDaRef()); + .append(getDoRef()) + .append('.') + .append(getDaRef()); return stringBuilder.toString(); } @@ -120,13 +125,19 @@ public List getBdaNames(){ return List.of(daName.getStructNames().toArray(new String[0])); } - public void addStructName(String structName, Class cls){ - if(cls.equals(DaTypeName.class) && isDaNameDefined()) { - daName.addStructName(structName); - } else if(cls.equals(DoTypeName.class) && isDoNameDefined()) { + public void addDoStructName(String structName){ + if(isDoNameDefined()) { doName.addStructName(structName); } else { - throw new IllegalArgumentException("Cannot add Struct name for undefined data type"); + throw new IllegalArgumentException("DO name must be defined before adding DO StructName"); + } + } + + public void addDaStructName(String structName){ + if(isDaNameDefined()) { + daName.addStructName(structName); + } else { + throw new IllegalArgumentException("DA name must be defined before adding DA StructName"); } } @@ -190,7 +201,6 @@ public void setValImport(boolean valImport) { } } - public boolean isValImport(){ return daName.isValImport(); } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTO.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTO.java index e71b07b04..4dc060eb1 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTO.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTO.java @@ -5,17 +5,19 @@ package org.lfenergy.compas.sct.commons.dto; import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonGetter; -import com.fasterxml.jackson.annotation.JsonSetter; import com.fasterxml.jackson.annotation.JsonValue; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.Setter; -import org.lfenergy.compas.scl2007b4.model.TSubNetwork; +import org.apache.commons.lang3.tuple.Pair; +import org.lfenergy.compas.sct.commons.scl.com.CommunicationAdapter; +import org.lfenergy.compas.sct.commons.scl.com.ConnectedAPAdapter; import org.lfenergy.compas.sct.commons.scl.com.SubNetworkAdapter; import java.util.HashSet; +import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; @Getter @@ -95,4 +97,25 @@ public static SubnetworkType fromValue(String text) { return null; } } + + public static Set createDefaultSubnetwork(String iedName, CommunicationAdapter comAdapter, Map, List> comMap){ + Set subNetworkDTOS = new HashSet<>(); + comMap.forEach((subnetworkNameType, apNames) -> { + SubNetworkDTO subNetworkDTO = new SubNetworkDTO(subnetworkNameType.getLeft(), subnetworkNameType.getRight()); + apNames.forEach(s -> { + if(getStdConnectedApNames(comAdapter).contains(s)){ + ConnectedApDTO connectedApDTO = new ConnectedApDTO(iedName, s); + subNetworkDTO.addConnectedAP(connectedApDTO);} + }); + subNetworkDTOS.add(subNetworkDTO); + }); + return subNetworkDTOS; + } + + private static List getStdConnectedApNames(CommunicationAdapter comAdapter){ + return comAdapter.getSubNetworkAdapters().stream() + .map(SubNetworkAdapter::getConnectedAPAdapters) + .flatMap(connectedAPAdapters -> connectedAPAdapters.stream().map(ConnectedAPAdapter::getApName)) + .collect(Collectors.toList()); + } } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java index 16fec6109..f8266ac0f 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java @@ -7,11 +7,15 @@ import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.Pair; +import org.lfenergy.compas.scl.extensions.commons.CompasExtensionsConstants; import org.lfenergy.compas.scl2007b4.model.*; +import org.lfenergy.compas.sct.commons.CommonConstants; import org.lfenergy.compas.sct.commons.Utils; import org.lfenergy.compas.sct.commons.dto.*; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.com.CommunicationAdapter; +import org.lfenergy.compas.sct.commons.scl.com.ConnectedAPAdapter; +import org.lfenergy.compas.sct.commons.scl.com.SubNetworkAdapter; import org.lfenergy.compas.sct.commons.scl.dtt.DataTypeTemplateAdapter; import org.lfenergy.compas.sct.commons.scl.dtt.EnumTypeAdapter; import org.lfenergy.compas.sct.commons.scl.dtt.LNodeTypeAdapter; @@ -23,28 +27,48 @@ import org.lfenergy.compas.sct.commons.scl.sstation.SubstationAdapter; import org.lfenergy.compas.sct.commons.scl.sstation.VoltageLevelAdapter; +import javax.xml.bind.JAXBElement; +import javax.xml.namespace.QName; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; +import static org.lfenergy.compas.sct.commons.CommonConstants.ICD_SYSTEM_VERSION_UUID; + @Slf4j public class SclService { public static final String UNKNOWN_LDEVICE_S_IN_IED_S = "Unknown LDevice (%s) in IED (%s)"; public static final String INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO = "Invalid or missing attributes in ExtRef binding info"; - private SclService(){ throw new IllegalStateException("SclService class"); } + private SclService() { + throw new IllegalStateException("SclService class"); + } public static SclRootAdapter initScl(Optional hId, String hVersion, String hRevision) throws ScdException { UUID headerId = hId.orElseGet(UUID::randomUUID); - return new SclRootAdapter(headerId.toString(), hVersion, hRevision); + SclRootAdapter scdAdapter = new SclRootAdapter(headerId.toString(), hVersion, hRevision); + scdAdapter.addPrivate(initSclFileType()); + return scdAdapter; } - public static SclRootAdapter addHistoryItem(SCL scd, String who, String what, String why){ + private static TPrivate initSclFileType() { + TPrivate fileTypePrivate = new TPrivate(); + fileTypePrivate.setType(CommonConstants.COMPAS_SCL_FILE_TYPE); + JAXBElement compasFileType = new JAXBElement<>( + new QName(CompasExtensionsConstants.COMPAS_EXTENSION_NS_URI, CommonConstants.SCL_FILE_TYPE), + TCompasSclFileType.class, TCompasSclFileType.SCD); + fileTypePrivate.getContent().add(compasFileType); + return fileTypePrivate; + } + + public static SclRootAdapter addHistoryItem(SCL scd, String who, String what, String why) { SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); HeaderAdapter headerAdapter = sclRootAdapter.getHeaderAdapter(); - headerAdapter.addHistoryItem(who,what,why); + headerAdapter.addHistoryItem(who, what, why); return sclRootAdapter; } + public static SclRootAdapter updateHeader(@NonNull SCL scd, @NonNull HeaderDTO headerDTO) { SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); @@ -53,17 +77,17 @@ public static SclRootAdapter updateHeader(@NonNull SCL scd, @NonNull HeaderDTO h boolean hUpdated = false; String hVersion = headerDTO.getVersion(); String hRevision = headerDTO.getRevision(); - if(hVersion != null && !hVersion.equals(headerAdapter.getHeaderVersion())){ + if (hVersion != null && !hVersion.equals(headerAdapter.getHeaderVersion())) { headerAdapter.updateVersion(hVersion); hUpdated = true; } - if(hRevision != null && !hRevision.equals(headerAdapter.getHeaderRevision())){ + if (hRevision != null && !hRevision.equals(headerAdapter.getHeaderRevision())) { headerAdapter.updateRevision(hRevision); hUpdated = true; } - if(hUpdated && !headerDTO.getHistoryItems().isEmpty()){ + if (hUpdated && !headerDTO.getHistoryItems().isEmpty()) { headerAdapter.addHistoryItem( headerDTO.getHistoryItems().get(0).getWho(), headerDTO.getHistoryItems().get(0).getWhat(), @@ -74,24 +98,32 @@ public static SclRootAdapter updateHeader(@NonNull SCL scd, @NonNull HeaderDTO h return sclRootAdapter; } - public static IEDAdapter addIED(SCL scd, String iedName, SCL icd) throws ScdException { SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - return sclRootAdapter.addIED(icd,iedName); + return sclRootAdapter.addIED(icd, iedName); } - public static Optional addSubnetworks(SCL scd, Set subNetworks) throws ScdException { + public static Optional addSubnetworks(SCL scd, Set subNetworks, Optional icd) throws ScdException { SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - CommunicationAdapter communicationAdapter = null; - if(!subNetworks.isEmpty()) { + CommunicationAdapter communicationAdapter; + if (!subNetworks.isEmpty()) { communicationAdapter = sclRootAdapter.getCommunicationAdapter(true); for (SubNetworkDTO subNetworkDTO : subNetworks) { String snName = subNetworkDTO.getName(); String snType = subNetworkDTO.getType(); for (ConnectedApDTO accessPoint : subNetworkDTO.getConnectedAPs()) { - communicationAdapter.addSubnetwork(snName, snType, - accessPoint.getIedName(), accessPoint.getApName()); + String iedName = accessPoint.getIedName(); + String apName = accessPoint.getApName(); + communicationAdapter.addSubnetwork(snName, snType, iedName, apName); + + Optional subNetworkAdapter = communicationAdapter.getSubnetworkByName(snName); + if (subNetworkAdapter.isPresent()) { + ConnectedAPAdapter connectedAPAdapter = subNetworkAdapter.get() + .getConnectedAPAdapter(iedName, apName); + connectedAPAdapter.copyAddressAndPhysConnFromIcd(icd); + } + } } return Optional.of(communicationAdapter); @@ -121,7 +153,7 @@ public static List getExtRefInfo(SCL scd, String iedName, String ldI public static List getExtRefBinders(SCL scd, String iedName, String ldInst, - String lnClass, String lnInst, String prefix, ExtRefSignalInfo signalInfo) throws ScdException { + String lnClass, String lnInst, String prefix, ExtRefSignalInfo signalInfo) throws ScdException { SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst) @@ -141,14 +173,14 @@ public static List getExtRefBinders(SCL scd, String iedName, // find potential binders for the signalInfo List potentialBinders = new ArrayList<>(); - for(IEDAdapter iedA : sclRootAdapter.getIEDAdapters()){ + for (IEDAdapter iedA : sclRootAdapter.getIEDAdapters()) { potentialBinders.addAll(iedA.getExtRefBinders(signalInfo)); } return potentialBinders; } public static void updateExtRefBinders(SCL scd, ExtRefInfo extRefInfo) throws ScdException { - if(extRefInfo.getBindingInfo() == null || extRefInfo.getSignalInfo() == null){ + if (extRefInfo.getBindingInfo() == null || extRefInfo.getSignalInfo() == null) { throw new ScdException("ExtRef Signal and/or Binding information are missing"); } String iedName = extRefInfo.getHolderIEDName(); @@ -157,11 +189,11 @@ public static void updateExtRefBinders(SCL scd, ExtRefInfo extRefInfo) throws Sc IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst) .orElseThrow( - () -> new ScdException( - String.format( - UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName - ) - ) + () -> new ScdException( + String.format( + UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName + ) + ) ); AbstractLNAdapter abstractLNAdapter = AbstractLNAdapter.builder() @@ -179,16 +211,16 @@ public static List> getExtRefSourceInfo(SCL scd, ExtRefInfo extR ExtRefSignalInfo signalInfo = extRefInfo.getSignalInfo(); - if(!signalInfo.isValid()){ + if (!signalInfo.isValid()) { throw new ScdException("Invalid or missing attributes in ExtRef signal info"); } ExtRefBindingInfo bindingInfo = extRefInfo.getBindingInfo(); - if(!bindingInfo.isValid()){ + if (!bindingInfo.isValid()) { throw new ScdException(INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO); } String iedName = extRefInfo.getHolderIEDName(); - if(bindingInfo.getIedName().equals(iedName)){ + if (bindingInfo.getIedName().equals(iedName)) { throw new ScdException("Internal binding can't have control block"); } @@ -234,18 +266,18 @@ public static TExtRef updateExtRefSource(SCL scd, ExtRefInfo extRefInfo) throws String prefix = extRefInfo.getHolderLnPrefix(); ExtRefSignalInfo signalInfo = extRefInfo.getSignalInfo(); - if(signalInfo == null || !signalInfo.isValid()){ + if (signalInfo == null || !signalInfo.isValid()) { throw new ScdException("Invalid or missing attributes in ExtRef signal info"); } ExtRefBindingInfo bindingInfo = extRefInfo.getBindingInfo(); - if(bindingInfo == null || !bindingInfo.isValid()){ + if (bindingInfo == null || !bindingInfo.isValid()) { throw new ScdException(INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO); } - if(bindingInfo.getIedName().equals(iedName)){ + if (bindingInfo.getIedName().equals(iedName)) { throw new ScdException("Internal binding can't have control block"); } ExtRefSourceInfo sourceInfo = extRefInfo.getSourceInfo(); - if(sourceInfo == null || !sourceInfo.isValid()){ + if (sourceInfo == null || !sourceInfo.isValid()) { throw new ScdException(INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO); } @@ -265,16 +297,15 @@ public static TExtRef updateExtRefSource(SCL scd, ExtRefInfo extRefInfo) throws } public static Set getDAI(SCL scd, String iedName, String ldInst, - ResumedDataTemplate rDtt, boolean updatable) throws ScdException { + ResumedDataTemplate rDtt, boolean updatable) throws ScdException { SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - IEDAdapter iedAdapter = new IEDAdapter(sclRootAdapter,iedName); + IEDAdapter iedAdapter = new IEDAdapter(sclRootAdapter, iedName); LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst) .orElseThrow( () -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName)) ); return lDeviceAdapter.getDAI(rDtt, updatable); - } public static void updateDAI(SCL scd, String iedName, String ldInst, ResumedDataTemplate rDtt) throws ScdException { @@ -284,9 +315,9 @@ public static void updateDAI(SCL scd, String iedName, String ldInst, ResumedData DataTypeTemplateAdapter dttAdapter = sclRootAdapter.getDataTypeTemplateAdapter(); LNodeTypeAdapter lNodeTypeAdapter = dttAdapter.getLNodeTypeAdapterById(rDtt.getLnType()) .orElseThrow(() -> new ScdException("Unknown LNodeType : " + rDtt.getLnType())); - lNodeTypeAdapter.check(rDtt.getDoName(),rDtt.getDaName()); + lNodeTypeAdapter.check(rDtt.getDoName(), rDtt.getDaName()); - if(TPredefinedBasicTypeEnum.OBJ_REF == rDtt.getBType()){ + if (TPredefinedBasicTypeEnum.OBJ_REF == rDtt.getBType()) { Long sGroup = rDtt.getDaName().getDaiValues().keySet().stream().findFirst().orElse(-1L); String val = sGroup < 0 ? null : rDtt.getDaName().getDaiValues().get(sGroup); sclRootAdapter.checkObjRef(val); @@ -306,8 +337,8 @@ public static void updateDAI(SCL scd, String iedName, String ldInst, ResumedData .withLnPrefix(rDtt.getPrefix()) .build(); - if(TPredefinedCDCEnum.ING == rDtt.getCdc() || TPredefinedCDCEnum.ASG == rDtt.getCdc() ){ - DAITracker daiTracker = new DAITracker(lnAdapter,rDtt.getDoName(),rDtt.getDaName()); + if (TPredefinedCDCEnum.ING == rDtt.getCdc() || TPredefinedCDCEnum.ASG == rDtt.getCdc()) { + DAITracker daiTracker = new DAITracker(lnAdapter, rDtt.getDoName(), rDtt.getDaName()); daiTracker.validateBoundedDAI(); } lnAdapter.updateDAI(rDtt); @@ -316,44 +347,45 @@ public static void updateDAI(SCL scd, String iedName, String ldInst, ResumedData public static Set> getEnumTypeElements(SCL scd, String idEnum) throws ScdException { SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - DataTypeTemplateAdapter dataTypeTemplateAdapter = sclRootAdapter.getDataTypeTemplateAdapter(); + DataTypeTemplateAdapter dataTypeTemplateAdapter = sclRootAdapter.getDataTypeTemplateAdapter(); EnumTypeAdapter enumTypeAdapter = dataTypeTemplateAdapter.getEnumTypeAdapterById(idEnum) - .orElseThrow(() -> new ScdException("Unknown EnumType Id: " + idEnum)); + .orElseThrow(() -> new ScdException("Unknown EnumType Id: " + idEnum)); return enumTypeAdapter.getCurrentElem().getEnumVal().stream() - .map(tEnumVal -> Pair.of(tEnumVal.getOrd(),tEnumVal.getValue())) + .map(tEnumVal -> Pair.of(tEnumVal.getOrd(), tEnumVal.getValue())) .collect(Collectors.toSet()); } public static SclRootAdapter addSubstation(@NonNull SCL scd, @NonNull SCL ssd) throws ScdException { SclRootAdapter scdRootAdapter = new SclRootAdapter(scd); SclRootAdapter ssdRootAdapter = new SclRootAdapter(ssd); - if(scdRootAdapter.getCurrentElem().getSubstation().size() > 1 - || ssdRootAdapter.currentElem.getSubstation().size() != 1) { + if (scdRootAdapter.getCurrentElem().getSubstation().size() > 1 + || ssdRootAdapter.currentElem.getSubstation().size() != 1) { throw new ScdException("SCD file must have one or zero Substation and " + "SCD file must have one Substation. The files are rejected."); } TSubstation ssdTSubstation = ssdRootAdapter.currentElem.getSubstation().get(0); - if(scdRootAdapter.getCurrentElem().getSubstation().isEmpty()) { + if (scdRootAdapter.getCurrentElem().getSubstation().isEmpty()) { scdRootAdapter.getCurrentElem().getSubstation().add(ssdTSubstation); return scdRootAdapter; } else { TSubstation scdTSubstation = scdRootAdapter.currentElem.getSubstation().get(0); - if(scdTSubstation.getName().equalsIgnoreCase(ssdTSubstation.getName())) { + if (scdTSubstation.getName().equalsIgnoreCase(ssdTSubstation.getName())) { SubstationAdapter scdSubstationAdapter = scdRootAdapter.getSubstationAdapter(scdTSubstation.getName()); - for(TVoltageLevel tvl : ssdTSubstation.getVoltageLevel()){ + for (TVoltageLevel tvl : ssdTSubstation.getVoltageLevel()) { updateVoltageLevel(scdSubstationAdapter, tvl); } - } else throw new ScdException("SCD file must have only one Substation and the Substation name from SSD file is" + - " different from the one in SCD file. The files are rejected."); + } else + throw new ScdException("SCD file must have only one Substation and the Substation name from SSD file is" + + " different from the one in SCD file. The files are rejected."); } return scdRootAdapter; } private static void updateVoltageLevel(@NonNull SubstationAdapter scdSubstationAdapter, TVoltageLevel vl) throws ScdException { - if(scdSubstationAdapter.getVoltageLevelAdapter(vl.getName()).isPresent()) { + if (scdSubstationAdapter.getVoltageLevelAdapter(vl.getName()).isPresent()) { VoltageLevelAdapter scdVoltageLevelAdapter = scdSubstationAdapter.getVoltageLevelAdapter(vl.getName()) .orElseThrow(() -> new ScdException("Unable to create VoltageLevelAdapter")); - for (TBay tbay: vl.getBay()) { + for (TBay tbay : vl.getBay()) { updateBay(scdVoltageLevelAdapter, tbay); } } else { @@ -362,12 +394,124 @@ private static void updateVoltageLevel(@NonNull SubstationAdapter scdSubstationA } private static void updateBay(@NonNull VoltageLevelAdapter scdVoltageLevelAdapter, TBay tBay) { - if(scdVoltageLevelAdapter.getBayAdapter(tBay.getName()).isPresent()){ - scdVoltageLevelAdapter.getCurrentElem().getBay() - .removeIf(t -> t.getName().equalsIgnoreCase(tBay.getName())); + if (scdVoltageLevelAdapter.getBayAdapter(tBay.getName()).isPresent()) { + scdVoltageLevelAdapter.getCurrentElem().getBay() + .removeIf(t -> t.getName().equalsIgnoreCase(tBay.getName())); scdVoltageLevelAdapter.getCurrentElem().getBay().add(tBay); } else { scdVoltageLevelAdapter.getCurrentElem().getBay().add(tBay); } } + + public static SclRootAdapter importSTDElementsInSCD(@NonNull SclRootAdapter scdRootAdapter, Set stds, + Map, List> comMap) throws ScdException { + + //Check SCD and STD compatibilities + Map>> mapICDSystemVersionUuidAndSTDFile = createMapICDSystemVersionUuidAndSTDFile(stds); + checkSTDCorrespondanceWithLNodeCompasICDHeader(mapICDSystemVersionUuidAndSTDFile); + // List all Private and remove duplicated one with same iedName + Map mapIEDNameAndPrivate = createMapIEDNameAndPrivate(scdRootAdapter); + //For each Private.ICDSystemVersionUUID and Private.iedName find STD File + for (Map.Entry entry : mapIEDNameAndPrivate.entrySet()) { + String iedName = entry.getKey(); + TPrivate tPrivate = entry.getValue(); + String icdSysVerUuid = getCompasICDHeader(tPrivate).map(TCompasICDHeader::getICDSystemVersionUUID).orElseThrow( + () -> new ScdException(ICD_SYSTEM_VERSION_UUID + " is not present in COMPAS-ICDHeader in LNode") + ); + + if (!mapICDSystemVersionUuidAndSTDFile.containsKey(icdSysVerUuid)) + throw new ScdException("There is no STD file found corresponding to " + stdCheckFormatExceptionMessage(tPrivate)); + // import /ied /dtt in Scd + SCL std = mapICDSystemVersionUuidAndSTDFile.get(icdSysVerUuid).getRight().get(0); + SclRootAdapter stdRootAdapter = new SclRootAdapter(std); + IEDAdapter stdIedAdapter = new IEDAdapter(stdRootAdapter, std.getIED().get(0)); + Optional optionalTPrivate = stdIedAdapter.getPrivateHeader(CommonConstants.COMPAS_ICDHEADER); + if (optionalTPrivate.isPresent() && comparePrivateCompasICDHeaders(optionalTPrivate.get(), tPrivate)) { + copyCompasICDHeaderFromLNodePrivateIntoSTDPrivate(optionalTPrivate.get(), tPrivate); + } else throw new ScdException("COMPAS-ICDHeader is not the same in Substation and in IED"); + scdRootAdapter.addIED(std, iedName); + + //import connectedAP and rename ConnectedAP/@iedName + CommunicationAdapter comAdapter = stdRootAdapter.getCommunicationAdapter(false); + Set subNetworkDTOSet = SubNetworkDTO.createDefaultSubnetwork(iedName, comAdapter, comMap); + addSubnetworks(scdRootAdapter.getCurrentElem(), subNetworkDTOSet, Optional.of(std)); + } + return scdRootAdapter; + } + + private static void checkSTDCorrespondanceWithLNodeCompasICDHeader(Map>> mapICDSystemVersionUuidAndSTDFile) throws ScdException { + for (Pair> pairOfPrivateAndSTDs : mapICDSystemVersionUuidAndSTDFile.values()) { + if (pairOfPrivateAndSTDs.getRight().size() != 1) { + TPrivate key = pairOfPrivateAndSTDs.getLeft(); + throw new ScdException("There are several STD files corresponding to " + stdCheckFormatExceptionMessage(key)); + } + } + } + + private static String stdCheckFormatExceptionMessage(TPrivate key) { + return CommonConstants.HEADER_ID + " = " + getCompasICDHeader(key).map(TCompasICDHeader::getHeaderId).orElse(null) + + CommonConstants.HEADER_VERSION + " = " + getCompasICDHeader(key).map(TCompasICDHeader::getHeaderVersion).orElse(null) + + CommonConstants.HEADER_REVISION + " = " + getCompasICDHeader(key).map(TCompasICDHeader::getHeaderRevision).orElse(null) + + "and " + ICD_SYSTEM_VERSION_UUID + " = " + getCompasICDHeader(key).map(TCompasICDHeader::getICDSystemVersionUUID).orElse(null); + } + + private static Map createMapIEDNameAndPrivate(SclRootAdapter scdRootAdapter) { + return scdRootAdapter.getCurrentElem().getSubstation().get(0).getVoltageLevel().stream() + .map(TVoltageLevel::getBay).flatMap(Collection::stream) + .map(TBay::getFunction).flatMap(Collection::stream) + .map(TFunction::getLNode).flatMap(Collection::stream) + .map(TLNode::getPrivate).flatMap(Collection::stream) + .filter(tPrivate -> + tPrivate.getType().equals(CommonConstants.COMPAS_ICDHEADER) + && getCompasICDHeader(tPrivate).isPresent() && getCompasICDHeader(tPrivate).get().getIEDName() != null) + .collect(Collectors.toMap(tPrivate -> getCompasICDHeader(tPrivate).get().getIEDName(), Function.identity())); + } + + private static Map>> createMapICDSystemVersionUuidAndSTDFile(Set stds) { + Map>> stringSCLMap = new HashMap<>(); + stds.forEach(std -> std.getIED().forEach(ied -> ied.getPrivate().forEach(tp -> { + getCompasICDHeader(tp).map(TCompasICDHeader::getICDSystemVersionUUID).ifPresent(icdSysVer -> { + Pair> pair = stringSCLMap.get(icdSysVer); + List list = pair != null ? pair.getRight() : new ArrayList<>(); + list.add(std); + stringSCLMap.put(icdSysVer, Pair.of(tp, list)); + }); + }))); + return stringSCLMap; + } + + private static boolean comparePrivateCompasICDHeaders(TPrivate iedPrivate, TPrivate scdPrivate) throws ScdException { + TCompasICDHeader iedCompasICDHeader = getCompasICDHeader(iedPrivate).orElseThrow( + () -> new ScdException(CommonConstants.COMPAS_ICDHEADER + "not found in IED Private ")); + TCompasICDHeader scdCompasICDHeader = getCompasICDHeader(scdPrivate).orElseThrow( + () -> new ScdException(CommonConstants.COMPAS_ICDHEADER + "not found in LNode Private ")); + return iedCompasICDHeader.getIEDType().equals(scdCompasICDHeader.getIEDType()) + && iedCompasICDHeader.getICDSystemVersionUUID().equals(scdCompasICDHeader.getICDSystemVersionUUID()) + && iedCompasICDHeader.getVendorName().equals(scdCompasICDHeader.getVendorName()) + && iedCompasICDHeader.getIEDredundancy().equals(scdCompasICDHeader.getIEDredundancy()) + && iedCompasICDHeader.getIEDmodel().equals(scdCompasICDHeader.getIEDmodel()) + && iedCompasICDHeader.getHwRev().equals(scdCompasICDHeader.getHwRev()) + && iedCompasICDHeader.getSwRev().equals(scdCompasICDHeader.getSwRev()) + && iedCompasICDHeader.getHeaderId().equals(scdCompasICDHeader.getHeaderId()) + && iedCompasICDHeader.getHeaderRevision().equals(scdCompasICDHeader.getHeaderRevision()) + && iedCompasICDHeader.getHeaderVersion().equals(scdCompasICDHeader.getHeaderVersion()); + } + + private static void copyCompasICDHeaderFromLNodePrivateIntoSTDPrivate(TPrivate stdPrivate, TPrivate lNodePrivate) throws ScdException { + TCompasICDHeader lNodeCompasICDHeader = getCompasICDHeader(lNodePrivate).orElseThrow( + () -> new ScdException(CommonConstants.COMPAS_ICDHEADER + "not found in LNode Private ")); + stdPrivate.getContent().clear(); + stdPrivate.getContent().add(lNodeCompasICDHeader); + + } + + private static Optional getCompasICDHeader(TPrivate tPrivate) { + Optional> tCompasICDHeader = !tPrivate.getType().equals(CommonConstants.COMPAS_ICDHEADER) ? Optional.empty() : + tPrivate.getContent().stream() + .filter(JAXBElement.class::isInstance) + .map(o -> (JAXBElement) o) + .findFirst(); + return tCompasICDHeader.map(JAXBElement::getValue); + } + } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/CommunicationAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/CommunicationAdapter.java index 917ea2853..37d54dd67 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/CommunicationAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/CommunicationAdapter.java @@ -1,4 +1,3 @@ - // SPDX-FileCopyrightText: 2021 RTE FRANCE // // SPDX-License-Identifier: Apache-2.0 @@ -43,16 +42,16 @@ public SubNetworkAdapter addSubnetwork(String snName, String snType, String iedName, String apName) throws ScdException { IEDAdapter iedAdapter = parentAdapter.getIEDAdapterByName(iedName); - if(!iedAdapter.findAccessPointByName(apName)){ + if (!iedAdapter.findAccessPointByName(apName)) { throw new ScdException("Unknown AccessPoint :" + apName + " in IED :" + iedName); } Optional opSubNetworkAdapter = getSubnetworkByName(snName); - if(!opSubNetworkAdapter.isPresent()){ // create new subnetwork + if (opSubNetworkAdapter.isEmpty()) { // create new subnetwork TSubNetwork subNetwork = new TSubNetwork(); subNetwork.setName(snName); subNetwork.setType(snType); currentElem.getSubNetwork().add(subNetwork); - opSubNetworkAdapter = Optional.of(new SubNetworkAdapter(this,subNetwork)); + opSubNetworkAdapter = Optional.of(new SubNetworkAdapter(this, subNetwork)); } opSubNetworkAdapter.get().addConnectedAP(iedName,apName); @@ -65,13 +64,13 @@ public Optional getSubnetworkByName(String snName) { .stream() .filter(tSubNetwork -> tSubNetwork.getName().equals(snName)) .findFirst() - .map(tSubNetwork -> new SubNetworkAdapter(this,tSubNetwork)); + .map(tSubNetwork -> new SubNetworkAdapter(this, tSubNetwork)); } public List getSubNetworkAdapters() { return currentElem.getSubNetwork() .stream() - .map(tSubNetwork -> new SubNetworkAdapter(this,tSubNetwork)) + .map(tSubNetwork -> new SubNetworkAdapter(this, tSubNetwork)) .collect(Collectors.toList()); } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapter.java index b0fd21141..280b15fba 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapter.java @@ -4,10 +4,13 @@ package org.lfenergy.compas.sct.commons.scl.com; +import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.scl2007b4.model.TConnectedAP; import org.lfenergy.compas.scl2007b4.model.TPrivate; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; +import java.util.Optional; + public class ConnectedAPAdapter extends SclElementAdapter { public ConnectedAPAdapter(SubNetworkAdapter parentAdapter, TConnectedAP currentElem) { @@ -31,4 +34,20 @@ public String getIedName() { public String getApName() { return currentElem.getApName(); } + + public void copyAddressAndPhysConnFromIcd(Optional icd) { + if (icd.isPresent() && icd.get().getCommunication() != null) { + icd.stream() + .map(SCL::getCommunication) + .findFirst() + .flatMap(com -> com.getSubNetwork().stream() + .flatMap(subNet -> subNet.getConnectedAP().stream() + .filter(connAP -> connAP.getApName().equals(currentElem.getApName()))) + .findFirst()).ifPresent(connectedAP -> { + currentElem.setAddress(connectedAP.getAddress()); + currentElem.getPhysConn().addAll(connectedAP.getPhysConn()); + }); + + } + } } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapter.java index eaad69172..9e2c796af 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapter.java @@ -12,7 +12,10 @@ import org.lfenergy.compas.sct.commons.dto.ResumedDataTemplate; import org.lfenergy.compas.sct.commons.exception.ScdException; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; @Slf4j @@ -197,45 +200,33 @@ public void check(DaTypeName daTypeName) throws ScdException { * Each Resumed Data Type Template is instantiated from a reference resumed Data Type. * @apiNote This method doesn't check relationship between DO/SDO and DA. Check should be done by caller * @param rootRDTT reference Resumed Data Type Template used to build the list - * @param visitedBDA a cache to stored visited SDO * @param filter filter for DO/SDO and DA/BDA * @return list of completed Resumed Data Type Templates beginning from this DoType (Do or SDO). */ - public List getResumedDTTs(ResumedDataTemplate rootRDTT, - Set visitedBDA, ResumedDataTemplate filter) { + public List getResumedDTTs(ResumedDataTemplate rootRDTT, ResumedDataTemplate filter) { - List resumedDataTemplates = new ArrayList<>(); + List resultRDTTs = new ArrayList<>(); for(TBDA bda : currentElem.getBDA()){ if(filter != null && filter.isDaNameDefined() && !filter.getBdaNames().contains(bda.getName())){ continue; } - rootRDTT.setBType(bda.getBType().value()); + ResumedDataTemplate currentRDTT = ResumedDataTemplate.copyFrom(rootRDTT); + currentRDTT.setBType(bda.getBType().value()); if(bda.getBType() == TPredefinedBasicTypeEnum.STRUCT) { - if(visitedBDA.contains(bda.getType())) { - continue; - } - - DATypeAdapter daTypeAdapter = parentAdapter.getDATypeAdapterById(bda.getType()).orElse(null); - visitedBDA.add(bda.getType()); - rootRDTT.addStructName(bda.getName(),DaTypeName.class); - if(daTypeAdapter != null){ - List resumedDataTemplateList = daTypeAdapter.getResumedDTTs( - rootRDTT,visitedBDA,filter - ); - resumedDataTemplates.addAll(resumedDataTemplateList); - } + currentRDTT.addDaStructName(bda.getName()); + parentAdapter.getDATypeAdapterById(bda.getType()).ifPresent( + daTypeAdapter -> resultRDTTs.addAll(daTypeAdapter.getResumedDTTs(currentRDTT, filter))); } else { - ResumedDataTemplate resumedDataTemplate = ResumedDataTemplate.copyFrom(rootRDTT); - resumedDataTemplate.addStructName(bda.getName(),DaTypeName.class); - resumedDataTemplate.setType(bda.getType()); - resumedDataTemplate.getDaName().setValImport(bda.isValImport()); - resumedDataTemplate.getDaName().addDaiValues(bda.getVal()); - resumedDataTemplates.add(resumedDataTemplate); + currentRDTT.addDaStructName(bda.getName()); + currentRDTT.setType(bda.getType()); + currentRDTT.getDaName().setValImport(bda.isValImport()); + currentRDTT.getDaName().addDaiValues(bda.getVal()); + resultRDTTs.add(currentRDTT); } } - return resumedDataTemplates; + return resultRDTTs; } public Optional getDATypeAdapterByBdaName(String name) { diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapter.java index 931757ae7..84c3a7166 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapter.java @@ -317,65 +317,60 @@ public TPredefinedCDCEnum getCdc() { * return a list of Resumed Data Type Templates beginning from this DoType (Do or SDO). * @apiNote This method doesn't check relationship between DO/SDO and DA. Check should be done by caller * @param rootRDTT reference Resumed Data Type Template used to build the list - * @param visitedSdo a cache to stored visited SDO * @param filter filter for DO/SDO and DA/BDA * @return list of Resumed Data Type Templates beginning from this DoType (Do or SDO) */ - public List getResumedDTTs(ResumedDataTemplate rootRDTT, - Set visitedSdo, ResumedDataTemplate filter) { - - List rDtts = new ArrayList<>(); + public List getResumedDTTs(ResumedDataTemplate rootRDTT, ResumedDataTemplate filter) { + List resultRDTTs = new ArrayList<>(); for(TUnNaming tUnNaming: currentElem.getSDOOrDA()){ if(tUnNaming.getClass() == TDA.class){ TDA tda = (TDA)tUnNaming; - if(filter.isDaNameDefined() && - !filter.getDaName().getName().equals(tda.getName()) ){ - // filter out - continue; - } - - rootRDTT.getDaName().setName(tda.getName()); - rootRDTT.getDaName().setFc(tda.getFc()); - rootRDTT.getDaName().setBType(tda.getBType()); - if(tda.getBType() == TPredefinedBasicTypeEnum.STRUCT){ - DATypeAdapter daTypeAdapter = parentAdapter.getDATypeAdapterById(tda.getType()).orElse(null); - if(daTypeAdapter != null){ - // get list of Resumed Data Type Templates beginning from this DAType - List resumedDataTemplateList = daTypeAdapter.getResumedDTTs( - rootRDTT,new HashSet<>(), filter - ); - rDtts.addAll(resumedDataTemplateList); - } - } else { - ResumedDataTemplate resumedDataTemplate = ResumedDataTemplate.copyFrom(rootRDTT); - resumedDataTemplate.getDaName().setType(tda.getType()); - resumedDataTemplate.getDaName().setValImport(tda.isValImport()); - resumedDataTemplate.setDaiValues(tda.getVal()); - rDtts.add(resumedDataTemplate); - } + resultRDTTs.addAll(getResumedDTTsOfDA(rootRDTT, filter, tda)); } else { TSDO tsdo = (TSDO)tUnNaming; - if((filter != null && - !filter.getSdoNames().isEmpty() && - !filter.getSdoNames().contains(tsdo.getName())) || - visitedSdo.contains(tsdo.getType())){ + if(excludedByFilter(filter, tsdo)){ continue; } - ResumedDataTemplate rDtt = ResumedDataTemplate.copyFrom(rootRDTT); - - DOTypeAdapter doTypeAdapter = parentAdapter.getDOTypeAdapterById(tsdo.getType()).orElse(null); - visitedSdo.add(tsdo.getType()); - rDtt.addStructName(tsdo.getName(),DoTypeName.class); - if(doTypeAdapter != null){ - // get list of Resumed Data Type Templates beginning from this SDO - List localRDtts = doTypeAdapter.getResumedDTTs(rDtt,visitedSdo, filter); - rDtts.addAll(localRDtts); - } + ResumedDataTemplate currentRDTT = ResumedDataTemplate.copyFrom(rootRDTT); + currentRDTT.addDoStructName(tsdo.getName()); + parentAdapter.getDOTypeAdapterById(tsdo.getType()).ifPresent( + doTypeAdapter -> + resultRDTTs.addAll(doTypeAdapter.getResumedDTTs(currentRDTT, filter))); } } - return rDtts; + return resultRDTTs; } + private List getResumedDTTsOfDA(ResumedDataTemplate rootRDTT, ResumedDataTemplate filter, TDA da){ + if(excludedByFilter(filter, da)){ + return Collections.emptyList(); + } + ResumedDataTemplate currentRDTT = ResumedDataTemplate.copyFrom(rootRDTT); + currentRDTT.getDaName().setName(da.getName()); + currentRDTT.getDaName().setFc(da.getFc()); + currentRDTT.getDaName().setBType(da.getBType()); + if(da.getBType() == TPredefinedBasicTypeEnum.STRUCT){ + return parentAdapter.getDATypeAdapterById(da.getType()) + .map(daTypeAdapter -> daTypeAdapter.getResumedDTTs(currentRDTT, filter)) + .orElse(Collections.emptyList()); + } else { + currentRDTT.getDaName().setType(da.getType()); + currentRDTT.getDaName().setValImport(da.isValImport()); + currentRDTT.setDaiValues(da.getVal()); + return List.of(currentRDTT); + } + } + + private boolean excludedByFilter(ResumedDataTemplate filter, TDA da) { + return filter != null && filter.isDaNameDefined() && + !filter.getDaName().getName().equals(da.getName()); + } + + private boolean excludedByFilter(ResumedDataTemplate filter, TSDO tsdo) { + return filter != null && + !filter.getSdoNames().isEmpty() && + !filter.getSdoNames().contains(tsdo.getName()); + } public Optional getDOTypeAdapterBySdoName(String name) { Optional opSdo = getSDOByName(name); diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapter.java index d3f17e979..48c425c0d 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapter.java @@ -17,7 +17,10 @@ import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; @Slf4j public class LNodeTypeAdapter @@ -101,11 +104,11 @@ public List getResumedDTTs(@NonNull ResumedDataTemplate fil return resumedDataTemplates; } } - ResumedDataTemplate rootResumedRTT = new ResumedDataTemplate(); - rootResumedRTT.setLnType(currentElem.getId()); - rootResumedRTT.setLnClass(filter.getLnClass()); - rootResumedRTT.setLnInst(filter.getLnInst()); - rootResumedRTT.setPrefix(filter.getPrefix()); + ResumedDataTemplate rootRDTT = new ResumedDataTemplate(); + rootRDTT.setLnType(currentElem.getId()); + rootRDTT.setLnClass(filter.getLnClass()); + rootRDTT.setLnInst(filter.getLnInst()); + rootRDTT.setPrefix(filter.getPrefix()); for(TDO tdo : currentElem.getDO()){ if(filter.isDoNameDefined() && @@ -113,16 +116,14 @@ public List getResumedDTTs(@NonNull ResumedDataTemplate fil continue; } - rootResumedRTT.getDoName().setName(tdo.getName()); - DOTypeAdapter doTypeAdapter = parentAdapter.getDOTypeAdapterById(tdo.getType()).orElse(null); - if(doTypeAdapter != null){ - rootResumedRTT.getDoName().setCdc(doTypeAdapter.getCdc()); - List rDTTList = doTypeAdapter.getResumedDTTs( - rootResumedRTT,new HashSet<>(), filter - ); - resumedDataTemplates.addAll(rDTTList); - } // else this should never happen or the scd won't be built in the first place and we'd never be here - // may be use an assert here to enforce constrain + parentAdapter.getDOTypeAdapterById(tdo.getType()).ifPresent( + doTypeAdapter -> { + ResumedDataTemplate currentRDTT = ResumedDataTemplate.copyFrom(rootRDTT); + currentRDTT.getDoName().setName(tdo.getName()); + currentRDTT.getDoName().setCdc(doTypeAdapter.getCdc()); + resumedDataTemplates.addAll(doTypeAdapter.getResumedDTTs(currentRDTT, filter)); + } + ); // else this should never happen or the scd won't be built in the first place and we'd never be here } return resumedDataTemplates; } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractLNAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractLNAdapter.java index 8da50b079..8ce8570ce 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractLNAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractLNAdapter.java @@ -7,34 +7,8 @@ import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.lfenergy.compas.scl2007b4.model.LN0; -import org.lfenergy.compas.scl2007b4.model.TAnyLN; -import org.lfenergy.compas.scl2007b4.model.TControl; -import org.lfenergy.compas.scl2007b4.model.TDOI; -import org.lfenergy.compas.scl2007b4.model.TDataSet; -import org.lfenergy.compas.scl2007b4.model.TExtRef; -import org.lfenergy.compas.scl2007b4.model.TFCDA; -import org.lfenergy.compas.scl2007b4.model.TFCEnum; -import org.lfenergy.compas.scl2007b4.model.TGSEControl; -import org.lfenergy.compas.scl2007b4.model.TLLN0Enum; -import org.lfenergy.compas.scl2007b4.model.TReportControl; -import org.lfenergy.compas.scl2007b4.model.TSampledValueControl; -import org.lfenergy.compas.scl2007b4.model.TServiceType; -import org.lfenergy.compas.scl2007b4.model.TVal; -import org.lfenergy.compas.sct.commons.dto.ControlBlock; -import org.lfenergy.compas.sct.commons.dto.DaTypeName; -import org.lfenergy.compas.sct.commons.dto.DataSetInfo; -import org.lfenergy.compas.sct.commons.dto.DoTypeName; -import org.lfenergy.compas.sct.commons.dto.ExtRefBindingInfo; -import org.lfenergy.compas.sct.commons.dto.ExtRefInfo; -import org.lfenergy.compas.sct.commons.dto.ExtRefSignalInfo; -import org.lfenergy.compas.sct.commons.dto.ExtRefSourceInfo; -import org.lfenergy.compas.sct.commons.dto.FCDAInfo; -import org.lfenergy.compas.sct.commons.dto.GooseControlBlock; -import org.lfenergy.compas.sct.commons.dto.LNodeMetaData; -import org.lfenergy.compas.sct.commons.dto.ReportControlBlock; -import org.lfenergy.compas.sct.commons.dto.ResumedDataTemplate; -import org.lfenergy.compas.sct.commons.dto.SMVControlBlock; +import org.lfenergy.compas.scl2007b4.model.*; +import org.lfenergy.compas.sct.commons.dto.*; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.ObjectReference; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; @@ -43,13 +17,7 @@ import org.lfenergy.compas.sct.commons.scl.dtt.LNodeTypeAdapter; import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; @@ -472,11 +440,11 @@ public TExtRef checkExtRefInfoCoherence(@NonNull ExtRefInfo extRefInfo) throws S /** * Returns a list of resumed DataTypeTemplate for DataAttribute (updatable or not) * @param rDtt reference resumed DataTypeTemplate (used as filter) - * @param updatable true to retrieve updatable DAI, false otherwise + * @param updatableOnly true to retrieve only updatable DAI, false to retrieve all DAI * @return List of resumed DataTypeTemplate for DataAttribute (updatable or not) * @throws ScdException SCD illegal arguments exception */ - public List getDAI(ResumedDataTemplate rDtt, boolean updatable) throws ScdException { + public List getDAI(ResumedDataTemplate rDtt, boolean updatableOnly) throws ScdException { String lnType = currentElem.getLnType(); if(!StringUtils.isBlank(rDtt.getLnType())){ lnType = rDtt.getLnType(); @@ -492,36 +460,48 @@ public List getDAI(ResumedDataTemplate rDtt, boolean updata ); List resumedDTTs = lNodeTypeAdapter.getResumedDTTs(rDtt); - // complete the list by the overridden information in DAI - resumedDTTs = resumedDTTs.stream() - .map(rDTT -> completeResumedDTTFromDAI(rDTT,updatable)) - .filter(rDTT -> !updatable || (rDTT.isUpdatable())) - .collect(Collectors.toList()); - return resumedDTTs; - } + resumedDTTs.forEach(this::overrideAttributesFromDAI); - protected ResumedDataTemplate completeResumedDTTFromDAI(ResumedDataTemplate rDtt, boolean updatable){ - Optional opDaiAdapter = findMatch(rDtt.getDoName(), rDtt.getDaName()); - if(opDaiAdapter.isPresent()) { - AbstractDAIAdapter daiAdapter = (AbstractDAIAdapter) opDaiAdapter.get(); - if(daiAdapter.isValImport() != null) { - rDtt.setValImport(daiAdapter.isValImport()); - } - rDtt.setDaiValues(daiAdapter.getCurrentElem().getVal()); - if (updatable && (daiAdapter.isValImport() == null || daiAdapter.isValImport())) { - boolean isSg = daiAdapter.getCurrentElem().getVal().stream() - .anyMatch(tVal -> tVal.getSGroup() != null && tVal.getSGroup().intValue() > 0); - - if (isSg) { - IEDAdapter iedAdapter = parentAdapter.getParentAdapter(); - rDtt.setValImport(iedAdapter.isSettingConfig(parentAdapter.getInst())); // override - } else if (rDtt.getDaName().getFc() == TFCEnum.SG || rDtt.getDaName().getFc() == TFCEnum.SE) { - log.warn("Inconsistencies in the SCD file (Setting group and DAI FC)!"); - rDtt.setValImport(false); + if (updatableOnly){ + return resumedDTTs.stream().filter(ResumedDataTemplate::isUpdatable).collect(Collectors.toList()); + } else { + return resumedDTTs; + } + } + + protected void overrideAttributesFromDAI(final ResumedDataTemplate rDtt) { + findMatch(rDtt.getDoName(), rDtt.getDaName()) + .map(iDataAdapter -> (AbstractDAIAdapter) iDataAdapter) + .map(AbstractDAIAdapter::getCurrentElem) + .ifPresent(tdai -> { + rDtt.setDaiValues(tdai.getVal()); + if (rDtt.getDaName().getFc() == TFCEnum.SG || rDtt.getDaName().getFc() == TFCEnum.SE) { + boolean isGroup = hasSgGroup(tdai); + if (isGroup) { + rDtt.setValImport(!Boolean.FALSE.equals(tdai.isValImport()) && iedHasConfSG()); + } else { + rDtt.setValImport(false); + log.warn("Inconsistency in the SCD file - DAI {} with fc={} must have a sGroup attribute", + rDtt.getObjRef(getCurrentIED().getName(), parentAdapter.getInst()), rDtt.getDaName().getFc()); + } + } else if (tdai.isValImport() != null) { + rDtt.setValImport(tdai.isValImport()); } - } - } - return rDtt; + }); + } + + private boolean iedHasConfSG() { + IEDAdapter iedAdapter = getCurrentIED(); + return iedAdapter.isSettingConfig(this.parentAdapter.getInst()); + } + + private IEDAdapter getCurrentIED() { + LDeviceAdapter lDeviceAdapter = this.parentAdapter; + return lDeviceAdapter.getParentAdapter(); + } + + private boolean hasSgGroup(TDAI tdai) { + return tdai.getVal().stream().anyMatch(tVal -> tVal.getSGroup() != null && tVal.getSGroup().intValue() > 0); } /** @@ -531,13 +511,13 @@ protected ResumedDataTemplate completeResumedDTTFromDAI(ResumedDataTemplate rDtt * @param daTypeName defined-DA (da.bda1[.bda2...bda_n]) * @return Optional of DAIAdapter for the matched DAI */ - protected Optional findMatch(DoTypeName doTypeName, DaTypeName daTypeName){ + protected Optional findMatch(DoTypeName doTypeName, DaTypeName daTypeName){ DAITracker daiTracker = new DAITracker(this,doTypeName,daTypeName); DAITracker.MatchResult matchResult = daiTracker.search(); if(matchResult != DAITracker.MatchResult.FULL_MATCH){ return Optional.empty(); } - return Optional.of((AbstractDAIAdapter) daiTracker.getBdaiOrDaiAdapter()); + return Optional.of(daiTracker.getBdaiOrDaiAdapter()); } public void updateDAI(@NonNull ResumedDataTemplate rDtt) throws ScdException { @@ -638,10 +618,10 @@ public boolean matches(ObjectReference objRef) { String.format("Corrupted SCD file: Reference to unknown LNodeType(%s)", getLnType()) ) ); - ResumedDataTemplate filter = new ResumedDataTemplate(); - filter.setLnInst(getLNInst()); - filter.setLnClass(getLNClass()); - filter.setLnType(currentElem.getLnType()); + ResumedDataTemplate filter = ResumedDataTemplate.builder() + .lnInst(getLNInst()) + .lnClass(getLNClass()) + .lnType(currentElem.getLnType()).build(); List rDtts = lNodeTypeAdapter.getResumedDTTs(filter); return matchesDataAttributes(dataAttribute) || diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapter.java index 6d1f8da31..1d79e330a 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapter.java @@ -259,4 +259,11 @@ public ControlBlock createControlBlock(ControlBlock getPrivateHeader(String privateType){ + return currentElem.getPrivate() + .stream() + .filter(tPrivate -> tPrivate.getType().equals(privateType)) + .findFirst(); + } } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LDeviceAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LDeviceAdapter.java index fa3d85831..fdfbf6f89 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LDeviceAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LDeviceAdapter.java @@ -133,17 +133,13 @@ public Set getDAI(ResumedDataTemplate rDtt, boolean updatab } Set resumedDataTemplateSet = new HashSet<>(); - List resumedDataTemplateList; - ResumedDataTemplate filter; for(AbstractLNAdapter lnAdapter : lnAdapters){ - - filter = ResumedDataTemplate.copyFrom(rDtt); + ResumedDataTemplate filter = ResumedDataTemplate.copyFrom(rDtt); filter.setLnClass(lnAdapter.getLNClass()); filter.setLnInst(lnAdapter.getLNInst()); filter.setPrefix(lnAdapter.getPrefix()); filter.setLnType(lnAdapter.getLnType()); - resumedDataTemplateList = lnAdapter.getDAI(filter, updatable); - resumedDataTemplateSet.addAll(resumedDataTemplateList); + resumedDataTemplateSet.addAll(lnAdapter.getDAI(filter, updatable)); } return resumedDataTemplateSet; diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DTO.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DTO.java index 904273c5e..2ff372b10 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DTO.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DTO.java @@ -4,9 +4,13 @@ package org.lfenergy.compas.sct.commons.dto; +import org.apache.commons.lang3.tuple.Pair; import org.lfenergy.compas.scl2007b4.model.*; import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; +import java.util.Map; import java.util.UUID; public class DTO { @@ -288,4 +292,8 @@ public static HeaderDTO.HistoryItem createHeaderItem(String now){ return historyItem; } + + public static final Map, List> comMap = Map.of( + Pair.of("RSPACE_PROCESS_NETWORK", SubNetworkDTO.SubnetworkType.MMS.toString()), Arrays.asList("PROCESS_AP", "TOTO_AP_GE"), + Pair.of("RSPACE_ADMIN_NETWORK", SubNetworkDTO.SubnetworkType.IP.toString()), Arrays.asList("ADMIN_AP","TATA_AP_EFFACEC")); } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DaTypeNameTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DaTypeNameTest.java index 19f687ac0..bc7ddf010 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DaTypeNameTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DaTypeNameTest.java @@ -6,40 +6,120 @@ import org.junit.jupiter.api.Test; import org.lfenergy.compas.scl2007b4.model.TFCEnum; -import org.lfenergy.compas.scl2007b4.model.TPredefinedBasicTypeEnum; -import org.lfenergy.compas.scl2007b4.model.TPredefinedCDCEnum; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; -import static org.junit.jupiter.api.Assertions.*; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.lfenergy.compas.sct.commons.testhelpers.DataTypeUtils.createDa; class DaTypeNameTest { @Test - void testConstructor(){ - DaTypeName daTypeName = new DaTypeName("da.bda1.bda2"); - daTypeName.setFc(TFCEnum.CF); - daTypeName.setBType(TPredefinedBasicTypeEnum.CHECK); - daTypeName.setType("IfExist_Its_EnumType"); - assertEquals("da",daTypeName.getName()); - assertEquals(TFCEnum.CF,daTypeName.getFc()); - assertThat(daTypeName.getStructNames(), contains("bda1","bda2")); + void testConstructorWithRef() { + // given : nothing + // when + DaTypeName daTypeName = new DaTypeName("da1.bda1.bda2"); + // then + assertThat(daTypeName.getName()).isEqualTo("da1"); + assertThat(daTypeName.getStructNames()).containsExactly("bda1", "bda2"); + assertThat(daTypeName.getDaiValues()).isNotNull().isEmpty(); + } + + @Test + void testConstructorWithRefWhenEmptyStruct() { + // given : nothing + // when + DaTypeName daTypeName = new DaTypeName("da1"); + // then + assertThat(daTypeName.getName()).isEqualTo("da1"); + assertThat(daTypeName.getStructNames()).isNotNull().isEmpty(); + assertThat(daTypeName.getDaiValues()).isNotNull().isEmpty(); + } + + @Test + void testConstructorWithRefWithNullName() { + // given : nothing + // when + DaTypeName daTypeName = new DaTypeName(null); + // then + assertThat(daTypeName.getName()).isEqualTo(""); + assertThat(daTypeName.getStructNames()).isNotNull().isEmpty(); + assertThat(daTypeName.getDaiValues()).isNotNull().isEmpty(); + } + + @Test + void testConstructor2WithRef() { + // given : nothing + // when + DaTypeName daTypeName = new DaTypeName("da1", "bda1.bda2"); + // then + assertThat(daTypeName.getName()).isEqualTo("da1"); + assertThat(daTypeName.getStructNames()).containsExactly("bda1", "bda2"); + assertThat(daTypeName.getDaiValues()).isNotNull().isEmpty(); + } + + @Test + void testConstructor2WithRefWhenEmptyStruct() { + // given : nothing + // when + DaTypeName daTypeName = new DaTypeName("da1", null); + // then + assertThat(daTypeName.getName()).isEqualTo("da1"); + assertThat(daTypeName.getStructNames()).isNotNull().isEmpty(); + assertThat(daTypeName.getDaiValues()).isNotNull().isEmpty(); + } + + @Test + void testConstructor2WithRefWithNullName() { + // given : nothing + // when + DaTypeName daTypeName = new DaTypeName(null, null); + // then + assertThat(daTypeName.getName()).isEqualTo(""); + assertThat(daTypeName.getStructNames()).isNotNull().isEmpty(); + assertThat(daTypeName.getDaiValues()).isNotNull().isEmpty(); + } - DaTypeName daTypeName1 = new DaTypeName("da","bda1.bda2"); - daTypeName1.setFc(TFCEnum.CF); - daTypeName1.setBType(TPredefinedBasicTypeEnum.CHECK); - daTypeName1.setType("IfExist_Its_EnumType"); - assertEquals(daTypeName,daTypeName1); - assertEquals(daTypeName.hashCode(),daTypeName1.hashCode()); + @Test + void testConstructorWithNameAndStructNames() { + // given : nothing + // when + DaTypeName daTypeName = new DaTypeName("da1", "bda1.bda2"); - daTypeName1.setType("toto"); - assertNotEquals(daTypeName,daTypeName1); + // then + assertThat(daTypeName.getName()).isEqualTo("da1"); + assertThat(daTypeName.getStructNames()).containsExactly("bda1", "bda2"); + } - daTypeName1.setBType(TPredefinedBasicTypeEnum.DBPOS); - assertNotEquals(daTypeName,daTypeName1); + @Test + void testEquals() { + // given : nothing + DaTypeName da1 = createDa("da1.bda1.bda2", TFCEnum.CF, true, Map.of(0L, "value")); + DaTypeName da2 = createDa("da1.bda1.bda2", TFCEnum.CF, true, Map.of(0L, "value")); + // when + boolean result = da1.equals(da2); + // then + assertThat(result).isTrue(); + } - daTypeName1.setFc(TFCEnum.BL); - assertNotEquals(daTypeName,daTypeName1); + @Test + void testNotEquals() { + // given : nothing + DaTypeName da1 = createDa("da1.bda1.bda2", TFCEnum.CF, true, Map.of(0L, "value")); + DaTypeName da2 = createDa("da1.bda1.bda2", TFCEnum.DC, true, Map.of(0L, "value")); + // when + boolean result = da1.equals(da2); + // then + assertThat(result).isFalse(); + } + @Test + void testFrom() { + // given : nothing + DaTypeName da1 = createDa("da1.bda1.bda2", TFCEnum.CF, true, Map.of(0L, "value")); + // when + DaTypeName da2 = DaTypeName.from(da1); + // then + assertThat(da2).isEqualTo(da1); } -} \ No newline at end of file +} diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DoTypeNameTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DoTypeNameTest.java index fc3ca897f..4199498b5 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DoTypeNameTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DoTypeNameTest.java @@ -4,30 +4,114 @@ package org.lfenergy.compas.sct.commons.dto; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; import org.junit.jupiter.api.Test; import org.lfenergy.compas.scl2007b4.model.TPredefinedCDCEnum; -import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.lfenergy.compas.sct.commons.testhelpers.DataTypeUtils.createDo; class DoTypeNameTest { @Test - void testConstructor(){ - DoTypeName doTypeName = new DoTypeName("do.Sdo1.Sdo2"); - doTypeName.setCdc(TPredefinedCDCEnum.WYE); - assertEquals("do",doTypeName.getName()); - assertEquals(TPredefinedCDCEnum.WYE,doTypeName.getCdc()); - assertThat(doTypeName.getStructNames(), contains("Sdo1","Sdo2")); + void testConstructorWithRef() { + // given : nothing + // when + DoTypeName doTypeName = new DoTypeName("do1.bdo1.bdo2"); + // then + assertThat(doTypeName.getName()).isEqualTo("do1"); + assertThat(doTypeName.getStructNames()).containsExactly("bdo1", "bdo2"); + } - DoTypeName doTypeName2 = new DoTypeName("do","Sdo1.Sdo2"); - doTypeName2.setCdc(TPredefinedCDCEnum.WYE); - assertEquals(doTypeName,doTypeName2); - assertEquals(doTypeName.hashCode(),doTypeName2.hashCode()); + @Test + void testConstructorWithRefWhenEmptyStruct() { + // given : nothing + // when + DoTypeName doTypeName = new DoTypeName("do1"); + // then + assertThat(doTypeName.getName()).isEqualTo("do1"); + assertThat(doTypeName.getStructNames()).isNotNull().isEmpty(); + } - doTypeName2.setCdc(TPredefinedCDCEnum.ACD); - assertNotEquals(doTypeName,doTypeName2); + @Test + void testConstructorWithRefWithNullName() { + // given : nothing + // when + DoTypeName doTypeName = new DoTypeName(null); + // then + assertThat(doTypeName.getName()).isEqualTo(""); + assertThat(doTypeName.getStructNames()).isNotNull().isEmpty(); + } + + @Test + void testConstructor2WithRef() { + // given : nothing + // when + DoTypeName doTypeName = new DoTypeName("do1", "bdo1.bdo2"); + // then + assertThat(doTypeName.getName()).isEqualTo("do1"); + assertThat(doTypeName.getStructNames()).containsExactly("bdo1", "bdo2"); + } + + @Test + void testConstructor2WithRefWhenEmptyStruct() { + // given : nothing + // when + DoTypeName doTypeName = new DoTypeName("do1", null); + // then + assertThat(doTypeName.getName()).isEqualTo("do1"); + assertThat(doTypeName.getStructNames()).isNotNull().isEmpty(); + } + + @Test + void testConstructor2WithRefWithNullName() { + // given : nothing + // when + DoTypeName doTypeName = new DoTypeName(null, null); + // then + assertThat(doTypeName.getName()).isEqualTo(""); + assertThat(doTypeName.getStructNames()).isNotNull().isEmpty(); } -} \ No newline at end of file + @Test + void testConstructorWithNameAndStructNames() { + // given : nothing + // when + DoTypeName doTypeName = new DoTypeName("do1", "bdo1.bdo2"); + + // then + assertThat(doTypeName.getName()).isEqualTo("do1"); + assertThat(doTypeName.getStructNames()).containsExactly("bdo1", "bdo2"); + } + + @Test + void testEquals() { + // given : nothing + DoTypeName do1 = createDo("do1.bdo1.bdo2", TPredefinedCDCEnum.DPS); + DoTypeName do2 = createDo("do1.bdo1.bdo2", TPredefinedCDCEnum.DPS); + // when + boolean result = do1.equals(do2); + // then + assertThat(result).isTrue(); + } + + @Test + void testNotEquals() { + // given : nothing + DoTypeName do1 = createDo("do1.bdo1.bdo2", TPredefinedCDCEnum.DPS); + DoTypeName do2 = createDo("do1.bdo1.bdo2", TPredefinedCDCEnum.ACD); + // when + boolean result = do1.equals(do2); + // then + assertThat(result).isFalse(); + } + + @Test + void testFrom() { + // given : nothing + DoTypeName do1 = createDo("do1.bdo1.bdo2", TPredefinedCDCEnum.DPS); + // when + DoTypeName do2 = DoTypeName.from(do1); + // then + assertThat(do2).isEqualTo(do1); + } +} diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LNodeDTOTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LNodeDTOTest.java index 870b3c261..97f8ca1fd 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LNodeDTOTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LNodeDTOTest.java @@ -6,14 +6,17 @@ import org.junit.jupiter.api.Test; import org.lfenergy.compas.scl2007b4.model.TExtRef; +import org.lfenergy.compas.sct.commons.scl.dtt.DataTypeTemplateAdapter; +import org.lfenergy.compas.sct.commons.scl.dtt.LNodeTypeAdapter; import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter; import org.lfenergy.compas.sct.commons.scl.ied.LDeviceAdapter; import org.lfenergy.compas.sct.commons.scl.ied.LNAdapter; -import org.mockito.Mockito; import java.util.List; +import java.util.Optional; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; class LNodeDTOTest { @@ -34,7 +37,7 @@ void testConstructor(){ ()-> assertEquals(DTO.LN_TYPE,lNodeDTO.getNodeType()), ()-> assertEquals(DTO.HOLDER_LN_PREFIX,lNodeDTO.getPrefix()) ); - lNodeDTO.addResumedDataTemplate(new ResumedDataTemplate()); + lNodeDTO.addResumedDataTemplate(ResumedDataTemplate.builder().daName(new DaTypeName("da1")).build()); lNodeDTO.addExtRefInfo(new ExtRefInfo()); lNodeDTO.addControlBlock(new ReportControlBlock()); lNodeDTO.addDataSet(new DataSetInfo()); @@ -42,7 +45,7 @@ void testConstructor(){ lNodeDTO.addAllControlBlocks(List.of(new SMVControlBlock())); lNodeDTO.addAllDatSets(List.of(new DataSetInfo())); lNodeDTO.addAllExtRefInfo(List.of(new ExtRefInfo())); - lNodeDTO.addAllResumedDataTemplate(List.of(new ResumedDataTemplate())); + lNodeDTO.addAllResumedDataTemplate(List.of(ResumedDataTemplate.builder().daName(new DaTypeName("da2")).build())); assertEquals(2, lNodeDTO.getExtRefs().size()); assertEquals(2, lNodeDTO.getDatSets().size()); @@ -53,24 +56,30 @@ void testConstructor(){ @Test void testFrom(){ - IEDAdapter iedAdapter = Mockito.mock(IEDAdapter.class); - LDeviceAdapter lDeviceAdapter = Mockito.mock(LDeviceAdapter.class); - Mockito.when(iedAdapter.getName()).thenReturn(DTO.HOLDER_IED_NAME); - Mockito.when(lDeviceAdapter.getInst()).thenReturn(DTO.HOLDER_LD_INST); - Mockito.when(lDeviceAdapter.getParentAdapter()).thenReturn(iedAdapter); - - LNAdapter lnAdapter = Mockito.mock(LNAdapter.class); - Mockito.when(lnAdapter.getParentAdapter()).thenReturn(lDeviceAdapter); - Mockito.when(lnAdapter.getLNClass()).thenReturn(DTO.HOLDER_LN_CLASS); - Mockito.when(lnAdapter.getLNInst()).thenReturn(DTO.HOLDER_LN_INST); - Mockito.when(lnAdapter.getLnType()).thenReturn(DTO.LN_TYPE); - Mockito.when(lnAdapter.getPrefix()).thenReturn(DTO.HOLDER_LN_PREFIX); + IEDAdapter iedAdapter = mock(IEDAdapter.class); + LDeviceAdapter lDeviceAdapter = mock(LDeviceAdapter.class); + when(iedAdapter.getName()).thenReturn(DTO.HOLDER_IED_NAME); + when(lDeviceAdapter.getInst()).thenReturn(DTO.HOLDER_LD_INST); + when(lDeviceAdapter.getParentAdapter()).thenReturn(iedAdapter); + + LNAdapter lnAdapter = mock(LNAdapter.class); + when(lnAdapter.getParentAdapter()).thenReturn(lDeviceAdapter); + when(lnAdapter.getLNClass()).thenReturn(DTO.HOLDER_LN_CLASS); + when(lnAdapter.getLNInst()).thenReturn(DTO.HOLDER_LN_INST); + when(lnAdapter.getLnType()).thenReturn(DTO.LN_TYPE); + when(lnAdapter.getPrefix()).thenReturn(DTO.HOLDER_LN_PREFIX); + + DataTypeTemplateAdapter dataTypeTemplateAdapter = mock(DataTypeTemplateAdapter.class); + when(lnAdapter.getDataTypeTemplateAdapter()).thenReturn(dataTypeTemplateAdapter); + LNodeTypeAdapter lNodeTypeAdapter = mock(LNodeTypeAdapter.class); + when(dataTypeTemplateAdapter.getLNodeTypeAdapterById(any())).thenReturn(Optional.of(lNodeTypeAdapter)); + when(lNodeTypeAdapter.getResumedDTTs(any())).thenReturn(List.of(ResumedDataTemplate.builder().build())); TExtRef extRef = DTO.createExtRef(); - Mockito.when(lnAdapter.getExtRefs(null)).thenReturn(List.of(extRef)); + when(lnAdapter.getExtRefs(null)).thenReturn(List.of(extRef)); LNodeDTO lNodeDTO = LNodeDTO.from(lnAdapter, - new LogicalNodeOptions(true,false,false,false)); + new LogicalNodeOptions(true,true,false,false)); assertNotNull(lNodeDTO); assertAll("LNODE", ()-> assertEquals(DTO.HOLDER_LN_INST,lNodeDTO.getInst()), @@ -86,21 +95,20 @@ void testFrom(){ assertEquals(DTO.HOLDER_LN_CLASS,extRefInfo.getHolderLnClass()); assertEquals(DTO.HOLDER_LN_INST,extRefInfo.getHolderLnInst()); assertEquals(DTO.HOLDER_LN_PREFIX,extRefInfo.getHolderLnPrefix()); - } @Test void testExtractExtRefInfo(){ - LNAdapter lnAdapter = Mockito.mock(LNAdapter.class); - Mockito.when(lnAdapter.getLNClass()).thenReturn(DTO.HOLDER_LN_CLASS); - Mockito.when(lnAdapter.getLNInst()).thenReturn(DTO.HOLDER_LN_INST); - Mockito.when(lnAdapter.getLnType()).thenReturn(DTO.LN_TYPE); - Mockito.when(lnAdapter.getPrefix()).thenReturn(DTO.HOLDER_LN_PREFIX); - Mockito.when(lnAdapter.hasInputs()).thenReturn(true); + LNAdapter lnAdapter = mock(LNAdapter.class); + when(lnAdapter.getLNClass()).thenReturn(DTO.HOLDER_LN_CLASS); + when(lnAdapter.getLNInst()).thenReturn(DTO.HOLDER_LN_INST); + when(lnAdapter.getLnType()).thenReturn(DTO.LN_TYPE); + when(lnAdapter.getPrefix()).thenReturn(DTO.HOLDER_LN_PREFIX); + when(lnAdapter.hasInputs()).thenReturn(true); TExtRef extRef = DTO.createExtRef(); - Mockito.when(lnAdapter.getExtRefs(null)).thenReturn(List.of(extRef)); + when(lnAdapter.getExtRefs(null)).thenReturn(List.of(extRef)); LNodeDTO lNodeDTO = LNodeDTO.extractExtRefInfo(lnAdapter); @@ -113,4 +121,4 @@ void testExtractExtRefInfo(){ ()-> assertEquals(1,lNodeDTO.getExtRefs().size()) ); } -} \ No newline at end of file +} diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplateTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplateTest.java index 28f60e910..385eda9e6 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplateTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplateTest.java @@ -7,6 +7,11 @@ import org.junit.jupiter.api.Test; import org.lfenergy.compas.scl2007b4.model.TFCEnum; import org.lfenergy.compas.scl2007b4.model.TPredefinedCDCEnum; +import org.lfenergy.compas.scl2007b4.model.TVal; + +import java.util.List; +import java.util.Map; + import static org.junit.jupiter.api.Assertions.*; class ResumedDataTemplateTest { @@ -18,6 +23,99 @@ void testGetObjRef(){ String objRef = resumedDataTemplate.getObjRef("IED","LDTM"); assertEquals(expected,objRef); } + + @Test + void testGetObjRefWhenLLN0(){ + // given + ResumedDataTemplate resumedDataTemplate = DTO.createRTT("pre","LLN0","1"); + // when + String objRef = resumedDataTemplate.getObjRef("IED","LDTM"); + // then + assertEquals("IEDLDTM/LLN0.do.sdo1.sdo2.da.bda1.bda2",objRef); + } + + @Test + void testGetDataAttributes(){ + // given + ResumedDataTemplate resumedDataTemplate = DTO.createRTT("pre","lnclass","1"); + // when + String dataAttributes = resumedDataTemplate.getDataAttributes(); + // then + String expected = "do.sdo1.sdo2.da.bda1.bda2"; + assertEquals(expected, dataAttributes); + } + + @Test + void testAddDoStructName(){ + // given + ResumedDataTemplate resumedDataTemplate = DTO.createRTT("pre","lnclass","1"); + resumedDataTemplate.setDaName(new DaTypeName()); + // when + resumedDataTemplate.addDoStructName("added_sdo"); + // then + String expected = "do.sdo1.sdo2.added_sdo"; + assertEquals(expected, resumedDataTemplate.getDoRef()); + } + + @Test + void testAddDoStructNameWhenNoDoName(){ + // given + ResumedDataTemplate resumedDataTemplate = DTO.createRTT("pre","lnclass","1"); + resumedDataTemplate.setDaName(new DaTypeName()); + resumedDataTemplate.setDoName(new DoTypeName()); + // when & then + assertThrows(IllegalArgumentException.class, () -> resumedDataTemplate.addDoStructName("added_sdo")); + } + + @Test + void testAddDaStructName(){ + // given + ResumedDataTemplate resumedDataTemplate = DTO.createRTT("pre","lnclass","1"); + // when + resumedDataTemplate.addDaStructName("added_bda"); + // then + String expected = "da.bda1.bda2.added_bda"; + assertEquals(expected, resumedDataTemplate.getDaRef()); + } + + @Test + void testAddDaStructNameWhenNoDoName(){ + // given + ResumedDataTemplate resumedDataTemplate = DTO.createRTT("pre","lnclass","1"); + resumedDataTemplate.setDaName(new DaTypeName()); + resumedDataTemplate.setDoName(new DoTypeName()); + // when & then + assertThrows(IllegalArgumentException.class, () -> resumedDataTemplate.addDaStructName("added_sda")); + } + + @Test + void testSetDaiValues(){ + // given + ResumedDataTemplate resumedDataTemplate = DTO.createRTT("pre","lnclass","1"); + TVal val = new TVal(); + val.setValue("test"); + // when + resumedDataTemplate.setDaiValues(List.of(val)); + // then + assertEquals(Map.of(0L, "test"), resumedDataTemplate.getDaName().getDaiValues()); + } + + @Test + void testSetDaiValuesWhenMultipleVal(){ + // given + ResumedDataTemplate resumedDataTemplate = DTO.createRTT("pre","lnclass","1"); + TVal val1 = new TVal(); + val1.setValue("test1"); + val1.setSGroup(0L); + TVal val2 = new TVal(); + val2.setValue("test2"); + val2.setSGroup(1L); + // when + resumedDataTemplate.setDaiValues(List.of(val1, val2)); + // then + assertEquals(Map.of(0L, "test1", 1L, "test2"), resumedDataTemplate.getDaName().getDaiValues()); + } + @Test void testCopyFrom() { ResumedDataTemplate rDtt = DTO.createRTT("pre","lnclass","1"); @@ -58,4 +156,4 @@ void testIsUpdatable(){ rDtt.getDaName().setFc(TFCEnum.BL); assertFalse(rDtt.isUpdatable()); } -} \ No newline at end of file +} diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTOTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTOTest.java index 544524bd6..e9471bc07 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTOTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTOTest.java @@ -4,13 +4,19 @@ package org.lfenergy.compas.sct.commons.dto; +import org.apache.commons.lang3.tuple.Pair; import org.junit.jupiter.api.Test; +import org.lfenergy.compas.sct.commons.scl.com.CommunicationAdapter; import org.lfenergy.compas.sct.commons.scl.com.ConnectedAPAdapter; import org.lfenergy.compas.sct.commons.scl.com.SubNetworkAdapter; import org.mockito.Mockito; +import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.Set; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class SubNetworkDTOTest { @@ -42,4 +48,27 @@ void testFrom(){ } + @Test + void testCreateDefaultSubnetwork() { + CommunicationAdapter comAdapter = Mockito.mock(CommunicationAdapter.class); + SubNetworkAdapter subNetworkAdapter = Mockito.mock(SubNetworkAdapter.class); + ConnectedAPAdapter connectedAPAdapter = Mockito.mock(ConnectedAPAdapter.class); + + Mockito.when(comAdapter.getSubNetworkAdapters()).thenReturn(List.of(subNetworkAdapter)); + Mockito.when(subNetworkAdapter.getConnectedAPAdapters()).thenReturn(List.of(connectedAPAdapter)); + Mockito.when(subNetworkAdapter.getName()).thenReturn("sName"); + Mockito.when(subNetworkAdapter.getType()).thenReturn(SubNetworkDTO.SubnetworkType.IP.toString()); + Mockito.when(connectedAPAdapter.getApName()).thenReturn("PROCESS_AP"); + Mockito.when(connectedAPAdapter.getIedName()).thenReturn("IEDName"); + + final Map, List> comMap = Map.of( + Pair.of("RSPACE_PROCESS_NETWORK", SubNetworkDTO.SubnetworkType.MMS.toString()), Arrays.asList("PROCESS_AP", "TOTO_AP_GE"), + Pair.of("RSPACE_ADMIN_NETWORK", SubNetworkDTO.SubnetworkType.IP.toString()), Arrays.asList("ADMIN_AP","TATA_AP_EFFACEC")); + + Set subNetworkDTOS = SubNetworkDTO.createDefaultSubnetwork("IEDName", comAdapter, comMap); + assertThat(subNetworkDTOS).hasSize(2); + SubNetworkDTO expectedSubNetwork = subNetworkDTOS.stream().filter(subNetworkDTO -> !subNetworkDTO.getConnectedAPs().isEmpty()).findFirst().orElse(new SubNetworkDTO()); + assertThat(expectedSubNetwork.getConnectedAPs()).hasSize(1); + + } } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java index e817b30a3..c068214f5 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java @@ -4,10 +4,12 @@ package org.lfenergy.compas.sct.commons.scl; +import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.lfenergy.compas.scl2007b4.model.*; +import org.lfenergy.compas.sct.commons.CommonConstants; import org.lfenergy.compas.sct.commons.dto.*; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter; @@ -16,43 +18,44 @@ import org.lfenergy.compas.sct.commons.testhelpers.MarshallerWrapper; import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; +import java.util.*; +import java.util.stream.Collectors; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; +import static org.lfenergy.compas.sct.commons.testhelpers.DataTypeUtils.createDa; +import static org.lfenergy.compas.sct.commons.testhelpers.DataTypeUtils.createDo; class SclServiceTest { @Test void testAddHistoryItem() throws ScdException { - SclRootAdapter sclRootAdapter= new SclRootAdapter("hId",SclRootAdapter.VERSION,SclRootAdapter.REVISION); + SclRootAdapter sclRootAdapter = new SclRootAdapter("hId", SclRootAdapter.VERSION, SclRootAdapter.REVISION); SCL scd = sclRootAdapter.getCurrentElem(); - SclService.addHistoryItem(scd,"who","what","why"); + SclService.addHistoryItem(scd, "who", "what", "why"); assertNotNull(scd.getHeader()); THeader.History history = scd.getHeader().getHistory(); assertNotNull(history); - assertEquals(1,history.getHitem().size()); + assertEquals(1, history.getHitem().size()); THitem tHitem = history.getHitem().get(0); - assertEquals("who",tHitem.getWho()); - assertEquals("what",tHitem.getWhat()); - assertEquals("why",tHitem.getWhy()); - assertEquals(SclRootAdapter.REVISION,tHitem.getRevision()); - assertEquals(SclRootAdapter.VERSION,tHitem.getVersion()); + assertEquals("who", tHitem.getWho()); + assertEquals("what", tHitem.getWhat()); + assertEquals("why", tHitem.getWhy()); + assertEquals(SclRootAdapter.REVISION, tHitem.getRevision()); + assertEquals(SclRootAdapter.VERSION, tHitem.getVersion()); } @Test void testAddIED() throws Exception { - SclRootAdapter sclRootAdapter= new SclRootAdapter("hId",SclRootAdapter.VERSION,SclRootAdapter.REVISION); + SclRootAdapter sclRootAdapter = new SclRootAdapter("hId", SclRootAdapter.VERSION, SclRootAdapter.REVISION); SCL scd = sclRootAdapter.getCurrentElem(); assertNull(sclRootAdapter.getCurrentElem().getDataTypeTemplates()); SCL icd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); - IEDAdapter iedAdapter = assertDoesNotThrow(() -> SclService.addIED(scd,"IED_NAME1",icd)); + IEDAdapter iedAdapter = assertDoesNotThrow(() -> SclService.addIED(scd, "IED_NAME1", icd)); assertEquals("IED_NAME1", iedAdapter.getName()); assertNotNull(sclRootAdapter.getCurrentElem().getDataTypeTemplates()); @@ -77,11 +80,60 @@ void testAddSubnetworks() throws Exception { connectedApDTO.setIedName("IED_NAME1"); subNetworkDTO.addConnectedAP(connectedApDTO); - assertDoesNotThrow(() -> SclService.addSubnetworks(scd, Set.of(subNetworkDTO)).get()); + assertDoesNotThrow(() -> SclService.addSubnetworks(scd, Set.of(subNetworkDTO), Optional.of(icd)).get()); MarshallerWrapper marshallerWrapper = SclTestMarshaller.createWrapper(); System.out.println(marshallerWrapper.marshall(scd)); } + @Test + void testAddSubnetworksWithoutCommunicationTagInIcd() throws Exception { + SclRootAdapter sclRootAdapter = new SclRootAdapter("hId", SclRootAdapter.VERSION, SclRootAdapter.REVISION); + SCL scd = sclRootAdapter.getCurrentElem(); + assertNull(sclRootAdapter.getCurrentElem().getDataTypeTemplates()); + SCL icd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); + + assertDoesNotThrow(() -> SclService.addIED(scd, "IED_NAME1", icd)); + + assertDoesNotThrow(() -> SclService.addSubnetworks(scd, new HashSet<>(), Optional.of(icd))); + MarshallerWrapper marshallerWrapper = SclTestMarshaller.createWrapper(); + String marshalledScd = marshallerWrapper.marshall(scd); + assertThat(marshalledScd).doesNotContain(" SclService.addIED(scd, "IED_NAME1", icd)); + + Set subNetworkDTOSet = new HashSet<>(SclService.getSubnetwork(icd)); + assertDoesNotThrow(() -> SclService.addSubnetworks(scd, subNetworkDTOSet, Optional.of(icd)).get()); + + MarshallerWrapper marshallerWrapper = SclTestMarshaller.createWrapper(); + String marshalledScd = marshallerWrapper.marshall(scd); + assertThat(marshalledScd).contains("
", "PhysConn"); + } + + @Test + void testAddSubnetworksWithoutImportingIcdAddressAndPhysConn() throws Exception { + SclRootAdapter sclRootAdapter = new SclRootAdapter("hId", SclRootAdapter.VERSION, SclRootAdapter.REVISION); + SCL scd = sclRootAdapter.getCurrentElem(); + assertNull(sclRootAdapter.getCurrentElem().getDataTypeTemplates()); + SCL icd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_with_filled_communication.xml"); + + assertDoesNotThrow(() -> SclService.addIED(scd, "IED_NAME1", icd)); + + Set subNetworkDTOSet = new HashSet<>(SclService.getSubnetwork(icd)); + assertDoesNotThrow(() -> SclService.addSubnetworks(scd, subNetworkDTOSet, Optional.empty()).get()); + + MarshallerWrapper marshallerWrapper = SclTestMarshaller.createWrapper(); + String marshalledScd = marshallerWrapper.marshall(scd); + assertThat(marshalledScd).doesNotContain("
", "PhysConn"); + } + @Test void testGetSubnetwork() throws Exception { @@ -100,26 +152,26 @@ void testGetSubnetwork() throws Exception { connectedApDTO.setIedName("IED_NAME1"); subNetworkDTO.addConnectedAP(connectedApDTO); - assertDoesNotThrow(() -> SclService.addSubnetworks(scd, Set.of(subNetworkDTO)).get()); + assertDoesNotThrow(() -> SclService.addSubnetworks(scd, Set.of(subNetworkDTO), Optional.of(icd)).get()); - List subNetworkDTOS = assertDoesNotThrow(()-> SclService.getSubnetwork(scd)); - assertEquals(1,subNetworkDTOS.size()); + List subNetworkDTOS = assertDoesNotThrow(() -> SclService.getSubnetwork(scd)); + assertEquals(1, subNetworkDTOS.size()); } @Test void testGetExtRefInfo() throws Exception { - SclRootAdapter sclRootAdapter= new SclRootAdapter("hId",SclRootAdapter.VERSION,SclRootAdapter.REVISION); + SclRootAdapter sclRootAdapter = new SclRootAdapter("hId", SclRootAdapter.VERSION, SclRootAdapter.REVISION); SCL scd = sclRootAdapter.getCurrentElem(); assertNull(sclRootAdapter.getCurrentElem().getDataTypeTemplates()); SCL icd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); - assertDoesNotThrow(() -> SclService.addIED(scd,"IED_NAME1",icd)); - var extRefInfos = assertDoesNotThrow(() -> SclService.getExtRefInfo(scd,"IED_NAME1","LD_INST11")); - assertEquals(1,extRefInfos.size()); + assertDoesNotThrow(() -> SclService.addIED(scd, "IED_NAME1", icd)); + var extRefInfos = assertDoesNotThrow(() -> SclService.getExtRefInfo(scd, "IED_NAME1", "LD_INST11")); + assertEquals(1, extRefInfos.size()); - assertEquals("IED_NAME1",extRefInfos.get(0).getHolderIEDName()); + assertEquals("IED_NAME1", extRefInfos.get(0).getHolderIEDName()); - assertThrows(ScdException.class, () -> SclService.getExtRefInfo(scd,"IED_NAME1","UNKNOWN_LD")); + assertThrows(ScdException.class, () -> SclService.getExtRefInfo(scd, "IED_NAME1", "UNKNOWN_LD")); } @Test @@ -127,36 +179,36 @@ void testGetExtRefBinders() throws Exception { SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_binders_test.xml"); ExtRefSignalInfo signalInfo = createSignalInfo( - "Do11.sdo11","da11.bda111.bda112.bda113","INT_ADDR11" + "Do11.sdo11", "da11.bda111.bda112.bda113", "INT_ADDR11" ); List potentialBinders = assertDoesNotThrow( () -> SclService.getExtRefBinders( - scd,"IED_NAME1","LD_INST11","LLN0","","",signalInfo + scd, "IED_NAME1", "LD_INST11", "LLN0", "", "", signalInfo ) ); assertThrows( ScdException.class, () -> SclService.getExtRefBinders( - scd,"IED_NAME1","UNKNOWN_LD","LLN0","","",signalInfo + scd, "IED_NAME1", "UNKNOWN_LD", "LLN0", "", "", signalInfo ) ); } @Test void testUpdateExtRefBinders() throws Exception { - SclRootAdapter sclRootAdapter= new SclRootAdapter("hId",SclRootAdapter.VERSION,SclRootAdapter.REVISION); + SclRootAdapter sclRootAdapter = new SclRootAdapter("hId", SclRootAdapter.VERSION, SclRootAdapter.REVISION); SCL scd = sclRootAdapter.getCurrentElem(); assertNull(sclRootAdapter.getCurrentElem().getDataTypeTemplates()); SCL icd1 = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); SCL icd2 = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_2_test.xml"); - assertDoesNotThrow(() -> SclService.addIED(scd,"IED_NAME1",icd1)); - assertDoesNotThrow(() -> SclService.addIED(scd,"IED_NAME2",icd2)); + assertDoesNotThrow(() -> SclService.addIED(scd, "IED_NAME1", icd1)); + assertDoesNotThrow(() -> SclService.addIED(scd, "IED_NAME2", icd2)); ExtRefSignalInfo signalInfo = createSignalInfo( - "Do11.sdo11","da11.bda111.bda112.bda113","INT_ADDR11" + "Do11.sdo11", "da11.bda111.bda112.bda113", "INT_ADDR11" ); signalInfo.setPServT(null); signalInfo.setPLN(null); @@ -182,13 +234,13 @@ void testUpdateExtRefBinders() throws Exception { lNodeDTO.getExtRefs().add(extRefInfo); assertDoesNotThrow( - () -> SclService.updateExtRefBinders(scd,extRefInfo) + () -> SclService.updateExtRefBinders(scd, extRefInfo) ); extRefInfo.setHolderLDInst("UNKNOWN_LD"); assertThrows( ScdException.class, - () -> SclService.updateExtRefBinders( scd,extRefInfo) + () -> SclService.updateExtRefBinders(scd, extRefInfo) ); } @@ -211,10 +263,10 @@ void testGetExtRefSourceInfo() throws Exception { extRefInfo.setHolderLDInst(ldInst); extRefInfo.setHolderLnClass(lnClass); - var controlBlocks = SclService.getExtRefSourceInfo(scd,extRefInfo); - assertEquals(2,controlBlocks.size()); + var controlBlocks = SclService.getExtRefSourceInfo(scd, extRefInfo); + assertEquals(2, controlBlocks.size()); controlBlocks.forEach(controlBlock -> assertTrue( - controlBlock.getName().equals("goose1") || controlBlock.getName().equals("smv1") + controlBlock.getName().equals("goose1") || controlBlock.getName().equals("smv1") ) ); } @@ -227,21 +279,21 @@ void testUpdateExtRefSource() throws Exception { extRefInfo.setHolderLDInst("LD_INST21"); extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value()); - assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd,extRefInfo)); // signal = null + assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd, extRefInfo)); // signal = null extRefInfo.setSignalInfo(new ExtRefSignalInfo()); - assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd,extRefInfo)); // signal invalid + assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd, extRefInfo)); // signal invalid extRefInfo.getSignalInfo().setIntAddr("INT_ADDR21"); extRefInfo.getSignalInfo().setPDA("da21.bda211.bda212.bda213"); extRefInfo.getSignalInfo().setPDO("Do21.sdo21"); - assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd,extRefInfo)); // binding = null + assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd, extRefInfo)); // binding = null extRefInfo.setBindingInfo(new ExtRefBindingInfo()); - assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd,extRefInfo)); // binding invalid + assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd, extRefInfo)); // binding invalid extRefInfo.getBindingInfo().setIedName("IED_NAME2"); // internal binding extRefInfo.getBindingInfo().setLdInst("LD_INST12"); extRefInfo.getBindingInfo().setLnClass(TLLN0Enum.LLN_0.value()); - assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd,extRefInfo)); // CB not allowed + assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd, extRefInfo)); // CB not allowed extRefInfo.getBindingInfo().setIedName("IED_NAME1"); @@ -249,12 +301,12 @@ void testUpdateExtRefSource() throws Exception { extRefInfo.getSourceInfo().setSrcLDInst(extRefInfo.getBindingInfo().getLdInst()); extRefInfo.getSourceInfo().setSrcLNClass(extRefInfo.getBindingInfo().getLnClass()); extRefInfo.getSourceInfo().setSrcCBName("goose1"); - TExtRef extRef = assertDoesNotThrow( () -> SclService.updateExtRefSource(scd,extRefInfo)); - assertEquals(extRefInfo.getSourceInfo().getSrcCBName(),extRef.getSrcCBName()); + TExtRef extRef = assertDoesNotThrow(() -> SclService.updateExtRefSource(scd, extRefInfo)); + assertEquals(extRefInfo.getSourceInfo().getSrcCBName(), extRef.getSrcCBName()); } - private ExtRefSignalInfo createSignalInfo(String pDO, String pDA, String intAddr){ + private ExtRefSignalInfo createSignalInfo(String pDO, String pDA, String intAddr) { final String DESC = "DESC"; final String P_LN = TLLN0Enum.LLN_0.value(); @@ -272,50 +324,226 @@ private ExtRefSignalInfo createSignalInfo(String pDO, String pDA, String intAddr } @Test - void testGetDAI() throws Exception { + void getDAI_should_return_all_dai() throws Exception { + // given SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); + // when + Set allResults = SclService.getDAI(scd, "IED_NAME1", "LD_INST12", new ResumedDataTemplate(), true); - Set resumedDataTemplates = assertDoesNotThrow( - ()-> SclService.getDAI( - scd,"IED_NAME1","LD_INST12",new ResumedDataTemplate(),true - ) + // then + assertThat(allResults).hasSize(733); + + List resultsWithDa = allResults.stream().filter(rdt -> StringUtils.isNotBlank(rdt.getDaRef())).collect(Collectors.toList()); + assertThat(resultsWithDa).hasSize(733); + + List resultsWithNoBda = allResults.stream().filter(rdt -> rdt.getBdaNames().isEmpty()).collect(Collectors.toList()); + assertThat(resultsWithNoBda).hasSize(3); + List resultsWithBdaDepth1 = allResults.stream().filter(rdt -> rdt.getBdaNames().size() == 1).collect(Collectors.toList()); + assertThat(resultsWithBdaDepth1).isEmpty(); + List resultsWithBdaDepth2 = allResults.stream().filter(rdt -> rdt.getBdaNames().size() == 2).collect(Collectors.toList()); + assertThat(resultsWithBdaDepth2).hasSize(1); + List resultsWithBdaDepth3 = allResults.stream().filter(rdt -> rdt.getBdaNames().size() == 3).collect(Collectors.toList()); + assertThat(resultsWithBdaDepth3).hasSize(729); + + + List resultsWithDo = allResults.stream().filter(rdt -> StringUtils.isNotBlank(rdt.getDoRef())).collect(Collectors.toList()); + assertThat(resultsWithDo).hasSize(733); + + List resultsWithNoSdo = allResults.stream().filter(rdt -> rdt.getSdoNames().isEmpty()).collect(Collectors.toList()); + assertThat(resultsWithNoSdo).hasSize(3); + List resultsWithSdoDepth1 = allResults.stream().filter(rdt -> rdt.getSdoNames().size() == 1).collect(Collectors.toList()); + assertThat(resultsWithSdoDepth1).isEmpty(); + List resultsWithSdoDepth2 = allResults.stream().filter(rdt -> rdt.getSdoNames().size() == 2).collect(Collectors.toList()); + assertThat(resultsWithSdoDepth2).hasSize(730); + List resultsWithSdoDepth3 = allResults.stream().filter(rdt -> rdt.getSdoNames().size() == 3).collect(Collectors.toList()); + assertThat(resultsWithSdoDepth3).isEmpty(); + } + + @Test + void getDAI_should_aggregate_attribute_from_DAI() throws Exception { + // given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_aggregate_DAI.xml"); + + // when + Set dais = SclService.getDAI(scd, "VirtualBCU", "LDMODEXPF", new ResumedDataTemplate(), false); + + // then + ResumedDataTemplate lln0 = ResumedDataTemplate.builder().prefix("").lnType("lntype1").lnClass("LLN0").lnInst("").build(); + ResumedDataTemplate lln0DoA = lln0.toBuilder().doName(createDo("DoA", TPredefinedCDCEnum.DPL)).build(); + ResumedDataTemplate lln0DoB = lln0.toBuilder().doName(createDo("DoB", TPredefinedCDCEnum.ACD)).build(); + + assertThat(dais).containsExactlyInAnyOrder( + lln0DoA.toBuilder().daName(createDa("daNotInDai", TFCEnum.CF, false, Map.of(0L, "0"))).build(), + lln0DoA.toBuilder().daName(createDa("daNotInDai2", TFCEnum.CF, true, Map.of())).build(), + lln0DoA.toBuilder().daName(createDa("daiOverrideVal", TFCEnum.CF, false, Map.of(0L, "1"))).build(), + lln0DoA.toBuilder().daName(createDa("daiOverrideValImport", TFCEnum.CF, true, Map.of())).build(), + lln0DoA.toBuilder().daName(createDa("daiOverrideValImport2", TFCEnum.CF, false, Map.of())).build(), + + lln0DoB.toBuilder().daName(createDa("structDa.daNotInDai", TFCEnum.ST, false, Map.of(0L, "0"))).build(), + lln0DoB.toBuilder().daName(createDa("structDa.daNotInDai2", TFCEnum.ST, true, Map.of())).build(), + lln0DoB.toBuilder().daName(createDa("structDa.daiOverrideVal", TFCEnum.ST, false, Map.of(0L, "1"))).build(), + lln0DoB.toBuilder().daName(createDa("structDa.daiOverrideValImport", TFCEnum.ST, true, Map.of())).build(), + lln0DoB.toBuilder().daName(createDa("structDa.daiOverrideValImport2", TFCEnum.ST, false, Map.of())).build(), + + ResumedDataTemplate.builder().prefix("").lnType("lntype2").lnClass("LPHD").lnInst("0") + .doName(createDo("PhyNam", TPredefinedCDCEnum.DPS)) + .daName(createDa("aDa", TFCEnum.BL, false, Map.of())).build() ); - assertEquals(13,resumedDataTemplates.size()); + } - assertThrows( - ScdException.class, - ()-> SclService.getDAI( - scd,"IED_NAME1","UNKNOWNLD",new ResumedDataTemplate(),true - ) + @Test + void getDAI_when_LDevice_not_found_should_throw_exception() throws Exception { + // given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); + + // when & then + assertThrows(ScdException.class, + () -> SclService.getDAI(scd, "IED_NAME1", "UNKNOWNLD", new ResumedDataTemplate(), true)); + } + + @Test + void getDAI_should_filter_updatable_DA() throws Exception { + // given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_updatable_DAI.xml"); + + // when + Set dais = SclService.getDAI(scd, "VirtualBCU", "LDMODEXPF", new ResumedDataTemplate(), true); + + // then + assertThat(dais).isNotNull(); + List resultSimpleDa = dais.stream() + .filter(rdtt -> rdtt.getBdaNames().isEmpty()) // test only simple DA + .map(ResumedDataTemplate::getLNRef).collect(Collectors.toList()); + assertThat(resultSimpleDa).containsExactlyInAnyOrder( + // ...AndTrueInDai : If ValImport is True in DAI, DA is updatable + "LLN0.DoA.valImportNotSetAndTrueInDai", + "LLN0.DoA.valImportTrueAndTrueInDai", + "LLN0.DoA.valImportFalseAndTrueInDai", + // valImportTrue : If ValImport is True in DA and DAI does not exist, DA is updatable + "LLN0.DoA.valImportTrue", + // valImportTrueAndNotSetInDai : If ValImport is True in DA and DAI exists but DAI ValImport is not set, DA is updatable + "LLN0.DoA.valImportTrueAndNotSetInDai", + // Only these FC are updatable + "LLN0.DoA.fcCF", + "LLN0.DoA.fcDC", + "LLN0.DoA.fcSG", + "LLN0.DoA.fcSP", + "LLN0.DoA.fcST", + "LLN0.DoA.fcSE" ); } @Test - void testInitScl(){ + void getDAI_should_filter_updatable_BDA() throws Exception { + // given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_updatable_DAI.xml"); + + // when + Set dais = SclService.getDAI(scd, "VirtualBCU", "LDMODEXPF", new ResumedDataTemplate(), true); + + // then + assertThat(dais).isNotNull(); + List resultStructDa = dais.stream() + .filter(rdtt -> !rdtt.getBdaNames().isEmpty()) // test only struct DA + .map(ResumedDataTemplate::getLNRef).collect(Collectors.toList()); + assertThat(resultStructDa).containsExactlyInAnyOrder( + // ...AndTrueInDai : If ValImport is True in DAI, BDA is updatable + "LLN0.DoB.structValImportNotSet.bValImportFalseAndTrueInDai", + "LLN0.DoB.structValImportNotSet.bValImportNotSetAndTrueInDai", + "LLN0.DoB.structValImportNotSet.bValImportTrueAndTrueInDai", + "LLN0.DoB.structValImportTrue.bValImportFalseAndTrueInDai", + "LLN0.DoB.structValImportTrue.bValImportNotSetAndTrueInDai", + "LLN0.DoB.structValImportTrue.bValImportTrueAndTrueInDai", + "LLN0.DoB.structValImportFalse.bValImportFalseAndTrueInDai", + "LLN0.DoB.structValImportFalse.bValImportNotSetAndTrueInDai", + "LLN0.DoB.structValImportFalse.bValImportTrueAndTrueInDai", + // bValImportTrue : If ValImport is True in BDA and DAI does not exist, BDA is updatable + "LLN0.DoB.structValImportFalse.bValImportTrue", + "LLN0.DoB.structValImportTrue.bValImportTrue", + "LLN0.DoB.structValImportNotSet.bValImportTrue", + // bValImportTrueAndNotSetInDai : If ValImport is True in BDA and DAI exists but DAI ValImport is not set, BDA is updatable + "LLN0.DoB.structValImportTrue.bValImportTrueAndNotSetInDai", + "LLN0.DoB.structValImportNotSet.bValImportTrueAndNotSetInDai", + "LLN0.DoB.structValImportFalse.bValImportTrueAndNotSetInDai", + // Only these FC are updatable + "LLN0.DoB.structWithFcCF.bda1", + "LLN0.DoB.structWithFcDC.bda1", + "LLN0.DoB.structWithFcSG.bda1", + "LLN0.DoB.structWithFcSP.bda1", + "LLN0.DoB.structWithFcST.bda1", + "LLN0.DoB.structWithFcSE.bda1" + ); + } + + @Test + void getDAI_should_filter_updatable_DA_with_sGroup_Val() throws Exception { + // given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_updatable_DAI.xml"); + + // when + Set dais = SclService.getDAI(scd, "VirtualBCU", "LDCAP", new ResumedDataTemplate(), true); + + // then + assertThat(dais).isNotNull(); + List resultSimpleDa = dais.stream() + .filter(rdtt -> rdtt.getBdaNames().isEmpty()) // test only simple DA + .map(ResumedDataTemplate::getLNRef).collect(Collectors.toList()); + assertThat(resultSimpleDa).containsExactlyInAnyOrder( + "LLN0.DoD.sGroupValImportNotSet", + "LLN0.DoD.sGroupValImportTrue" + ); + } + + @Test + void getDAI_should_filter_updatable_DA_with_sGroup_Val_without_ConfSg() throws Exception { + // given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_updatable_DAI.xml"); + + // when + Set dais = SclService.getDAI(scd, "VirtualBCU", "LDMOD", new ResumedDataTemplate(), true); + + // then + assertThat(dais) + .isNotNull() + .isEmpty(); + } + + @Test + void testInitScl() { assertDoesNotThrow( - () -> SclService.initScl(Optional.empty(), "hVersion","hRevision") + () -> SclService.initScl(Optional.empty(), "hVersion", "hRevision") ); } @Test - void testInitScl_With_hId_shouldNotThrowError(){ + void testInitScl_With_hId_shouldNotThrowError() { UUID hid = UUID.randomUUID(); assertDoesNotThrow( - () -> SclService.initScl(Optional.of(hid),"hVersion","hRevision") + () -> SclService.initScl(Optional.of(hid), "hVersion", "hRevision") ); } + @Test + void testInitScl_Create_Private_SCL_FILETYPE() { + UUID hid = UUID.randomUUID(); + SclRootAdapter rootAdapter = assertDoesNotThrow( + () -> SclService.initScl(Optional.of(hid), "hVersion", "hRevision") + ); + assertThat(rootAdapter.getCurrentElem().getPrivate()).isNotEmpty(); + assertThat(rootAdapter.getCurrentElem().getPrivate().get(0).getType()).isEqualTo(CommonConstants.COMPAS_SCL_FILE_TYPE); + } + @Test void testUpdateHeader() { SclRootAdapter sclRootAdapter = assertDoesNotThrow( - () -> SclService.initScl(Optional.empty(),"hVersion","hRevision") + () -> SclService.initScl(Optional.empty(), "hVersion", "hRevision") ); UUID hId = UUID.fromString(sclRootAdapter.getHeaderAdapter().getHeaderId()); HeaderDTO headerDTO = DTO.createHeaderDTO(hId); - SclService.updateHeader(sclRootAdapter.getCurrentElem(),headerDTO); - SclService.updateHeader(sclRootAdapter.getCurrentElem(),headerDTO); + SclService.updateHeader(sclRootAdapter.getCurrentElem(), headerDTO); + SclService.updateHeader(sclRootAdapter.getCurrentElem(), headerDTO); } @@ -326,8 +554,8 @@ void testUpdateDAI() throws Exception { SCL scd = SclTestMarshaller.getSCLFromFile("/ied-test-schema-conf/ied_unit_test.xml"); SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - assertThrows(ScdException.class, ()-> SclService.updateDAI( - scd,"IED","LD",rDtt + assertThrows(ScdException.class, () -> SclService.updateDAI( + scd, "IED", "LD", rDtt )); rDtt.setLnType("LNO1"); rDtt.setLnClass(TLLN0Enum.LLN_0.value()); @@ -337,17 +565,17 @@ void testUpdateDAI() throws Exception { TVal tVal = new TVal(); tVal.setValue("newValue"); rDtt.setDaiValues(List.of(tVal)); - assertDoesNotThrow(() -> SclService.updateDAI(scd,"IED_NAME","LD_INS1",rDtt)); + assertDoesNotThrow(() -> SclService.updateDAI(scd, "IED_NAME", "LD_INS1", rDtt)); } @Test void testGetEnumTypeElements() throws Exception { SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); - assertThrows(ScdException.class, ()-> SclService.getEnumTypeElements(scd,"unknwnID")); + assertThrows(ScdException.class, () -> SclService.getEnumTypeElements(scd, "unknwnID")); var enumList = assertDoesNotThrow( - ()-> SclService.getEnumTypeElements(scd,"RecCycModKind") + () -> SclService.getEnumTypeElements(scd, "RecCycModKind") ); assertFalse(enumList.isEmpty()); } @@ -359,7 +587,7 @@ void testAddSubstation_Check_SSD_Validity(String ssdFileName) throws Exception { SCL ssd = SclTestMarshaller.getSCLFromFile(ssdFileName); assertThrows(ScdException.class, - () ->SclService.addSubstation(scd, ssd)); + () -> SclService.addSubstation(scd, ssd)); } @Test @@ -380,7 +608,7 @@ void testAddSubstation_SCD_With_Different_Substation_Name() throws Exception { SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml"); assertThrows(ScdException.class, - () ->SclService.addSubstation(scd, ssd)); + () -> SclService.addSubstation(scd, ssd)); } @Test @@ -397,4 +625,64 @@ void testAddSubstation_SCD_With_Substation() throws Exception { assertEquals(expectedTSubstation.getName(), tSubstation.getName()); assertEquals(expectedTSubstation.getVoltageLevel().size(), tSubstation.getVoltageLevel().size()); } -} \ No newline at end of file + + @Test + void testImportSTDElementsInSCD() throws Exception { + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd.xml"); + SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); + SclRootAdapter scdRootAdapter = new SclRootAdapter(scd); + + SclRootAdapter expectedScdAdapter = assertDoesNotThrow( () -> SclService.importSTDElementsInSCD( + scdRootAdapter, Set.of(std), DTO.comMap)); + assertThat(expectedScdAdapter.getCurrentElem().getIED()).hasSize(1); + assertThat(expectedScdAdapter.getCurrentElem().getDataTypeTemplates()).hasNoNullFieldsOrProperties(); + assertThat(expectedScdAdapter.getCurrentElem().getCommunication().getSubNetwork()).hasSize(2); + } + + @Test + void testImportSTDElementsInSCD_with_Multiple_STD() throws Exception { + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd_lnode_with_many_compas_icdheader.xml"); + SCL std0 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); + SCL std1 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std_SITESITE1GTW1.xml"); + SCL std2 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std_SITESITE1GTW2.xml"); + SclRootAdapter scdRootAdapter = new SclRootAdapter(scd); + + SclRootAdapter expectedScdAdapter = assertDoesNotThrow( () -> SclService.importSTDElementsInSCD( + scdRootAdapter, Set.of(std0, std1, std2), DTO.comMap)); + assertThat(expectedScdAdapter.getCurrentElem().getIED()).hasSize(3); + assertThat(expectedScdAdapter.getCurrentElem().getDataTypeTemplates()).hasNoNullFieldsOrProperties(); + assertThat(expectedScdAdapter.getCurrentElem().getCommunication().getSubNetwork()).hasSize(2); + assertThat(expectedScdAdapter.getCurrentElem().getCommunication().getSubNetwork().get(0).getConnectedAP()).hasSizeBetween(1,3); + assertThat(expectedScdAdapter.getCurrentElem().getCommunication().getSubNetwork().get(1).getConnectedAP()).hasSizeBetween(1,3); + } + + @Test + void testImportSTDElementsInSCD_Several_STD_Match_Compas_ICDHeader() throws Exception { + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd.xml"); + SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); + SCL std1 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); + SclRootAdapter scdRootAdapter = new SclRootAdapter(scd); + + assertThrows(ScdException.class, () -> SclService.importSTDElementsInSCD(scdRootAdapter, Set.of(std, std1), DTO.comMap)); + + } + + @Test + void testImportSTDElementsInSCD_Compas_ICDHeader_Not_Match() throws Exception { + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd.xml"); + SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std_with_same_ICDSystemVersionUUID.xml"); + SclRootAdapter scdRootAdapter = new SclRootAdapter(scd); + + assertThrows(ScdException.class, ()-> SclService.importSTDElementsInSCD(scdRootAdapter, Set.of(std), DTO.comMap)); + + } + + @Test + void testImportSTDElementsInSCD_No_STD_Match() throws Exception { + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/ssd.xml"); + SclRootAdapter scdRootAdapter = new SclRootAdapter(scd); + + assertThrows(ScdException.class, ()-> SclService.importSTDElementsInSCD(scdRootAdapter, new HashSet<>(), DTO.comMap)); + + } +} diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapterTest.java index 1bdc8db25..b71d8790d 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapterTest.java @@ -4,40 +4,48 @@ package org.lfenergy.compas.sct.commons.scl.com; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.scl2007b4.model.TConnectedAP; import org.lfenergy.compas.scl2007b4.model.TPrivate; import org.lfenergy.compas.scl2007b4.model.TSubNetwork; import org.lfenergy.compas.sct.commons.dto.DTO; +import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; +import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; + +import java.util.Optional; import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.Assertions.*; class ConnectedAPAdapterTest { - @Test - void testAmChildElementRef() { - SubNetworkAdapter subNetworkAdapter = new SubNetworkAdapter(null, new TSubNetwork()); + private SubNetworkAdapter subNetworkAdapter; + + @BeforeEach + void setUp() { + subNetworkAdapter = new SubNetworkAdapter(null, new TSubNetwork()); TConnectedAP tConnectedAP = new TConnectedAP(); tConnectedAP.setIedName(DTO.HOLDER_IED_NAME); tConnectedAP.setApName(DTO.AP_NAME); subNetworkAdapter.getCurrentElem().getConnectedAP().add(tConnectedAP); + } + @Test + void testAmChildElementRef() { ConnectedAPAdapter connectedAPAdapter = assertDoesNotThrow( - () ->subNetworkAdapter.getConnectedAPAdapter(DTO.HOLDER_IED_NAME,DTO.AP_NAME) + () -> subNetworkAdapter.getConnectedAPAdapter(DTO.HOLDER_IED_NAME, DTO.AP_NAME) ); - assertEquals(DTO.HOLDER_IED_NAME,connectedAPAdapter.getIedName()); - assertEquals(DTO.AP_NAME,connectedAPAdapter.getApName()); + assertEquals(DTO.HOLDER_IED_NAME, connectedAPAdapter.getIedName()); + assertEquals(DTO.AP_NAME, connectedAPAdapter.getApName()); } @Test void addPrivate() throws Exception { - SubNetworkAdapter subNetworkAdapter = new SubNetworkAdapter(null, new TSubNetwork()); - TConnectedAP tConnectedAP = new TConnectedAP(); - tConnectedAP.setIedName(DTO.HOLDER_IED_NAME); - tConnectedAP.setApName(DTO.AP_NAME); - subNetworkAdapter.getCurrentElem().getConnectedAP().add(tConnectedAP); - ConnectedAPAdapter connectedAPAdapter = subNetworkAdapter.getConnectedAPAdapter(DTO.HOLDER_IED_NAME,DTO.AP_NAME); + ConnectedAPAdapter connectedAPAdapter = subNetworkAdapter.getConnectedAPAdapter(DTO.HOLDER_IED_NAME, DTO.AP_NAME); TPrivate tPrivate = new TPrivate(); tPrivate.setType("Private Type"); tPrivate.setSource("Private Source"); @@ -45,4 +53,41 @@ void addPrivate() throws Exception { connectedAPAdapter.addPrivate(tPrivate); assertEquals(1, connectedAPAdapter.getCurrentElem().getPrivate().size()); } + + @Test + void testCopyAddressAndPhysConnFromIcd_withFilledCommunication() throws Exception { + // GIVEN + ConnectedAPAdapter connectedAPAdapter = assertDoesNotThrow( + () -> subNetworkAdapter.getConnectedAPAdapter(DTO.HOLDER_IED_NAME, DTO.AP_NAME) + ); + + SCL icd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_with_filled_communication.xml"); + SclRootAdapter icdRootAdapter = new SclRootAdapter(icd); + Optional opIcd = Optional.of(icdRootAdapter.getCurrentElem()); + + // WHEN + connectedAPAdapter.copyAddressAndPhysConnFromIcd(opIcd); + + // THEN + assertThat(connectedAPAdapter.getCurrentElem().getAddress()).isNotNull(); + assertThat(connectedAPAdapter.getCurrentElem().getPhysConn()).isNotNull(); + assertThat(connectedAPAdapter.getCurrentElem().getGSE()).isEmpty(); + } + + @Test + void testCopyAddressAndPhysConnFromIcd_withEmptyIcd() { + // GIVEN + ConnectedAPAdapter connectedAPAdapter = assertDoesNotThrow( + () -> subNetworkAdapter.getConnectedAPAdapter(DTO.HOLDER_IED_NAME, DTO.AP_NAME) + ); + Optional opIcd = Optional.empty(); + + // WHEN + connectedAPAdapter.copyAddressAndPhysConnFromIcd(opIcd); + + // THEN + assertThat(connectedAPAdapter.getCurrentElem().getAddress()).isNull(); + assertThat(connectedAPAdapter.getCurrentElem().getPhysConn()).isEmpty(); + assertThat(connectedAPAdapter.getCurrentElem().getGSE()).isEmpty(); + } } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapterTest.java index b99bf63d2..5f40825a7 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapterTest.java @@ -16,7 +16,6 @@ import org.mockito.Mockito; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -122,9 +121,7 @@ void testGetResumedRTTs() throws Exception { ResumedDataTemplate rootRDtt = new ResumedDataTemplate(); rootRDtt.getDaName().setName("origin"); rootRDtt.getDoName().setName("StrVal"); - var rDtts = daTypeAdapter.getResumedDTTs( - rootRDtt, new HashSet<>(), new ResumedDataTemplate() - ); + List rDtts = daTypeAdapter.getResumedDTTs(rootRDtt, new ResumedDataTemplate()); assertEquals(2,rDtts.size()); } @@ -156,4 +153,4 @@ void addPrivate() throws Exception { daTypeAdapter.addPrivate(tPrivate); assertEquals(2, daTypeAdapter.getCurrentElem().getPrivate().size()); } -} \ No newline at end of file +} diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapterTest.java index 4c4ff8795..843bd9684 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapterTest.java @@ -12,7 +12,6 @@ import org.lfenergy.compas.sct.commons.exception.ScdException; import org.mockito.Mockito; -import java.util.HashSet; import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -95,23 +94,36 @@ void testCheckAndCompleteStructData() throws Exception { } @Test - void testGetResumedDTTs() throws Exception { + void testGetResumedDTTs_filter_on_DO() throws Exception { + // given DataTypeTemplateAdapter dttAdapter = AbstractDTTLevel.initDttAdapterFromFile(AbstractDTTLevel.SCD_DTT); DOTypeAdapter doTypeAdapter = assertDoesNotThrow(() ->dttAdapter.getDOTypeAdapterById("DO2").get()); ResumedDataTemplate rootRDtt = new ResumedDataTemplate(); rootRDtt.setDoName(new DoTypeName("Op")); ResumedDataTemplate filter = new ResumedDataTemplate(); filter.setDoName(new DoTypeName("Op.res")); - var rDtts = doTypeAdapter.getResumedDTTs( - rootRDtt, new HashSet<>(), filter - ); + + // when + List rDtts = doTypeAdapter.getResumedDTTs(rootRDtt, filter); + + // then assertEquals(2,rDtts.size()); + } + @Test + void testGetResumedDTTs_filter_on_DO_and_DA() throws Exception { + // given + DataTypeTemplateAdapter dttAdapter = AbstractDTTLevel.initDttAdapterFromFile(AbstractDTTLevel.SCD_DTT); + DOTypeAdapter doTypeAdapter = assertDoesNotThrow(() ->dttAdapter.getDOTypeAdapterById("DO2").get()); + ResumedDataTemplate rootRDtt = new ResumedDataTemplate(); + rootRDtt.setDoName(new DoTypeName("Op")); + ResumedDataTemplate filter = new ResumedDataTemplate(); filter.setDoName(new DoTypeName("Op.res")); filter.setDaName(new DaTypeName("d")); - rDtts = doTypeAdapter.getResumedDTTs( - rootRDtt, new HashSet<>(), filter - ); + // when + List rDtts = doTypeAdapter.getResumedDTTs(rootRDtt, filter); + + // then assertEquals(1,rDtts.size()); } @@ -159,4 +171,4 @@ void addPrivate() throws Exception { doTypeAdapter.addPrivate(tPrivate); assertEquals(1, doTypeAdapter.getCurrentElem().getPrivate().size()); } -} \ No newline at end of file +} diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java index 277d8bcf3..5b05181e3 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java @@ -275,7 +275,7 @@ void testFindMatch() throws Exception { LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter(); DoTypeName doTypeName = new DoTypeName("Do.sdo1.d"); DaTypeName daTypeName = new DaTypeName("antRef.bda1.bda2.bda3"); - AbstractDAIAdapter daiAdapter = assertDoesNotThrow(() -> ln0Adapter.findMatch(doTypeName,daTypeName).get()); + AbstractDAIAdapter daiAdapter = (AbstractDAIAdapter) assertDoesNotThrow(() -> ln0Adapter.findMatch(doTypeName,daTypeName).get()); assertEquals("bda3",daiAdapter.getCurrentElem().getName()); assertEquals("Completed-diff",daiAdapter.getCurrentElem().getVal().get(0).getValue()); @@ -325,4 +325,4 @@ void addPrivate() { lnAdapter.addPrivate(tPrivate); assertEquals(1, lnAdapter.getCurrentElem().getPrivate().size()); } -} \ No newline at end of file +} diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/DataTypeUtils.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/DataTypeUtils.java new file mode 100644 index 000000000..72b5ad47f --- /dev/null +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/DataTypeUtils.java @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: 2021 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons.testhelpers; + +import org.lfenergy.compas.scl2007b4.model.TFCEnum; +import org.lfenergy.compas.scl2007b4.model.TPredefinedBasicTypeEnum; +import org.lfenergy.compas.scl2007b4.model.TPredefinedCDCEnum; +import org.lfenergy.compas.sct.commons.dto.DaTypeName; +import org.lfenergy.compas.sct.commons.dto.DoTypeName; + +import java.util.Map; + +public class DataTypeUtils { + public static DaTypeName createDa(String nameRef, TFCEnum fc, boolean valImport, Map daiValues) { + DaTypeName resultDa = new DaTypeName(nameRef); + resultDa.setFc(fc); + resultDa.setBType(TPredefinedBasicTypeEnum.INT_8); + resultDa.setValImport(valImport); + resultDa.setDaiValues(daiValues); + return resultDa; + } + + public static DoTypeName createDo(String nameRef, TPredefinedCDCEnum cdc) { + DoTypeName resultDo = new DoTypeName(nameRef); + resultDo.setCdc(cdc); + return resultDo; + } + + private DataTypeUtils() { + throw new UnsupportedOperationException("This is a utility class, it should not be instantiated."); + } +} diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/MarshallerWrapper.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/MarshallerWrapper.java index 11c36035e..92fb85aa0 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/MarshallerWrapper.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/MarshallerWrapper.java @@ -14,7 +14,9 @@ import javax.xml.transform.Result; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.StringWriter; @Slf4j public class MarshallerWrapper { @@ -59,7 +61,7 @@ public T unmarshall(final InputStream xml, Class cls) { return cls.cast(result); } catch (JAXBException exp) { String message = String.format("Error unmarshalling to the Class: %s", exp.getLocalizedMessage()); - log.error(message); + log.error(message, exp); throw new CompasException(CompasErrorCode.UNMARSHAL_ERROR_CODE, message); } } diff --git a/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/scd.xml b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/scd.xml new file mode 100644 index 000000000..5080de6e1 --- /dev/null +++ b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/scd.xml @@ -0,0 +1,35 @@ + + + + + SCD + +
+ + + 0 + + + + + + + + + + + + + + + + + + + + + diff --git a/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/scd_lnode_with_many_compas_icdheader.xml b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/scd_lnode_with_many_compas_icdheader.xml new file mode 100644 index 000000000..393510a21 --- /dev/null +++ b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/scd_lnode_with_many_compas_icdheader.xml @@ -0,0 +1,41 @@ + + + + + SCD + +
+ + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/ssd.xml b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/ssd.xml new file mode 100644 index 000000000..4a091c6f5 --- /dev/null +++ b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/ssd.xml @@ -0,0 +1,26 @@ + + + + + SCD + +
+ + + 0 + + + + + + + + + + + + diff --git a/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std.xml b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std.xml new file mode 100644 index 000000000..1e3d4da21 --- /dev/null +++ b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std.xml @@ -0,0 +1,344 @@ + + + + +
+ + + +
+ + + +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + Phase 1_Pilotes + 9d13ab59-1ec8-4c46-91c8-0326e6a5408e + 1 + 1.0 + + + + Ldevice current status + + + + + off + + + 1000 + + + Activation_deactivation command + + + + + + + + m + + + A + + + + + 10 + + + + + 20 + + + + + 20 + + + + + 10 + + + + Rated Input Current High + + + + + + + + + + + + + + + + + + + + 4800 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IEC 61850-8-1:2003 + + + + + + + + + IEC 61850-8-1:2003 + + + on + blocked + test + test/blocked + off + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + + status-only + direct-with-enhanced-security + + + + m + kg + s + A + K + mol + cd + deg + rad + sr + Gy + Bq + °C + Sv + F + C + S + H + V + ohm + J + N + Hz + lx + Lm + Wb + T + W + Pa + + + m/s + m/s² + m³/s + m/m³ + M + kg/m³ + m²/s + W/m K + J/K + ppm + 1/s + rad/s + W/m² + J/m² + S/m + K/s + Pa/s + J/kg K + VA + Watts + VAr + phi + cos(phi) + Vs + + As + + A²t + VAh + Wh + VArh + V/Hz + Hz/s + char + char/s + kgm² + dB + J/Wh + W/s + l/s + dBm + h + min + Ohm/m + percent/s + A/V + A/Vs + + + y + z + a + f + p + n + µ + m + c + d + + da + h + k + M + G + T + P + E + Z + Y + + +
\ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std_SITESITE1GTW1.xml b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std_SITESITE1GTW1.xml new file mode 100644 index 000000000..09d31de67 --- /dev/null +++ b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std_SITESITE1GTW1.xml @@ -0,0 +1,344 @@ + + + + +
+ + + +
+ + + +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + Phase 1_Pilotes + 9d13ab59-1ec8-4c46-91c8-0326e6a5408e + 1 + 1.0 + + + + Ldevice current status + + + + + off + + + 1000 + + + Activation_deactivation command + + + + + + + + m + + + A + + + + + 10 + + + + + 20 + + + + + 20 + + + + + 10 + + + + Rated Input Current High + + + + + + + + + + + + + + + + + + + + 4800 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IEC 61850-8-1:2003 + + + + + + + + + IEC 61850-8-1:2003 + + + on + blocked + test + test/blocked + off + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + + status-only + direct-with-enhanced-security + + + + m + kg + s + A + K + mol + cd + deg + rad + sr + Gy + Bq + °C + Sv + F + C + S + H + V + ohm + J + N + Hz + lx + Lm + Wb + T + W + Pa + + + m/s + m/s² + m³/s + m/m³ + M + kg/m³ + m²/s + W/m K + J/K + ppm + 1/s + rad/s + W/m² + J/m² + S/m + K/s + Pa/s + J/kg K + VA + Watts + VAr + phi + cos(phi) + Vs + + As + + A²t + VAh + Wh + VArh + V/Hz + Hz/s + char + char/s + kgm² + dB + J/Wh + W/s + l/s + dBm + h + min + Ohm/m + percent/s + A/V + A/Vs + + + y + z + a + f + p + n + µ + m + c + d + + da + h + k + M + G + T + P + E + Z + Y + + +
\ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std_SITESITE1GTW2.xml b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std_SITESITE1GTW2.xml new file mode 100644 index 000000000..d9d112f2e --- /dev/null +++ b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std_SITESITE1GTW2.xml @@ -0,0 +1,344 @@ + + + + +
+ + + +
+ + + +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + Phase 1_Pilotes + 9d13ab59-1ec8-4c46-91c8-0326e6a5408e + 1 + 1.0 + + + + Ldevice current status + + + + + off + + + 1000 + + + Activation_deactivation command + + + + + + + + m + + + A + + + + + 10 + + + + + 20 + + + + + 20 + + + + + 10 + + + + Rated Input Current High + + + + + + + + + + + + + + + + + + + + 4800 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IEC 61850-8-1:2003 + + + + + + + + + IEC 61850-8-1:2003 + + + on + blocked + test + test/blocked + off + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + + status-only + direct-with-enhanced-security + + + + m + kg + s + A + K + mol + cd + deg + rad + sr + Gy + Bq + °C + Sv + F + C + S + H + V + ohm + J + N + Hz + lx + Lm + Wb + T + W + Pa + + + m/s + m/s² + m³/s + m/m³ + M + kg/m³ + m²/s + W/m K + J/K + ppm + 1/s + rad/s + W/m² + J/m² + S/m + K/s + Pa/s + J/kg K + VA + Watts + VAr + phi + cos(phi) + Vs + + As + + A²t + VAh + Wh + VArh + V/Hz + Hz/s + char + char/s + kgm² + dB + J/Wh + W/s + l/s + dBm + h + min + Ohm/m + percent/s + A/V + A/Vs + + + y + z + a + f + p + n + µ + m + c + d + + da + h + k + M + G + T + P + E + Z + Y + + +
\ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std_with_same_ICDSystemVersionUUID.xml b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std_with_same_ICDSystemVersionUUID.xml new file mode 100644 index 000000000..48aafb3cb --- /dev/null +++ b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/std_with_same_ICDSystemVersionUUID.xml @@ -0,0 +1,344 @@ + + + + +
+ + + +
+ + + +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + Phase 1_Pilotes + 9d13ab59-1ec8-4c46-91c8-0326e6a5408e + 1 + 1.0 + + + + Ldevice current status + + + + + off + + + 1000 + + + Activation_deactivation command + + + + + + + + m + + + A + + + + + 10 + + + + + 20 + + + + + 20 + + + + + 10 + + + + Rated Input Current High + + + + + + + + + + + + + + + + + + + + 4800 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IEC 61850-8-1:2003 + + + + + + + + + IEC 61850-8-1:2003 + + + on + blocked + test + test/blocked + off + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + + status-only + direct-with-enhanced-security + + + + m + kg + s + A + K + mol + cd + deg + rad + sr + Gy + Bq + °C + Sv + F + C + S + H + V + ohm + J + N + Hz + lx + Lm + Wb + T + W + Pa + + + m/s + m/s² + m³/s + m/m³ + M + kg/m³ + m²/s + W/m K + J/K + ppm + 1/s + rad/s + W/m² + J/m² + S/m + K/s + Pa/s + J/kg K + VA + Watts + VAr + phi + cos(phi) + Vs + + As + + A²t + VAh + Wh + VArh + V/Hz + Hz/s + char + char/s + kgm² + dB + J/Wh + W/s + l/s + dBm + h + min + Ohm/m + percent/s + A/V + A/Vs + + + y + z + a + f + p + n + µ + m + c + d + + da + h + k + M + G + T + P + E + Z + Y + + +
\ No newline at end of file diff --git a/sct-commons/src/test/resources/scl-srv-import-ieds/ied_test_aggregate_DAI.xml b/sct-commons/src/test/resources/scl-srv-import-ieds/ied_test_aggregate_DAI.xml new file mode 100644 index 000000000..895a91c85 --- /dev/null +++ b/sct-commons/src/test/resources/scl-srv-import-ieds/ied_test_aggregate_DAI.xml @@ -0,0 +1,87 @@ + + + + + +
+ + + + + + + + + + 1 + + + + + + + + + + 1 + + + + + + + + + + VDF + + + + + + + + + + + + + + + + + + + + 0 + + + + + 0 + + + + + + + + + + + + + + + 0 + + + + + 0 + + + + + + diff --git a/sct-commons/src/test/resources/scl-srv-import-ieds/ied_test_updatable_DAI.xml b/sct-commons/src/test/resources/scl-srv-import-ieds/ied_test_updatable_DAI.xml new file mode 100644 index 000000000..e44309a2f --- /dev/null +++ b/sct-commons/src/test/resources/scl-srv-import-ieds/ied_test_updatable_DAI.xml @@ -0,0 +1,257 @@ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + + + VDF + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sct-commons/src/test/resources/scl-srv-import-ieds/ied_with_filled_communication.xml b/sct-commons/src/test/resources/scl-srv-import-ieds/ied_with_filled_communication.xml new file mode 100644 index 000000000..6639adcf7 --- /dev/null +++ b/sct-commons/src/test/resources/scl-srv-import-ieds/ied_with_filled_communication.xml @@ -0,0 +1,111 @@ + + + + + +
+ + + +
+

1.2.3.4

+
+ +
+

11

+
+
+ +

PL

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + myVal + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Completed-diff + + + \ No newline at end of file diff --git a/sct-coverage/pom.xml b/sct-coverage/pom.xml index 1a918db14..852a7029d 100644 --- a/sct-coverage/pom.xml +++ b/sct-coverage/pom.xml @@ -20,6 +20,7 @@ true + **/scl2007b4/**/* @@ -43,6 +44,11 @@ org.jacoco jacoco-maven-plugin + + + **/scl2007b4/**/* + + report-aggregate