diff --git a/.github/workflows/automate_javadoc.yml b/.github/workflows/automate_javadoc.yml index 1519c9f7b..1efba5dd7 100644 --- a/.github/workflows/automate_javadoc.yml +++ b/.github/workflows/automate_javadoc.yml @@ -64,7 +64,7 @@ jobs: git merge ${{ env.DEPENDABOT_BRANCH }} - name: Push Git Branch - uses: ad-m/github-push-action@v0.6.0 + uses: ad-m/github-push-action@v0.8.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} branch: ${{ env.DEPLOYMENT_BRANCH }} \ No newline at end of file diff --git a/docs/QUICK_START.md b/docs/QUICK_START.md index 8a441541f..5228af057 100644 --- a/docs/QUICK_START.md +++ b/docs/QUICK_START.md @@ -30,7 +30,6 @@ Actually there are 4 packages available: - compas-sct - sct-commons - sct-app -- sct-data #### 2. Usage diff --git a/docs/compas-sct.md b/docs/compas-sct.md index d6b979443..8b677515d 100644 --- a/docs/compas-sct.md +++ b/docs/compas-sct.md @@ -5,19 +5,18 @@ ## Introduction The CoMPAS SCT (System Configuration Tool) is part of the CoMPAS (Configuration Module for Power System Automation) -ecosystem which is an open source project aimed at providing a tool for configuring control system and -profile management related to the 61850 standard. Its architecture allows an easy integration with the other -components of CoMPAS, in addition to being modular and flexible with a high level of abstraction, it gives +ecosystem which is an open source project aimed at providing a tool for configuring control system and +profile management related to the 61850 standard. Its architecture allows an easy integration with the other +components of CoMPAS, in addition to being modular and flexible with a high level of abstraction, it gives the freedom to implement the tool with the database of its choice. -The below package diagram shows different part of the tool architecture. +The below package diagram shows different part of the tool architecture. ![Package Diagram](images/PackageDiagram-CompasSCT.png) Hence, we can distinguish four major parts: * **[sct-commons](#SCT-COMMONS)** : a library that contents shared functionalities for the bound SCL object. -* **[sct-data](#SCT-DATA)** : It holds data models and database connectivity services. * **[sct-app](#SCT-APPLICATION)** : *TODO*. ## SCT COMMONS @@ -96,43 +95,6 @@ should always return `true`: [...] } -## SCT DATA -Data models and connectivity to database are defined here. Data access layer is an abstract layer that defined connectivity -interfaces. This layer manages a database with single table (SQL-Like database) or single collection (NoSQL-Like database). -The concrete data access layers are implemented in specific packages. A data model can implement the following interface - -``` -public interface IScd { - ID getId(); - byte[] getRawXml(); - ID getHeaderId(); - String getHeaderRevision(); - String getHeaderVersion(); - String filename(); -} -``` - -* ### SQL-Like Database -An implementation of the sct-data connectivity interface with custom data models. This allows the application to work with sql-like database. -The libraries ares use for SQL-Like databases, those that support XML type (PostgreSql, Oracle, etc) - -* ### NoSQL-Like Database -Like SQL-like part, this package contains the sct-data connector interfaces implementation for NoSQL-Like databases (BaseX, existDB, etc ) -that support XML processing. - -This can also be a local repository connector (file system). For example, with meta-data headerID, headerVersion, headerRevision and filename -one can implement the connector to have the below output (with the constraint of having a single file in /pathTo/headerId/headerVersion/headerRevision): - -``` - myRepo - ├─── - │ ├─── - │ │ └─── - │ │ | ├─── - │ │ └─── - │ │ ├─── -``` - ## SCT APPLICATION **TODO** > In progress diff --git a/docs/drawio/compas-sct.drawio b/docs/drawio/compas-sct.drawio index a10c3126b..90a9b4be8 100644 --- a/docs/drawio/compas-sct.drawio +++ b/docs/drawio/compas-sct.drawio @@ -1 +1,49 @@ -7Vtbd9o4EP41nLP7QI4lWzZ+TAhke9JLtrTb5qnH2AJ8aluuLQr011fC8lU2mGAubZeXSCNZSPN9M8yMnJ469NcPkRUu3hAHez2oOOueet+DEIABZH+4ZJNIDFUI5pHriEm5YOL+wEKoCOnSdXBcmkgJ8agbloU2CQJs05LMiiKyKk+bEa/8raE1x5JgYlueLP3kOnSRSAfQyOX/YHe+SL8Z6GYy4lvpZHGSeGE5ZFUQqaOeOowIoUnLXw+xx5WX6iV5btwwmm0swgFt84DvjYzXoy/jV+EXH719/7AiD6/6qtjcd8tbihMP3715up2IPdNNqgi2/ZA3l743jiyfNe9WC5fiSWjZXL5i+DPZgvoe6wHWnLmeNyQeibYLqI5iY8xOfRfTiHzFhRGkI2DwBeOV63tWgMflJ++1ERgjNi4fWWjhO44oXhdEQgUPmPiYRhs2JR3VxIkFH9PuKgdXN4RsUQAWaUiQShBqni2d65w1hNoPgQA0QNCfDD90AEN6MsD4wQbSM6mKDNFsNoO2XQeRo091pDdDNNt+OoLIKENkyhBpsAYiTVdOBRFsgmj47v2oS4zUEkZbxBo0PgL3aGTIGJrmcDged4OEDstIZL6sAAXQa6AAp4NClaCIbdq3ie+TIG6Egvt9HHFtkYBOxDjXfMwwcYP5BxJyAdc3taapp9dEP/PwQEsETyR2qUsCJvLwjO72ewgPHK3OqAZwqup6N1BpOipDZchQmXV+7WRAabVAORa1/lyU4EDZi1Ltr8/JUEKNKPXD+Z8LFDC1cpiALg2U3gzUdH0VQHXhxYB+ZWof1KrdCsMe1D2ugGnEWnPe+staUsLCfq4ftpUw/PsqYLmI/aiVyAGkjqYYOdQFcSdDUpMznY8xlhDCgXPL00bWIyFmGr1jEpGWAp69OFa8wI7QbUHNeO3Sz6yt3CDRey6M3HO9KGlnU+g84chlJ+RsSGQBO+3nYue52NkuBPPupjhYXasRyJgsIxu34D21ojmmLeIx7JTyaJkYdSFjhD1mLt/LqXYd8mK5J+KygzTmclm4mi6RHFM8VUyNKwupyp6FEjVIC22JmJ3xCG7KKeAvy02EStzcuqiLkVP7Hcip6jfl2D4rqp2LnnL6u4ubU4/YX6tsZOM8gc3oUuJtkaoZxW5QkWSgRLKW/o/jnv66koguyJwEljfKpc0kvGpuZdXRaph0LsfHoLY2hWkhnxAfvuGmfUnztd3zVYB2zWeNZMfdmoVcithlFgEJcBsfXfDQStFDw1Yu+givqh9OaLQjguvafxov5XgDl7rmuKbqtd/TuC/jQI6jnfNPxHG5ipMmPjx16fGLlzSB0L8t+V0Go6AKNWhCXBQpcXq1k8pAcTjJoNKlWRYUlOwonci/s78SZLtlUzTuwBLeK9saaz9Oiqx8MCCRb3nZ+PbhZBt8FMBwLW8htj2oKMZUS/fC1JZsp7xFJk4UkIqvINNrtP0DKr7XVqDS5AJVt6Fxi5C2HG2o8OCIdm8woV0wmEB6GXJVUTsKJkA7R9uZr9pRIusZd+v1umfcX4WhXqb2bFZipJra2gCd07SNTuOnc9RN9hvydQVRTXHxwbYNzAvbtlyHtQKuR3sZU+Kzxn3zb3BAKGfOnjtYEaBsDZhblWtb3q3nzrkJU278d5boCYMuOYZ+V4XTStibeeei5wc1jKlmbt2ZqXkaM+0gv2/U995kR2tbQroyg5ayoupF+69i0OhcJc+mdLqUTScx3QsrnsbR8eH+3FxtSddLVqWQYZYopSrGy7hpVAJJTYHn5eZhhR1BzBczEcBDuXiDgNo2XTmiOFqu2R7B3kEtKdvQGf4WzrZK6HMX8JFcxalztixEqSQq5YRE/LQXsxchSiMjm3Fjm0RVAyjfdRyvKQiLyDJwtqazk2cHVDEqJT+gy7fP2jljKCRXMSTt51oA+4NVwmNPunUXNe9xdvrC7KBS1lTlgBQqpqxMUI0outOmnOj/KtrUqsXoGm2CugLbCbVZl4bvL/Eq7DObyQXUyb+v+69fPY5EStauWnodnienAerIEWWOflOBv1hOHZzTEcl59DFgvyX/w120boj2wg1ATY2tC7wfHldfHj865g+0gf992zifHp/HfTnLagN38qm7HElf4K2++zYjvGn5XMvBNA57+U1JPskjdnIdI41EOOT1UsJPfL33Kzlh9JwwEjtqONRIGFTNdGpqsnXv1w9OxZfrvdKWkocWWj5PmoBgw0urh6YJWpUNJ7qplja85+ZZ0+v31Ti/+j9Wx91Us27+X3LJ9Px/DdXRTw== \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/images/PackageDiagram-CompasSCT.png b/docs/images/PackageDiagram-CompasSCT.png index 55b8d5017..d4b483edc 100644 Binary files a/docs/images/PackageDiagram-CompasSCT.png and b/docs/images/PackageDiagram-CompasSCT.png differ diff --git a/pom.xml b/pom.xml index 65e41b5df..b31c36062 100644 --- a/pom.xml +++ b/pom.xml @@ -121,7 +121,6 @@ sct-commons sct-coverage - sct-data sct-app diff --git a/sct-app/pom.xml b/sct-app/pom.xml index 42afea091..23cd3d5a7 100644 --- a/sct-app/pom.xml +++ b/sct-app/pom.xml @@ -27,11 +27,6 @@ sct-commons ${project.version} - - org.lfenergy.compas - sct-data - ${project.version} - org.lfenergy.compas sct-commons 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 9046f6966..76e0795e4 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 @@ -7,6 +7,7 @@ import lombok.NonNull; import lombok.RequiredArgsConstructor; import org.lfenergy.compas.scl2007b4.model.SCL; +import org.lfenergy.compas.sct.commons.api.ControlBlockEditor; import org.lfenergy.compas.sct.commons.api.SclEditor; import org.lfenergy.compas.sct.commons.api.SubstationEditor; import org.lfenergy.compas.sct.commons.dto.HeaderDTO; @@ -30,6 +31,7 @@ public class SclAutomationService { private final SclEditor sclEditor; private final SubstationEditor substationEditor; + private final ControlBlockEditor controlBlockEditor; /** * Possible Subnetwork and ConnectedAP names which should be used in generated SCD in order a have global coherence @@ -56,7 +58,7 @@ public SCL createSCD(@NonNull SCL ssd, @NonNull HeaderDTO headerDTO, List s } substationEditor.addSubstation(scd, ssd); sclEditor.importSTDElementsInSCD(scd, stds, SUB_NETWORK_TYPES); - sclEditor.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scd); + controlBlockEditor.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scd); return scd; } } diff --git a/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceIntegrationTest.java b/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceIntegrationTest.java index 9beb9195a..5ccc21468 100644 --- a/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceIntegrationTest.java +++ b/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceIntegrationTest.java @@ -8,8 +8,10 @@ import org.junit.jupiter.api.Test; import org.lfenergy.compas.scl2007b4.model.LN0; import org.lfenergy.compas.scl2007b4.model.SCL; -import org.lfenergy.compas.sct.commons.SclEditorService; +import org.lfenergy.compas.sct.commons.ControlBlockService; +import org.lfenergy.compas.sct.commons.SclService; import org.lfenergy.compas.sct.commons.SubstationService; +import org.lfenergy.compas.sct.commons.api.ControlBlockEditor; import org.lfenergy.compas.sct.commons.api.SclEditor; import org.lfenergy.compas.sct.commons.api.SubstationEditor; import org.lfenergy.compas.sct.commons.dto.HeaderDTO; @@ -29,8 +31,9 @@ class SclAutomationServiceIntegrationTest { private SclAutomationService sclAutomationService ; - private static final SclEditor sclEditor = new SclEditorService() ; + private static final SclEditor sclEditor = new SclService() ; private static final SubstationEditor substationEditor = new SubstationService() ; + private static final ControlBlockEditor controlBlockEditor = new ControlBlockService() ; private HeaderDTO headerDTO; @@ -40,7 +43,7 @@ void setUp() { headerDTO.setId(UUID.randomUUID()); headerDTO.setRevision("hRevision"); headerDTO.setVersion("hVersion"); - sclAutomationService = new SclAutomationService(sclEditor, substationEditor); + sclAutomationService = new SclAutomationService(sclEditor, substationEditor, controlBlockEditor); } @Test 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 f2b03508c..6c511c927 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 @@ -10,6 +10,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.scl2007b4.model.THeader; +import org.lfenergy.compas.sct.commons.api.ControlBlockEditor; import org.lfenergy.compas.sct.commons.api.SclEditor; import org.lfenergy.compas.sct.commons.api.SubstationEditor; import org.lfenergy.compas.sct.commons.dto.HeaderDTO; @@ -39,6 +40,8 @@ class SclAutomationServiceTest { private SclEditor sclEditor; @Mock private SubstationEditor substationEditor; + @Mock + private ControlBlockEditor controlBlockEditor; public static final short RELEASE = 4; public static final String REVISION = "B"; @@ -81,7 +84,7 @@ void createSCD_without_headerHistory_should_return_generatedSCD() throws Invocat verify(sclEditor, times(0)).addHistoryItem(any(SCL.class), anyString(), anyString(), anyString()); verify(substationEditor, times(1)).addSubstation(any(SCL.class), any(SCL.class)); verify(sclEditor, times(1)).importSTDElementsInSCD(any(SCL.class), anyList(), anyList()); - verify(sclEditor, times(1)).removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(any(SCL.class)); + verify(controlBlockEditor, times(1)).removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(any(SCL.class)); } @Test @@ -110,7 +113,7 @@ void createSCD_with_headerHistory_should_return_generatedSCD() throws Invocation verify(sclEditor, times(1)).addHistoryItem(any(SCL.class), eq(historyItem.getWho()), eq(historyItem.getWhat()), eq(historyItem.getWhy())); verify(substationEditor, times(1)).addSubstation(any(SCL.class), any(SCL.class)); verify(sclEditor, times(1)).importSTDElementsInSCD(any(SCL.class), anyList(), anyList()); - verify(sclEditor, times(1)).removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(any(SCL.class)); + verify(controlBlockEditor, times(1)).removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(any(SCL.class)); } @Test @@ -172,7 +175,7 @@ void createSCD_when_sclEditor_importSTDElementsInSCD_Fail_should_throw_exception } @Test - void createSCD_when_sclEditor_removeAllControlBlocksAndDatasetsAndExtRefSrcBindings_Fail_should_throw_exception() throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { + void createSCD_when_controlBlockEditor_removeAllControlBlocksAndDatasetsAndExtRefSrcBindings_Fail_should_throw_exception() throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { // Given SCL ssd = (SCL) BeanUtils.cloneBean(scl); SCL std = (SCL) BeanUtils.cloneBean(scl); @@ -182,7 +185,7 @@ void createSCD_when_sclEditor_removeAllControlBlocksAndDatasetsAndExtRefSrcBindi doNothing().when(substationEditor).addSubstation(any(SCL.class), any(SCL.class)); doNothing().when(sclEditor).importSTDElementsInSCD(any(SCL.class), anyList(), anyList()); doThrow(new ScdException("removeAllControlBlocksAndDatasetsAndExtRefSrcBindings fail")) - .when(sclEditor).removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(any(SCL.class)); + .when(controlBlockEditor).removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(any(SCL.class)); // When Then assertThatThrownBy(() -> sclAutomationService.createSCD(ssd, headerDTO, List.of(std))) .isInstanceOf(ScdException.class) diff --git a/sct-commons/pom.xml b/sct-commons/pom.xml index ebf2db877..3b9236fa4 100644 --- a/sct-commons/pom.xml +++ b/sct-commons/pom.xml @@ -161,23 +161,41 @@ 3.1.0 - xjc + scl xjc + + + ${project.build.outputDirectory}/xsd/SCL2007B4/SCL.xsd + ${project.build.outputDirectory}/xsd/SCL_CoMPAS.xsd + + + ${project.basedir}/src/main/resources/binding_configuration.xjb + + org.lfenergy.compas.scl2007b4.model + true + false + + + + epf + + xjc + + + + ${project.basedir}/src/main/resources/xsd/LDEPF_Config_file_v2.xsd + + + ${project.basedir}/src/main/resources/binding_configuration.xjb + + org.lfenergy.compas.sct.commons.model.epf + true + false + - - - ${project.build.outputDirectory}/xsd/SCL2007B4/SCL.xsd - ${project.build.outputDirectory}/xsd/SCL_CoMPAS.xsd - - - ${project.basedir}/src/main/resources/binding_configuration.xjb - - org.lfenergy.compas.scl2007b4.model - true - org.apache.maven.plugins diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ControlBlockService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ControlBlockService.java new file mode 100644 index 000000000..eafecb9ea --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ControlBlockService.java @@ -0,0 +1,153 @@ +// SPDX-FileCopyrightText: 2022 2023 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons; + +import org.apache.commons.lang3.StringUtils; +import org.lfenergy.compas.scl2007b4.model.*; +import org.lfenergy.compas.sct.commons.api.ControlBlockEditor; +import org.lfenergy.compas.sct.commons.dto.*; +import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.NetworkRanges; +import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.RangesPerCbType; +import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.Settings; +import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.SettingsOrError; +import org.lfenergy.compas.sct.commons.exception.ScdException; +import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; +import org.lfenergy.compas.sct.commons.scl.ied.*; +import org.lfenergy.compas.sct.commons.util.*; + +import java.util.*; +import java.util.stream.Stream; + +public class ControlBlockService implements ControlBlockEditor { + + + @Override + public List analyzeDataGroups(SCL scd) { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + return sclRootAdapter.streamIEDAdapters() + .map(iedAdapter -> { + List list = new ArrayList<>(); + list.addAll(iedAdapter.checkDataGroupCoherence()); + list.addAll(iedAdapter.checkBindingDataGroupCoherence()); + return list; + }).flatMap(Collection::stream).toList(); + } + + @Override + public List createDataSetAndControlBlocks(SCL scd, Set allowedFcdas) { + checkFcdaInitDataPresence(allowedFcdas); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + Stream lDeviceAdapters = sclRootAdapter.streamIEDAdapters().flatMap(IEDAdapter::streamLDeviceAdapters); + return createDataSetAndControlBlocks(lDeviceAdapters, allowedFcdas); + } + + @Override + public List createDataSetAndControlBlocks(SCL scd, String targetIedName, Set allowedFcdas) { + checkFcdaInitDataPresence(allowedFcdas); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(targetIedName); + return createDataSetAndControlBlocks(iedAdapter.streamLDeviceAdapters(), allowedFcdas); + + } + + @Override + public List createDataSetAndControlBlocks(SCL scd, String targetIedName, String targetLDeviceInst, Set allowedFcdas) { + if (StringUtils.isBlank(targetIedName)) { + throw new ScdException("IED.name parameter is missing"); + } + checkFcdaInitDataPresence(allowedFcdas); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(targetIedName); + LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(targetLDeviceInst); + return createDataSetAndControlBlocks(Stream.of(lDeviceAdapter), allowedFcdas); + } + + private void checkFcdaInitDataPresence(Set allowedFcdas) { + if (allowedFcdas == null || allowedFcdas.isEmpty()) { + throw new ScdException("Accepted FCDAs list is empty, you should initialize allowed FCDA lists with CsvHelper class before"); + } + } + + private List createDataSetAndControlBlocks(Stream lDeviceAdapters, Set allowedFcdas) { + return lDeviceAdapters + .map(lDeviceAdapter -> lDeviceAdapter.createDataSetAndControlBlocks(allowedFcdas)) + .flatMap(List::stream) + .toList(); + } + + @Override + public List configureNetworkForAllControlBlocks(SCL scd, ControlBlockNetworkSettings controlBlockNetworkSettings, + RangesPerCbType rangesPerCbType) { + List sclReportItems = new ArrayList<>(); + sclReportItems.addAll(configureNetworkForControlBlocks(scd, controlBlockNetworkSettings, rangesPerCbType.gse(), ControlBlockEnum.GSE)); + sclReportItems.addAll(configureNetworkForControlBlocks(scd, controlBlockNetworkSettings, rangesPerCbType.sampledValue(), ControlBlockEnum.SAMPLED_VALUE)); + return sclReportItems; + } + + @Override + public void removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(final SCL scl) { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scl); + List lDeviceAdapters = sclRootAdapter.streamIEDAdapters() + .flatMap(IEDAdapter::streamLDeviceAdapters).toList(); + // LN0 + lDeviceAdapters.stream() + .map(LDeviceAdapter::getLN0Adapter) + .forEach(ln0 -> { + ln0.removeAllControlBlocksAndDatasets(); + ln0.removeAllExtRefSourceBindings(); + }); + // Other LN + lDeviceAdapters.stream() + .map(LDeviceAdapter::getLNAdapters).flatMap(List::stream) + .forEach(LNAdapter::removeAllControlBlocksAndDatasets); + } + + + private List configureNetworkForControlBlocks(SCL scd, ControlBlockNetworkSettings controlBlockNetworkSettings, + NetworkRanges networkRanges, ControlBlockEnum controlBlockEnum) { + PrimitiveIterator.OfLong appIdIterator = Utils.sequence(networkRanges.appIdStart(), networkRanges.appIdEnd()); + Iterator macAddressIterator = Utils.macAddressSequence(networkRanges.macAddressStart(), networkRanges.macAddressEnd()); + + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + return sclRootAdapter.streamIEDAdapters() + .flatMap(iedAdapter -> + iedAdapter.streamLDeviceAdapters() + .filter(LDeviceAdapter::hasLN0) + .map(LDeviceAdapter::getLN0Adapter) + .flatMap(ln0Adapter -> ln0Adapter.streamControlBlocks(controlBlockEnum)) + .map(controlBlockAdapter -> configureControlBlockNetwork(controlBlockNetworkSettings, appIdIterator, macAddressIterator, controlBlockAdapter))) + .flatMap(Optional::stream) + .toList(); + } + + private Optional configureControlBlockNetwork(ControlBlockNetworkSettings controlBlockNetworkSettings, PrimitiveIterator.OfLong appIdIterator, Iterator macAddressIterator, ControlBlockAdapter controlBlockAdapter) { + SettingsOrError settingsOrError = controlBlockNetworkSettings.getNetworkSettings(controlBlockAdapter); + if (settingsOrError.errorMessage() != null) { + return Optional.of(controlBlockAdapter.buildFatalReportItem( + "Cannot configure network for this ControlBlock because: " + settingsOrError.errorMessage())); + } + Settings settings = settingsOrError.settings(); + if (settings == null) { + return Optional.of(controlBlockAdapter.buildFatalReportItem( + "Cannot configure network for this ControlBlock because no settings was provided")); + } + if (settings.vlanId() == null) { + return Optional.of(controlBlockAdapter.buildFatalReportItem( + "Cannot configure network for this ControlBlock because no Vlan Id was provided in the settings")); + } + if (!appIdIterator.hasNext()) { + return Optional.of(controlBlockAdapter.buildFatalReportItem( + "Cannot configure network for this ControlBlock because range of appId is exhausted")); + } + if (!macAddressIterator.hasNext()) { + return Optional.of(controlBlockAdapter.buildFatalReportItem( + "Cannot configure network for this ControlBlock because range of MAC Address is exhausted")); + } + + return controlBlockAdapter.configureNetwork(appIdIterator.nextLong(), macAddressIterator.next(), settings.vlanId(), settings.vlanPriority(), + settings.minTime(), settings.maxTime()); + } + +} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ExtRefService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ExtRefService.java index efcb6cae1..bdfe88d38 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ExtRefService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ExtRefService.java @@ -4,15 +4,11 @@ package org.lfenergy.compas.sct.commons; -import org.apache.commons.lang3.StringUtils; import org.lfenergy.compas.scl2007b4.model.*; import org.lfenergy.compas.sct.commons.api.ExtRefEditor; import org.lfenergy.compas.sct.commons.dto.*; -import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.NetworkRanges; -import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.RangesPerCbType; -import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.Settings; -import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.SettingsOrError; import org.lfenergy.compas.sct.commons.exception.ScdException; +import org.lfenergy.compas.sct.commons.model.epf.*; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; import org.lfenergy.compas.sct.commons.scl.ied.*; import org.lfenergy.compas.sct.commons.util.*; @@ -20,10 +16,10 @@ import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; -import java.util.stream.Stream; +import static org.apache.commons.lang3.StringUtils.*; import static org.lfenergy.compas.sct.commons.util.CommonConstants.*; -import static org.lfenergy.compas.sct.commons.util.Utils.isExtRefFeedBySameControlBlock; +import static org.lfenergy.compas.sct.commons.util.Utils.*; public class ExtRefService implements ExtRefEditor { private static final String INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO = "Invalid or missing attributes in ExtRef binding info"; @@ -112,83 +108,32 @@ public List updateAllExtRefIedNames(SCL scd) { } @Override - public List createDataSetAndControlBlocks(SCL scd, Set allowedFcdas) { - checkFcdaInitDataPresence(allowedFcdas); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - Stream lDeviceAdapters = sclRootAdapter.streamIEDAdapters().flatMap(IEDAdapter::streamLDeviceAdapters); - return createDataSetAndControlBlocks(lDeviceAdapters, allowedFcdas); - } - - @Override - public List createDataSetAndControlBlocks(SCL scd, String targetIedName, Set allowedFcdas) { - checkFcdaInitDataPresence(allowedFcdas); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(targetIedName); - return createDataSetAndControlBlocks(iedAdapter.streamLDeviceAdapters(), allowedFcdas); - - } - - @Override - public List createDataSetAndControlBlocks(SCL scd, String targetIedName, String targetLDeviceInst, Set allowedFcdas) { - if (StringUtils.isBlank(targetIedName)) { - throw new ScdException("IED.name parameter is missing"); - } - checkFcdaInitDataPresence(allowedFcdas); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(targetIedName); - LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(targetLDeviceInst); - return createDataSetAndControlBlocks(Stream.of(lDeviceAdapter), allowedFcdas); - } - - private void checkFcdaInitDataPresence(Set allowedFcdas) { - if (allowedFcdas == null || allowedFcdas.isEmpty()) { - throw new ScdException("Accepted FCDAs list is empty, you should initialize allowed FCDA lists with CsvHelper class before"); - } - } - - private List createDataSetAndControlBlocks(Stream lDeviceAdapters, Set allowedFcdas) { - return lDeviceAdapters - .map(lDeviceAdapter -> lDeviceAdapter.createDataSetAndControlBlocks(allowedFcdas)) - .flatMap(List::stream) - .toList(); - } - - @Override - public List configureNetworkForAllControlBlocks(SCL scd, ControlBlockNetworkSettings controlBlockNetworkSettings, - RangesPerCbType rangesPerCbType) { + public List manageBindingForLDEPF(SCL scd, EPF epf) { List sclReportItems = new ArrayList<>(); - sclReportItems.addAll(configureNetworkForControlBlocks(scd, controlBlockNetworkSettings, rangesPerCbType.gse(), ControlBlockEnum.GSE)); - sclReportItems.addAll(configureNetworkForControlBlocks(scd, controlBlockNetworkSettings, rangesPerCbType.sampledValue(), ControlBlockEnum.SAMPLED_VALUE)); - return sclReportItems; - } - - @Override - public List manageBindingForLDEPF(SCL scd, ILDEPFSettings settings) { + if(!epf.isSetChannels()) return sclReportItems; SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - List sclReportItems = new ArrayList<>(); sclRootAdapter.streamIEDAdapters() - .filter(iedAdapter -> !iedAdapter.getName().equals(IED_TEST_NAME)) + .filter(iedAdapter -> !iedAdapter.getName().contains("TEST")) .map(iedAdapter -> iedAdapter.findLDeviceAdapterByLdInst(LDEVICE_LDEPF)) .flatMap(Optional::stream) - .forEach(lDeviceAdapter -> - lDeviceAdapter.getExtRefBayReferenceForActifLDEPF(sclReportItems) - .forEach(extRefBayRef -> settings.getLDEPFSettingDataMatchExtRef(extRefBayRef.extRef()) - .ifPresent(lDPFSettingMatchingExtRef -> { - List iedSources = settings.getIedSources(sclRootAdapter, extRefBayRef.compasBay(), lDPFSettingMatchingExtRef); - if (iedSources.size() == 1) { - updateLDEPFExtRefBinding(extRefBayRef.extRef(), iedSources.get(0), lDPFSettingMatchingExtRef); - sclReportItems.addAll(updateLDEPFDos(lDeviceAdapter, extRefBayRef.extRef(), lDPFSettingMatchingExtRef)); - } else { - if (iedSources.size() > 1) { - sclReportItems.add(SclReportItem.warning(null, "There is more than one IED source to bind the signal " + - "/IED@name=" + extRefBayRef.iedName() + "/LDevice@inst=LDEPF/LN0" + - "/ExtRef@desc=" + extRefBayRef.extRef().getDesc())); - } - } - })) + .forEach(lDeviceAdapter -> lDeviceAdapter.getExtRefBayReferenceForActifLDEPF(sclReportItems) + .forEach(extRefBayRef -> epf.getChannels().getChannel().stream().filter(tChannel -> doesExtRefMatchLDEPFChannel(extRefBayRef.extRef(), tChannel)) + .findFirst().ifPresent(channel -> { + List iedSources = getIedSources(sclRootAdapter, extRefBayRef.compasBay(), channel); + if (iedSources.size() == 1) { + updateLDEPFExtRefBinding(extRefBayRef.extRef(), iedSources.get(0), channel); + sclReportItems.addAll(updateLDEPFDos(lDeviceAdapter, extRefBayRef.extRef(), channel)); + } else { + if (iedSources.size() > 1) { + sclReportItems.add(SclReportItem.warning(null, "There is more than one IED source to bind the signal " + + "/IED@name=" + extRefBayRef.iedName() + "/LDevice@inst=LDEPF/LN0" + + "/ExtRef@desc=" + extRefBayRef.extRef().getDesc())); + } + // If the source IED is not found, there will be no update or report message. + } + })) ); return sclReportItems; - } private List validateIed(SclRootAdapter sclRootAdapter) { @@ -204,8 +149,8 @@ private List checkIedCompasIcdHeaderAttributes(SclRootAdapter scl if (compasPrivate.isEmpty()) { return iedAdapter.buildFatalReportItem(String.format("IED has no Private %s element", PrivateEnum.COMPAS_ICDHEADER.getPrivateType())); } - if (StringUtils.isBlank(compasPrivate.get().getICDSystemVersionUUID()) - || StringUtils.isBlank(compasPrivate.get().getIEDName())) { + if (isBlank(compasPrivate.get().getICDSystemVersionUUID()) + || isBlank(compasPrivate.get().getIEDName())) { return iedAdapter.buildFatalReportItem(String.format("IED private %s as no icdSystemVersionUUID or iedName attribute", PrivateEnum.COMPAS_ICDHEADER.getPrivateType())); } @@ -222,7 +167,7 @@ private List checkIedUnityOfIcdSystemVersionUuid(SclRootAdapter s .orElse(""))); return systemVersionToIedList.entrySet().stream() - .filter(entry -> StringUtils.isNotBlank(entry.getKey())) + .filter(entry -> isNotBlank(entry.getKey())) .filter(entry -> entry.getValue().size() > 1) .map(entry -> SclReportItem.error(entry.getValue().stream() .map(tied -> new IEDAdapter(sclRootAdapter, tied)) @@ -233,50 +178,6 @@ private List checkIedUnityOfIcdSystemVersionUuid(SclRootAdapter s .toList(); } - private List configureNetworkForControlBlocks(SCL scd, ControlBlockNetworkSettings controlBlockNetworkSettings, - NetworkRanges networkRanges, ControlBlockEnum controlBlockEnum) { - PrimitiveIterator.OfLong appIdIterator = Utils.sequence(networkRanges.appIdStart(), networkRanges.appIdEnd()); - Iterator macAddressIterator = Utils.macAddressSequence(networkRanges.macAddressStart(), networkRanges.macAddressEnd()); - - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - return sclRootAdapter.streamIEDAdapters() - .flatMap(iedAdapter -> - iedAdapter.streamLDeviceAdapters() - .filter(LDeviceAdapter::hasLN0) - .map(LDeviceAdapter::getLN0Adapter) - .flatMap(ln0Adapter -> ln0Adapter.streamControlBlocks(controlBlockEnum)) - .map(controlBlockAdapter -> configureControlBlockNetwork(controlBlockNetworkSettings, appIdIterator, macAddressIterator, controlBlockAdapter))) - .flatMap(Optional::stream) - .toList(); - } - private Optional configureControlBlockNetwork(ControlBlockNetworkSettings controlBlockNetworkSettings, PrimitiveIterator.OfLong appIdIterator, Iterator macAddressIterator, ControlBlockAdapter controlBlockAdapter) { - SettingsOrError settingsOrError = controlBlockNetworkSettings.getNetworkSettings(controlBlockAdapter); - if (settingsOrError.errorMessage() != null) { - return Optional.of(controlBlockAdapter.buildFatalReportItem( - "Cannot configure network for this ControlBlock because: " + settingsOrError.errorMessage())); - } - Settings settings = settingsOrError.settings(); - if (settings == null) { - return Optional.of(controlBlockAdapter.buildFatalReportItem( - "Cannot configure network for this ControlBlock because no settings was provided")); - } - if (settings.vlanId() == null) { - return Optional.of(controlBlockAdapter.buildFatalReportItem( - "Cannot configure network for this ControlBlock because no Vlan Id was provided in the settings")); - } - if (!appIdIterator.hasNext()) { - return Optional.of(controlBlockAdapter.buildFatalReportItem( - "Cannot configure network for this ControlBlock because range of appId is exhausted")); - } - if (!macAddressIterator.hasNext()) { - return Optional.of(controlBlockAdapter.buildFatalReportItem( - "Cannot configure network for this ControlBlock because range of MAC Address is exhausted")); - } - - return controlBlockAdapter.configureNetwork(appIdIterator.nextLong(), macAddressIterator.next(), settings.vlanId(), settings.vlanPriority(), - settings.minTime(), settings.maxTime()); - } - /** * Remove ExtRef which are fed by same Control Block * @@ -291,19 +192,143 @@ public static List filterDuplicatedExtRefs(List tExtRefs) { return filteredList; } - private void updateLDEPFExtRefBinding(TExtRef extRef, TIED iedSource, LDEPFSettingData setting) { + /** + * Provides valid IED sources according to EPF configuration.
+ * EPF verification include:
+ * 1. COMPAS-Bay verification that should be closed to the provided Flow Kind
+ * 2. COMPAS-ICDHeader verification that should match the provided parameters
+ * 3. Active LDevice source object that should match the provided parameters
+ * 4. Active LNode source object that should match the provided parameters
+ * 5. Valid DataTypeTemplate Object hierarchy that should match the DO/DA/BDA parameters
+ * @param sclRootAdapter SCL scl object + * @param compasBay TCompasBay represent Bay Private + * @param channel TChannel represent parameters + * @return the IED sources matching the LDEPF parameters + */ + private static List getIedSources(SclRootAdapter sclRootAdapter, TCompasBay compasBay, TChannel channel) { + return sclRootAdapter.streamIEDAdapters() + .filter(iedAdapter -> (channel.getBayScope().equals(TCBscopeType.BAY_EXTERNAL) + && iedAdapter.getPrivateCompasBay().stream().noneMatch(bay -> bay.getUUID().equals(compasBay.getUUID()))) + || (channel.getBayScope().equals(TCBscopeType.BAY_INTERNAL) + && iedAdapter.getPrivateCompasBay().stream().anyMatch(bay -> bay.getUUID().equals(compasBay.getUUID())))) + .filter(iedAdapter -> doesIcdHeaderMatchLDEPFChannel(iedAdapter, channel)) + .filter(iedAdapter -> getActiveSourceLDeviceByLDEPFChannel(iedAdapter, channel) + .map(lDeviceAdapter -> getActiveLNSourceByLDEPFChannel(lDeviceAdapter, channel) + .map(lnAdapter -> isValidDataTypeTemplate(lnAdapter, channel)) + .orElse(false)) + .orElse(false)) + .map(IEDAdapter::getCurrentElem).limit(2).toList(); + } + + /** + * Verify if an Extref matches the EPF Channel or not. + * @param extRef TExtRef + * @param tChannel TChannel + * @return true if the TExtRef matches the EPF channel + */ + private static Boolean doesExtRefMatchLDEPFChannel(TExtRef extRef, TChannel tChannel) { + Boolean doesExtRefDescMatchAnalogChannel = tChannel.getChannelType().equals(TChannelType.ANALOG) + && extRef.getDesc().startsWith("DYN_LDEPF_ANALOG CHANNEL " + tChannel.getChannelNum()+"_1_AnalogueValue") + && extRef.getDesc().endsWith("_" + tChannel.getDAName() + "_1"); + Boolean doesExtRefDescMatchDigitalChannel = tChannel.getChannelType().equals(TChannelType.DIGITAL) + && extRef.getDesc().startsWith("DYN_LDEPF_DIGITAL CHANNEL " + tChannel.getChannelNum()+"_1_BOOLEEN") + && extRef.getDesc().endsWith("_" + tChannel.getDAName() + "_1"); + return extRef.isSetDesc() && (doesExtRefDescMatchAnalogChannel || doesExtRefDescMatchDigitalChannel) + && extRef.isSetPLN() && Utils.lnClassEquals(extRef.getPLN(), tChannel.getLNClass()) + && extRef.isSetPDO() && extRef.getPDO().equals(tChannel.getDOName()); + } + + /** + * Verify whether the IED satisfies the EPF channel for the private element `TCompasICDHeader` + * @param iedAdapter IEDAdapter + * @param channel TChannel + * @return true if the TCompasICDHeader matches the EPF channel + */ + private static boolean doesIcdHeaderMatchLDEPFChannel(IEDAdapter iedAdapter, TChannel channel) { + return iedAdapter.getCompasICDHeader() + .map(compasICDHeader -> compasICDHeader.getIEDType().value().equals(channel.getIEDType()) + && compasICDHeader.getIEDredundancy().value().equals(channel.getIEDRedundancy().value()) + && compasICDHeader.getIEDSystemVersioninstance().toString().equals(channel.getIEDSystemVersionInstance())) + .orElse(false); + } + + /** + * Provides Active LDevice according to EPF channel's inst attribute + * @param iedAdapter IEDAdapter + * @param channel TChannel + * @return LDeviceAdapter object that matches the EPF channel + */ + private static Optional getActiveSourceLDeviceByLDEPFChannel(IEDAdapter iedAdapter, TChannel channel) { + return iedAdapter.findLDeviceAdapterByLdInst(channel.getLDInst()) + .filter(lDeviceAdapter -> new Ldevice(lDeviceAdapter.getCurrentElem()).getLdeviceStatus() + .map(status -> status.equals(LdeviceStatus.ON)) + .orElse(false)); + } + + /** + * Provides Active LN Object that satisfies the EPF channel attributes (lnClass, lnInst, prefix) + * @param lDeviceAdapter LDeviceAdapter + * @param channel TChannel + * @return AbstractLNAdapter object that matches the EPF channel + */ + private static Optional> getActiveLNSourceByLDEPFChannel(LDeviceAdapter lDeviceAdapter, TChannel channel) { + return lDeviceAdapter.getLNAdaptersIncludingLN0().stream() + .filter(lnAdapter -> lnAdapter.getLNClass().equals(channel.getLNClass()) + && lnAdapter.getLNInst().equals(channel.getLNInst()) + && trimToEmpty(channel.getLNPrefix()).equals(trimToEmpty(lnAdapter.getPrefix()))) + .findFirst() + .filter(lnAdapter -> lnAdapter.getDaiModStValValue() + .map(status -> status.equals(LdeviceStatus.ON.getValue())) + .orElse(true)); + } + + /** + * Verify whether the LN satisfies the EPF channel parameters for Data Type Template elements. + * @param lnAdapter AbstractLNAdapter + * @param channel TChannel + * @return true if the LN matches the EPF channel + */ + private static boolean isValidDataTypeTemplate(AbstractLNAdapter lnAdapter, TChannel channel) { + if(isBlank(channel.getDOName())){ + return true; + } + String doName = isBlank(channel.getDOInst()) || channel.getDOInst().equals("0") ? channel.getDOName() : channel.getDOName() + channel.getDOInst(); + DoTypeName doTypeName = new DoTypeName(doName); + if(isNotBlank(channel.getSDOName())){ + doTypeName.getStructNames().add(channel.getSDOName()); + } + DaTypeName daTypeName = new DaTypeName(channel.getDAName()); + if(isNotBlank(channel.getBDAName())){ + daTypeName.setBType(TPredefinedBasicTypeEnum.STRUCT); + daTypeName.getStructNames().add(channel.getBDAName()); + } + if(isNotBlank(channel.getSBDAName())){ + daTypeName.getStructNames().add(channel.getSBDAName()); + } + return lnAdapter.getDataTypeTemplateAdapter().getLNodeTypeAdapterById(lnAdapter.getLnType()) + .filter(lNodeTypeAdapter -> { + try { + lNodeTypeAdapter.check(doTypeName, daTypeName); + } catch (ScdException ex) { + return false; + } + return true; + }).isPresent(); + } + + private void updateLDEPFExtRefBinding(TExtRef extRef, TIED iedSource, TChannel setting) { extRef.setIedName(iedSource.getName()); - extRef.setLdInst(setting.getLdInst()); - extRef.getLnClass().add(setting.getLnClass()); - extRef.setLnInst(setting.getLnInst()); - if(setting.getLnPrefix() != null){ - extRef.setPrefix(setting.getLnPrefix()); + extRef.setLdInst(setting.getLDInst()); + extRef.getLnClass().add(setting.getLNClass()); + extRef.setLnInst(setting.getLNInst()); + if(!isBlank(setting.getLNPrefix())) { + extRef.setPrefix(setting.getLNPrefix()); } - String doName = StringUtils.isEmpty(setting.getDoInst()) || StringUtils.isBlank(setting.getDoInst()) || setting.getDoInst().equals("0") ? setting.getDoName() : setting.getDoName() + setting.getDoInst(); + String doName = isBlank(setting.getDOInst()) || setting.getDOInst().equals("0") ? setting.getDOName() : setting.getDOName() + setting.getDOInst(); extRef.setDoName(doName); } - private List updateLDEPFDos(LDeviceAdapter lDeviceAdapter, TExtRef extRef, LDEPFSettingData setting) { + private List updateLDEPFDos(LDeviceAdapter lDeviceAdapter, TExtRef extRef, TChannel setting) { List sclReportItems = new ArrayList<>(); List doNameAndDaNameList = List.of( new DoNameAndDaName(CHNUM1_DO_NAME, DU_DA_NAME), @@ -311,30 +336,30 @@ private List updateLDEPFDos(LDeviceAdapter lDeviceAdapter, TExtRe new DoNameAndDaName(MOD_DO_NAME, STVAL_DA_NAME), new DoNameAndDaName(SRCREF_DO_NAME, SETSRCREF_DA_NAME) ); - if (setting.getChannelDigitalNum() != null && setting.getChannelAnalogNum() == null) { + if (setting.getChannelType().equals(TChannelType.DIGITAL)) { //digital - lDeviceAdapter.findLnAdapter(LN_RBDR, String.valueOf(setting.getChannelDigitalNum()), null) + lDeviceAdapter.findLnAdapter(LN_RBDR, setting.getChannelNum(), null) .ifPresent(lnAdapter -> doNameAndDaNameList.forEach(doNameAndDaName -> updateVal(lnAdapter, doNameAndDaName.doName, doNameAndDaName.daName, extRef, setting).ifPresent(sclReportItems::add))); - lDeviceAdapter.findLnAdapter(LN_RBDR, String.valueOf(setting.getChannelDigitalNum()), LN_PREFIX_B) + lDeviceAdapter.findLnAdapter(LN_RBDR, setting.getChannelNum(), LN_PREFIX_B) .ifPresent(lnAdapter -> doNameAndDaNameList.forEach(doNameAndDaName -> updateVal(lnAdapter, doNameAndDaName.doName, doNameAndDaName.daName, extRef, setting).ifPresent(sclReportItems::add))); } - if (setting.getChannelDigitalNum() == null && setting.getChannelAnalogNum() != null) { + if (setting.getChannelType().equals(TChannelType.ANALOG)) { //analog - lDeviceAdapter.findLnAdapter(LN_RADR, String.valueOf(setting.getChannelAnalogNum()), null) + lDeviceAdapter.findLnAdapter(LN_RADR, setting.getChannelNum(), null) .ifPresent(lnAdapter -> doNameAndDaNameList.forEach(doNameAndDaName -> updateVal(lnAdapter, doNameAndDaName.doName, doNameAndDaName.daName, extRef, setting).ifPresent(sclReportItems::add))); - lDeviceAdapter.findLnAdapter(LN_RADR, String.valueOf(setting.getChannelAnalogNum()), LN_PREFIX_A) + lDeviceAdapter.findLnAdapter(LN_RADR, setting.getChannelNum(), LN_PREFIX_A) .ifPresent(lnAdapter -> doNameAndDaNameList.forEach(doNameAndDaName -> updateVal(lnAdapter, doNameAndDaName.doName, doNameAndDaName.daName, extRef, setting).ifPresent(sclReportItems::add))); } return sclReportItems; } - private Optional updateVal(AbstractLNAdapter lnAdapter, String doName, String daName, TExtRef extRef, LDEPFSettingData setting) { + private Optional updateVal(AbstractLNAdapter lnAdapter, String doName, String daName, TExtRef extRef, TChannel setting) { String value = switch (daName) { case DU_DA_NAME -> setting.getChannelShortLabel(); case SETVAL_DA_NAME -> - LN_PREFIX_B.equals(lnAdapter.getPrefix()) || LN_PREFIX_A.equals(lnAdapter.getPrefix()) ? setting.getChannelLevModQ() : setting.getChannelLevMod(); + LN_PREFIX_B.equals(lnAdapter.getPrefix()) || LN_PREFIX_A.equals(lnAdapter.getPrefix()) ? setting.getChannelLevModQ().value() : setting.getChannelLevMod().value(); case STVAL_DA_NAME -> LdeviceStatus.ON.getValue(); - case SETSRCREF_DA_NAME -> computeDaiValue(lnAdapter, extRef, setting.getDaName()); + case SETSRCREF_DA_NAME -> computeDaiValue(lnAdapter, extRef, setting.getDAName()); default -> null; }; return lnAdapter.getDOIAdapterByName(doName).updateDAI(daName, value); @@ -347,16 +372,16 @@ private String computeDaiValue(AbstractLNAdapter lnAdapter, TExtRef extRef, S if (LN_PREFIX_B.equals(lnAdapter.getPrefix()) || LN_PREFIX_A.equals(lnAdapter.getPrefix())) { return extRef.getIedName() + extRef.getLdInst() + "/" + - StringUtils.trimToEmpty(extRef.getPrefix()) + + trimToEmpty(extRef.getPrefix()) + extRef.getLnClass().get(0) + - StringUtils.trimToEmpty(extRef.getLnInst()) + "." + + trimToEmpty(extRef.getLnInst()) + "." + extRef.getDoName() + "." + Q_DA_NAME; } else { return extRef.getIedName() + extRef.getLdInst() + "/" + - StringUtils.trimToEmpty(extRef.getPrefix()) + + trimToEmpty(extRef.getPrefix()) + extRef.getLnClass().get(0) + - StringUtils.trimToEmpty(extRef.getLnInst()) + "." + + trimToEmpty(extRef.getLnInst()) + "." + extRef.getDoName() + "." + daName; } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/SclEditorService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/SclService.java similarity index 88% rename from sct-commons/src/main/java/org/lfenergy/compas/sct/commons/SclEditorService.java rename to sct-commons/src/main/java/org/lfenergy/compas/sct/commons/SclService.java index f52cc3b27..3364bdf52 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/SclEditorService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/SclService.java @@ -30,7 +30,7 @@ import static org.lfenergy.compas.sct.commons.util.PrivateEnum.COMPAS_ICDHEADER; @Slf4j -public class SclEditorService implements SclEditor { +public class SclService implements SclEditor { @Override public SCL initScl(final UUID hId, final String hVersion, final String hRevision) throws ScdException { @@ -170,26 +170,6 @@ public void importSTDElementsInSCD(SCL scd, List stds, List lDeviceAdapters = sclRootAdapter.streamIEDAdapters() - .flatMap(IEDAdapter::streamLDeviceAdapters).toList(); - - // LN0 - lDeviceAdapters.stream() - .map(LDeviceAdapter::getLN0Adapter) - .forEach(ln0 -> { - ln0.removeAllControlBlocksAndDatasets(); - ln0.removeAllExtRefSourceBindings(); - }); - - // Other LN - lDeviceAdapters.stream() - .map(LDeviceAdapter::getLNAdapters).flatMap(List::stream) - .forEach(LNAdapter::removeAllControlBlocksAndDatasets); - } - @Override public List updateLDeviceStatus(SCL scd) { SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); @@ -203,18 +183,6 @@ public List updateLDeviceStatus(SCL scd) { .toList(); } - @Override - public List analyzeDataGroups(SCL scd) { - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - return sclRootAdapter.streamIEDAdapters() - .map(iedAdapter -> { - List list = new ArrayList<>(); - list.addAll(iedAdapter.checkDataGroupCoherence()); - list.addAll(iedAdapter.checkBindingDataGroupCoherence()); - return list; - }).flatMap(Collection::stream).toList(); - } - @Override public List updateDoInRef(SCL scd) { SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ControlBlockEditor.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ControlBlockEditor.java new file mode 100644 index 000000000..7406c23c3 --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ControlBlockEditor.java @@ -0,0 +1,101 @@ +// SPDX-FileCopyrightText: 2022 2023 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons.api; + +import org.lfenergy.compas.scl2007b4.model.SCL; +import org.lfenergy.compas.scl2007b4.model.TExtRef; +import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings; +import org.lfenergy.compas.sct.commons.dto.FcdaForDataSetsCreation; +import org.lfenergy.compas.sct.commons.dto.SclReportItem; +import org.lfenergy.compas.sct.commons.util.Utils; + +import java.util.List; +import java.util.Set; + +/** + * Service class that will be used to create, update or delete elements related to the {@link TExtRef TExtRef} object. + *

The following features are supported:

+ *
    + *
  • ExtRef features
  • + *
      + *
    1. {@link ControlBlockEditor#createDataSetAndControlBlocks(SCL, Set) Create DataSet and ControlBlock based on the TExtRef}
    2. + *
    3. {@link ControlBlockEditor#createDataSetAndControlBlocks(SCL, String, Set) Create DataSet and ControlBlock based on the TExtRef in given IED}
    4. + *
    5. {@link ControlBlockEditor#createDataSetAndControlBlocks(SCL, String,String, Set) Create DataSet and ControlBlock based on the TExtRef in given IED and LDevice}
    6. + *
    7. {@link ControlBlockEditor#configureNetworkForAllControlBlocks Configure the network for the ControlBlocks}
    8. + *
    9. {@link ControlBlockEditor#removeAllControlBlocksAndDatasetsAndExtRefSrcBindings Removes all ControlBlocks and DataSets for all LNs in SCL}
    10. + *
    11. {@link ControlBlockEditor#analyzeDataGroups(SCL)} Checks Control Blocks, DataSets and FCDA number limitation into Access Points }
    12. + *
    + *
+ */ +public interface ControlBlockEditor { + + + /** + * Removes all ControlBlocks and DataSets for all LNs in SCL + * + * @param scl SCL file for which ControlBlocks and DataSets should be deleted + */ + void removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(final SCL scl); + + + /** + * Checks Control Blocks, DataSets and FCDA number limitation into Access Points + * + * @param scd SCL file for which LDevice should be activated or deactivated + * @return list of encountered errors + */ + List analyzeDataGroups(SCL scd); + + + /** + * Create All DataSet and ControlBlock in the SCL based on the ExtRef + * + * @param scd input SCD object. It could be modified by adding new DataSet and ControlBlocks + * @param allowedFcdas List of allowed FCDA for DataSets and Control Blocks creation + * @return list of encountered errors + */ + List createDataSetAndControlBlocks(SCL scd, Set allowedFcdas); + + /** + * Create All DataSet and ControlBlock for the ExtRef in given IED + * + * @param scd input SCD object. The object will be modified with the new DataSet and ControlBlocks + * @param targetIedName the name of the IED where the ExtRef are + * @param allowedFcdas List of allowed FCDA for DataSets and Control Blocks creation + * @return list of encountered errors + */ + List createDataSetAndControlBlocks(SCL scd, String targetIedName, Set allowedFcdas); + + /** + * Create All DataSet and ControlBlock for the ExtRef in given IED and LDevice + * + * @param scd input SCD object. The object will be modified with the new DataSet and ControlBlocks + * @param targetIedName the name of the IED where the ExtRef are + * @param targetLDeviceInst the name of the LDevice where the ExtRef are + * @param allowedFcdas List of allowed FCDA for DataSets and Control Blocks creation + * @return list of encountered errors + */ + List createDataSetAndControlBlocks(SCL scd, String targetIedName, String targetLDeviceInst, Set allowedFcdas); + + /** + * Configure the network for all the ControlBlocks. + * Create (or update if already existing) these elements + * - the Communication/SubNetwork/ConnectedAP/GSE element, for the GSEControl blocks + * - the Communication/SubNetwork/ConnectedAP/SMV element, for the SampledValueControl blocks + * + * @param scd input SCD object. The object will be modified with the new DataGSESet and SMV elements + * @param controlBlockNetworkSettings a method tha gives the network configuration information for a given ControlBlock + * @param rangesPerCbType provide NetworkRanges for GSEControl and SampledValueControl. NetworkRanges contains : + * start-end app APPID range (long value), start-end MAC-Addresses (Mac-Addresses values: Ex: "01-0C-CD-01-01-FF") + * @return list of encountered errors + * @see Utils#macAddressToLong(String) for the expected MAC address format + * @see ControlBlockNetworkSettings + * @see ControlBlockNetworkSettings.RangesPerCbType + * @see ControlBlockNetworkSettings.NetworkRanges + */ + List configureNetworkForAllControlBlocks(SCL scd, ControlBlockNetworkSettings controlBlockNetworkSettings, + ControlBlockNetworkSettings.RangesPerCbType rangesPerCbType); + +} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ExtRefEditor.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ExtRefEditor.java index 74ad792bb..5b49ffb81 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ExtRefEditor.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ExtRefEditor.java @@ -6,16 +6,12 @@ import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.scl2007b4.model.TExtRef; -import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings; import org.lfenergy.compas.sct.commons.dto.ExtRefInfo; -import org.lfenergy.compas.sct.commons.dto.FcdaForDataSetsCreation; import org.lfenergy.compas.sct.commons.dto.SclReportItem; import org.lfenergy.compas.sct.commons.exception.ScdException; -import org.lfenergy.compas.sct.commons.util.ILDEPFSettings; -import org.lfenergy.compas.sct.commons.util.Utils; +import org.lfenergy.compas.sct.commons.model.epf.EPF; import java.util.List; -import java.util.Set; /** * Service class that will be used to create, update or delete elements related to the {@link TExtRef TExtRef} object. @@ -26,10 +22,6 @@ *
  • {@link ExtRefEditor#updateExtRefBinders Update the TExtRef reference object for given ExtRefBindingInfo model}
  • *
  • {@link ExtRefEditor#updateExtRefSource Update the TExtRef reference object for given ExtRefSourceInfo model}
  • *
  • {@link ExtRefEditor#updateAllExtRefIedNames Update the iedName attribute in all TExtRef}
  • - *
  • {@link ExtRefEditor#createDataSetAndControlBlocks(SCL) Create DataSet and ControlBlock based on the TExtRef}
  • - *
  • {@link ExtRefEditor#createDataSetAndControlBlocks(SCL, String) Create DataSet and ControlBlock based on the TExtRef in given IED}
  • - *
  • {@link ExtRefEditor#createDataSetAndControlBlocks(SCL, String, String) Create DataSet and ControlBlock based on the TExtRef in given IED and LDevice}
  • - *
  • {@link ExtRefEditor#configureNetworkForAllControlBlocks Configure the network for the ControlBlocks}
  • *
  • {@link ExtRefEditor#manageBindingForLDEPF Manage TExtRef Binding For LDevice (inst=LDEPF) within LDEPF configuration}
  • * * @@ -63,60 +55,11 @@ public interface ExtRefEditor { List updateAllExtRefIedNames(SCL scd); /** - * Create All DataSet and ControlBlock in the SCL based on the ExtRef - * - * @param scd input SCD object. It could be modified by adding new DataSet and ControlBlocks - * @param allowedFcdas List of allowed FCDA for DataSets and Control Blocks creation - * @return list of encountered errors - */ - List createDataSetAndControlBlocks(SCL scd, Set allowedFcdas); - - /** - * Create All DataSet and ControlBlock for the ExtRef in given IED - * - * @param scd input SCD object. The object will be modified with the new DataSet and ControlBlocks - * @param targetIedName the name of the IED where the ExtRef are - * @param allowedFcdas List of allowed FCDA for DataSets and Control Blocks creation - * @return list of encountered errors - */ - List createDataSetAndControlBlocks(SCL scd, String targetIedName, Set allowedFcdas); - - /** - * Create All DataSet and ControlBlock for the ExtRef in given IED and LDevice - * - * @param scd input SCD object. The object will be modified with the new DataSet and ControlBlocks - * @param targetIedName the name of the IED where the ExtRef are - * @param targetLDeviceInst the name of the LDevice where the ExtRef are - * @param allowedFcdas List of allowed FCDA for DataSets and Control Blocks creation - * @return list of encountered errors - */ - List createDataSetAndControlBlocks(SCL scd, String targetIedName, String targetLDeviceInst, Set allowedFcdas); - - /** - * Configure the network for all the ControlBlocks. - * Create (or update if already existing) these elements - * - the Communication/SubNetwork/ConnectedAP/GSE element, for the GSEControl blocks - * - the Communication/SubNetwork/ConnectedAP/SMV element, for the SampledValueControl blocks - * - * @param scd input SCD object. The object will be modified with the new DataGSESet and SMV elements - * @param controlBlockNetworkSettings a method tha gives the network configuration information for a given ControlBlock - * @param rangesPerCbType provide NetworkRanges for GSEControl and SampledValueControl. NetworkRanges contains : - * start-end app APPID range (long value), start-end MAC-Addresses (Mac-Addresses values: Ex: "01-0C-CD-01-01-FF") - * @return list of encountered errors - * @see Utils#macAddressToLong(String) for the expected MAC address format - * @see ControlBlockNetworkSettings - * @see ControlBlockNetworkSettings.RangesPerCbType - * @see ControlBlockNetworkSettings.NetworkRanges - */ - List configureNetworkForAllControlBlocks(SCL scd, ControlBlockNetworkSettings controlBlockNetworkSettings, - ControlBlockNetworkSettings.RangesPerCbType rangesPerCbType); - - /** - * ExtRef Binding For LDevice (inst=LDEPF) that matching LDEPF configuration + * ExtRef Binding For LDevice (inst=LDEPF) that matching EPF configuration * @param scd SCL - * @param settings ILDEPFSettings + * @param epf EPF * @return list of encountered errors */ - List manageBindingForLDEPF(SCL scd, ILDEPFSettings settings); + List manageBindingForLDEPF(SCL scd, EPF epf); } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/SclEditor.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/SclEditor.java index d98582303..9055372be 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/SclEditor.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/SclEditor.java @@ -130,13 +130,6 @@ public interface SclEditor { */ void importSTDElementsInSCD(SCL scd, List stds, List subNetworkTypes) throws ScdException; - /** - * Removes all ControlBlocks and DataSets for all LNs in SCL - * - * @param scl SCL file for which ControlBlocks and DataSets should be deleted - */ - void removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(final SCL scl); - /** * Activate used LDevice and Deactivate unused LDevice in {@link TLNode TLNode } * @@ -145,14 +138,6 @@ public interface SclEditor { */ List updateLDeviceStatus(SCL scd); - /** - * Checks Control Blocks, DataSets and FCDA number limitation into Access Points - * - * @param scd SCL file for which LDevice should be activated or deactivated - * @return list of encountered errors - */ - List analyzeDataGroups(SCL scd); - /** * Update DAIs of DO InRef in all LN0 of the SCD using matching ExtRef information. * diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/LDEPFSettingData.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/LDEPFSettingData.java deleted file mode 100644 index 1c0567068..000000000 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/LDEPFSettingData.java +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-FileCopyrightText: 2023 RTE FRANCE -// -// SPDX-License-Identifier: Apache-2.0 - -package org.lfenergy.compas.sct.commons.dto; - -import com.opencsv.bean.CsvBindByPosition; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.lfenergy.compas.scl2007b4.model.TCompasFlowKind; -import org.lfenergy.compas.scl2007b4.model.TExtRef; -import org.lfenergy.compas.sct.commons.util.Utils; - -import java.math.BigInteger; - -/** - * A representation of settings made for LDEPF LDevice - * - * @see Issue !256 - */ -@Getter -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class LDEPFSettingData { - - @CsvBindByPosition(position = 0) - private TCompasFlowKind bayScope; - @CsvBindByPosition(position = 1) - private String iedType; - @CsvBindByPosition(position = 2) - private String iedRedundancy; - @CsvBindByPosition(position = 3) - private BigInteger iedInstance; - @CsvBindByPosition(position = 4) - private String channelShortLabel; - @CsvBindByPosition(position = 5) - private String channelMREP; - @CsvBindByPosition(position = 6) - private String channelLevModQ; - @CsvBindByPosition(position = 7) - private String channelLevMod; - @CsvBindByPosition(position = 8) - private String bapVariant; - @CsvBindByPosition(position = 9) - private String bapIgnoredValue; - @CsvBindByPosition(position = 10) - private String ldInst; - @CsvBindByPosition(position = 11) - private String lnPrefix; - @CsvBindByPosition(position = 12) - private String lnClass; - @CsvBindByPosition(position = 13) - private String lnInst; - @CsvBindByPosition(position = 14) - private String doName; - @CsvBindByPosition(position = 15) - private String doInst; - @CsvBindByPosition(position = 16) - private String sdoName; - @CsvBindByPosition(position = 17) - private String daName; - @CsvBindByPosition(position = 18) - private String daType; - @CsvBindByPosition(position = 19) - private String dabType; - @CsvBindByPosition(position = 20) - private String bdaName; - @CsvBindByPosition(position = 21) - private String sbdaName; - @CsvBindByPosition(position = 22) - private Integer channelAnalogNum; - @CsvBindByPosition(position = 23) - private Integer channelDigitalNum; - @CsvBindByPosition(position = 24) - private String opt; - - /** - * verify if an Extref matches the Analog type or not. - */ - private Boolean isAnalogTypeMatchDesc(TExtRef extRef) { - return getChannelAnalogNum() != null && getChannelDigitalNum() == null - && extRef.getDesc().startsWith("DYN_LDEPF_ANALOG CHANNEL " + getChannelAnalogNum()+"_1_AnalogueValue") - && extRef.getDesc().endsWith("_" + getDaName() + "_1"); - } - - /** - * verify if an Extref matches the Digital type or not. - */ - private Boolean isDigitalTypeMatchDesc(TExtRef extRef) { - return getChannelDigitalNum() != null && getChannelAnalogNum() == null - && extRef.getDesc().startsWith("DYN_LDEPF_DIGITAL CHANNEL " + getChannelDigitalNum()+"_1_BOOLEEN") - && extRef.getDesc().endsWith("_" + getDaName() + "_1"); - } - - /** - * verify if an Extref matches the LDEPFSettingData or not. - */ - public Boolean isMatchExtRef(TExtRef extRef) { - return extRef.isSetDesc() && (isAnalogTypeMatchDesc(extRef) || isDigitalTypeMatchDesc(extRef)) - && extRef.isSetPLN() && Utils.lnClassEquals(extRef.getPLN(), getLnClass()) - && extRef.isSetPDO() && extRef.getPDO().equals(getDoName()); - } - -} 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 9d2d5e104..130d1044f 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 @@ -5,7 +5,6 @@ package org.lfenergy.compas.sct.commons.scl.ied; import lombok.NonNull; -import org.apache.commons.lang3.StringUtils; import org.lfenergy.compas.scl2007b4.model.*; import org.lfenergy.compas.sct.commons.dto.ExtRefBindingInfo; import org.lfenergy.compas.sct.commons.dto.ExtRefSignalInfo; @@ -23,6 +22,8 @@ import java.util.function.Function; import java.util.stream.Stream; +import static org.apache.commons.lang3.StringUtils.isBlank; + /** * A representation of the model object * {@link org.lfenergy.compas.scl2007b4.model.TIED IED}. @@ -169,7 +170,7 @@ public LDeviceAdapter getLDeviceAdapterByLdInst(String ldInst) throws ScdExcepti * @return optional of LDeviceAdapter object */ public Optional findLDeviceAdapterByLdInst(String ldInst) { - if (StringUtils.isBlank(ldInst)) { + if (isBlank(ldInst)) { return Optional.empty(); } return streamLDevices() @@ -230,7 +231,7 @@ public String getName() { * @return Boolean value of check result */ public boolean matches(ObjectReference objRef) { - if (StringUtils.isBlank(getName()) + if (isBlank(getName()) || !objRef.getLdName().startsWith(getName())) { return false; } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/ILDEPFSettings.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/ILDEPFSettings.java deleted file mode 100644 index 49dc223a1..000000000 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/ILDEPFSettings.java +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-FileCopyrightText: 2023 RTE FRANCE -// -// SPDX-License-Identifier: Apache-2.0 - -package org.lfenergy.compas.sct.commons.util; - -import org.lfenergy.compas.scl2007b4.model.*; -import org.lfenergy.compas.sct.commons.dto.LDEPFSettingData; -import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; - -import java.util.List; -import java.util.Optional; - - -/** - * This interface showcases the LDEPF parameters for the LDEPF LDevice. - */ -public interface ILDEPFSettings { - - /** - * Provides the matching setting for an ExtRef. - * @param extRef The ExtRef object - * @return the matching LDEPFSettingDTO for an ExtRef - */ - Optional getLDEPFSettingDataMatchExtRef(TExtRef extRef); - - /** - * Provides valid IED sources with LDEPF configuration.
    - * Example of LDEPF configuration include:
    - * 1. COMPAS-Bay verification that should be closed to the provided Flow Kind
    - * 2. COMPAS-ICDHeader verification that should match the provided parameters, see {@link Utils#isIcdHeaderMatch}
    - * 3. Active LDevice source object that should match the provided parameters, see {@link Utils#getActiveSourceLDevice}
    - * 4. Active LNode source object that should match the provided parameters, see {@link Utils#getActiveLNodeSource}
    - * 5. Valid DataTypeTemplate Object hierarchy that should match the DO/DA/BDA parameters, see {@link Utils#isValidDataTypeTemplate}
    - * @param sclRootAdapter SCL - * @param compasBay TCompasBay - * @param setting LDEPFSetting - * @return the IED sources matching the LDEPFSetting - */ - List getIedSources(SclRootAdapter sclRootAdapter, TCompasBay compasBay, LDEPFSettingData setting); - -} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/SettingLDEPFCsvHelper.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/SettingLDEPFCsvHelper.java deleted file mode 100644 index f107e6b5f..000000000 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/SettingLDEPFCsvHelper.java +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-FileCopyrightText: 2023 RTE FRANCE -// -// SPDX-License-Identifier: Apache-2.0 - -package org.lfenergy.compas.sct.commons.util; - -import lombok.Getter; -import org.lfenergy.compas.scl2007b4.model.TCompasBay; -import org.lfenergy.compas.scl2007b4.model.TCompasFlowKind; -import org.lfenergy.compas.scl2007b4.model.TExtRef; -import org.lfenergy.compas.scl2007b4.model.TIED; -import org.lfenergy.compas.sct.commons.dto.LDEPFSettingData; -import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; -import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter; - -import java.io.Reader; -import java.util.List; -import java.util.Optional; - -import static org.lfenergy.compas.sct.commons.util.Utils.*; - - -/** - * This class is an implementation example for interface ILDEPFSettings. - * It relies on a CSV file. - * - * @see CsvUtils - */ -@Getter -public class SettingLDEPFCsvHelper implements ILDEPFSettings { - - private final List settings ; - - /** - * Constructor - * - * @param reader input - */ - public SettingLDEPFCsvHelper(Reader reader) { - this.settings = CsvUtils.parseRows(reader, LDEPFSettingData.class); - } - - @Override - public Optional getLDEPFSettingDataMatchExtRef(TExtRef extRef) { - return this.settings.stream().filter(setting -> setting.isMatchExtRef(extRef)).findFirst(); - } - - @Override - public List getIedSources(SclRootAdapter sclRootAdapter, TCompasBay compasBay, LDEPFSettingData setting) { - return sclRootAdapter.streamIEDAdapters() - .filter(iedAdapter -> (setting.getBayScope().equals(TCompasFlowKind.BAY_EXTERNAL) - && iedAdapter.getPrivateCompasBay().stream().noneMatch(bay -> bay.getUUID().equals(compasBay.getUUID()))) - || (setting.getBayScope().equals(TCompasFlowKind.BAY_INTERNAL) - && iedAdapter.getPrivateCompasBay().stream().anyMatch(bay -> bay.getUUID().equals(compasBay.getUUID())))) - .filter(iedAdapter -> isIcdHeaderMatch(iedAdapter, setting)) - .filter(iedAdapter -> getActiveSourceLDevice(iedAdapter, setting) - .map(lDeviceAdapter -> getActiveLNodeSource(lDeviceAdapter, setting) - .map(lnAdapter -> isValidDataTypeTemplate(lnAdapter, setting)) - .orElse(false)) - .orElse(false)) - .map(IEDAdapter::getCurrentElem).limit(2).toList(); - } - -} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/Utils.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/Utils.java index bcbfb36ac..89e72a82b 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/Utils.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/Utils.java @@ -12,14 +12,7 @@ import org.apache.commons.lang3.StringUtils; import org.lfenergy.compas.scl2007b4.model.TExtRef; import org.lfenergy.compas.scl2007b4.model.TLLN0Enum; -import org.lfenergy.compas.scl2007b4.model.TPredefinedBasicTypeEnum; -import org.lfenergy.compas.sct.commons.dto.DaTypeName; -import org.lfenergy.compas.sct.commons.dto.DoTypeName; -import org.lfenergy.compas.sct.commons.dto.LDEPFSettingData; import org.lfenergy.compas.sct.commons.exception.ScdException; -import org.lfenergy.compas.sct.commons.scl.ied.AbstractLNAdapter; -import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter; -import org.lfenergy.compas.sct.commons.scl.ied.LDeviceAdapter; import javax.xml.namespace.QName; import java.util.*; @@ -394,73 +387,4 @@ public static boolean isExtRefFeedBySameControlBlock(TExtRef t1, TExtRef t2) { && Objects.equals(t1.getServiceType(), t2.getServiceType()); } - /** - * verify whether the IED satisfies the LDEPF settings for the private element `TCompasICDHeader` - */ - public static boolean isIcdHeaderMatch(IEDAdapter iedAdapter,LDEPFSettingData setting) { - return iedAdapter.getCompasICDHeader() - .map(compasICDHeader -> compasICDHeader.getIEDType().value().equals(setting.getIedType()) - && compasICDHeader.getIEDredundancy().value().equals(setting.getIedRedundancy()) - && compasICDHeader.getIEDSystemVersioninstance().equals(setting.getIedInstance())) - .orElse(false); - } - - /** - * provides Active LDevice for LDEPF setting's inst attribute - */ - public static Optional getActiveSourceLDevice(IEDAdapter iedAdapter, LDEPFSettingData setting) { - return iedAdapter.findLDeviceAdapterByLdInst(setting.getLdInst()) - .filter(lDeviceAdapter -> lDeviceAdapter.getLDeviceStatus() - .map(status -> status.equals(LdeviceStatus.ON.getValue())) - .orElse(false)) - .stream().findFirst(); - } - - /** - * provides Active LN Object that satisfies the LDEPF settings attributes (lnClass, lnInst, prefix) - */ - public static Optional> getActiveLNodeSource(LDeviceAdapter lDeviceAdapter, LDEPFSettingData setting) { - return lDeviceAdapter.getLNAdaptersIncludingLN0().stream() - .filter(lnAdapter -> lnAdapter.getLNClass().equals(setting.getLnClass()) - && lnAdapter.getLNInst().equals(setting.getLnInst()) - && Utils.equalsOrBothBlank(setting.getLnPrefix(), lnAdapter.getPrefix())) - .findFirst() - .filter(lnAdapter -> lnAdapter.getDaiModStValValue() - .map(status -> status.equals(LdeviceStatus.ON.getValue())) - .orElse(true)); - } - - - /** - * verify whether the LN satisfies the LDEPF settings for Data Type Template elements. - */ - public static boolean isValidDataTypeTemplate(AbstractLNAdapter lnAdapter,LDEPFSettingData setting) { - if(StringUtils.isEmpty(setting.getDoName()) || StringUtils.isBlank(setting.getDoName())){ - return true; - } - String doName = StringUtils.isEmpty(setting.getDoInst()) || StringUtils.isBlank(setting.getDoInst()) || setting.getDoInst().equals("0") - ? setting.getDoName() : setting.getDoName() + setting.getDoInst(); - DoTypeName doTypeName = new DoTypeName(doName); - if(!StringUtils.isEmpty(setting.getSdoName()) && !StringUtils.isBlank(setting.getSdoName())){ - doTypeName.getStructNames().add(setting.getSdoName()); - } - DaTypeName daTypeName = new DaTypeName(setting.getDaName()); - if(!StringUtils.isEmpty(setting.getBdaName()) && !StringUtils.isBlank(setting.getBdaName())){ - daTypeName.setBType(TPredefinedBasicTypeEnum.STRUCT); - daTypeName.getStructNames().add(setting.getBdaName()); - } - if(!StringUtils.isEmpty(setting.getSbdaName()) && !StringUtils.isBlank(setting.getSbdaName())){ - daTypeName.getStructNames().add(setting.getSbdaName()); - } - return lnAdapter.getDataTypeTemplateAdapter().getLNodeTypeAdapterById(lnAdapter.getLnType()) - .filter(lNodeTypeAdapter -> { - try { - lNodeTypeAdapter.check(doTypeName, daTypeName); - } catch (Exception ex) { - return false; - } - return true; - }).isPresent(); - } - } diff --git a/sct-commons/src/main/resources/xsd/LDEPF_Config_file_v2.xsd b/sct-commons/src/main/resources/xsd/LDEPF_Config_file_v2.xsd new file mode 100644 index 000000000..5f1af5c9f --- /dev/null +++ b/sct-commons/src/main/resources/xsd/LDEPF_Config_file_v2.xsd @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ControlBlockServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ControlBlockServiceTest.java new file mode 100644 index 000000000..f5b28b367 --- /dev/null +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ControlBlockServiceTest.java @@ -0,0 +1,520 @@ +// SPDX-FileCopyrightText: 2023 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons; + +import org.assertj.core.groups.Tuple; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +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.SclElementAdapter; +import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; +import org.lfenergy.compas.sct.commons.scl.ied.DataSetAdapter; +import org.lfenergy.compas.sct.commons.scl.ied.LDeviceAdapter; +import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter; +import org.lfenergy.compas.sct.commons.scl.ied.AbstractLNAdapter; +import org.lfenergy.compas.sct.commons.scl.ied.LNAdapter; +import org.lfenergy.compas.sct.commons.scl.ied.LN0Adapter; +import org.lfenergy.compas.sct.commons.testhelpers.FCDARecord; +import org.lfenergy.compas.sct.commons.testhelpers.MarshallerWrapper; +import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; +import org.lfenergy.compas.sct.commons.util.CsvUtils; +import org.mockito.InjectMocks; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.lfenergy.compas.scl2007b4.model.TFCEnum.ST; +import static org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.*; +import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.*; +import static org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller.assertIsMarshallable; +import static org.lfenergy.compas.sct.commons.util.ControlBlockEnum.*; +import static org.lfenergy.compas.sct.commons.util.SclConstructorHelper.newDurationInMilliSec; + +@ExtendWith(MockitoExtension.class) +class ControlBlockServiceTest { + + @InjectMocks + ControlBlockService controlBlockService; + + private Set allowedFcdas; + + private static final long GSE_APP_ID_MIN = 0x9; + private static final long SMV_APP_ID_MIN = 0x400A; + private static final String GSE_MAC_ADDRESS_PREFIX = "01-02-03-04-"; + private static final String SMV_MAC_ADDRESS_PREFIX = "0A-0B-0C-0D-"; + private static final NetworkRanges GSE_NETWORK_RANGES = new NetworkRanges(GSE_APP_ID_MIN, GSE_APP_ID_MIN + 10, GSE_MAC_ADDRESS_PREFIX + "00-FF", GSE_MAC_ADDRESS_PREFIX + "01-AA"); + private static final NetworkRanges SMV_NETWORK_RANGES = new NetworkRanges(SMV_APP_ID_MIN, SMV_APP_ID_MIN + 10, SMV_MAC_ADDRESS_PREFIX + "00-FF", SMV_MAC_ADDRESS_PREFIX + "01-AA"); + private static final RangesPerCbType RANGES_PER_CB_TYPE = new RangesPerCbType(GSE_NETWORK_RANGES, SMV_NETWORK_RANGES); + + + @BeforeEach + void init() { + allowedFcdas = new HashSet<>(CsvUtils.parseRows("FcdaCandidates.csv", StandardCharsets.UTF_8, FcdaForDataSetsCreation.class)); + } + + @Test + void analyzeDataGroups_should_success() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_limitation_bound_ied_controls_fcda.xml"); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iedAdapter1 = sclRootAdapter.getIEDAdapterByName("IED_NAME1"); + iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxAttributes(9L); + iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxGOOSE(3L); + iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxSMV(2L); + iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxReports(1L); + // When + List sclReportItems = controlBlockService.analyzeDataGroups(scd); + //Then + assertThat(sclReportItems).isEmpty(); + + } + + @Test + void analyzeDataGroups_should_return_errors_messages() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_limitation_bound_ied_controls_fcda.xml"); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME2"); + iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getConfDataSet().setMaxAttributes(1L); + iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getConfDataSet().setMax(3L); + iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getSMVsc().setMax(1L); + iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getGOOSE().setMax(2L); + iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getConfReportControl().setMax(0L); + // When + List sclReportItems = controlBlockService.analyzeDataGroups(scd); + //Then + assertThat(sclReportItems).hasSize(11) + .extracting(SclReportItem::message) + .containsExactlyInAnyOrder( + "The Client IED IED_NAME1 subscribes to too much FCDA: 9 > 8 max", + "The Client IED IED_NAME1 subscribes to too much GOOSE Control Blocks: 3 > 2 max", + "The Client IED IED_NAME1 subscribes to too much Report Control Blocks: 1 > 0 max", + "The Client IED IED_NAME1 subscribes to too much SMV Control Blocks: 2 > 1 max", + "There are too much FCDA for the DataSet dataset6 for the LDevice LD_INST21 in IED IED_NAME2: 2 > 1 max", + "There are too much FCDA for the DataSet dataset6 for the LDevice LD_INST22 in IED IED_NAME2: 2 > 1 max", + "There are too much FCDA for the DataSet dataset5 for the LDevice LD_INST22 in IED IED_NAME2: 2 > 1 max", + "There are too much DataSets for the IED IED_NAME2: 6 > 3 max", + "There are too much Report Control Blocks for the IED IED_NAME2: 1 > 0 max", + "There are too much GOOSE Control Blocks for the IED IED_NAME2: 3 > 2 max", + "There are too much SMV Control Blocks for the IED IED_NAME2: 3 > 1 max"); + } + + + @Test + void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_srcXXX_attributes_on_ExtRef() { + // Given + SCL scl = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml"); + // When + controlBlockService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl); + // Then + SclRootAdapter scdRootAdapter = new SclRootAdapter(scl); + List extRefs = scdRootAdapter + .streamIEDAdapters() + .flatMap(IEDAdapter::streamLDeviceAdapters) + .map(LDeviceAdapter::getLN0Adapter) + .map(AbstractLNAdapter::getExtRefs).flatMap(List::stream) + .collect(Collectors.toList()); + assertThat(extRefs) + .isNotEmpty() + .noneMatch(TExtRef::isSetSrcLDInst) + .noneMatch(TExtRef::isSetSrcPrefix) + .noneMatch(TExtRef::isSetSrcLNInst) + .noneMatch(TExtRef::isSetSrcCBName) + .noneMatch(TExtRef::isSetSrcLNClass); + assertIsMarshallable(scl); + } + + + private static Stream provideAllowedFcdaListEmptyOrNull() { + return Stream.of( + Arguments.of("Set of allowed FCDA is null", null), + Arguments.of("Set of allow FCDA is Empty", Collections.EMPTY_SET) + ); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("provideAllowedFcdaListEmptyOrNull") + void createDataSetAndControlBlocks_should_Throw_Exception_when_list_allowed_fcda_not_initialized(String testName, Set fcdaForDataSets) { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); + // When Then + assertThatCode(() -> controlBlockService.createDataSetAndControlBlocks(scd, fcdaForDataSets)) + .isInstanceOf(ScdException.class) + .hasMessage("Accepted FCDAs list is empty, you should initialize allowed FCDA lists with CsvHelper class before"); + } + + @Test + void createDataSetAndControlBlocks_should_create_DataSet() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); + // When + List sclReportItems = controlBlockService.createDataSetAndControlBlocks(scd, allowedFcdas); + // Then + assertThat(sclReportItems).isEmpty(); + assertThat(streamAllDataSets(scd)).hasSize(6); + + // Check dataSet names + findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_CYCI"); + findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_DQCI"); + findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_GMI"); + findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_SVI"); + findDataSet(scd, "IED_NAME3", "LD_INST31", "DS_LD_INST31_GSE"); + findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_GSI"); + + // Check one DataSet content + DataSetAdapter aDataSet = findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_GSI"); + assertThat(aDataSet.getCurrentElem().getFCDA()).hasSize(4); + assertThat(aDataSet.getCurrentElem().getFCDA().stream().map(FCDARecord::toFCDARecord)) + .containsExactly( + new FCDARecord("LD_INST21", "ANCR", "1", "", "DoName", "daNameST", ST), + new FCDARecord("LD_INST21", "ANCR", "1", "", "DoWithInst1", "daNameST", ST), + new FCDARecord("LD_INST21", "ANCR", "1", "", "DoWithInst2.subDo", "daNameST", ST), + new FCDARecord("LD_INST21", "ANCR", "1", "", "OtherDoName", "daNameST", ST) + ); + + } + + @Test + void createDataSetAndControlBlocks_should_create_ControlBlocks() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); + // When + List sclReportItems = controlBlockService.createDataSetAndControlBlocks(scd, allowedFcdas); + // Then + assertThat(sclReportItems).isEmpty(); + + // Check ControlBlock names, id and datSet + assertControlBlockExists(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_CYCI", "DS_LD_INST21_CYCI", "IED_NAME2LD_INST21/LLN0.CB_LD_INST21_CYCI", REPORT); + assertControlBlockExists(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_DQCI", "DS_LD_INST21_DQCI", "IED_NAME2LD_INST21/LLN0.CB_LD_INST21_DQCI", REPORT); + assertControlBlockExists(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_GMI", "DS_LD_INST21_GMI", "IED_NAME2LD_INST21/LLN0.CB_LD_INST21_GMI", GSE); + assertControlBlockExists(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_SVI", "DS_LD_INST21_SVI", "IED_NAME2LD_INST21/LLN0.CB_LD_INST21_SVI", SAMPLED_VALUE); + assertControlBlockExists(scd, "IED_NAME3", "LD_INST31", "CB_LD_INST31_GSE", "DS_LD_INST31_GSE", "IED_NAME3LD_INST31/LLN0.CB_LD_INST31_GSE", GSE); + assertControlBlockExists(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_GSI", "DS_LD_INST21_GSI", "IED_NAME2LD_INST21/LLN0.CB_LD_INST21_GSI", GSE); + + // Check one ControlBlock content (ReportControl with sourceDA.fc=MX) + TReportControl tReportControl = findControlBlock(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_CYCI", TReportControl.class); + assertThat(tReportControl).extracting(TReportControl::getConfRev, TReportControl::isBuffered, TReportControl::getBufTime, TReportControl::isIndexed, + TControlWithTriggerOpt::getIntgPd) + .containsExactly(1L, true, 0L, true, 60000L); + + assertThat(tReportControl.getTrgOps()) + .extracting(TTrgOps::isDchg, TTrgOps::isQchg, TTrgOps::isDupd, TTrgOps::isPeriod, TTrgOps::isGi) + .containsExactly(false, false, false, true, true); + + assertThat(tReportControl.getRptEnabled().getMax()).isEqualTo(1L); + assertThat(tReportControl.getRptEnabled().getClientLN().stream().map(ControlBlockTarget::from)) + .containsExactly( + new ControlBlockTarget("AP_NAME", "IED_NAME1", "LD_INST11", "", "LLN0", "", "")); + } + + @Test + void createDataSetAndControlBlocks_should_set_ExtRef_srcXXX_attributes() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); + // When + List sclReportItems = controlBlockService.createDataSetAndControlBlocks(scd, allowedFcdas); + // Then + assertThat(sclReportItems).isEmpty(); + + // assert all ExtRef.srcPrefix srcLNClass srcLNInst are not set + assertThat(streamAllExtRef(scd)) + .extracting(TExtRef::getSrcPrefix, TExtRef::isSetSrcLNClass, TExtRef::getSrcLNInst) + .containsOnly(Tuple.tuple(null, false, null)); + + // check some ExtRef + assertThat(findExtRef(scd, "IED_NAME1", "LD_INST11", "test bay internal")) + .extracting(TExtRef::getSrcCBName, TExtRef::getSrcLDInst) + .containsExactly("CB_LD_INST21_GSI", "LD_INST21"); + assertThat(findExtRef(scd, "IED_NAME1", "LD_INST11", "test bay external")) + .extracting(TExtRef::getSrcCBName, TExtRef::getSrcLDInst) + .containsExactly("CB_LD_INST31_GSE", "LD_INST31"); + assertThat(findExtRef(scd, "IED_NAME1", "LD_INST11", "test ServiceType is SMV, no daName and DO contains ST and MX, but only ST is FCDA candidate")) + .extracting(TExtRef::getSrcCBName, TExtRef::getSrcLDInst) + .containsExactly("CB_LD_INST21_SVI", "LD_INST21"); + assertThat(findExtRef(scd, "IED_NAME1", "LD_INST11", "test ServiceType is Report_daReportMX_1")) + .extracting(TExtRef::getSrcCBName, TExtRef::getSrcLDInst) + .containsExactly("CB_LD_INST21_CYCI", "LD_INST21"); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("provideAllowedFcdaListEmptyOrNull") + void createDataSetAndControlBlocks_with_targetIedName_should_Throw_Exception_when_list_allowed_fcda_not_initialized(String testName, Set fcdaForDataSets) { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); + // When Then + assertThatCode(() -> controlBlockService.createDataSetAndControlBlocks(scd, "IED_NAME1", fcdaForDataSets)) + .isInstanceOf(ScdException.class) + .hasMessage("Accepted FCDAs list is empty, you should initialize allowed FCDA lists with CsvHelper class before"); + } + + @Test + void createDataSetAndControlBlocks_when_targetIedName_is_provided_should_succeed() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); + // When + List sclReportItems = controlBlockService.createDataSetAndControlBlocks(scd, "IED_NAME1", allowedFcdas); + // Then + assertThat(sclReportItems).isEmpty(); + assertThat(streamAllDataSets(scd)).hasSize(6); + List ln0s = streamAllLn0Adapters(scd).map(SclElementAdapter::getCurrentElem).toList(); + assertThat(ln0s).flatMap(TLN0::getGSEControl).hasSize(3); + assertThat(ln0s).flatMap(TLN0::getSampledValueControl).hasSize(1); + assertThat(ln0s).flatMap(TLN0::getReportControl).hasSize(2); + MarshallerWrapper.assertValidateXmlSchema(scd); + } + + @Test + void createDataSetAndControlBlocks_when_targetIedName_is_provided_and_no_ext_ref_should_do_nothing() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); + // When + List sclReportItems = controlBlockService.createDataSetAndControlBlocks(scd, "IED_NAME2", allowedFcdas); + // Then + assertThat(sclReportItems).isEmpty(); + assertThat(streamAllDataSets(scd)).isEmpty(); + } + + @Test + void createDataSetAndControlBlocks_when_targetIedName_is_not_found_should_throw_exception() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); + // When & Then + assertThatThrownBy(() -> controlBlockService.createDataSetAndControlBlocks(scd, "non_existing_IED_name", allowedFcdas)) + .isInstanceOf(ScdException.class) + .hasMessage("IED.name 'non_existing_IED_name' not found in SCD"); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("provideAllowedFcdaListEmptyOrNull") + void createDataSetAndControlBlocks_with_targetIedName_and_targetLDeviceInst_should_Throw_Exception_when_list_allowed_fcda_not_initialized(String testName, Set fcdaForDataSets) { + // Given + SCL scd = new SCL(); + // When Then + assertThatCode(() -> controlBlockService.createDataSetAndControlBlocks(scd, "IED_NAME1", "LD_INST11", fcdaForDataSets)) + .isInstanceOf(ScdException.class) + .hasMessage("Accepted FCDAs list is empty, you should initialize allowed FCDA lists with CsvHelper class before"); + } + + @Test + void createDataSetAndControlBlocks_when_targetIedName_and_targetLDeviceInst_is_provided_should_succeed() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); + // When + List sclReportItems = controlBlockService.createDataSetAndControlBlocks(scd, "IED_NAME1", "LD_INST11", allowedFcdas); + // Then + assertThat(sclReportItems).isEmpty(); + } + + @Test + void createDataSetAndControlBlocks_when_targetIedName_is_not_found_and_targetLDeviceInst_is_provided_should_throw_exception() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); + // When & Then + assertThatThrownBy(() -> controlBlockService.createDataSetAndControlBlocks(scd, "non_existing_IED_name", "LD_INST11", allowedFcdas)) + .isInstanceOf(ScdException.class) + .hasMessage("IED.name 'non_existing_IED_name' not found in SCD"); + } + + @Test + void createDataSetAndControlBlocks_when_targetIedName_and_targetLDeviceInst_is_not_found_should_throw_exception() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); + // When & Then + assertThatThrownBy(() -> controlBlockService.createDataSetAndControlBlocks(scd, "IED_NAME1", "non_existing_LDevice_inst", allowedFcdas)) + .isInstanceOf(ScdException.class) + .hasMessage("LDevice.inst 'non_existing_LDevice_inst' not found in IED 'IED_NAME1'"); + } + + @Test + void createDataSetAndControlBlocks_when_targetLDeviceInst_is_provided_without_targetIedName_should_throw_exception() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); + // When & Then + assertThatThrownBy(() -> controlBlockService.createDataSetAndControlBlocks(scd, null, "LD_INST11", allowedFcdas)) + .isInstanceOf(ScdException.class) + .hasMessage("IED.name parameter is missing"); + } + + + + @Test + void updateAllSourceDataSetsAndControlBlocks_should_sort_FCDA_inside_DataSet_and_avoid_duplicates() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success_test_fcda_sort.xml"); + // When + List sclReportItems = controlBlockService.createDataSetAndControlBlocks(scd, allowedFcdas); + // Then + assertThat(sclReportItems).isEmpty(); + DataSetAdapter dataSetAdapter = findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_GSI"); + assertThat(dataSetAdapter.getCurrentElem().getFCDA()) + .map(TFCDA::getLnInst, TFCDA::getDoName) + .containsExactly( + Tuple.tuple("1", "FirstDo"), + Tuple.tuple("1", "SecondDo"), + Tuple.tuple("1", "ThirdDo"), + Tuple.tuple("02", "FirstDo") + ); + } + + @Test + void configureNetworkForAllControlBlocks_should_create_GSE_and_SMV_elements() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml"); + + TDurationInMilliSec minTime = newDurationInMilliSec(10); + TDurationInMilliSec maxTime = newDurationInMilliSec(2000); + ControlBlockNetworkSettings controlBlockNetworkSettings = controlBlockAdapter -> new SettingsOrError(new Settings(0x1D6, (byte) 4, minTime, maxTime), null); + + // When + List sclReportItems = controlBlockService.configureNetworkForAllControlBlocks(scd, controlBlockNetworkSettings, RANGES_PER_CB_TYPE); + // Then + assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); + TConnectedAP connectedAP = new SclRootAdapter(scd).findConnectedApAdapter("IED_NAME2", "AP_NAME").get().getCurrentElem(); + TGSE gse = connectedAP.getGSE().stream() + .filter(tgse -> "CB_LD_INST21_GSI".equals(tgse.getCbName())) + .findFirst().get(); + assertThat(gse.getLdInst()).isEqualTo("LD_INST21"); + assertThat(gse.getMinTime()).extracting(TDurationInMilliSec::getUnit, TDurationInMilliSec::getMultiplier, TDurationInMilliSec::getValue) + .containsExactly("s", "m", new BigDecimal("10")); + assertThat(gse.getMaxTime()).extracting(TDurationInMilliSec::getUnit, TDurationInMilliSec::getMultiplier, TDurationInMilliSec::getValue) + .containsExactly("s", "m", new BigDecimal("2000")); + assertThat(gse.getAddress().getP()).extracting(TP::getType, TP::getValue) + .containsExactlyInAnyOrder( + Tuple.tuple("VLAN-PRIORITY", "4"), + Tuple.tuple("APPID", "0009"), + Tuple.tuple("MAC-Address", "01-02-03-04-00-FF"), + Tuple.tuple("VLAN-ID", "1D6") + ); + TSMV smv = connectedAP.getSMV().stream() + .filter(tsmv -> "CB_LD_INST21_SVI".equals(tsmv.getCbName())) + .findFirst().get(); + assertThat(smv.getLdInst()).isEqualTo("LD_INST21"); + assertThat(smv.getAddress().getP()).extracting(TP::getType, TP::getValue) + .containsExactlyInAnyOrder( + Tuple.tuple("VLAN-PRIORITY", "4"), + Tuple.tuple("APPID", "400A"), + Tuple.tuple("MAC-Address", "0A-0B-0C-0D-00-FF"), + Tuple.tuple("VLAN-ID", "1D6") + ); + MarshallerWrapper.assertValidateXmlSchema(scd); + } + + @Test + void configureNetworkForAllControlBlocks_should_create_GSE_with_incremental_appid_and_mac_addresses() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml"); + + TDurationInMilliSec minTime = newDurationInMilliSec(10); + TDurationInMilliSec maxTime = newDurationInMilliSec(2000); + ControlBlockNetworkSettings controlBlockNetworkSettings = controlBlockAdapter -> new SettingsOrError(new Settings(0x1D6, (byte) 4, minTime, maxTime), null); + // When + List sclReportItems = controlBlockService.configureNetworkForAllControlBlocks(scd, controlBlockNetworkSettings, RANGES_PER_CB_TYPE); + // Then + assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); + assertThat(streamAllConnectedApGseP(scd, "APPID")) + .containsExactlyInAnyOrder("0009", "000A", "000B"); + assertThat(streamAllConnectedApGseP(scd, "MAC-Address")) + .containsExactlyInAnyOrder("01-02-03-04-00-FF", "01-02-03-04-01-00", "01-02-03-04-01-01"); + } + + @ParameterizedTest + @MethodSource("provideConfigureNetworkForAllControlBlocksErrors") + void configureNetworkForAllControlBlocks_should_fail_when_no_settings_for_this_controlBlock(ControlBlockNetworkSettings controlBlockNetworkSettings, + RangesPerCbType rangesPerCbType, + String expectedMessage) { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml"); + // When + List sclReportItems = controlBlockService.configureNetworkForAllControlBlocks(scd, controlBlockNetworkSettings, rangesPerCbType); + // Then + assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isFalse(); + assertThat(sclReportItems) + .extracting(SclReportItem::message, SclReportItem::xpath) + .contains(Tuple.tuple(expectedMessage, + "/SCL/IED[@name=\"IED_NAME2\"]/AccessPoint/Server/LDevice[@inst=\"LD_INST21\"]/LN0/GSEControl[@name=\"CB_LD_INST21_GMI\"]")); + } + + @Test + void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_controlBlocks_and_Dataset_on_ln0() { + // Given + SCL scl = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml"); + // When + controlBlockService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl); + // Then + SclRootAdapter scdRootAdapter = new SclRootAdapter(scl); + List lDevices = scdRootAdapter.streamIEDAdapters().flatMap(IEDAdapter::streamLDeviceAdapters).toList(); + List ln0s = lDevices.stream().map(LDeviceAdapter::getLN0Adapter).map(LN0Adapter::getCurrentElem).toList(); + assertThat(ln0s) + .isNotEmpty() + .noneMatch(TAnyLN::isSetDataSet) + .noneMatch(TAnyLN::isSetLogControl) + .noneMatch(TAnyLN::isSetReportControl) + .noneMatch(LN0::isSetGSEControl) + .noneMatch(LN0::isSetSampledValueControl); + assertIsMarshallable(scl); + } + + @Test + void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_controlBlocks_and_Dataset_on_ln() { + // Given + SCL scl = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml"); + // When + controlBlockService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl); + // Then + SclRootAdapter scdRootAdapter = new SclRootAdapter(scl); + List lns = scdRootAdapter.streamIEDAdapters() + .flatMap(IEDAdapter::streamLDeviceAdapters) + .map(LDeviceAdapter::getLNAdapters).flatMap(List::stream) + .map(LNAdapter::getCurrentElem).collect(Collectors.toList()); + assertThat(lns) + .isNotEmpty() + .noneMatch(TAnyLN::isSetDataSet) + .noneMatch(TAnyLN::isSetLogControl) + .noneMatch(TAnyLN::isSetReportControl); + assertIsMarshallable(scl); + } + + public static Stream provideConfigureNetworkForAllControlBlocksErrors() { + Settings settingsWithNullVlanId = new Settings(null, (byte) 1, newDurationInMilliSec(1), newDurationInMilliSec(2)); + Settings settings = new Settings(1, (byte) 1, newDurationInMilliSec(1), newDurationInMilliSec(2)); + return Stream.of( + Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(null, null), + RANGES_PER_CB_TYPE, + "Cannot configure network for this ControlBlock because no settings was provided"), + Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(null, "Custom error message"), + RANGES_PER_CB_TYPE, + "Cannot configure network for this ControlBlock because: Custom error message"), + Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(settingsWithNullVlanId, null), + RANGES_PER_CB_TYPE, + "Cannot configure network for this ControlBlock because no Vlan Id was provided in the settings"), + Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(settings, null), + new RangesPerCbType( + new NetworkRanges(GSE_APP_ID_MIN, GSE_APP_ID_MIN, GSE_MAC_ADDRESS_PREFIX + "00-FF", GSE_MAC_ADDRESS_PREFIX + "01-AA"), + SMV_NETWORK_RANGES), + "Cannot configure network for this ControlBlock because range of appId is exhausted"), + Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(settings, null), + new RangesPerCbType( + new NetworkRanges(GSE_APP_ID_MIN, GSE_APP_ID_MIN + 10, GSE_MAC_ADDRESS_PREFIX + "00-FF", GSE_MAC_ADDRESS_PREFIX + "00-FF"), + SMV_NETWORK_RANGES), + "Cannot configure network for this ControlBlock because range of MAC Address is exhausted") + ); + } + +} diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ExtRefServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ExtRefServiceTest.java index 93ed987f1..04492391a 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ExtRefServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ExtRefServiceTest.java @@ -5,8 +5,6 @@ package org.lfenergy.compas.sct.commons; import org.assertj.core.api.Assertions; -import org.assertj.core.groups.Tuple; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -16,37 +14,22 @@ 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.SclElementAdapter; +import org.lfenergy.compas.sct.commons.model.epf.*; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; import org.lfenergy.compas.sct.commons.scl.ied.AbstractLNAdapter; -import org.lfenergy.compas.sct.commons.scl.ied.DataSetAdapter; import org.lfenergy.compas.sct.commons.scl.ied.LDeviceAdapter; -import org.lfenergy.compas.sct.commons.testhelpers.FCDARecord; -import org.lfenergy.compas.sct.commons.testhelpers.MarshallerWrapper; import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; -import org.lfenergy.compas.sct.commons.util.CsvUtils; -import org.lfenergy.compas.sct.commons.util.ILDEPFSettings; import org.lfenergy.compas.sct.commons.util.PrivateUtils; -import org.lfenergy.compas.sct.commons.util.SettingLDEPFCsvHelper; import org.mockito.InjectMocks; import org.mockito.junit.jupiter.MockitoExtension; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.lfenergy.compas.scl2007b4.model.TFCEnum.ST; -import static org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.*; import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.*; import static org.lfenergy.compas.sct.commons.util.CommonConstants.*; -import static org.lfenergy.compas.sct.commons.util.ControlBlockEnum.*; -import static org.lfenergy.compas.sct.commons.util.SclConstructorHelper.newDurationInMilliSec; @ExtendWith(MockitoExtension.class) class ExtRefServiceTest { @@ -54,21 +37,6 @@ class ExtRefServiceTest { @InjectMocks ExtRefService extRefService; - private Set allowedFcdas; - - @BeforeEach - void init() { - allowedFcdas = new HashSet<>(CsvUtils.parseRows("FcdaCandidates.csv", StandardCharsets.UTF_8, FcdaForDataSetsCreation.class)); - } - - private static final long GSE_APP_ID_MIN = 0x9; - private static final long SMV_APP_ID_MIN = 0x400A; - private static final String GSE_MAC_ADDRESS_PREFIX = "01-02-03-04-"; - private static final String SMV_MAC_ADDRESS_PREFIX = "0A-0B-0C-0D-"; - private static final NetworkRanges GSE_NETWORK_RANGES = new NetworkRanges(GSE_APP_ID_MIN, GSE_APP_ID_MIN + 10, GSE_MAC_ADDRESS_PREFIX + "00-FF", GSE_MAC_ADDRESS_PREFIX + "01-AA"); - private static final NetworkRanges SMV_NETWORK_RANGES = new NetworkRanges(SMV_APP_ID_MIN, SMV_APP_ID_MIN + 10, SMV_MAC_ADDRESS_PREFIX + "00-FF", SMV_MAC_ADDRESS_PREFIX + "01-AA"); - private static final RangesPerCbType RANGES_PER_CB_TYPE = new RangesPerCbType(GSE_NETWORK_RANGES, SMV_NETWORK_RANGES); - @Test void updateAllExtRefIedNames_should_update_iedName_and_ExtRefIedName() { // Given : An ExtRef with a matching compas:Flow @@ -221,216 +189,6 @@ void updateAllExtRefIedNames_when_FlowStatus_INACTIVE_should_remove_binding() { assertExtRefIsNotBound(extRef); } - private static Stream provideAllowedFcdaListEmptyOrNull() { - return Stream.of( - Arguments.of("Set of allowed FCDA is null", null), - Arguments.of("Set of allow FCDA is Empty", Collections.EMPTY_SET) - ); - } - - @ParameterizedTest(name = "{0}") - @MethodSource("provideAllowedFcdaListEmptyOrNull") - void createDataSetAndControlBlocks_should_Throw_Exception_when_list_allowed_fcda_not_initialized(String testName, Set fcdaForDataSets) { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); - // When Then - assertThatCode(() -> extRefService.createDataSetAndControlBlocks(scd, fcdaForDataSets)) - .isInstanceOf(ScdException.class) - .hasMessage("Accepted FCDAs list is empty, you should initialize allowed FCDA lists with CsvHelper class before"); - } - - @Test - void createDataSetAndControlBlocks_should_create_DataSet() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); - // When - List sclReportItems = extRefService.createDataSetAndControlBlocks(scd, allowedFcdas); - // Then - assertThat(sclReportItems).isEmpty(); - assertThat(streamAllDataSets(scd)).hasSize(6); - - // Check dataSet names - findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_CYCI"); - findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_DQCI"); - findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_GMI"); - findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_SVI"); - findDataSet(scd, "IED_NAME3", "LD_INST31", "DS_LD_INST31_GSE"); - findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_GSI"); - - // Check one DataSet content - DataSetAdapter aDataSet = findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_GSI"); - assertThat(aDataSet.getCurrentElem().getFCDA()).hasSize(4); - assertThat(aDataSet.getCurrentElem().getFCDA().stream().map(FCDARecord::toFCDARecord)) - .containsExactly( - new FCDARecord("LD_INST21", "ANCR", "1", "", "DoName", "daNameST", ST), - new FCDARecord("LD_INST21", "ANCR", "1", "", "DoWithInst1", "daNameST", ST), - new FCDARecord("LD_INST21", "ANCR", "1", "", "DoWithInst2.subDo", "daNameST", ST), - new FCDARecord("LD_INST21", "ANCR", "1", "", "OtherDoName", "daNameST", ST) - ); - - } - - @Test - void createDataSetAndControlBlocks_should_create_ControlBlocks() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); - // When - List sclReportItems = extRefService.createDataSetAndControlBlocks(scd, allowedFcdas); - // Then - assertThat(sclReportItems).isEmpty(); - - // Check ControlBlock names, id and datSet - assertControlBlockExists(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_CYCI", "DS_LD_INST21_CYCI", "IED_NAME2LD_INST21/LLN0.CB_LD_INST21_CYCI", REPORT); - assertControlBlockExists(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_DQCI", "DS_LD_INST21_DQCI", "IED_NAME2LD_INST21/LLN0.CB_LD_INST21_DQCI", REPORT); - assertControlBlockExists(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_GMI", "DS_LD_INST21_GMI", "IED_NAME2LD_INST21/LLN0.CB_LD_INST21_GMI", GSE); - assertControlBlockExists(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_SVI", "DS_LD_INST21_SVI", "IED_NAME2LD_INST21/LLN0.CB_LD_INST21_SVI", SAMPLED_VALUE); - assertControlBlockExists(scd, "IED_NAME3", "LD_INST31", "CB_LD_INST31_GSE", "DS_LD_INST31_GSE", "IED_NAME3LD_INST31/LLN0.CB_LD_INST31_GSE", GSE); - assertControlBlockExists(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_GSI", "DS_LD_INST21_GSI", "IED_NAME2LD_INST21/LLN0.CB_LD_INST21_GSI", GSE); - - // Check one ControlBlock content (ReportControl with sourceDA.fc=MX) - TReportControl tReportControl = findControlBlock(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_CYCI", TReportControl.class); - assertThat(tReportControl).extracting(TReportControl::getConfRev, TReportControl::isBuffered, TReportControl::getBufTime, TReportControl::isIndexed, - TControlWithTriggerOpt::getIntgPd) - .containsExactly(1L, true, 0L, true, 60000L); - - assertThat(tReportControl.getTrgOps()) - .extracting(TTrgOps::isDchg, TTrgOps::isQchg, TTrgOps::isDupd, TTrgOps::isPeriod, TTrgOps::isGi) - .containsExactly(false, false, false, true, true); - - assertThat(tReportControl.getRptEnabled().getMax()).isEqualTo(1L); - assertThat(tReportControl.getRptEnabled().getClientLN().stream().map(ControlBlockTarget::from)) - .containsExactly( - new ControlBlockTarget("AP_NAME", "IED_NAME1", "LD_INST11", "", "LLN0", "", "")); - } - - @Test - void createDataSetAndControlBlocks_should_set_ExtRef_srcXXX_attributes() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); - // When - List sclReportItems = extRefService.createDataSetAndControlBlocks(scd, allowedFcdas); - // Then - assertThat(sclReportItems).isEmpty(); - - // assert all ExtRef.srcPrefix srcLNClass srcLNInst are not set - assertThat(streamAllExtRef(scd)) - .extracting(TExtRef::getSrcPrefix, TExtRef::isSetSrcLNClass, TExtRef::getSrcLNInst) - .containsOnly(Tuple.tuple(null, false, null)); - - // check some ExtRef - assertThat(findExtRef(scd, "IED_NAME1", "LD_INST11", "test bay internal")) - .extracting(TExtRef::getSrcCBName, TExtRef::getSrcLDInst) - .containsExactly("CB_LD_INST21_GSI", "LD_INST21"); - assertThat(findExtRef(scd, "IED_NAME1", "LD_INST11", "test bay external")) - .extracting(TExtRef::getSrcCBName, TExtRef::getSrcLDInst) - .containsExactly("CB_LD_INST31_GSE", "LD_INST31"); - assertThat(findExtRef(scd, "IED_NAME1", "LD_INST11", "test ServiceType is SMV, no daName and DO contains ST and MX, but only ST is FCDA candidate")) - .extracting(TExtRef::getSrcCBName, TExtRef::getSrcLDInst) - .containsExactly("CB_LD_INST21_SVI", "LD_INST21"); - assertThat(findExtRef(scd, "IED_NAME1", "LD_INST11", "test ServiceType is Report_daReportMX_1")) - .extracting(TExtRef::getSrcCBName, TExtRef::getSrcLDInst) - .containsExactly("CB_LD_INST21_CYCI", "LD_INST21"); - } - - @ParameterizedTest(name = "{0}") - @MethodSource("provideAllowedFcdaListEmptyOrNull") - void createDataSetAndControlBlocks_with_targetIedName_should_Throw_Exception_when_list_allowed_fcda_not_initialized(String testName, Set fcdaForDataSets) { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); - // When Then - assertThatCode(() -> extRefService.createDataSetAndControlBlocks(scd, "IED_NAME1", fcdaForDataSets)) - .isInstanceOf(ScdException.class) - .hasMessage("Accepted FCDAs list is empty, you should initialize allowed FCDA lists with CsvHelper class before"); - } - - @Test - void createDataSetAndControlBlocks_when_targetIedName_is_provided_should_succeed() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); - // When - List sclReportItems = extRefService.createDataSetAndControlBlocks(scd, "IED_NAME1", allowedFcdas); - // Then - assertThat(sclReportItems).isEmpty(); - assertThat(streamAllDataSets(scd)).hasSize(6); - List ln0s = streamAllLn0Adapters(scd).map(SclElementAdapter::getCurrentElem).toList(); - assertThat(ln0s).flatMap(TLN0::getGSEControl).hasSize(3); - assertThat(ln0s).flatMap(TLN0::getSampledValueControl).hasSize(1); - assertThat(ln0s).flatMap(TLN0::getReportControl).hasSize(2); - MarshallerWrapper.assertValidateXmlSchema(scd); - } - - @Test - void createDataSetAndControlBlocks_when_targetIedName_is_provided_and_no_ext_ref_should_do_nothing() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); - // When - List sclReportItems = extRefService.createDataSetAndControlBlocks(scd, "IED_NAME2", allowedFcdas); - // Then - assertThat(sclReportItems).isEmpty(); - assertThat(streamAllDataSets(scd)).isEmpty(); - } - - @Test - void createDataSetAndControlBlocks_when_targetIedName_is_not_found_should_throw_exception() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); - // When & Then - assertThatThrownBy(() -> extRefService.createDataSetAndControlBlocks(scd, "non_existing_IED_name", allowedFcdas)) - .isInstanceOf(ScdException.class) - .hasMessage("IED.name 'non_existing_IED_name' not found in SCD"); - } - - @ParameterizedTest(name = "{0}") - @MethodSource("provideAllowedFcdaListEmptyOrNull") - void createDataSetAndControlBlocks_with_targetIedName_and_targetLDeviceInst_should_Throw_Exception_when_list_allowed_fcda_not_initialized(String testName, Set fcdaForDataSets) { - // Given - SCL scd = new SCL(); - // When Then - assertThatCode(() -> extRefService.createDataSetAndControlBlocks(scd, "IED_NAME1", "LD_INST11", fcdaForDataSets)) - .isInstanceOf(ScdException.class) - .hasMessage("Accepted FCDAs list is empty, you should initialize allowed FCDA lists with CsvHelper class before"); - } - - @Test - void createDataSetAndControlBlocks_when_targetIedName_and_targetLDeviceInst_is_provided_should_succeed() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); - // When - List sclReportItems = extRefService.createDataSetAndControlBlocks(scd, "IED_NAME1", "LD_INST11", allowedFcdas); - // Then - assertThat(sclReportItems).isEmpty(); - } - - @Test - void createDataSetAndControlBlocks_when_targetIedName_is_not_found_and_targetLDeviceInst_is_provided_should_throw_exception() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); - // When & Then - assertThatThrownBy(() -> extRefService.createDataSetAndControlBlocks(scd, "non_existing_IED_name", "LD_INST11", allowedFcdas)) - .isInstanceOf(ScdException.class) - .hasMessage("IED.name 'non_existing_IED_name' not found in SCD"); - } - - @Test - void createDataSetAndControlBlocks_when_targetIedName_and_targetLDeviceInst_is_not_found_should_throw_exception() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); - // When & Then - assertThatThrownBy(() -> extRefService.createDataSetAndControlBlocks(scd, "IED_NAME1", "non_existing_LDevice_inst", allowedFcdas)) - .isInstanceOf(ScdException.class) - .hasMessage("LDevice.inst 'non_existing_LDevice_inst' not found in IED 'IED_NAME1'"); - } - - @Test - void createDataSetAndControlBlocks_when_targetLDeviceInst_is_provided_without_targetIedName_should_throw_exception() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml"); - // When & Then - assertThatThrownBy(() -> extRefService.createDataSetAndControlBlocks(scd, null, "LD_INST11", allowedFcdas)) - .isInstanceOf(ScdException.class) - .hasMessage("IED.name parameter is missing"); - } - private void assertExtRefIsNotBound(TExtRef extRef) { assertThat(extRef.isSetIedName()).isFalse(); assertThat(extRef.isSetLdInst()).isFalse(); @@ -447,129 +205,6 @@ private void assertExtRefIsNotBound(TExtRef extRef) { assertThat(extRef.isSetSrcCBName()).isFalse(); } - @Test - void updateAllSourceDataSetsAndControlBlocks_should_sort_FCDA_inside_DataSet_and_avoid_duplicates() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success_test_fcda_sort.xml"); - // When - List sclReportItems = extRefService.createDataSetAndControlBlocks(scd, allowedFcdas); - // Then - assertThat(sclReportItems).isEmpty(); - DataSetAdapter dataSetAdapter = findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_GSI"); - assertThat(dataSetAdapter.getCurrentElem().getFCDA()) - .map(TFCDA::getLnInst, TFCDA::getDoName) - .containsExactly( - Tuple.tuple("1", "FirstDo"), - Tuple.tuple("1", "SecondDo"), - Tuple.tuple("1", "ThirdDo"), - Tuple.tuple("02", "FirstDo") - ); - } - - @Test - void configureNetworkForAllControlBlocks_should_create_GSE_and_SMV_elements() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml"); - - TDurationInMilliSec minTime = newDurationInMilliSec(10); - TDurationInMilliSec maxTime = newDurationInMilliSec(2000); - ControlBlockNetworkSettings controlBlockNetworkSettings = controlBlockAdapter -> new SettingsOrError(new Settings(0x1D6, (byte) 4, minTime, maxTime), null); - - // When - List sclReportItems = extRefService.configureNetworkForAllControlBlocks(scd, controlBlockNetworkSettings, RANGES_PER_CB_TYPE); - // Then - assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); - TConnectedAP connectedAP = new SclRootAdapter(scd).findConnectedApAdapter("IED_NAME2", "AP_NAME").get().getCurrentElem(); - TGSE gse = connectedAP.getGSE().stream() - .filter(tgse -> "CB_LD_INST21_GSI".equals(tgse.getCbName())) - .findFirst().get(); - assertThat(gse.getLdInst()).isEqualTo("LD_INST21"); - assertThat(gse.getMinTime()).extracting(TDurationInMilliSec::getUnit, TDurationInMilliSec::getMultiplier, TDurationInMilliSec::getValue) - .containsExactly("s", "m", new BigDecimal("10")); - assertThat(gse.getMaxTime()).extracting(TDurationInMilliSec::getUnit, TDurationInMilliSec::getMultiplier, TDurationInMilliSec::getValue) - .containsExactly("s", "m", new BigDecimal("2000")); - assertThat(gse.getAddress().getP()).extracting(TP::getType, TP::getValue) - .containsExactlyInAnyOrder( - Tuple.tuple("VLAN-PRIORITY", "4"), - Tuple.tuple("APPID", "0009"), - Tuple.tuple("MAC-Address", "01-02-03-04-00-FF"), - Tuple.tuple("VLAN-ID", "1D6") - ); - TSMV smv = connectedAP.getSMV().stream() - .filter(tsmv -> "CB_LD_INST21_SVI".equals(tsmv.getCbName())) - .findFirst().get(); - assertThat(smv.getLdInst()).isEqualTo("LD_INST21"); - assertThat(smv.getAddress().getP()).extracting(TP::getType, TP::getValue) - .containsExactlyInAnyOrder( - Tuple.tuple("VLAN-PRIORITY", "4"), - Tuple.tuple("APPID", "400A"), - Tuple.tuple("MAC-Address", "0A-0B-0C-0D-00-FF"), - Tuple.tuple("VLAN-ID", "1D6") - ); - MarshallerWrapper.assertValidateXmlSchema(scd); - } - - @Test - void configureNetworkForAllControlBlocks_should_create_GSE_with_incremental_appid_and_mac_addresses() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml"); - - TDurationInMilliSec minTime = newDurationInMilliSec(10); - TDurationInMilliSec maxTime = newDurationInMilliSec(2000); - ControlBlockNetworkSettings controlBlockNetworkSettings = controlBlockAdapter -> new SettingsOrError(new Settings(0x1D6, (byte) 4, minTime, maxTime), null); - // When - List sclReportItems = extRefService.configureNetworkForAllControlBlocks(scd, controlBlockNetworkSettings, RANGES_PER_CB_TYPE); - // Then - assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); - assertThat(streamAllConnectedApGseP(scd, "APPID")) - .containsExactlyInAnyOrder("0009", "000A", "000B"); - assertThat(streamAllConnectedApGseP(scd, "MAC-Address")) - .containsExactlyInAnyOrder("01-02-03-04-00-FF", "01-02-03-04-01-00", "01-02-03-04-01-01"); - } - - @ParameterizedTest - @MethodSource("provideConfigureNetworkForAllControlBlocksErrors") - void configureNetworkForAllControlBlocks_should_fail_when_no_settings_for_this_controlBlock(ControlBlockNetworkSettings controlBlockNetworkSettings, - RangesPerCbType rangesPerCbType, - String expectedMessage) { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml"); - // When - List sclReportItems = extRefService.configureNetworkForAllControlBlocks(scd, controlBlockNetworkSettings, rangesPerCbType); - // Then - assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isFalse(); - assertThat(sclReportItems) - .extracting(SclReportItem::message, SclReportItem::xpath) - .contains(Tuple.tuple(expectedMessage, - "/SCL/IED[@name=\"IED_NAME2\"]/AccessPoint/Server/LDevice[@inst=\"LD_INST21\"]/LN0/GSEControl[@name=\"CB_LD_INST21_GMI\"]")); - } - - public static Stream provideConfigureNetworkForAllControlBlocksErrors() { - Settings settingsWithNullVlanId = new Settings(null, (byte) 1, newDurationInMilliSec(1), newDurationInMilliSec(2)); - Settings settings = new Settings(1, (byte) 1, newDurationInMilliSec(1), newDurationInMilliSec(2)); - return Stream.of( - Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(null, null), - RANGES_PER_CB_TYPE, - "Cannot configure network for this ControlBlock because no settings was provided"), - Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(null, "Custom error message"), - RANGES_PER_CB_TYPE, - "Cannot configure network for this ControlBlock because: Custom error message"), - Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(settingsWithNullVlanId, null), - RANGES_PER_CB_TYPE, - "Cannot configure network for this ControlBlock because no Vlan Id was provided in the settings"), - Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(settings, null), - new RangesPerCbType( - new NetworkRanges(GSE_APP_ID_MIN, GSE_APP_ID_MIN, GSE_MAC_ADDRESS_PREFIX + "00-FF", GSE_MAC_ADDRESS_PREFIX + "01-AA"), - SMV_NETWORK_RANGES), - "Cannot configure network for this ControlBlock because range of appId is exhausted"), - Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(settings, null), - new RangesPerCbType( - new NetworkRanges(GSE_APP_ID_MIN, GSE_APP_ID_MIN + 10, GSE_MAC_ADDRESS_PREFIX + "00-FF", GSE_MAC_ADDRESS_PREFIX + "00-FF"), - SMV_NETWORK_RANGES), - "Cannot configure network for this ControlBlock because range of MAC Address is exhausted") - ); - } - @Test void filterDuplicatedExtRefs_should_remove_duplicated_extrefs() { // Given @@ -607,28 +242,31 @@ void filterDuplicatedExtRefs_should_not_remove_not_duplicated_extrefs() { @Test void manageBindingForLDEPF_whenFlowKindIsInternalAndAllExtRefInSameBay_should_return_noReportAndExtRefUpdateSuccessfully() { - //Given - String fileName = "LDEPF_Setting_file.csv"; - InputStream inputStream = Objects.requireNonNull(CsvUtils.class.getClassLoader().getResourceAsStream(fileName), "Resource not found: " + fileName); - InputStreamReader reader = new InputStreamReader(inputStream); - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); + //Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_iedSources_in_different_bay.xml"); - - LDEPFSettingData expectedSettingData = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_INTERNAL) - .channelDigitalNum(1) - .channelAnalogNum(null) - .channelShortLabel("MR.PX1") - .channelLevMod("Positive or Rising") - .channelLevModQ("Other") - .iedType("BCU").iedRedundancy("None").iedInstance(BigInteger.valueOf(1)) - .ldInst("LDPX") - .lnClass("PTRC").lnInst("0").lnPrefix(null) - .doName("Str").doInst("0").daName("general") - .build(); - + TChannel channel = new TChannel(); + channel.setBayScope(TCBscopeType.BAY_INTERNAL); + channel.setChannelType(TChannelType.DIGITAL); + channel.setChannelNum("1"); + channel.setChannelShortLabel("MR.PX1"); + channel.setChannelLevMod(TChannelLevMod.POSITIVE_OR_RISING); + channel.setChannelLevModQ(TChannelLevMod.OTHER); + channel.setIEDType("BCU"); + channel.setIEDRedundancy(TIEDredundancy.NONE); + channel.setIEDSystemVersionInstance("1"); + channel.setLDInst("LDPX"); + channel.setLNClass("PTRC"); + channel.setLNInst("0"); + channel.setDOName("Str"); + channel.setDOInst("0"); + channel.setDAName("general"); + + EPF epf = new EPF(); + Channels channels = new Channels(); + channels.getChannel().add(channel); + epf.setChannels(channels); // When - List sclReportItems = extRefService.manageBindingForLDEPF(scd, settingLDEPFCsvHelper); + List sclReportItems = extRefService.manageBindingForLDEPF(scd, epf); // Then assertThat(sclReportItems).isEmpty(); TExtRef extRef1 = findExtRef(scd, "IED_NAME1", "LDEPF", "DYN_LDEPF_DIGITAL CHANNEL 1_1_BOOLEEN_1_general_1"); @@ -638,9 +276,9 @@ void manageBindingForLDEPF_whenFlowKindIsInternalAndAllExtRefInSameBay_should_re TExtRef extRef3 = findExtRef(scd, "IED_NAME3", "LDEPF", "DYN_LDEPF_DIGITAL CHANNEL 1_1_BOOLEEN_1_general_1"); assertThat(extRef3.getIedName()).isEqualTo("IED_NAME1"); - assertExtRefIsBoundAccordingTOLDEPF(extRef1, expectedSettingData); - assertExtRefIsBoundAccordingTOLDEPF(extRef2, expectedSettingData); - assertExtRefIsBoundAccordingTOLDEPF(extRef3, expectedSettingData); + assertExtRefIsBoundAccordingTOLDEPF(extRef1, channel); + assertExtRefIsBoundAccordingTOLDEPF(extRef2, channel); + assertExtRefIsBoundAccordingTOLDEPF(extRef3, channel); AbstractLNAdapter lnRbdr = findLn(scd, "IED_NAME1", "LDEPF", "RBDR", "1", ""); assertThat(getDaiValue(lnRbdr, CHNUM1_DO_NAME, DU_DA_NAME)) @@ -669,25 +307,41 @@ void manageBindingForLDEPF_whenFlowKindIsInternalAndAllExtRefInSameBay_should_re assertThat(getDaiValue(lnBrbdr, SRCREF_DO_NAME, SETSRCREF_DA_NAME)) .isNotEqualTo("setSrcRef_old_val") .isEqualTo("IED_NAME1LDPX/PTRC0.Str.q"); - } @Test - void manageBindingForLDEPF_when_extRef_withDifferentIedType_update_successfully_should_return_no_report() { + void manageBindingForLDEPF_when_internalBindingMatchEPFChannel_should_update_successfully_the_ExtRef_And_DAI_In_RBDR_bRBDR_LNodes_without_report() { // Given - String fileName = "LDEPF_Setting_file.csv"; - InputStream inputStream = Objects.requireNonNull(CsvUtils.class.getClassLoader().getResourceAsStream(fileName), "Resource not found: " + fileName); - InputStreamReader reader = new InputStreamReader(inputStream); - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_extref_with_BCU_BPU.xml"); - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_extref_with_IedType_BCU.xml"); + TChannel channel = new TChannel(); + channel.setBayScope(TCBscopeType.BAY_INTERNAL); + channel.setChannelType(TChannelType.DIGITAL); + channel.setChannelNum("1"); + channel.setChannelShortLabel("MR.PX1"); + channel.setChannelLevMod(TChannelLevMod.POSITIVE_OR_RISING); + channel.setChannelLevModQ(TChannelLevMod.OTHER); + channel.setIEDType("BCU"); + channel.setIEDRedundancy(TIEDredundancy.NONE); + channel.setIEDSystemVersionInstance("1"); + channel.setLDInst("LDPX"); + channel.setLNClass("PTRC"); + channel.setLNInst("0"); + channel.setDOName("Str"); + channel.setDOInst("0"); + channel.setDAName("general"); + + EPF epf = new EPF(); + Channels channels = new Channels(); + channels.getChannel().add(channel); + epf.setChannels(channels); // When - List sclReportItems = extRefService.manageBindingForLDEPF(scd, settingLDEPFCsvHelper); + List sclReportItems = extRefService.manageBindingForLDEPF(scd, epf); // Then assertThat(sclReportItems).isEmpty(); SclTestMarshaller.assertIsMarshallable(new SclRootAdapter(scd).getCurrentElem()); TExtRef extRef1 = findExtRef(scd, "IED_NAME1", "LDEPF", "DYN_LDEPF_DIGITAL CHANNEL 1_1_BOOLEEN_1_general_1"); assertThat(extRef1.getIedName()).isEqualTo("IED_NAME1"); - assertExtRefIsBoundAccordingTOLDEPF(extRef1, getLDEPFSettingByDigitalNum(settingLDEPFCsvHelper.getSettings(), 1)); + assertExtRefIsBoundAccordingTOLDEPF(extRef1, channel); AbstractLNAdapter lnRbdr = findLn(scd, "IED_NAME1", "LDEPF", "RBDR", "1", ""); assertThat(getDaiValue(lnRbdr, CHNUM1_DO_NAME, DU_DA_NAME)) @@ -716,50 +370,35 @@ void manageBindingForLDEPF_when_extRef_withDifferentIedType_update_successfully_ assertThat(getDaiValue(lnBrbdr, SRCREF_DO_NAME, SETSRCREF_DA_NAME)) .isNotEqualTo("setSrcRef_old_val") .isEqualTo("IED_NAME1LDPX/PTRC0.Str.q"); - - TExtRef extRef2 = findExtRef(scd, "IED_NAME2", "LDEPF", "DYN_LDEPF_DIGITAL CHANNEL 15_1_BOOLEEN_1_general_1"); - assertThat(extRef2.getIedName()).isEqualTo("IED_NAME2"); - assertExtRefIsBoundAccordingTOLDEPF(extRef2, getLDEPFSettingByDigitalNum(settingLDEPFCsvHelper.getSettings(), 15)); - - AbstractLNAdapter lnRbdr2 = findLn(scd, "IED_NAME2", "LDEPF", "RBDR", "15", ""); - assertThat(getDaiValue(lnRbdr2, CHNUM1_DO_NAME, DU_DA_NAME)) - .isNotEqualTo("dU_old_val") - .isEqualTo("MR.PX2"); - assertThat(getDaiValue(lnRbdr2, LEVMOD_DO_NAME, SETVAL_DA_NAME)) - .isNotEqualTo("setVal_old_val") - .isEqualTo("Positive or Rising"); - assertThat(getDaiValue(lnRbdr2, MOD_DO_NAME, STVAL_DA_NAME)) - .isNotEqualTo("off") - .isEqualTo("on"); - assertThat(getDaiValue(lnRbdr2, SRCREF_DO_NAME, SETSRCREF_DA_NAME)) - .isNotEqualTo("setSrcRef_old_val") - .isEqualTo("IED_NAME2LDPX/PTRC0.Str.general"); - - AbstractLNAdapter lnBrbdr2 = findLn(scd, "IED_NAME2", "LDEPF", "RBDR", "15", "b"); - assertThat(getDaiValue(lnBrbdr2, CHNUM1_DO_NAME, DU_DA_NAME)) - .isNotEqualTo("dU_old_val") - .isEqualTo("MR.PX2"); - assertThat(getDaiValue(lnBrbdr2, LEVMOD_DO_NAME, SETVAL_DA_NAME)) - .isNotEqualTo("setVal_old_val") - .isEqualTo("Other"); - assertThat(getDaiValue(lnBrbdr2, MOD_DO_NAME, STVAL_DA_NAME)) - .isNotEqualTo("off") - .isEqualTo("on"); - assertThat(getDaiValue(lnBrbdr2, SRCREF_DO_NAME, SETSRCREF_DA_NAME)) - .isNotEqualTo("setSrcRef_old_val") - .isEqualTo("IED_NAME2LDPX/PTRC0.Str.q"); } @Test - void manageBindingForLDEPF_when_manyIedSourceFound_should_return_report() { + void manageBindingForLDEPF_when_manyIedSourceFound_should_return_reportMassages() { //Given - String fileName = "LDEPF_Setting_file.csv"; - InputStream inputStream = Objects.requireNonNull(CsvUtils.class.getClassLoader().getResourceAsStream(fileName), "Resource not found: " + fileName); - InputStreamReader reader = new InputStreamReader(inputStream); SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_manyIedSources_in_same_bay.xml"); - ILDEPFSettings settings = new SettingLDEPFCsvHelper(reader); + TChannel channel = new TChannel(); + channel.setBayScope(TCBscopeType.BAY_INTERNAL); + channel.setChannelType(TChannelType.DIGITAL); + channel.setChannelNum("1"); + channel.setChannelShortLabel("MR.PX1"); + channel.setChannelLevMod(TChannelLevMod.POSITIVE_OR_RISING); + channel.setChannelLevModQ(TChannelLevMod.OTHER); + channel.setIEDType("BCU"); + channel.setIEDRedundancy(TIEDredundancy.NONE); + channel.setIEDSystemVersionInstance("1"); + channel.setLDInst("LDPX"); + channel.setLNClass("PTRC"); + channel.setLNInst("0"); + channel.setDOName("Str"); + channel.setDOInst("0"); + channel.setDAName("general"); + + EPF epf = new EPF(); + Channels channels = new Channels(); + channels.getChannel().add(channel); + epf.setChannels(channels); // When - List sclReportItems = extRefService.manageBindingForLDEPF(scd, settings); + List sclReportItems = extRefService.manageBindingForLDEPF(scd, epf); // Then assertThat(sclReportItems).hasSize(2) .extracting(SclReportItem::message) @@ -794,21 +433,66 @@ void manageBindingForLDEPF_when_manyIedSourceFound_should_return_report() { } @Test - void manageBindingForLDEPF_when_extRefInFlowKindInternalAndExternal_update_successfully_should_return_no_report() { + void manageBindingForLDEPF_when_extRefMatchFlowKindInternalOrExternal_should_update_successfully_the_ExtRef_And_DAI_In_RBDR_bRBDR_LNodes_with_no_report() { //Given - String fileName = "LDEPF_Setting_file.csv"; - InputStream inputStream = Objects.requireNonNull(CsvUtils.class.getClassLoader().getResourceAsStream(fileName), "Resource not found: " + fileName); - InputStreamReader reader = new InputStreamReader(inputStream); SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateValid.xml"); - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); + + TChannel analogueChannel1WithBayInternalScope = new TChannel(); + analogueChannel1WithBayInternalScope.setBayScope(TCBscopeType.BAY_INTERNAL); + analogueChannel1WithBayInternalScope.setChannelType(TChannelType.ANALOG); + analogueChannel1WithBayInternalScope.setChannelNum("1"); + analogueChannel1WithBayInternalScope.setChannelShortLabel("V0"); + analogueChannel1WithBayInternalScope.setChannelLevMod(TChannelLevMod.NA); + analogueChannel1WithBayInternalScope.setChannelLevModQ(TChannelLevMod.NA); + analogueChannel1WithBayInternalScope.setBAPVariant("8"); + analogueChannel1WithBayInternalScope.setBAPIgnoredValue("N/A"); + analogueChannel1WithBayInternalScope.setIEDType("SAMU"); + analogueChannel1WithBayInternalScope.setIEDRedundancy(TIEDredundancy.A); + analogueChannel1WithBayInternalScope.setIEDSystemVersionInstance("1"); + analogueChannel1WithBayInternalScope.setLDInst("LDTM1"); + analogueChannel1WithBayInternalScope.setLNClass("TVTR"); + analogueChannel1WithBayInternalScope.setLNInst("11"); + analogueChannel1WithBayInternalScope.setLNPrefix("U01A"); + analogueChannel1WithBayInternalScope.setDOName("VolSv"); + analogueChannel1WithBayInternalScope.setDOInst("0"); + analogueChannel1WithBayInternalScope.setDAName("instMag"); + analogueChannel1WithBayInternalScope.setBDAName("i"); + + TChannel analogueChannel10WithBayExternalBayScope = new TChannel(); + analogueChannel10WithBayExternalBayScope.setBayScope(TCBscopeType.BAY_EXTERNAL); + analogueChannel10WithBayExternalBayScope.setChannelType(TChannelType.ANALOG); + analogueChannel10WithBayExternalBayScope.setChannelNum("10"); + analogueChannel10WithBayExternalBayScope.setChannelShortLabel("U101"); + analogueChannel10WithBayExternalBayScope.setChannelLevMod(TChannelLevMod.NA); + analogueChannel10WithBayExternalBayScope.setChannelLevModQ(TChannelLevMod.NA); + analogueChannel10WithBayExternalBayScope.setBAPVariant("8"); + analogueChannel10WithBayExternalBayScope.setBAPIgnoredValue("N/A"); + analogueChannel10WithBayExternalBayScope.setIEDType("SAMU"); + analogueChannel10WithBayExternalBayScope.setIEDRedundancy(TIEDredundancy.A); + analogueChannel10WithBayExternalBayScope.setIEDSystemVersionInstance("1"); + analogueChannel10WithBayExternalBayScope.setLDInst("LDPHAS1"); + analogueChannel10WithBayExternalBayScope.setLNClass("MMXU"); + analogueChannel10WithBayExternalBayScope.setLNInst("101"); + analogueChannel10WithBayExternalBayScope.setSDOName("phsB"); + analogueChannel10WithBayExternalBayScope.setDOName("PhV"); + analogueChannel10WithBayExternalBayScope.setDOInst("0"); + analogueChannel10WithBayExternalBayScope.setDAName("cVal"); + analogueChannel10WithBayExternalBayScope.setBDAName("mag"); + analogueChannel10WithBayExternalBayScope.setSBDAName("f"); + + EPF epf = new EPF(); + Channels channels = new Channels(); + channels.getChannel().add(analogueChannel1WithBayInternalScope); + channels.getChannel().add(analogueChannel10WithBayExternalBayScope); + epf.setChannels(channels); // When - List sclReportItems = extRefService.manageBindingForLDEPF(scd, settingLDEPFCsvHelper); + List sclReportItems = extRefService.manageBindingForLDEPF(scd, epf); // Then assertThat(sclReportItems).isEmpty(); SclTestMarshaller.assertIsMarshallable(scd); TExtRef extRefBindInternally = findExtRef(scd, "IED_NAME1", "LDEPF", "DYN_LDEPF_ANALOG CHANNEL 1_1_AnalogueValue_1_instMag_1"); assertThat(extRefBindInternally.getIedName()).isEqualTo("IED_NAME1"); - assertExtRefIsBoundAccordingTOLDEPF(extRefBindInternally, getLDEPFSettingByAnalogNum(settingLDEPFCsvHelper.getSettings(), 1)); + assertExtRefIsBoundAccordingTOLDEPF(extRefBindInternally, analogueChannel1WithBayInternalScope); AbstractLNAdapter lnRadr = findLn(scd, "IED_NAME1", "LDEPF", "RADR", "1", ""); assertThat(getDaiValue(lnRadr, CHNUM1_DO_NAME, DU_DA_NAME)) @@ -840,27 +524,15 @@ void manageBindingForLDEPF_when_extRefInFlowKindInternalAndExternal_update_succe TExtRef extRefBindExternally = findExtRef(scd, "IED_NAME1", "LDEPF", "DYN_LDEPF_ANALOG CHANNEL 10_1_AnalogueValue_1_cVal_1"); assertThat(extRefBindExternally.getIedName()).isEqualTo("IED_NAME2"); - assertExtRefIsBoundAccordingTOLDEPF(extRefBindExternally, getLDEPFSettingByAnalogNum(settingLDEPFCsvHelper.getSettings(), 10)); - } - - private void assertExtRefIsBoundAccordingTOLDEPF(TExtRef extRef, LDEPFSettingData setting) { - assertThat(extRef.getLdInst()).isEqualTo(setting.getLdInst()); - assertThat(extRef.getLnClass()).contains(setting.getLnClass()); - assertThat(extRef.getLnInst()).isEqualTo(setting.getLnInst()); - assertThat(extRef.getPrefix()).isEqualTo(setting.getLnPrefix()); - assertThat(extRef.getDoName()).isEqualTo(setting.getDoName()); - } - - private LDEPFSettingData getLDEPFSettingByDigitalNum(List settings, Integer digitalNum) { - return settings.stream() - .filter(setting -> digitalNum.equals(setting.getChannelDigitalNum())) - .findFirst().get(); + assertExtRefIsBoundAccordingTOLDEPF(extRefBindExternally, analogueChannel10WithBayExternalBayScope); } - private LDEPFSettingData getLDEPFSettingByAnalogNum(List settings, Integer analogNum) { - return settings.stream() - .filter(setting -> analogNum.equals(setting.getChannelAnalogNum())) - .findFirst().get(); + private void assertExtRefIsBoundAccordingTOLDEPF(TExtRef extRef, TChannel setting) { + assertThat(extRef.getLdInst()).isEqualTo(setting.getLDInst()); + assertThat(extRef.getLnClass()).contains(setting.getLNClass()); + assertThat(extRef.getLnInst()).isEqualTo(setting.getLNInst()); + assertThat(extRef.getPrefix()).isEqualTo(setting.getLNPrefix()); + assertThat(extRef.getDoName()).isEqualTo(setting.getDOName()); } @Test diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SclEditorServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SclServiceTest.java similarity index 74% rename from sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SclEditorServiceTest.java rename to sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SclServiceTest.java index 5cbcbc0db..b482ad8ad 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SclEditorServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SclServiceTest.java @@ -17,13 +17,11 @@ import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; import org.lfenergy.compas.sct.commons.scl.ied.*; -import org.lfenergy.compas.sct.commons.testhelpers.MarshallerWrapper; -import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; +import org.lfenergy.compas.sct.commons.testhelpers.*; import org.mockito.InjectMocks; import org.mockito.junit.jupiter.MockitoExtension; import java.util.*; -import java.util.stream.Collectors; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; @@ -36,12 +34,12 @@ import static org.lfenergy.compas.sct.commons.util.PrivateEnum.COMPAS_SCL_FILE_TYPE; @ExtendWith(MockitoExtension.class) -class SclEditorServiceTest { +class SclServiceTest { @InjectMocks - SclEditorService sclEditorService; + SclService sclService; - private static Stream sclProviderMissingRequiredObjects() { + private static Stream sclProviderMissingRequiredObjects() { SCL scl1 = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test_KO_MissingBeh.scd"); SCL scl2 = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test_KO_MissingLDevicePrivate.scd"); SCL scl3 = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test_KO_MissingLDevicePrivateAttribute.scd"); @@ -101,7 +99,7 @@ void addHistoryItem_should_add_history_elements() throws ScdException { SclRootAdapter sclRootAdapter = new SclRootAdapter("hId", SclRootAdapter.VERSION, SclRootAdapter.REVISION); SCL scd = sclRootAdapter.getCurrentElem(); //When - sclEditorService.addHistoryItem(scd, "who", "what", "why"); + sclService.addHistoryItem(scd, "who", "what", "why"); //Then assertThat(scd.getHeader()).isNotNull(); THeader.History history = scd.getHeader().getHistory(); @@ -124,7 +122,7 @@ void addIED_should_add_ied_element() { assertThat(sclRootAdapter.getCurrentElem().getDataTypeTemplates()).isNull(); SCL icd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); //When Then - assertDoesNotThrow(() -> sclEditorService.addIED(scd, "IED_NAME1", icd)); + assertDoesNotThrow(() -> sclService.addIED(scd, "IED_NAME1", icd)); assertThat(scd.getIED().size()).isNotZero(); assertThat(scd.getIED().get(0).getName()).isEqualTo("IED_NAME1"); assertThat(scd.getDataTypeTemplates()).isNotNull(); @@ -140,14 +138,14 @@ void addSubnetworks_should_add_subnetwork() { assertThat(sclRootAdapter.getCurrentElem().getDataTypeTemplates()).isNull(); SCL icd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); //When Then - assertThatCode(() -> sclEditorService.addIED(scd, "IED_NAME1", icd)).doesNotThrowAnyException(); + assertThatCode(() -> sclService.addIED(scd, "IED_NAME1", icd)).doesNotThrowAnyException(); SubNetworkDTO subNetworkDTO = new SubNetworkDTO(); subNetworkDTO.setName("sName1"); subNetworkDTO.setType("IP"); ConnectedApDTO connectedApDTO = new ConnectedApDTO("IED_NAME1","AP_NAME"); subNetworkDTO.addConnectedAP(connectedApDTO); //When Then - assertThatCode(() -> sclEditorService.addSubnetworks(scd, List.of(subNetworkDTO), icd)).doesNotThrowAnyException(); + assertThatCode(() -> sclService.addSubnetworks(scd, List.of(subNetworkDTO), icd)).doesNotThrowAnyException(); assertIsMarshallable(scd); } @@ -160,9 +158,9 @@ void addSubnetworks_whenNoCommunicationTagInIcd_should_not_add_subnetwork() { assertThat(sclRootAdapter.getCurrentElem().getDataTypeTemplates()).isNull(); SCL icd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); //When Then - assertThatCode(() -> sclEditorService.addIED(scd, "IED_NAME1", icd)).doesNotThrowAnyException(); + assertThatCode(() -> sclService.addIED(scd, "IED_NAME1", icd)).doesNotThrowAnyException(); //When Then - assertThatCode(() -> sclEditorService.addSubnetworks(scd, List.of(), icd)).doesNotThrowAnyException(); + assertThatCode(() -> sclService.addSubnetworks(scd, List.of(), icd)).doesNotThrowAnyException(); String marshalledScd = assertIsMarshallable(scd); assertThat(marshalledScd).doesNotContain(" sclEditorService.initScl(headerId, "hVersion", "hRevision")); + SCL scd = assertDoesNotThrow(() -> sclService.initScl(headerId, "hVersion", "hRevision")); //Then assertIsMarshallable(scd); } @@ -182,7 +180,7 @@ void initScl_should_create_Private_SCL_FILETYPE() { // Given UUID headerId = UUID.randomUUID(); // When Then - SCL scd = assertDoesNotThrow(() -> sclEditorService.initScl(headerId, "hVersion", "hRevision")); + SCL scd = assertDoesNotThrow(() -> sclService.initScl(headerId, "hVersion", "hRevision")); assertThat(scd.getPrivate()).isNotEmpty(); assertThat(scd.getPrivate().get(0).getType()).isEqualTo(COMPAS_SCL_FILE_TYPE.getPrivateType()); assertIsMarshallable(scd); @@ -192,12 +190,12 @@ void initScl_should_create_Private_SCL_FILETYPE() { @Tag("issue-321") void updateHeader_should_update_header_tag() { //When Then - SCL scd = assertDoesNotThrow(() -> sclEditorService.initScl(UUID.randomUUID(), "hVersion", "hRevision")); + SCL scd = assertDoesNotThrow(() -> sclService.initScl(UUID.randomUUID(), "hVersion", "hRevision")); //Given UUID headerId = UUID.fromString(scd.getHeader().getId()); HeaderDTO headerDTO = DTO.createHeaderDTO(headerId); //When - sclEditorService.updateHeader(scd, headerDTO); + sclService.updateHeader(scd, headerDTO); //Then assertIsMarshallable(scd); } @@ -210,7 +208,7 @@ void updateDAI_should_not_throw_error() { dataAttributeRef.setLnType("unknownID"); SCL scd = SclTestMarshaller.getSCLFromFile("/ied-test-schema-conf/ied_unit_test.xml"); //When Then - assertThatThrownBy(() -> sclEditorService.updateDAI(scd, "IED", "LD", dataAttributeRef)) + assertThatThrownBy(() -> sclService.updateDAI(scd, "IED", "LD", dataAttributeRef)) .isInstanceOf(ScdException.class); //Given dataAttributeRef.setLnType("LNO1"); @@ -222,7 +220,7 @@ void updateDAI_should_not_throw_error() { tVal.setValue("newValue"); dataAttributeRef.setDaiValues(List.of(tVal)); //When Then - assertThatCode(() -> sclEditorService.updateDAI(scd, "IED_NAME", "LD_INS1", dataAttributeRef)) + assertThatCode(() -> sclService.updateDAI(scd, "IED_NAME", "LD_INS1", dataAttributeRef)) .doesNotThrowAnyException(); assertIsMarshallable(scd); } @@ -233,7 +231,7 @@ void testImportSTDElementsInSCD_whenCalledWithOneSTD_shouldNotThrowException() { SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd.xml"); SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); //When Then - assertThatCode(() -> sclEditorService.importSTDElementsInSCD(scd, List.of(std), DTO.SUB_NETWORK_TYPES)) + assertThatCode(() -> sclService.importSTDElementsInSCD(scd, List.of(std), DTO.SUB_NETWORK_TYPES)) .doesNotThrowAnyException(); assertThat(scd.getIED()).hasSize(1); assertThat(scd.getDataTypeTemplates()).hasNoNullFieldsOrProperties(); @@ -249,7 +247,7 @@ void importSTDElementsInSCD_whenCalledWithMultipleSTD_shouldNotThrowException() SCL std1 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std_SITESITE1SCU1.xml"); SCL std2 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std_SITESITE1SCU2.xml"); //When Then - assertThatCode(() -> sclEditorService.importSTDElementsInSCD(scd, List.of(std0, std1, std2), DTO.SUB_NETWORK_TYPES)) + assertThatCode(() -> sclService.importSTDElementsInSCD(scd, List.of(std0, std1, std2), DTO.SUB_NETWORK_TYPES)) .doesNotThrowAnyException(); assertThat(scd.getIED()).hasSize(3); assertThat(scd.getDataTypeTemplates()).hasNoNullFieldsOrProperties(); @@ -267,7 +265,7 @@ void importSTDElementsInSCD_whenManySTDMatchCompasICDHeader_shouldThrowException SCL std2 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); List stds = List.of(std1, std2); //When Then - assertThatThrownBy(() -> sclEditorService.importSTDElementsInSCD(scd, stds, DTO.SUB_NETWORK_TYPES)) + assertThatThrownBy(() -> sclService.importSTDElementsInSCD(scd, stds, DTO.SUB_NETWORK_TYPES)) .isInstanceOf(ScdException.class); assertIsMarshallable(scd); } @@ -278,7 +276,7 @@ void importSTDElementsInSCD_whenSCDFileContainsSameICDHeaderInTwoDifferentFuncti SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd_with_same_compas_icd_header_in_different_functions.xml"); SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); //When Then - assertThatCode(() -> sclEditorService.importSTDElementsInSCD(scd, List.of(std), DTO.SUB_NETWORK_TYPES)).doesNotThrowAnyException(); + assertThatCode(() -> sclService.importSTDElementsInSCD(scd, List.of(std), DTO.SUB_NETWORK_TYPES)).doesNotThrowAnyException(); assertIsMarshallable(scd); } @@ -289,7 +287,7 @@ void importSTDElementsInSCD_whenCompasICDHeaderNotMatch__shouldThrowException() SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std_with_same_ICDSystemVersionUUID.xml"); List stdList = List.of(std); //When Then - assertThatThrownBy(() -> sclEditorService.importSTDElementsInSCD(scd, stdList, DTO.SUB_NETWORK_TYPES)) + assertThatThrownBy(() -> sclService.importSTDElementsInSCD(scd, stdList, DTO.SUB_NETWORK_TYPES)) .isInstanceOf(ScdException.class) .hasMessageContaining("COMPAS-ICDHeader is not the same in Substation and in IED"); assertIsMarshallable(scd); @@ -301,75 +299,11 @@ void importSTDElementsInSCD_whenNoSTDMatch_shouldThrowException() { SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/ssd.xml"); List stdList = List.of(); //When Then - assertThatCode(() -> sclEditorService.importSTDElementsInSCD(scd, stdList, DTO.SUB_NETWORK_TYPES)) + assertThatCode(() -> sclService.importSTDElementsInSCD(scd, stdList, DTO.SUB_NETWORK_TYPES)) .isInstanceOf(ScdException.class) .hasMessage("There is no STD file found corresponding to headerId = f8dbc8c1-2db7-4652-a9d6-0b414bdeccfa, headerVersion = 01.00.00, headerRevision = 01.00.00 and ICDSystemVersionUUID = IED4d4fe1a8cda64cf88a5ee4176a1a0eef"); } - @Test - void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_controlBlocks_and_Dataset_on_ln0() { - // Given - SCL scl = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml"); - // When - sclEditorService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl); - // Then - SclRootAdapter scdRootAdapter = new SclRootAdapter(scl); - List lDevices = scdRootAdapter.streamIEDAdapters().flatMap(IEDAdapter::streamLDeviceAdapters).toList(); - List ln0s = lDevices.stream().map(LDeviceAdapter::getLN0Adapter).map(LN0Adapter::getCurrentElem).toList(); - assertThat(ln0s) - .isNotEmpty() - .noneMatch(TAnyLN::isSetDataSet) - .noneMatch(TAnyLN::isSetLogControl) - .noneMatch(TAnyLN::isSetReportControl) - .noneMatch(LN0::isSetGSEControl) - .noneMatch(LN0::isSetSampledValueControl); - assertIsMarshallable(scl); - } - - @Test - void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_controlBlocks_and_Dataset_on_ln() { - // Given - SCL scl = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml"); - // When - sclEditorService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl); - // Then - SclRootAdapter scdRootAdapter = new SclRootAdapter(scl); - List lns = scdRootAdapter.streamIEDAdapters() - .flatMap(IEDAdapter::streamLDeviceAdapters) - .map(LDeviceAdapter::getLNAdapters).flatMap(List::stream) - .map(LNAdapter::getCurrentElem).collect(Collectors.toList()); - assertThat(lns) - .isNotEmpty() - .noneMatch(TAnyLN::isSetDataSet) - .noneMatch(TAnyLN::isSetLogControl) - .noneMatch(TAnyLN::isSetReportControl); - assertIsMarshallable(scl); - } - - @Test - void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_srcXXX_attributes_on_ExtRef() { - // Given - SCL scl = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml"); - // When - sclEditorService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl); - // Then - SclRootAdapter scdRootAdapter = new SclRootAdapter(scl); - List extRefs = scdRootAdapter - .streamIEDAdapters() - .flatMap(IEDAdapter::streamLDeviceAdapters) - .map(LDeviceAdapter::getLN0Adapter) - .map(AbstractLNAdapter::getExtRefs).flatMap(List::stream) - .collect(Collectors.toList()); - assertThat(extRefs) - .isNotEmpty() - .noneMatch(TExtRef::isSetSrcLDInst) - .noneMatch(TExtRef::isSetSrcPrefix) - .noneMatch(TExtRef::isSetSrcLNInst) - .noneMatch(TExtRef::isSetSrcCBName) - .noneMatch(TExtRef::isSetSrcLNClass); - assertIsMarshallable(scl); - } - @ParameterizedTest(name = "{0}") @MethodSource("sclProviderMissingRequiredObjects") void updateLDeviceStatus_whenMissingRequiredObject_shouldReturnReportWithError(String testCase, SCL scl, Tuple... errors) { @@ -378,7 +312,7 @@ void updateLDeviceStatus_whenMissingRequiredObject_shouldReturnReportWithError(S assertThat(getLDeviceStatusValue(scl, "IedName1", "LDSUIED").get().getValue()).isEqualTo("off"); String before = MarshallerWrapper.marshall(scl); // When - List sclReportItems = sclEditorService.updateLDeviceStatus(scl); + List sclReportItems = sclService.updateLDeviceStatus(scl); // Then String after = MarshallerWrapper.marshall(scl); assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isFalse(); @@ -399,7 +333,7 @@ void updateLDeviceStatus_whenLDeviceStatusActiveOrUntestedOrInactive_shouldRetur assertThat(getLDeviceStatusValue(scl, "IedName3", "LDSUIED")).isEmpty(); String before = MarshallerWrapper.marshall(scl); // When - List sclReportItems = sclEditorService.updateLDeviceStatus(scl); + List sclReportItems = sclService.updateLDeviceStatus(scl); // Then String after = MarshallerWrapper.marshall(scl); assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isFalse(); @@ -421,7 +355,7 @@ void updateLDeviceStatus_whenAllLDeviceInactive_shouldReturnReportWithError() { assertThat(getLDeviceStatusValue(scl, "IedName2", "LDSUIED").get().getValue()).isEqualTo("on"); assertThat(getLDeviceStatusValue(scl, "IedName3", "LDSUIED")).isEmpty(); // When - List sclReportItems = sclEditorService.updateLDeviceStatus(scl); + List sclReportItems = sclService.updateLDeviceStatus(scl); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isFalse(); assertThat(sclReportItems) @@ -447,7 +381,7 @@ void updateLDeviceStatus_shouldReturnUpdatedFile() { assertThat(getLDeviceStatusValue(givenScl, "IedName2", "LDSUIED").get().getValue()).isEqualTo("on"); assertThat(getLDeviceStatusValue(givenScl, "IedName3", "LDSUIED")).isEmpty(); // When - List sclReportItems = sclEditorService.updateLDeviceStatus(givenScl); + List sclReportItems = sclService.updateLDeviceStatus(givenScl); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); assertThat(getLDeviceStatusValue(givenScl, "IedName1", "LDSUIED")).isPresent(); @@ -478,7 +412,7 @@ void updateLDeviceStatus_when_DAI_Mod_DO_stVal_whateverIsUpdatableOrNot_shouldRe .map(TVal::getValue) .hasValue("on"); // When - List sclReportItems = sclEditorService.updateLDeviceStatus(givenScl); + List sclReportItems = sclService.updateLDeviceStatus(givenScl); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); assertThat(getLDeviceStatusValue(givenScl, "IedName1", "LDSUIED")) @@ -515,10 +449,10 @@ void updateDoInRef_shouldReturnUpdatedFile(String testName, String ldInst, Strin // Given SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_issue_231_test_ok.xml"); // When - List sclReportItems = sclEditorService.updateDoInRef(givenScl); + List sclReportItems = sclService.updateDoInRef(givenScl); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); - SclTestMarshaller.assertIsMarshallable(givenScl); + assertIsMarshallable(givenScl); assertThat(getValFromDaiName(givenScl, "IED_NAME1", ldInst, doName, daName) .map(TVal::getValue)) .hasValue(expected); @@ -537,7 +471,7 @@ void updateDoInRef_should_not_update_DAI(String testName, String ldInst, String // Given SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_issue_231_test_ok.xml"); // When - List sclReportItems = sclEditorService.updateDoInRef(givenScl); + List sclReportItems = sclService.updateDoInRef(givenScl); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); assertThat(getValFromDaiName(givenScl, "IED_NAME1", ldInst, doName, daName)).isNotPresent(); @@ -549,7 +483,7 @@ void updateDoInRef_when_ExtRefNotCoherent_shouldReturnReportWithError() { // Given SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_issue_231_test_ko.xml"); // When - List sclReportItems = sclEditorService.updateDoInRef(givenScl); + List sclReportItems = sclService.updateDoInRef(givenScl); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); assertThat(sclReportItems).hasSize(4); @@ -571,59 +505,12 @@ private Optional getValFromDaiName(SCL scl, String iedName, String ldInst, .findFirst()); } - @Test - void analyzeDataGroups_should_success() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_limitation_bound_ied_controls_fcda.xml"); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - IEDAdapter iedAdapter1 = sclRootAdapter.getIEDAdapterByName("IED_NAME1"); - iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxAttributes(9L); - iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxGOOSE(3L); - iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxSMV(2L); - iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxReports(1L); - // When - List sclReportItems = sclEditorService.analyzeDataGroups(scd); - //Then - assertThat(sclReportItems).isEmpty(); - - } - - @Test - void analyzeDataGroups_should_return_errors_messages() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_limitation_bound_ied_controls_fcda.xml"); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME2"); - iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getConfDataSet().setMaxAttributes(1L); - iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getConfDataSet().setMax(3L); - iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getSMVsc().setMax(1L); - iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getGOOSE().setMax(2L); - iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getConfReportControl().setMax(0L); - // When - List sclReportItems = sclEditorService.analyzeDataGroups(scd); - //Then - assertThat(sclReportItems).hasSize(11) - .extracting(SclReportItem::message) - .containsExactlyInAnyOrder( - "The Client IED IED_NAME1 subscribes to too much FCDA: 9 > 8 max", - "The Client IED IED_NAME1 subscribes to too much GOOSE Control Blocks: 3 > 2 max", - "The Client IED IED_NAME1 subscribes to too much Report Control Blocks: 1 > 0 max", - "The Client IED IED_NAME1 subscribes to too much SMV Control Blocks: 2 > 1 max", - "There are too much FCDA for the DataSet dataset6 for the LDevice LD_INST21 in IED IED_NAME2: 2 > 1 max", - "There are too much FCDA for the DataSet dataset6 for the LDevice LD_INST22 in IED IED_NAME2: 2 > 1 max", - "There are too much FCDA for the DataSet dataset5 for the LDevice LD_INST22 in IED IED_NAME2: 2 > 1 max", - "There are too much DataSets for the IED IED_NAME2: 6 > 3 max", - "There are too much Report Control Blocks for the IED IED_NAME2: 1 > 0 max", - "There are too much GOOSE Control Blocks for the IED IED_NAME2: 3 > 2 max", - "There are too much SMV Control Blocks for the IED IED_NAME2: 3 > 1 max"); - } - @Test void manageMonitoringLns_should_update_and_create_lsvs_and_goose() { // Given SCL scd = SclTestMarshaller.getSCLFromFile("/monitoring_lns/scd_monitoring_lsvs_lgos.xml"); // When - List sclReportItems = sclEditorService.manageMonitoringLns(scd); + List sclReportItems = sclService.manageMonitoringLns(scd); //Then assertThat(sclReportItems).isEmpty(); LDeviceAdapter lDeviceAdapter = new SclRootAdapter(scd).getIEDAdapterByName("IED_NAME1").getLDeviceAdapterByLdInst(LD_SUIED); @@ -632,7 +519,7 @@ void manageMonitoringLns_should_update_and_create_lsvs_and_goose() { .extracting(LNAdapter::getLNClass, LNAdapter::getLNInst).containsExactlyInAnyOrder( Tuple.tuple("LGOS", "1"), Tuple.tuple("LGOS", "2"), Tuple.tuple("LSVS", "1"), Tuple.tuple("LSVS", "2")); - SclTestMarshaller.assertIsMarshallable(scd); + assertIsMarshallable(scd); } @Test @@ -645,7 +532,7 @@ void manageMonitoringLns_when_no_extRef_should_not_update_and_not_create_lsvs_an LDeviceAdapter lDeviceAdapter21 = sclRootAdapter.getIEDAdapterByName("IED_NAME1").getLDeviceAdapterByLdInst("LD_INST21"); lDeviceAdapter21.getLN0Adapter().getCurrentElem().setInputs(null); // When - List sclReportItems = sclEditorService.manageMonitoringLns(scd); + List sclReportItems = sclService.manageMonitoringLns(scd); //Then assertThat(sclReportItems).isEmpty(); LDeviceAdapter lDeviceAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME1").getLDeviceAdapterByLdInst(LD_SUIED); @@ -653,7 +540,7 @@ void manageMonitoringLns_when_no_extRef_should_not_update_and_not_create_lsvs_an .hasSize(2) .extracting(LNAdapter::getLNClass, LNAdapter::getLNInst).containsExactlyInAnyOrder( Tuple.tuple("LGOS", "3"), Tuple.tuple("LSVS", "9")); - SclTestMarshaller.assertIsMarshallable(scd); + assertIsMarshallable(scd); } @Test @@ -667,7 +554,7 @@ void manageMonitoringLns_when_dai_not_updatable_should_not_update_and_not_create getDAIAdapters(lDeviceAdapter, "LSVS", "SvCBRef", "setSrcRef") .forEach(daiAdapter -> daiAdapter.getCurrentElem().setValImport(false)); // When - List sclReportItems = sclEditorService.manageMonitoringLns(scd); + List sclReportItems = sclService.manageMonitoringLns(scd); //Then assertThat(sclReportItems) .isNotEmpty() @@ -678,7 +565,7 @@ void manageMonitoringLns_when_dai_not_updatable_should_not_update_and_not_create .hasSize(2) .extracting(LNAdapter::getLNClass, LNAdapter::getLNInst).containsExactlyInAnyOrder( Tuple.tuple("LGOS", "3"), Tuple.tuple("LSVS", "9")); - SclTestMarshaller.assertIsMarshallable(scd); + assertIsMarshallable(scd); } } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LDEPFSettingDataTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LDEPFSettingDataTest.java deleted file mode 100644 index f6f597e2c..000000000 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LDEPFSettingDataTest.java +++ /dev/null @@ -1,161 +0,0 @@ -// SPDX-FileCopyrightText: 2023 RTE FRANCE -// -// SPDX-License-Identifier: Apache-2.0 - -package org.lfenergy.compas.sct.commons.dto; - -import org.junit.jupiter.api.Test; -import org.lfenergy.compas.scl2007b4.model.TExtRef; - -import static org.assertj.core.api.Assertions.assertThat; - -class LDEPFSettingDataTest { - - @Test - void isMatchExtRef_with_DigitalSettingData_when_ExtRefDescMatch_should_return_true() { - //Given - LDEPFSettingData ldepfSettingData = LDEPFSettingData.builder() - .channelDigitalNum(22).lnClass("PTRC") - .doName("Str").daName("general").build(); - TExtRef tExtRef = new TExtRef(); - tExtRef.setDesc("DYN_LDEPF_DIGITAL CHANNEL 22_1_BOOLEEN_Y_general_1"); - tExtRef.getPLN().add("PTRC"); - tExtRef.setPDO("Str"); - //When - Boolean isMatchExtRef = ldepfSettingData.isMatchExtRef(tExtRef); - //Then - assertThat(isMatchExtRef).isTrue(); - } - - @Test - void isMatchExtRef_with_DigitalSettingData_when_ExtRefDesc_DigitalNum_NotMatch_should_return_false() { - //Given - LDEPFSettingData ldepfSettingData = LDEPFSettingData.builder() - .channelDigitalNum(22).lnClass("PTRC") - .doName("Str").daName("general").build(); - TExtRef tExtRef = new TExtRef(); - tExtRef.setDesc("DYN_LDEPF_DIGITAL CHANNEL 23_1_BOOLEEN_Y_general_1"); - tExtRef.getPLN().add("PTRC"); - tExtRef.setPDO("Str"); - //When - Boolean isMatchExtRef = ldepfSettingData.isMatchExtRef(tExtRef); - //Then - assertThat(isMatchExtRef).isFalse(); - } - - - @Test - void isMatchExtRef_with_DigitalSettingData_when_ExtRefDesc_DaName_NotMatch_should_return_false() { - //Given - LDEPFSettingData ldepfSettingData = LDEPFSettingData.builder() - .channelDigitalNum(22).lnClass("PTRC") - .doName("Str").daName("general").build(); - TExtRef tExtRef = new TExtRef(); - tExtRef.setDesc("DYN_LDEPF_DIGITAL CHANNEL 22_1_BOOLEEN_Y_daname_1"); - tExtRef.getPLN().add("PTRC"); - tExtRef.setPDO("Str"); - //When - Boolean isMatchExtRef = ldepfSettingData.isMatchExtRef(tExtRef); - //Then - assertThat(isMatchExtRef).isFalse(); - } - - - @Test - void isMatchExtRef_with_AnalogSettingData_when_ExtRefDescMatch_should_return_true() { - //Given - LDEPFSettingData ldepfSettingData = LDEPFSettingData.builder() - .channelAnalogNum(22).lnClass("PTRC") - .doName("Str").daName("instMag").build(); - TExtRef tExtRef = new TExtRef(); - tExtRef.setDesc("DYN_LDEPF_ANALOG CHANNEL 22_1_AnalogueValue_Y_instMag_1"); - tExtRef.getPLN().add("PTRC"); - tExtRef.setPDO("Str"); - //When - Boolean isMatchExtRef = ldepfSettingData.isMatchExtRef(tExtRef); - //Then - assertThat(isMatchExtRef).isTrue(); - } - - @Test - void isMatchExtRef_with_AnalogSettingData_when_ExtRefDesc_DigitalNum_NotMatch_should_return_false() { - //Given - LDEPFSettingData ldepfSettingData = LDEPFSettingData.builder() - .channelAnalogNum(22).lnClass("PTRC") - .doName("Str").daName("instMag").build(); - TExtRef tExtRef = new TExtRef(); - tExtRef.setDesc("DYN_LDEPF_ANALOG CHANNEL 23_1_AnalogueValue_Y_instMag_1"); - tExtRef.getPLN().add("PTRC"); - tExtRef.setPDO("Str"); - //When - Boolean isMatchExtRef = ldepfSettingData.isMatchExtRef(tExtRef); - //Then - assertThat(isMatchExtRef).isFalse(); - } - - - @Test - void isMatchExtRef_with_AnalogSettingData_when_ExtRefDesc_DaName_NotMatch_should_return_false() { - //Given - LDEPFSettingData ldepfSettingData = LDEPFSettingData.builder() - .channelAnalogNum(22).lnClass("PTRC") - .doName("Str").daName("instMag").build(); - TExtRef tExtRef = new TExtRef(); - tExtRef.setDesc("DYN_LDEPF_ANALOG CHANNEL 22_1_AnalogueValue_Y_daname_1"); - tExtRef.getPLN().add("PTRC"); - tExtRef.setPDO("Str"); - //When - Boolean isMatchExtRef = ldepfSettingData.isMatchExtRef(tExtRef); - //Then - assertThat(isMatchExtRef).isFalse(); - } - - @Test - void isMatchExtRef_when_ExtRefMatch_should_return_true() { - // Given - LDEPFSettingData ldepfSettingData = LDEPFSettingData.builder() - .channelDigitalNum(22).lnClass("PTRC") - .doName("Str").daName("general").build(); - TExtRef tExtRef = new TExtRef(); - tExtRef.setDesc("DYN_LDEPF_DIGITAL CHANNEL 22_1_BOOLEEN_Y_general_1"); - tExtRef.getPLN().add("PTRC"); - tExtRef.setPDO("Str"); - // When - Boolean isMatchExtRef = ldepfSettingData.isMatchExtRef(tExtRef); - // Then - assertThat(isMatchExtRef).isTrue(); - } - - @Test - void isMatchExtRef_when_ExtRefPLN_NotMatch_should_return_false() { - // Given - LDEPFSettingData ldepfSettingData = LDEPFSettingData.builder() - .channelDigitalNum(22).lnClass("PTRC") - .doName("Str").daName("general").build(); - TExtRef tExtRef = new TExtRef(); - tExtRef.setDesc("DYN_LDEPF_DIGITAL CHANNEL 22_1_BOOLEEN_Y_general_1"); - tExtRef.getPLN().add("TOTO"); - tExtRef.setPDO("Str"); - // When - Boolean isMatchExtRef = ldepfSettingData.isMatchExtRef(tExtRef); - // Then - assertThat(isMatchExtRef).isFalse(); - } - - @Test - void isMatchExtRef_when_ExtRefPDO_NotMatch_should_return_false() { - // Given - LDEPFSettingData ldepfSettingData = LDEPFSettingData.builder() - .channelDigitalNum(22).lnClass("PTRC") - .doName("Str").daName("general").build(); - TExtRef tExtRef = new TExtRef(); - tExtRef.setDesc("DYN_LDEPF_DIGITAL CHANNEL 22_1_BOOLEEN_Y_general_1"); - tExtRef.getPLN().add("PTRC"); - tExtRef.setPDO("TOTO"); - // When - Boolean isMatchExtRef = ldepfSettingData.isMatchExtRef(tExtRef); - // Then - assertThat(isMatchExtRef).isFalse(); - } - -} \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/util/SettingLDEPFCsvHelperTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/util/SettingLDEPFCsvHelperTest.java deleted file mode 100644 index 6eda32fb4..000000000 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/util/SettingLDEPFCsvHelperTest.java +++ /dev/null @@ -1,557 +0,0 @@ -// SPDX-FileCopyrightText: 2023 RTE FRANCE -// -// SPDX-License-Identifier: Apache-2.0 - -package org.lfenergy.compas.sct.commons.util; - -import org.junit.jupiter.api.*; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.*; -import org.lfenergy.compas.scl2007b4.model.*; -import org.lfenergy.compas.sct.commons.dto.LDEPFSettingData; -import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; -import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.math.BigInteger; -import java.util.List; -import java.util.Objects; -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; - -class SettingLDEPFCsvHelperTest { - - private InputStreamReader reader; - - @BeforeEach - void setup() { - String fileName = "LDEPF_Setting_file.csv"; - InputStream inputStream = Objects.requireNonNull(CsvUtils.class.getClassLoader().getResourceAsStream(fileName), "Resource not found: " + fileName); - reader = new InputStreamReader(inputStream); - } - - @Test - void readCsvFile_should_return_settings() { - // When Then - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - assertThat(settingLDEPFCsvHelper.getSettings()).hasSize(161); - } - - @Test - void getLDPFSettingMatchingExtRef_whenNotMatchExtRefDescValue_should_return_NoSetting() { - // Given - TExtRef tExtRef = new TExtRef(); - tExtRef.setDesc("desc1"); - tExtRef.getPLN().add("PTRC"); - tExtRef.setPDO("Str"); - // When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - var result = settingLDEPFCsvHelper.getLDEPFSettingDataMatchExtRef(tExtRef); - // Then - assertThat(result).isEmpty(); - } - - @Test - void getLDPFSettingMatchingExtRef_whenMatchExtRef_should_return_digitalSetting() { - // Given - TExtRef tExtRef = new TExtRef(); - tExtRef.setDesc("DYN_LDEPF_DIGITAL CHANNEL 1_1_BOOLEEN_Y_general_1"); - tExtRef.getPLN().add("PTRC"); - tExtRef.setPDO("Str"); - // When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - var result = settingLDEPFCsvHelper.getLDEPFSettingDataMatchExtRef(tExtRef); - // Then - assertThat(result).isPresent(); - assertThat(result.get().getChannelDigitalNum()).isEqualTo(1); - } - - @Test - void getLDPFSettingMatchingExtRef_whenMatchExtRef_should_return_analogSetting() { - // Given - TExtRef tExtRef = new TExtRef(); - tExtRef.setDesc("DYN_LDEPF_ANALOG CHANNEL 1_1_AnalogueValue_Y_instMag_1"); - tExtRef.getPLN().add("TVTR"); - tExtRef.setPDO("VolSv"); - // When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - var result = settingLDEPFCsvHelper.getLDEPFSettingDataMatchExtRef(tExtRef); - // Then - assertThat(result).isPresent(); - assertThat(result.get().getChannelAnalogNum()).isEqualTo(1); - } - - @Test - void getLDPFSettingMatchingExtRef_whenNotMatchExtRefPLNValue_should_return_NoSetting() { - // Given - TExtRef tExtRef = new TExtRef(); - tExtRef.setDesc("DYN_LDEPF_DIGITAL CHANNEL 1_1_BOOLEEN_Y_general_1"); - tExtRef.getPLN().add("TOTO"); - tExtRef.setPDO("Str"); - // When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - var result = settingLDEPFCsvHelper.getLDEPFSettingDataMatchExtRef(tExtRef); - // Then - assertThat(result).isEmpty(); - } - - @Test - void getLDPFSettingMatchingExtRef_when_AllSettingsNotMatchExtRefWithUnknownPDOValue_should_return_NoSetting() { - // Given - TExtRef tExtRef = new TExtRef(); - tExtRef.setDesc("DYN_LDEPF_DIGITAL CHANNEL 1_1_BOOLEEN_Y_general_1"); - tExtRef.getPLN().add("PTRC"); - tExtRef.setPDO("TOTO"); - // When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - var result = settingLDEPFCsvHelper.getLDEPFSettingDataMatchExtRef(tExtRef); - // Then - assertThat(result).isEmpty(); - } - - @Test - void getIedSources_whenFlowKindIsInternalAndMatchAllVerification_should_return_oneIedSource() { - // Given - String fileName = "LDEPF_Setting_file.csv"; - InputStream inputStream = Objects.requireNonNull(CsvUtils.class.getClassLoader().getResourceAsStream(fileName), "Resource not found: " + fileName); - InputStreamReader reader = new InputStreamReader(inputStream); - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_iedSources_in_different_bay.xml"); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - LDEPFSettingData digitalSetting = LDEPFSettingData.builder() - //required attribute to verify Kind of Flow - .bayScope(TCompasFlowKind.BAY_INTERNAL) - //required attributes to verify ExtRef - .channelDigitalNum(10) - .channelAnalogNum(null) - //required attributes to verify IED source for ExtRef - .iedType("BCU").iedRedundancy("None").iedInstance(BigInteger.valueOf(1)) - //required attributes to verify LDEVICE source for ExtRef - .ldInst("LDPX") - //required attributes to verify LNODE source for ExtRef - .lnClass("PTRC").lnInst("0").lnPrefix(null) - //required attributes to verify DO object source for ExtRef - .doName("Str").doInst("0") - .daName("general") - .build(); - TCompasBay compasBay = setCompasBayUUID(sclRootAdapter, "IED_NAME1", "bayUUID1"); - // When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, digitalSetting); - // Then - assertThat(iedSources).hasSize(1); - assertThat(iedSources.get(0).getName()).isEqualTo("IED_NAME1"); - } - - @Test - void getIedSources_whenFlowKindIsInternal_should_return_OneIedSource() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_iedSources_in_different_bay.xml"); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - LDEPFSettingData digitalSetting = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_EXTERNAL) - .channelDigitalNum(1) - .channelAnalogNum(null) - .iedType("BCU").iedRedundancy("None").iedInstance(BigInteger.valueOf(1)) - .ldInst("LDPX") - .lnClass("PTRC").lnInst("0").lnPrefix(null) - .doName("Str").doInst("0") - .daName("general") - .build(); - TCompasBay compasBay = setCompasBayUUID(sclRootAdapter, "IED_NAME1", "bayUUID1"); - // When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, digitalSetting); - // Then - assertThat(iedSources).hasSize(1); - } - - - @Test - void getIedSources_whenFlowKindIsExternalAndTwoIedSourcesFoundWithTheSameBayUUID_should_return_TwoIedSources() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_External_iedSources_in_same_bay.xml"); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - LDEPFSettingData digitalSetting = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_EXTERNAL) - .channelDigitalNum(10) - .channelAnalogNum(null) - .iedType("BCU").iedRedundancy("None").iedInstance(BigInteger.valueOf(1)) - .ldInst("LDPX") - .lnClass("PTRC").lnInst("0").lnPrefix(null) - .doName("Str").doInst("0") - .daName("general") - .build(); - TCompasBay compasBay = setCompasBayUUID(sclRootAdapter, "IED_NAME1", "bayUUID1"); - setCompasBayUUID(sclRootAdapter, "IED_NAME2", "bayUUID2"); - setCompasBayUUID(sclRootAdapter, "IED_NAME3", "bayUUID2"); - // When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, digitalSetting); - // Then - assertThat(iedSources).hasSize(2); - } - - @Test - void getIedSources_whenFlowKindIsExternalAndTwoIedSourcesFoundWithTheSameICDHeader_should_return_TwoIedSources() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_iedSources_in_different_bay.xml"); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - LDEPFSettingData digitalSetting = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_EXTERNAL) - .channelDigitalNum(10) - .channelAnalogNum(null) - .iedType("BCU").iedRedundancy("None").iedInstance(BigInteger.valueOf(1)) - .ldInst("LDPX") - .lnClass("PTRC").lnInst("0").lnPrefix(null) - .doName("Str").doInst("0") - .daName("general") - .build(); - TCompasBay compasBay = setCompasBayUUID(sclRootAdapter, "IED_NAME1", "bayUUID1"); - setCompasBayUUID(sclRootAdapter, "IED_NAME2", "bayUUID2"); - setCompasBayUUID(sclRootAdapter, "IED_NAME3", "bayUUID3"); - sclRootAdapter.getIEDAdapterByName("IED_NAME3").getCompasICDHeader().get().setIEDSystemVersioninstance(digitalSetting.getIedInstance()); - // When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, digitalSetting); - // Then - assertThat(iedSources).hasSize(2); - } - - @ParameterizedTest - @NullSource - @EmptySource - @ValueSource(strings = { - "NO_EXISTING_INST_OF_LDEVICE_SOURCE", - "LDEVICE_INVALID" - }) - void getIedSources_whenLDeviceInstEqual_shouldReturnNoIedSource(String ldInst) { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_iedSources_in_different_bay.xml"); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - LDEPFSettingData digitalSetting = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_INTERNAL) - .channelDigitalNum(10) - .channelAnalogNum(null) - .iedType("BCU").iedRedundancy("None").iedInstance(BigInteger.valueOf(1)) - //required attributes to match LDEVICE source for ExtRef - .ldInst(ldInst) - .lnClass("PTRC").lnInst("0").lnPrefix(null) - .doName("Str").doInst("0") - .daName("general") - .build(); - TCompasBay compasBay = setCompasBayUUID(sclRootAdapter, "IED_NAME1", "bayUUID1"); - // When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, digitalSetting); - // Then - assertThat(iedSources).isEmpty(); - } - - @Test - void getIedSources_whenFlowKindIsInternalAndNoExistingLNodeSource_should_return_NoIedSource() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_iedSources_in_different_bay.xml"); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - var digitalSetting = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_INTERNAL) - .channelDigitalNum(10) - .channelAnalogNum(null) - .iedType("BCU").iedRedundancy("None").iedInstance(BigInteger.valueOf(1)) - .ldInst("LDPX") - //required attributes to verify LNODE source for ExtRef - .lnClass("PTRC").lnInst("100000").lnPrefix(null) - .doName("Str").doInst("0") - .daName("general") - .build(); - TCompasBay compasBay = setCompasBayUUID(sclRootAdapter, "IED_NAME1", "buyUUID1"); - // When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, digitalSetting); - // Then - assertThat(iedSources).isEmpty(); - } - - - @Test - void getIedSources_whenFlowKindIsInternalAndLNodeSourceIsOff_should_return_NoIedSource() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_iedSources_in_different_bay.xml"); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - var digitalSetting = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_INTERNAL) - .channelDigitalNum(10) - .channelAnalogNum(null) - .iedType("BCU").iedRedundancy("None").iedInstance(BigInteger.valueOf(1)) - .ldInst("LDPX") - //required attributes to verify LNODE source for ExtRef - .lnClass("PTRC").lnInst("2").lnPrefix(null) - .doName("Str").doInst("0") - .daName("general") - .build(); - TCompasBay compasBay = setCompasBayUUID(sclRootAdapter, "IED_NAME1", "bayUUID1"); - // When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, digitalSetting); - // Then - assertThat(iedSources).isEmpty(); - } - - @Test - void getIedSources_whenFlowKindIsInternalAndDataTypeTemplateIsValid_should_return_OneIedSource() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateValid.xml"); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - LDEPFSettingData analogSetting1 = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_INTERNAL) - .channelDigitalNum(null).channelAnalogNum(1) - .iedType("SAMU").iedRedundancy("A").iedInstance(BigInteger.valueOf(1)) - .ldInst("LDTM1").lnClass("TVTR").lnInst("11").lnPrefix("U01A") - //required attributes to verify DataTypeTemplate (DoType and DaType objects) linked to IedSource for ExtRef - .doName("VolSv").doInst("0").daName("instMag").bdaName("i").build(); - TCompasBay compasBay = getCompasBayUUID(sclRootAdapter, "IED_NAME1"); - //When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, analogSetting1); - // Then - assertThat(iedSources).hasSize(1); - assertThat(compasBay.getUUID()).isEqualTo(getCompasBayUUID(sclRootAdapter, iedSources.get(0).getName()).getUUID()); - } - - @Test - void getIedSources_whenFlowKindIsExternalAndDataTypeTemplateIsValid_should_return_IedSource() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateValid.xml"); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - LDEPFSettingData analogSetting10 = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_EXTERNAL) - .channelDigitalNum(null).channelAnalogNum(10) - .iedType("SAMU").iedRedundancy("A").iedInstance(BigInteger.valueOf(1)) - .ldInst("LDPHAS1").lnClass("MMXU").lnInst("101").lnPrefix("") - //required attributes to verify DataTypeTemplate (DoType and DaType objects) linked to IedSource for ExtRef - .doName("PhV").doInst("0").sdoName("phsB").daName("cVal").bdaName("mag").sbdaName("f") - .build(); - TCompasBay compasBay = getCompasBayUUID(sclRootAdapter, "IED_NAME1"); - //When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, analogSetting10); - // Then - assertThat(iedSources).hasSize(1); - assertThat(compasBay.getUUID()).isNotEqualTo(getCompasBayUUID(sclRootAdapter, iedSources.get(0).getName()).getUUID()); - } - - @ParameterizedTest - @MethodSource("provideInternalAndExternalLDEPFSetting") - void getIedSources_whenInternalAndExternalFlowKindAreApplied_should_return_IedSource(final LDEPFSettingData setting, final boolean isInSameBay) { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateValid.xml"); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - TCompasBay compasBay = getCompasBayUUID(sclRootAdapter, "IED_NAME1"); - //When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, setting); - // Then - assertThat(iedSources).hasSize(1); - assertThat(getCompasBayUUID(sclRootAdapter, iedSources.get(0).getName()).getUUID() - .equals(compasBay.getUUID())).isEqualTo(isInSameBay); - } - - @ParameterizedTest - @MethodSource("provideInvalidDoName") - void getIedSources_whenInvalidDoName_should_return_NoSource(final SCL scd, final LDEPFSettingData setting) { - // Given - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - TCompasBay compasBay = getCompasBayUUID(new SclRootAdapter(scd), "IED_NAME1"); - //When - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, setting); - // Then - assertThat(iedSources).isEmpty(); - } - - @ParameterizedTest - @MethodSource("provideInvalidSdoName") - void getIedSources_whenInvalidSdoName_should_return_NoSource(final SCL scd, final LDEPFSettingData setting) { - // Given - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - TCompasBay compasBay = getCompasBayUUID(new SclRootAdapter(scd), "IED_NAME1"); - //When - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, setting); - // Then - assertThat(iedSources).isEmpty(); - SclTestMarshaller.assertIsMarshallable(scd); - } - - @ParameterizedTest - @MethodSource("provideInvalidDaName") - void getIedSources_whenInvalidDaName_should_return_NoSource(final SCL scd, final LDEPFSettingData setting) { - // Given - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - TCompasBay compasBay = getCompasBayUUID(new SclRootAdapter(scd), "IED_NAME1"); - //When - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, setting); - // Then - assertThat(iedSources).isEmpty(); - SclTestMarshaller.assertIsMarshallable(scd); - } - - @ParameterizedTest - @MethodSource("provideInvalidBdaName") - void getIedSources_whenInvalidBdaName_should_return_NoSource(final SCL scd, final LDEPFSettingData setting) { - // Given - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - TCompasBay compasBay = getCompasBayUUID(new SclRootAdapter(scd), "IED_NAME1"); - //When - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, setting); - // Then - assertThat(iedSources).isEmpty(); - SclTestMarshaller.assertIsMarshallable(scd); - } - - @ParameterizedTest - @MethodSource("provideInvalidSbdaName") - void getIedSources_whenInvalidSbdaName_should_return_NoSource(final SCL scd, final LDEPFSettingData setting) { - // Given - SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - TCompasBay compasBay = getCompasBayUUID(new SclRootAdapter(scd), "IED_NAME1"); - //When - List iedSources = settingLDEPFCsvHelper.getIedSources(sclRootAdapter, compasBay, setting); - // Then - assertThat(iedSources).isEmpty(); - SclTestMarshaller.assertIsMarshallable(scd); - } - - static Stream provideInternalAndExternalLDEPFSetting() { - LDEPFSettingData internalSetting = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_INTERNAL) - .channelDigitalNum(null).channelAnalogNum(1) - .iedType("SAMU").iedRedundancy("A").iedInstance(BigInteger.valueOf(1)) - .ldInst("LDTM1").lnClass("TVTR").lnInst("11").lnPrefix("U01A") - .doName("VolSv").doInst("0").daName("instMag").bdaName("i").build(); - LDEPFSettingData externalSetting = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_EXTERNAL) - .channelDigitalNum(null).channelAnalogNum(10) - .iedType("SAMU").iedRedundancy("A").iedInstance(BigInteger.valueOf(1)) - .ldInst("LDPHAS1").lnClass("MMXU").lnInst("101").lnPrefix("") - .doName("PhV").doInst("0").sdoName("phsB").daName("cVal").bdaName("mag").sbdaName("f") - .build(); - return Stream.of( - Arguments.of(Named.of("internal setting", - internalSetting), Named.of("identical same bay validation", true)), - Arguments.of(Named.of("external setting", - externalSetting), Named.of("identical same bay validation", false)) - ); - } - - static Stream provideInvalidDoName() { - SCL validScd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateValid.xml"); - SCL scdWithInvalidDoName = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidDoName.xml"); - LDEPFSettingData.LDEPFSettingDataBuilder settingBuilder = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_EXTERNAL) - .channelDigitalNum(null).channelAnalogNum(10) - .iedType("SAMU").iedRedundancy("A").iedInstance(BigInteger.valueOf(1)).ldInst("LDPHAS1").lnClass("MMXU").lnInst("101").lnPrefix("") - //required attributes to verify DataTypeTemplate (DoType and DaType objects) linked to IedSource for ExtRef - .doName("PhV").doInst("0").sdoName("phsB").daName("cVal").bdaName("mag").sbdaName("f"); - LDEPFSettingData validAnalogSetting = settingBuilder.build(); - LDEPFSettingData analogSettingWithInvalidDoName = settingBuilder.doName("WrongDoName").build(); - return Stream.of( - Arguments.of(Named.of("scd with invalid Do Name in dataTypeTemplate", scdWithInvalidDoName), - Named.of("valid setting", validAnalogSetting)), - Arguments.of(Named.of("valid scd", validScd), - Named.of("setting with invalid Do Name", analogSettingWithInvalidDoName)) - ); - } - - - static Stream provideInvalidSdoName() { - SCL validScd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateValid.xml"); - SCL scdWithInvalidSdoName = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidSdoName.xml"); - LDEPFSettingData.LDEPFSettingDataBuilder settingBuilder = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_EXTERNAL) - .channelDigitalNum(null).channelAnalogNum(10) - .iedType("SAMU").iedRedundancy("A").iedInstance(BigInteger.valueOf(1)).ldInst("LDPHAS1").lnClass("MMXU").lnInst("101").lnPrefix("") - //required attributes to verify DataTypeTemplate (DoType and DaType objects) linked to IedSource for ExtRef - .doName("PhV").doInst("0").sdoName("phsB").daName("cVal").bdaName("mag").sbdaName("f"); - LDEPFSettingData validAnalogSetting = settingBuilder.build(); - LDEPFSettingData analogSettingWithInvalidSdoName = settingBuilder.sdoName("wrongSdoName").build(); - return Stream.of( - Arguments.of(Named.of("scd with invalid Sdo Name in dataTypeTemplate", scdWithInvalidSdoName), - Named.of("valid setting", validAnalogSetting)), - Arguments.of(Named.of("valid scd", validScd), - Named.of("setting with invalid Sdo Name", analogSettingWithInvalidSdoName)) - ); - } - - static Stream provideInvalidDaName() { - SCL validScd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateValid.xml"); - SCL scdWithInvalidDaName = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidDaName.xml"); - LDEPFSettingData.LDEPFSettingDataBuilder settingBuilder = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_EXTERNAL) - .channelDigitalNum(null).channelAnalogNum(10) - .iedType("SAMU").iedRedundancy("A").iedInstance(BigInteger.valueOf(1)).ldInst("LDPHAS1").lnClass("MMXU").lnInst("101").lnPrefix("") - //required attributes to verify DataTypeTemplate (DoType and DaType objects) linked to IedSource for ExtRef - .doName("PhV").doInst("0").sdoName("phsB").daName("cVal").bdaName("mag").sbdaName("f"); - LDEPFSettingData validAnalogSetting = settingBuilder.build(); - LDEPFSettingData analogSettingWithInvalidDaName = settingBuilder.daName("wrongDaName").build(); - return Stream.of( - Arguments.of(Named.of("scd with invalid da Name in dataTypeTemplate", scdWithInvalidDaName), - Named.of("valid setting", validAnalogSetting)), - Arguments.of(Named.of("valid scd", validScd), - Named.of("setting with invalid da Name", analogSettingWithInvalidDaName)) - ); - } - - static Stream provideInvalidBdaName() { - SCL validScd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateValid.xml"); - SCL scdWithInvalidBdaName = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidBdaName.xml"); - LDEPFSettingData.LDEPFSettingDataBuilder settingBuilder = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_EXTERNAL) - .channelDigitalNum(null).channelAnalogNum(10) - .iedType("SAMU").iedRedundancy("A").iedInstance(BigInteger.valueOf(1)).ldInst("LDPHAS1").lnClass("MMXU").lnInst("101").lnPrefix("") - //required attributes to verify DataTypeTemplate (DoType and DaType objects) linked to IedSource for ExtRef - .doName("PhV").doInst("0").sdoName("phsB").daName("cVal").bdaName("mag").sbdaName("f"); - LDEPFSettingData validAnalogSetting = settingBuilder.build(); - LDEPFSettingData analogSettingWithInvalidBdaName = settingBuilder.bdaName("wrongBdaName").build(); - return Stream.of( - Arguments.of(Named.of("scd with invalid bda Name in dataTypeTemplate", scdWithInvalidBdaName), - Named.of("valid setting", validAnalogSetting)), - Arguments.of(Named.of("valid scd", validScd), - Named.of("setting with invalid bda Name", analogSettingWithInvalidBdaName)) - ); - } - - static Stream provideInvalidSbdaName() { - SCL validScd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateValid.xml"); - SCL scdWithInvalidSBdaName = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidSBdaName.xml"); - LDEPFSettingData.LDEPFSettingDataBuilder settingBuilder = LDEPFSettingData.builder() - .bayScope(TCompasFlowKind.BAY_EXTERNAL) - .channelDigitalNum(null).channelAnalogNum(10) - .iedType("SAMU").iedRedundancy("A").iedInstance(BigInteger.valueOf(1)).ldInst("LDPHAS1").lnClass("MMXU").lnInst("101").lnPrefix("") - //required attributes to verify DataTypeTemplate (DoType and DaType objects) linked to IedSource for ExtRef - .doName("PhV").doInst("0").sdoName("phsB").daName("cVal").bdaName("mag").sbdaName("f"); - LDEPFSettingData validAnalogSetting = settingBuilder.build(); - LDEPFSettingData analogSettingWithInvalidSBdaName = settingBuilder.sbdaName("wrongSbdaName").build(); - return Stream.of( - Arguments.of(Named.of("scd with invalid sbda Name in dataTypeTemplate", scdWithInvalidSBdaName), - Named.of("valid setting", validAnalogSetting)), - Arguments.of(Named.of("valid scd", validScd), - Named.of("setting with invalid sbda Name", analogSettingWithInvalidSBdaName)) - ); - } - - private TCompasBay getCompasBayUUID(SclRootAdapter sclRootAdapter, String iedName) { - return sclRootAdapter.getIEDAdapterByName(iedName).getPrivateCompasBay().get(); - } - private TCompasBay setCompasBayUUID(SclRootAdapter sclRootAdapter, String iedName, String uuid) { - TCompasBay compasBay = sclRootAdapter.getIEDAdapterByName(iedName).getPrivateCompasBay().get(); - compasBay.setUUID(uuid); - return compasBay; - } - - -} \ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_External_iedSources_in_same_bay.xml b/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_External_iedSources_in_same_bay.xml deleted file mode 100644 index 4b95cc2df..000000000 --- a/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_External_iedSources_in_same_bay.xml +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - - SCD - -
    - - - - - - - - - - - - - - - - - - on - - - - - - - - - - - - on - - - - - - - - - off - - - - - - - - - off - - - - - - - - - - - - - - - - - - - - - - - - on - - - - - - - - - - - - on - - - - - - - - - - - - - - - - - - - - - - - - on - - - - - - - - - - - - on - - - - - - - - - - - - - - - - - - - - - - - - - - - on - off - blocked - test - test/blocked - - - \ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidBdaName.xml b/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidBdaName.xml deleted file mode 100644 index 6399960b7..000000000 --- a/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidBdaName.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - SCD - -
    - - - - - - - - - - - - - - - - - - on - - - - - - - - - - - - - on - - - - - - - - - - - - - - - - - - - - - - - - on - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - on - off - blocked - test - test/blocked - - - \ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidDaName.xml b/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidDaName.xml deleted file mode 100644 index dc4625fb2..000000000 --- a/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidDaName.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - SCD - -
    - - - - - - - - - - - - - - - - - - on - - - - - - - - - - - - - on - - - - - - - - - - - - - - - - - - - - - - - - on - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - on - off - blocked - test - test/blocked - - - \ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidDoName.xml b/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidDoName.xml deleted file mode 100644 index 1f779ef97..000000000 --- a/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidDoName.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - SCD - -
    - - - - - - - - - - - - - - - - - - on - - - - - - - - - - - - - on - - - - - - - - - - - - - - - - - - - - - - - - on - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - on - off - blocked - test - test/blocked - - - \ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidSBdaName.xml b/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidSBdaName.xml deleted file mode 100644 index f2d4d0642..000000000 --- a/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidSBdaName.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - SCD - -
    - - - - - - - - - - - - - - - - - - on - - - - - - - - - - - - - on - - - - - - - - - - - - - - - - - - - - - - - - on - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - on - off - blocked - test - test/blocked - - - \ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidSdoName.xml b/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidSdoName.xml deleted file mode 100644 index 1f779ef97..000000000 --- a/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_dataTypeTemplateWithInvalidSdoName.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - SCD - -
    - - - - - - - - - - - - - - - - - - on - - - - - - - - - - - - - on - - - - - - - - - - - - - - - - - - - - - - - - on - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - on - off - blocked - test - test/blocked - - - \ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_extref_with_BCU_BPU.xml b/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_extref_with_IedType_BCU.xml similarity index 58% rename from sct-commons/src/test/resources/scd-ldepf/scd_ldepf_extref_with_BCU_BPU.xml rename to sct-commons/src/test/resources/scd-ldepf/scd_ldepf_extref_with_IedType_BCU.xml index b66648010..63a3ce64d 100644 --- a/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_extref_with_BCU_BPU.xml +++ b/sct-commons/src/test/resources/scd-ldepf/scd_ldepf_extref_with_IedType_BCU.xml @@ -132,116 +132,6 @@ - - - - - - - - - - - - - - - on - - - - - - - - - - - - - - - - - - - - - - - dU_old_val - - - - - - setVal_old_val - - - - - - off - - - - - - setSrcRef_old_val - - - - - - - - - dU_old_val - - - - - - setVal_old_val - - - - - - off - - - - - - setSrcRef_old_val - - - - - - - - - - on - - - - - - - - - - - - - - - diff --git a/sct-coverage/pom.xml b/sct-coverage/pom.xml index 66ac9ef72..95f98614e 100644 --- a/sct-coverage/pom.xml +++ b/sct-coverage/pom.xml @@ -29,11 +29,6 @@ sct-commons ${project.version} - - org.lfenergy.compas - sct-data - ${project.version} - org.lfenergy.compas sct-app diff --git a/sct-data/pom.xml b/sct-data/pom.xml deleted file mode 100644 index 27a1fbcf7..000000000 --- a/sct-data/pom.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - 4.0.0 - - - org.lfenergy.compas - compas-sct - local-SNAPSHOT - - - sct-data - local-SNAPSHOT - SCT-DATA - - - ${basedir}/${aggregate.report.dir} - true - - - - - org.projectlombok - lombok - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.assertj - assertj-core - test - - - - - - org.apache.maven.plugins - maven-source-plugin - - - - diff --git a/sct-data/src/main/java/org/lfenergy/compas/sct/data/model/IScd.java b/sct-data/src/main/java/org/lfenergy/compas/sct/data/model/IScd.java deleted file mode 100644 index 6d68c4b56..000000000 --- a/sct-data/src/main/java/org/lfenergy/compas/sct/data/model/IScd.java +++ /dev/null @@ -1,14 +0,0 @@ - -// SPDX-FileCopyrightText: 2021 RTE FRANCE -// -// SPDX-License-Identifier: Apache-2.0 - -package org.lfenergy.compas.sct.data.model; - -public interface IScd { - ID getId(); - byte[] getRawXml(); - ID getHeaderId(); - String getHeaderRevision(); - String getHeaderVersion(); -} diff --git a/sct-data/src/main/java/org/lfenergy/compas/sct/data/repository/CompasDataAccessException.java b/sct-data/src/main/java/org/lfenergy/compas/sct/data/repository/CompasDataAccessException.java deleted file mode 100644 index ab5f396db..000000000 --- a/sct-data/src/main/java/org/lfenergy/compas/sct/data/repository/CompasDataAccessException.java +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-FileCopyrightText: 2021 RTE FRANCE -// -// SPDX-License-Identifier: Apache-2.0 - -package org.lfenergy.compas.sct.data.repository; - -public class CompasDataAccessException extends RuntimeException { - - public CompasDataAccessException(String message, Throwable cause) { - super(message, cause); - } - - public CompasDataAccessException(String message) { - super(message); - } -} diff --git a/sct-data/src/main/java/org/lfenergy/compas/sct/data/repository/IScdCrudRepository.java b/sct-data/src/main/java/org/lfenergy/compas/sct/data/repository/IScdCrudRepository.java deleted file mode 100644 index fd45cd614..000000000 --- a/sct-data/src/main/java/org/lfenergy/compas/sct/data/repository/IScdCrudRepository.java +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-FileCopyrightText: 2021 RTE FRANCE -// -// SPDX-License-Identifier: Apache-2.0 - -package org.lfenergy.compas.sct.data.repository; - - -import org.lfenergy.compas.sct.data.model.IScd; - -import java.util.Optional; - -public interface IScdCrudRepository { - T save(T s) throws CompasDataAccessException; - T update(T s) throws CompasDataAccessException; - Optional findById(ID id); - boolean existsById(ID id) ; - boolean existsByHeaderId(ID id) ; - long count() ; - void deleteById(ID id) throws CompasDataAccessException; -} diff --git a/sct-data/src/test/java/org/lfenergy/compas/sct/data/repository/CompasDataAccessExceptionTest.java b/sct-data/src/test/java/org/lfenergy/compas/sct/data/repository/CompasDataAccessExceptionTest.java deleted file mode 100644 index 853e7e973..000000000 --- a/sct-data/src/test/java/org/lfenergy/compas/sct/data/repository/CompasDataAccessExceptionTest.java +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-FileCopyrightText: 2021 RTE FRANCE -// -// SPDX-License-Identifier: Apache-2.0 - -package org.lfenergy.compas.sct.data.repository; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class CompasDataAccessExceptionTest { - - @Test - void constructor_whenCalled_shouldFillValues(){ - // When - CompasDataAccessException compasDataAccessException = new CompasDataAccessException("msg",new RuntimeException()); - // Then - assertThat(compasDataAccessException.getLocalizedMessage()).isEqualTo("msg"); - assertThat(compasDataAccessException.getCause()).isNotNull(); - assertThat(compasDataAccessException.getCause().getClass()).isEqualTo(RuntimeException.class); - } - -} \ No newline at end of file